refactor!(stump): Move updated data to its own function - #81
refactor!(stump): Move updated data to its own function#81Davidson-Souza wants to merge 3 commits into
Conversation
8eb9f98 to
bfd09ed
Compare
38e545e to
427a309
Compare
|
@Davidson-Souza do you have a Floresta branch using this PR? |
No, waiting on Jose's pr with swift sync stuff |
|
It's time 🎅🏻 |
|
nit: on the commit description: the |
78d99d9 to
d86c319
Compare
| proof: &Proof<Hash>, | ||
| ) -> Result<(Self, UpdateData<Hash>), StumpError> { | ||
| let (intermediate, mut computed_roots) = self.remove(del_hashes, proof)?; | ||
| ) -> Result<Self, StumpError> { |
There was a problem hiding this comment.
Why no longer return UpdateData, a rebase issue? What is it for btw, I wonder
There was a problem hiding this comment.
Before this change, modify would return the data needed to update a proof for the new block. This requires additional internal computation and extra allocations. During IBD we may never use this, since proof update is only meant for updating a few blocks worth of changes. Now there's a method specific to pull the modify_data, and modify itself will only return a new Stump.
|
Needs rebase |
d86c319 to
df4572f
Compare
|
Rebased |
|
Unable to offer conceptual review but code LGTM |
| let stump = s.modify(&new_utxos, &[utxos[0]], &p1).unwrap(); | ||
|
|
||
| // and the proof | ||
| let update_data = s.get_update_data(&utxos, &[], &Proof::default()).unwrap(); |
There was a problem hiding this comment.
Question: why aren't we passing here the deleted utxos[0] and the proof p1? Maybe a comment about it, it's confusing.
There was a problem hiding this comment.
Everywhere else you pass the delete hashes and proof in get_update_data, so it seems wrong
| /// in the path to the root. This function returns the calculated roots and the hashes | ||
| /// that were calculated in the process. |
There was a problem hiding this comment.
This function no longer returns those hashes no? (forest nodes)
| /// proofs, it doesn't compute the roots after the deletion, only the roots that are | ||
| /// needed for verification (i.e. the current accumulator). | ||
| /// needed for verification (i.e. the current accumulator). `calculate_hashes_delete` also | ||
| /// won't return the hashes that were calculated, we won't need them for updating the |
There was a problem hiding this comment.
Nit, better?
| /// won't return the hashes that were calculated, we won't need them for updating the | |
| /// doesn't return the nodes that were calculated, as we won't need them for updating the |
| "29590a14c1b09384b94a2c0e94bf821ca75b62eacebc47893397ca88e3bbcbd7", | ||
| "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", | ||
| "2b77298feac78ab51bc5079099a074c6d789bd350442f5079fcba2b3402694e5", | ||
| "726fdd3b432cc59e68487d126e70f0db74a236267f8daeae30b31839a4e7ebed", |
There was a problem hiding this comment.
Only a question, is there a different place where we could repurpose these constants to check the computed hashes?
There was a problem hiding this comment.
We use similar tests in several other places, I don't think removing this here would be any problem.
df4572f to
0f90d32
Compare
|
Applied docs suggestions by @JoseSK999 |
0f90d32 to
d2c3dbd
Compare
|
First 3 comments not addressed yet |
d2c3dbd to
41e1159
Compare
Shoot, sorry! Should be fixed now |
41e1159 to
b97558b
Compare
b97558b to
eed1584
Compare
|
Applied nits by @JoseSK999 |
| if let Some(pos) = computed_roots.iter().position(|(old, _new)| old == root) { | ||
| let (old_root, new_root) = computed_roots.remove(pos); | ||
| if old_root == *root { | ||
| new_roots.push(new_root); | ||
| continue; | ||
| } | ||
| } |
There was a problem hiding this comment.
The if clause is always true, we can do this (same code as in modify)
if let Some(pos) = computed_roots.iter().position(|(old, _new)| old == root) {
let (_, new_root) = computed_roots.remove(pos);
new_roots.push(new_root);
continue;
}| updated_subtree.insert((pos, to_add)); | ||
| pos = util::parent(pos, after_rows); | ||
|
|
||
| to_add = AccumulatorHash::parent_hash(&root, &to_add); |
There was a problem hiding this comment.
Shouldn't we use the match arm here to also account for empty hashes?
There was a problem hiding this comment.
This function shouldn't use implicit deletions as we need the proof hashes to update the proof anyway.
|
|
||
| new_roots.push(*root); | ||
| } | ||
| let (_, updated, destroyed) = Self::compute_update_data_add(new_roots, utxos, self.leaves); |
There was a problem hiding this comment.
Shouldn't we also do this here?
// If there are still roots to be added, it means that the proof is invalid
// as we should have consumed all the roots.
if !computed_roots.is_empty() {
return Err(StumpError::InvalidProof(ProofError::RootsMismatch));
}
let (_, updated, destroyed) = ...There was a problem hiding this comment.
get_update_data assumes you already validated that block, but I can add it out of caution.
| let stump = s.modify(&new_utxos, &[utxos[0]], &p1).unwrap(); | ||
|
|
||
| // and the proof | ||
| let update_data = s.get_update_data(&utxos, &[utxos[0]], &p1).unwrap(); |
There was a problem hiding this comment.
This was wrong
| let update_data = s.get_update_data(&utxos, &[utxos[0]], &p1).unwrap(); | |
| let update_data = s.get_update_data(&new_utxos, &[utxos[0]], &p1).unwrap(); |
|
|
||
| /// A type representing what's changed for addition. | ||
| /// | ||
| /// It returns the final roots destroyed hashes and all the new positions created during this add. |
There was a problem hiding this comment.
Nit: I think order is inaccurate and there's a double space
Before this change, `modify` would return the data needed to update a proof for the new block. This requires additional internal computation and extra allocations. During IBD we may never use this, since proof update is only meant for updating a few blocks worth of changes. Now there's a method specific to pull the modify_data, and `modify` itself will only return a new Stump. When refactoring the addition function, I've modified it a little to allow a smarter one with a very nice property: it can pretend that it added a node, but actually represent it as deleted. The goal here is to do a Swift Sync-style protocol where you don't need deletions. If a txout is already spent, you give an empty hash (BitcoinNodeHash::empty()). This will be exactly equivalent as giving this txo's hash and later on calling delete for with this txo's hash. However, it does this with only one call to modify and doesn't require proofs to achieve that. This is an API breaking change, as modify now only returns one parameter, otherwise the behavior stays unchanged.
eed1584 to
e1afeb7
Compare
|
@JoseSK999 done! |
Before this change,
modifywould return the data needed to update a proof for the new block. This requires additional internal computation and extra allocations. During IBD we may never use this, since proof update is only meant for updating a few blocks worth of changes. Now there's a method specific to pull the modify_data, andmodifyitself will only return a new Stump.When refactoring the addition function, I've modified it a little to allow a smarter one with a very nice property: it can pretend that it added a node, but actually represent it as deleted. The goal here is to do a Swift Sync-style protocol where you don't need deletions.
If a txout is already spent, you give an empty hash (BitcoinNodeHash::empty()). This will be exactly equivalent as giving this txo's hash and later on calling delete for with this txo's hash. However, it does this with only one call to modify and doesn't require proofs to achieve that.
This is an API breaking change, as modify now only returns one parameter, otherwise the behavior stays unchanged.