shardtree: Don't insert empty subtrees in `ShardTree::insert_tree`

`ShardTree::max_leaf_position` relies on the invariant that the last
shard in the subtrees vector is never created without a leaf then being
added to it. `LocatedTree::decompose_to_level` can return a trailing
empty subtree for some inputs, and given that it is always correct to
not insert an empty subtree into `self`, we maintain the invariant by
skipping empty subtrees.
This commit is contained in:
Jack Grigg 2023-07-24 18:14:24 +00:00
parent 1eda8b2e24
commit 4666e9e370
1 changed files with 9 additions and 0 deletions

View File

@ -587,6 +587,15 @@ impl<
) -> Result<Vec<IncompleteAt>, ShardTreeError<S::Error>> {
let mut all_incomplete = vec![];
for subtree in tree.decompose_to_level(Self::subtree_level()).into_iter() {
// `ShardTree::max_leaf_position` relies on the invariant that the last shard
// in the subtrees vector is never created without a leaf then being added to
// it. `LocatedTree::decompose_to_level` can return a trailing empty subtree
// for some inputs, and given that it is always correct to not insert an empty
// subtree into `self`, we maintain the invariant by skipping empty subtrees.
if subtree.root().is_empty() {
continue;
}
// `LocatedTree::decompose_to_level` will return the tree as-is if it is
// smaller than a shard, so we can't assume that the address of `subtree` is a
// valid shard address.