Improved fix for MMR dup detection

This commit is contained in:
Ignotus Peverell 2017-12-06 00:47:26 +00:00 committed by Simon B
parent cac6181c21
commit be094883de
2 changed files with 24 additions and 29 deletions
chain/src
core/src/core

View file

@ -261,29 +261,22 @@ impl<'a> Extension<'a> {
}
}
// checking any position after the MMR size is useless, catches rewind
// edge cases
let output_max_index = self.output_pmmr.unpruned_size();
let kernel_max_index = self.kernel_pmmr.unpruned_size();
for out in &b.outputs {
let commit = out.commitment();
if let Ok(pos) = self.commit_index.get_output_pos(&commit) {
if pos <= output_max_index {
// we need to check whether the commitment is in the current MMR view
// as well as the index doesn't support rewind and is non-authoritative
// (non-historical node will have a much smaller one)
// note that this doesn't show the commitment *never* existed, just
// that this is not an existing unspent commitment right now
if let Some(c) = self.output_pmmr.get(pos) {
let hashsum = HashSum::from_summable(
pos, &SumCommit{commit}, Some(out.switch_commit_hash));
// as we're processing a new fork, we may get a position on the old
// fork that exists but matches a different node, filtering that
// case out
if c.hash == hashsum.hash {
return Err(Error::DuplicateCommitment(out.commitment()));
}
// we need to check whether the commitment is in the current MMR view
// as well as the index doesn't support rewind and is non-authoritative
// (non-historical node will have a much smaller one)
// note that this doesn't show the commitment *never* existed, just
// that this is not an existing unspent commitment right now
if let Some(c) = self.output_pmmr.get(pos) {
let hashsum = HashSum::from_summable(
pos, &SumCommit{commit}, Some(out.switch_commit_hash));
// as we're processing a new fork, we may get a position on the old
// fork that exists but matches a different node, filtering that
// case out
if c.hash == hashsum.hash {
return Err(Error::DuplicateCommitment(out.commitment()));
}
}
}
@ -307,14 +300,12 @@ impl<'a> Extension<'a> {
for kernel in &b.kernels {
if let Ok(pos) = self.commit_index.get_kernel_pos(&kernel.excess) {
if pos <= kernel_max_index {
// same as outputs
if let Some(k) = self.kernel_pmmr.get(pos) {
let hashsum = HashSum::from_summable(
pos, &NoSum(kernel), None::<RangeProof>);
if k.hash == hashsum.hash {
return Err(Error::DuplicateKernel(kernel.excess.clone()));
}
// same as outputs
if let Some(k) = self.kernel_pmmr.get(pos) {
let hashsum = HashSum::from_summable(
pos, &NoSum(kernel), None::<RangeProof>);
if k.hash == hashsum.hash {
return Err(Error::DuplicateKernel(kernel.excess.clone()));
}
}
}

View file

@ -347,7 +347,11 @@ where
/// Helper function to get the HashSum of a node at a given position from
/// the backend.
pub fn get(&self, position: u64) -> Option<HashSum<T>> {
self.backend.get(position)
if position > self.last_pos {
None
} else {
self.backend.get(position)
}
}
/// Helper function to get the last N nodes inserted, i.e. the last