fix(rpc): fix the implementation of get_block_proof
for light client
#4585
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The implementation of
get_block_proof
has the following issue that caused it to have O(n) complexity sometimes:In the above example, when we try to prove block 0, the current implementation, when trying to get the sibling of node 7, will do a useless traversal of a full binary tree with 4 leaves, whereas it does not need to recurse when it is known that the position is already outside of the number of leaves we have. More specifically, getting the left child (call to
get_merkle_tree_node
) should almost always be O(1) except when we are close to the right most leaf of the tree. For exampleif we have 11 leaves in the above example (only the rightmost part drawn), then we must get the parent of 8 and 9, and 10, respectively, to prove 0. This is because the parent of 10 will be different once 11 is inserted and the shape of the tree also changes slightly. Therefore, when we are at the parent of 10, we need to recursive in both directions and cannot just go to the left only. This condition is captured by a comparison between
index * counter
andtree_size
.Test plan
test_block_merkle_proof
still works and manually check that the hashmap constructed when we calltest_block_merkle_proof_with_len(10000)
is roughlylog2(10000)^2