Commit Graph

118 Commits

Author SHA1 Message Date
Kris Nuttycombe cfc4fcbac8 Extract incrementalmerkletree::testing module to a separate `incrementalmerkletree-testing` crate. 2024-09-25 13:37:03 -06:00
Eric Tu 16eff253ad FnMut instead of Fn 2024-09-10 15:57:50 -04:00
Eric Tu eb3843e0cf for_each_checkpoint 2024-09-10 10:12:30 -04:00
Eric Tu 0e9d4d635a Add max_checkpoints getter 2024-09-06 12:14:28 -04:00
Kris Nuttycombe ef7fcde5fa Release shardtree version 0.4.0 2024-08-12 11:33:36 -06:00
Kris Nuttycombe 192cb3ffda shardtree: Remove `Node::Pruned`
In 7e48886fd3, `Node::Pruned` was
introduced in order to fix problems with `LocatedTree::max_position`
resulting from reinsertion of subtree information as children of
a previously pruned subtree represented by a `Node::Leaf` at its
root. This fix introduced a large amount of complexity that is
better resolved by fixing the `max_position` function in a different
way and generally minimizing its usage.
2024-06-27 16:30:57 -06:00
Kris Nuttycombe 88681ae335 shardtree: Reduce dependence upon `LocatedTree::max_position` 2024-06-27 16:30:57 -06:00
Kris Nuttycombe b38b9d5d62 shardtree: Minor cleanups & documentation improvements. 2024-06-27 16:30:52 -06:00
Kris Nuttycombe f5adcd5a2c shardtree: Fix pruning of annotated `Parent` nodes with `Nil` children.
The current behavior of `unite` incorrectly discards annotation data.
2024-06-27 14:39:48 -06:00
Jack Grigg 020a7d76d7 shardtree: Use `Tree` constructors instead of struct creation
This makes it easier for us to track where new tree nodes are created,
and how the node kinds are used within the `ShardTree` data model.
2024-06-26 14:08:25 +00:00
Kris Nuttycombe d40e178f8d shardtree: Do not unify pruned nodes with empty nodes. 2024-05-28 19:22:45 -06:00
Kris Nuttycombe 7e48886fd3 shardtree: Add `Pruned` node type
In circumstances where insertion into a subtree results in pruning, and
then a subsequent insertion within the same range contains leaves that
must be retained, it is necessary to be able to distinguish the maximum
position among notes that have been observed but later pruned. This
fixes a bug wherein an insertion into an already-pruned tree could cause
the maximum position reported for the subtree to regress.
2024-05-28 19:22:45 -06:00
Kris Nuttycombe ffc087424d shardtree: Discard `REFERENCE` retention in leaf overwrites.
Also, disallow value-conflicted overwrites at the leaf level.
2024-05-28 17:13:31 -06:00
Kris Nuttycombe e55ff2d7f2 incrementalmerkletree: add `Reference` retention type.
This new retention type is intended to be used when inserting frontiers
that should not automatically be pruned.

Also, improve documentation for the `Retention` type.
2024-05-28 17:10:38 -06:00
Kris Nuttycombe 57b6e8999f shardtree: `Nil` nodes cannot replace any other sort of node in the tree. 2024-05-28 15:54:18 -06:00
Kris Nuttycombe 811d384bd4 shardtree: Improve tracing 2024-05-28 15:50:07 -06:00
Kris Nuttycombe ac9ecaca12 shardtree: Add `InsertionError::MarkedRetentionInvalid` 2024-03-24 18:26:00 -06:00
Kris Nuttycombe fa147c89c6 shardtree: Add `ShardTree::store_mut` 2024-03-11 13:03:03 -06:00
Kris Nuttycombe 25cb18973e shardtree: Add `ShardTree::insert_frontier` 2024-03-11 13:02:34 -06:00
Kris Nuttycombe 214d76e40a shardtree: Add an accessor for a `ShardTree`'s underlying `ShardStore` 2024-03-09 17:12:19 -07:00
Kris Nuttycombe 39ce028701 Apply suggestions from code review
Co-authored-by: str4d <thestr4d@gmail.com>
2023-11-07 07:44:07 -07:00
Kris Nuttycombe b2c5cd9fc4 shardtree: Correct erroneous `ShardStore::get_checkpoint_at_depth` documentation 2023-11-07 07:44:07 -07:00
Kris Nuttycombe 8d301a14dd shardtree: Add `witness_at_checkpoint_id` methods.
It is useful to be able to refer to a specific checkpoint, rather than
just a checkpoint depth, when computing a witness.
2023-11-07 07:44:07 -07:00
Kris Nuttycombe 9359c8d1b8 shardtree: Add `root_at_checkpoint_id` methods.
It can be useful to refer to a specific checkpoint, rather than just a
checkpoint depth, for which one wishes to compute the root.
2023-11-07 07:44:05 -07:00
Jack Grigg 3f8999816f shardtree: Migrate to `bitflags 2` 2023-07-27 23:17:06 +00:00
Jack Grigg f5fd2a0a3e Add docs.rs feature flag labels to `incrementalmerkletree` and `shardtree` 2023-07-27 22:57:09 +00:00
Jack Grigg 60caaeb99e shardtree: Update docs with content from readme 2023-07-27 22:28:55 +00:00
Jack Grigg 5753ce005d shardtree: Remove unnecessary methods from the public API 2023-07-25 17:19:43 +00:00
Jack Grigg 06199d6f45 shardtree: Improve documentation 2023-07-25 17:19:38 +00:00
Jack Grigg 0a6964ad05 shardtree: Move `ShardStore`-related types into module 2023-07-25 15:54:44 +00:00
Jack Grigg fb894cdbb7 shardtree: Add `std::error::Error` bound to `ShardStore::Error` 2023-07-25 15:54:44 +00:00
Jack Grigg 1bd0a7c941 shardtree: Move error types into module 2023-07-25 15:54:44 +00:00
Jack Grigg 8d699c9667 shardtree: Pass checkpoints alongside tree to `ShardTree::insert_tree`
There are no `ShardTree` APIs that allow for checkpointing at arbitrary
positions, which makes sense as the relevant leaf may have been pruned.
For this API to be a viable substitute for `ShardTree::batch_insert`, it
therefore needs to support marking any checkpoints associated with the
inserted tree.
2023-07-25 13:50:27 +00:00
Jack Grigg 4666e9e370 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.
2023-07-24 18:14:24 +00:00
Jack Grigg 1eda8b2e24 shardtree: Derive correct shard root addrs in `ShardTree::insert_tree`
`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.
2023-07-24 18:13:05 +00:00
Jack Grigg 8a62290ffe shardtree: Add tests comparing `insert_tree` to `batch_insert` 2023-07-24 17:22:28 +00:00
Jack Grigg faabef3106 shardtree: Extract an `arb_leaves` strategy from `arb_shardtree` 2023-07-24 02:16:12 +00:00
Jack Grigg 5b4dce85ca shardtree: Switch from `Rc` to `Arc` to make trees `Send` 2023-07-17 21:02:33 +00:00
Jack Grigg 7ec75fdd91 shardtree: Clarify documentation for `ShardStore::remove_checkpoint`
`CachingShardStore` relies on this method being a no-op when the
checkpoint doesn't exist.
2023-07-17 20:56:53 +00:00
Jack Grigg 2715a24943 Add `CachingShardStore` for batching writes to a backend `ShardStore` 2023-07-14 19:26:32 +00:00
Jack Grigg d87a85786c shardtree: Move batch construction methods into a submodule 2023-07-10 17:39:10 +00:00
Jack Grigg 2d28ed6d19 shardtree: Move methods behind `legacy-api` feature flag into a submodule
This doesn't affect the public API, as `impl` blocks for a struct can be
anywhere within the crate.
2023-07-10 17:39:06 +00:00
Jack Grigg 52b8de33e5 shardtree: Extract helper function inside `LocatedPrunableTree::from_iter` 2023-07-06 14:58:52 +00:00
Jack Grigg 278e4d2320 shardtree: Fix `LocatedPrunableTree::from_iter`
The general logic in this function is:
- Build a stack that contains all of the complete subtrees contained
  within the iterator.
- Take nodes off the top of the stack, and combine them together with
  each other and empty nodes until the resulting right-hand subtree is
  larger than all remaining subtrees on the stack.
- Make a single pass over the stack from bottom to top, accumulating
  subtrees and adding empty nodes on the left until a single tree is
  obtained.

The bug was that the second step was not leaving the right-hand subtree
sufficiently large. The final single-pass step expects every subtree in
the stack to be no smaller than the accumulated tree up to that point,
and in particular the right-hand subtree must be the direct right child
of the final tree. Some specific sequences of leaves were leaving the
right-hand subtree in a state where it was the same size as the largest
individual subtree of the rest of the stack, but smaller than their
accumulated tree.

The solution is to pre-compute what the address of the final tree will
be, and then add empty nodes on the right to the right-hand subtree
until it is the direct right child.

Co-authored-by: Kris Nuttycombe <kris@nutty.land>
2023-07-06 13:02:40 +00:00
Jack Grigg bddf6684e3 shardtree: Turn `LocatedPrunableTree::from_iter` test failure into panic
The logic in `LocatedPrunableTree::from_iter` is violating an invariant
of the `unite` helper function. The new assertion prevents an invalid
tree state from being returned.
2023-07-06 13:01:08 +00:00
Jack Grigg b325399f0d shardtree: Add test exposing `LocatedPrunableTree::from_iter` bug 2023-07-06 12:57:16 +00:00
Jack Grigg b604c801a8 Add more TRACE-level logging to `shardtree` internals 2023-07-06 11:51:43 +00:00
Jack Grigg f254ebcf67 shardtree: Simplify `LocatedPrunableTree::insert_subtree` node logic
The previous logic had the non-obvious behaviour that if the inserted
subtree was a leaf, then the `.iter().all()` was not rejecting subtrees
with non-matching values, because `Node::annotation` returns `None` for
leaves. This didn't cause a bug, because this behaviour is actually
intentionally triggered by the previous `is_complete` branch of the
conditional (as leaves are by definition complete subtrees).

The simplified logic is more obvious, because `PrunableTree::node_value`
returns the value of leaves and the annotation of nodes (which are the
same type for `PrunableTree`). It does change how leaves are treated by
this branch of the conditional, so a test has been added to ensure that
the intended behaviour is preserved if the `is_complete` branch is
refactored in future.

Co-authored-by: Kris Nuttycombe <kris@nutty.land>
2023-07-05 23:59:56 +00:00
Jack Grigg 54e8ab759c shardtree: Compare leaves by value when merging, and merge their flags
Co-authored-by: Kris Nuttycombe <kris@nutty.land>
2023-07-05 21:45:56 +00:00
Jack Grigg 2ef96ba4ba shardtree: Add test exposing `PrunableTree::merge_checked` bug 2023-07-05 21:41:25 +00:00