Skip to content

Commit 06faa1f

Browse files
committed
Fix minimize_proof
1 parent 258084e commit 06faa1f

File tree

1 file changed

+36
-30
lines changed

1 file changed

+36
-30
lines changed

lib/src/trie/minimize_proof.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,41 +45,47 @@ pub fn minimize_proof<T: AsRef<[u8]>>(
4545
) -> Result<Vec<u8>, MinimizeProofError> {
4646
let mut builder = ProofBuilder::new();
4747

48-
let key_nibbles = bytes_to_nibbles(key.iter().copied()).collect::<Vec<_>>();
49-
50-
// Set the node value of the leaf.
51-
let ancestor = if let Some(ancestor_key) = decoded_proof
52-
.closest_ancestor_in_proof(trie_root_merkle_value, key_nibbles.iter().copied())
53-
.map_err(|_| MinimizeProofError::KeyNotFound)?
54-
{
55-
decoded_proof
56-
.proof_entry(trie_root_merkle_value, ancestor_key)
57-
.unwrap()
58-
} else {
59-
// If the key is completely out of the trie, we have to add the root node in the output.
60-
decoded_proof
61-
.trie_root_proof_entry(trie_root_merkle_value)
62-
.ok_or(MinimizeProofError::KeyNotFound)?
63-
};
64-
builder.set_node_value(
65-
&key_nibbles,
66-
ancestor.node_value,
67-
match ancestor.trie_node_info.storage_value {
68-
StorageValue::Known { value, .. } => Some(value),
69-
_ => None,
70-
},
71-
);
48+
let mut key_nibbles_if_first_iter =
49+
Some(bytes_to_nibbles(key.iter().copied()).collect::<Vec<_>>());
7250

7351
// Query a missing node and provide its value. Stop when the proof is complete.
7452
loop {
75-
let Some(missing) = builder.missing_node_values().next().map(|v| Vec::from(v)) else {
53+
let Some(missing) = builder
54+
.missing_node_values()
55+
.next()
56+
.map(|v| Vec::from(v))
57+
.or_else(|| key_nibbles_if_first_iter.take())
58+
else {
7659
break;
7760
};
78-
let value = decoded_proof
79-
.proof_entry(trie_root_merkle_value, missing.iter().copied())
80-
.ok_or(MinimizeProofError::IncompleteProof)?
81-
.node_value;
82-
builder.set_node_value(&missing, value, None);
61+
62+
if let Some(ancestor_key) = decoded_proof
63+
.closest_ancestor_in_proof(trie_root_merkle_value, missing.iter().copied())
64+
.map_err(|_| MinimizeProofError::KeyNotFound)?
65+
{
66+
let ancestor = decoded_proof
67+
.proof_entry(trie_root_merkle_value, ancestor_key)
68+
.unwrap();
69+
builder.set_node_value(
70+
&missing,
71+
ancestor.node_value,
72+
match ancestor.trie_node_info.storage_value {
73+
StorageValue::Known { value, .. } => Some(value),
74+
_ => None,
75+
},
76+
);
77+
} else {
78+
// Add the root node in the output.
79+
// This should only ever happen if the input key is completely outside of the trie.
80+
debug_assert!(itertools::equal(
81+
missing.iter().copied(),
82+
bytes_to_nibbles(key.iter().copied())
83+
));
84+
let root = decoded_proof
85+
.trie_root_proof_entry(trie_root_merkle_value)
86+
.ok_or(MinimizeProofError::KeyNotFound)?;
87+
builder.set_node_value(&missing, root.node_value, None);
88+
};
8389
}
8490

8591
Ok(builder.build_to_vec())

0 commit comments

Comments
 (0)