zcash / librustzcash

Rust-language assets for Zcash
Other
324 stars 242 forks source link

Error in note commitment tree maintenance at the bounds of the chain tip shard. #1398

Closed nuttycom closed 1 week ago

nuttycom commented 1 month ago

A Zashi user encountered the following error:

Error while sending funds: An error occurred in querying or updating a note commitment tree: Unable to compute root; missing values for nodes [...]

where the node in question corresponds to the last level-1 subtree of a shardtree shard.

What happens is this:

We insert the frontier at the start of the block range being inserted. This gives us a CHECKPOINT leaf. Then, we insert the subtree fragment covering the range for notes in the subsequent block, which crosses the shard boundary, and then prune checkpoints.

Because the frontier was inserted for a not-yet-scanned block, we don't actually know (at the application level) whether the sibling nodes to the frontier should be pruned; we need to scan the block corresponding to the frontier to determine this. However, in shardtree, we don't have any distinction between leaves that were inserted as part of a frontier and leaves that were inserted as part of a scan. And so, shardtree is completely willing to prune nodes when we remove the CHECKPOINT - nodes that are later discovered to be necessary ommers when we discover our wallet's note at the tip of the blindly-inserted frontier.

The solution is to make the distinction between "known prunable" and "not known to be prunable" in the Retention type, and use not-known-prunable retention when inserting frontiers.