pub struct Tree { /* private fields */ }
Expand description
A sparse merkle tree witnessing up to 65,536 epochs of up to 65,536 blocks of up to 65,536
[Commitment
]s.
Implementations§
Source§impl Tree
impl Tree
Sourcepub fn root(&self) -> Root
pub fn root(&self) -> Root
Get the root hash of this Tree
.
Internal hashing is performed lazily to prevent unnecessary intermediary hashes from being computed, so the first hash returned after a long sequence of insertions may take more time than subsequent calls.
Computed hashes are cached so that subsequent calls without further modification are very fast.
Sourcepub fn insert(
&mut self,
witness: Witness,
commitment: StateCommitment,
) -> Result<Position, InsertError>
pub fn insert( &mut self, witness: Witness, commitment: StateCommitment, ) -> Result<Position, InsertError>
Add a new [Commitment
] to the most recent block of the most recent epoch of this Tree
.
If successful, returns the Position
at which the commitment was inserted.
§Errors
Returns InsertError
if any of:
- the
Tree
is full, - the current epoch is full, or
- the current block is full.
Sourcepub fn witness(&self, commitment: StateCommitment) -> Option<Proof>
pub fn witness(&self, commitment: StateCommitment) -> Option<Proof>
Get a Proof
of inclusion for the commitment at this index in the tree.
If the index is not witnessed in this tree, return None
.
Sourcepub fn forget(&mut self, commitment: StateCommitment) -> bool
pub fn forget(&mut self, commitment: StateCommitment) -> bool
Forget about the witness for the given [Commitment
].
Returns true
if the commitment was previously witnessed (and now is forgotten), and false
if
it was not witnessed.
Sourcepub fn position_of(&self, commitment: StateCommitment) -> Option<Position>
pub fn position_of(&self, commitment: StateCommitment) -> Option<Position>
Get the position in this Tree
of the given [Commitment
], if it is currently witnessed.
Sourcepub fn insert_block(
&mut self,
block: impl Into<Finalized>,
) -> Result<Root, InsertBlockError>
pub fn insert_block( &mut self, block: impl Into<Finalized>, ) -> Result<Root, InsertBlockError>
Add a new block all at once to the most recently inserted epoch of this Tree
, returning
the block root of the finalized block.
This can be used for two purposes:
- to insert a
block::Root
into the tree as a stand-in for an entire un-witnessed block, or - to insert a
block::Builder
into the tree that was constructed separately.
The latter block::Builder
API only accelerates tree construction when used in parallel,
but the former block::Root
insertion can be used to accelerate the construction of a
tree even in a single thread, because if the root is already known, only one set of hashes
need be performed, rather than performing hashing for each commitment in the block.
This function can be called on anything that implements Into<block::Finalized>
, in
particular:
block::Root
(treated as a finalized block with no witnessed commitments).block::Builder
(the block is finalized as it is inserted), and of courseblock::Finalized
.
§Errors
Returns InsertBlockError
containing the inserted block without adding it to the Tree
if the Tree
is full or the current epoch is full.
Sourcepub fn end_block(&mut self) -> Result<Root, InsertBlockError>
pub fn end_block(&mut self) -> Result<Root, InsertBlockError>
Explicitly mark the end of the current block in this tree, advancing the position to the next block, and returning the root of the block which was just finalized.
Sourcepub fn current_block_root(&self) -> Root
pub fn current_block_root(&self) -> Root
Get the root hash of the most recent block in the most recent epoch of this Tree
.
Sourcepub fn insert_epoch(
&mut self,
epoch: impl Into<Finalized>,
) -> Result<Root, InsertEpochError>
pub fn insert_epoch( &mut self, epoch: impl Into<Finalized>, ) -> Result<Root, InsertEpochError>
Add a new epoch all at once to this Tree
, returning the root of the finalized epoch
which was inserted.
This can be used for two purposes:
- to insert an
epoch::Root
into the tree as a stand-in for an entire un-witnessed block, or - to insert an
epoch::Builder
into the tree that was constructed separately.
The latter epoch::Builder
API only accelerates tree construction when used in parallel,
but the former epoch::Root
insertion can be used to accelerate the construction of a
tree even in a single thread, because if the root is already known, only one set of hashes
need be performed, rather than performing hashing for each commitment in the epoch.
This function can be called on anything that implements Into<epoch::Finalized>
, in
particular:
epoch::Root
(treated as a finalized epoch with no witnessed commitments).epoch::Builder
(the epoch is finalized as it is inserted), and of courseepoch::Finalized
.
§Errors
Returns InsertEpochError
containing the epoch without adding it to the Tree
if the
Tree
is full.
Sourcepub fn end_epoch(&mut self) -> Result<Root, InsertEpochError>
pub fn end_epoch(&mut self) -> Result<Root, InsertEpochError>
Explicitly mark the end of the current epoch in this tree, advancing the position to the next epoch, and returning the root of the epoch which was just finalized.
Sourcepub fn current_epoch_root(&self) -> Root
pub fn current_epoch_root(&self) -> Root
Get the root hash of the most recent epoch in this Tree
.
Sourcepub fn position(&self) -> Option<Position>
pub fn position(&self) -> Option<Position>
The position in this Tree
at which the next [Commitment
] would be inserted.
If the Tree
is full, returns None
.
The maximum capacity of a Tree
is 281,474,976,710,656 = 65,536 epochs of 65,536
blocks of 65,536 [Commitment
]s.
Note that forget
ting a commitment does not decrease this; it only
decreases the witnessed_count
.
Sourcepub fn forgotten(&self) -> Forgotten
pub fn forgotten(&self) -> Forgotten
The count of how many commitments have been forgotten explicitly using
forget
, or implicitly by being overwritten by a subsequent insertion of
the same commitment (this case is rare in practice).
This does not include commitments that were inserted using Witness::Forget
, only those
forgotten subsequent to their insertion.
Sourcepub fn witnessed_count(&self) -> usize
pub fn witnessed_count(&self) -> usize
Sourcepub fn commitments(
&self,
) -> impl Iterator<Item = (Position, StateCommitment)> + Send + Sync + '_
pub fn commitments( &self, ) -> impl Iterator<Item = (Position, StateCommitment)> + Send + Sync + '_
Get an iterator over all commitments currently witnessed in the tree, ordered by position.
Unlike commitments_unordered
, this guarantees that
commitments will be returned in order, but it may be slower by a constant factor.
Sourcepub fn commitments_unordered(
&self,
) -> impl Iterator<Item = (StateCommitment, Position)> + Send + Sync + '_
pub fn commitments_unordered( &self, ) -> impl Iterator<Item = (StateCommitment, Position)> + Send + Sync + '_
Get an iterator over all commitments currently witnessed in the tree.
Unlike commitments
, this does not guarantee that commitments will
be returned in order, but it may be faster by a constant factor.
Sourcepub fn structure(&self) -> Node<'_>
pub fn structure(&self) -> Node<'_>
Get a dynamic representation of the internal structure of the tree, which can be traversed and inspected arbitrarily.
Sourcepub fn from_reader<R: Read>(reader: &mut R) -> Result<Tree, R::Error>
pub fn from_reader<R: Read>(reader: &mut R) -> Result<Tree, R::Error>
Deserialize a tree from a storage::Read
of its contents, without checking for internal
consistency.
This can be more convenient than Tree::load
, since it is able to internally query the
storage for the last position and forgotten count.
⚠️ WARNING: Do not deserialize trees you did not serialize yourself, or risk violating internal invariants.
Sourcepub fn to_writer<W: Write>(&self, writer: &mut W) -> Result<(), W::Error>
pub fn to_writer<W: Write>(&self, writer: &mut W) -> Result<(), W::Error>
Serialize the tree incrementally from the last stored Position
and Forgotten
specified, into a storage::Write
, performing only the operations necessary to serialize
the changes to the tree.
This can be more convenient than using Tree::updates
, because it is able to internally
query the storage for the last position and forgotten count, and drive the storage
operations itself.
Sourcepub async fn from_async_reader<R: AsyncRead>(
reader: &mut R,
) -> Result<Tree, R::Error>
pub async fn from_async_reader<R: AsyncRead>( reader: &mut R, ) -> Result<Tree, R::Error>
Deserialize a tree from a storage::AsyncRead
of its contents, without checking for
internal consistency.
This can be more convenient than Tree::load
, since it is able to internally query the
storage for the last position and forgotten count.
⚠️ WARNING: Do not deserialize trees you did not serialize yourself, or risk violating internal invariants.
Sourcepub async fn to_async_writer<W: AsyncWrite>(
&self,
writer: &mut W,
) -> Result<(), W::Error>
pub async fn to_async_writer<W: AsyncWrite>( &self, writer: &mut W, ) -> Result<(), W::Error>
Serialize the tree incrementally from the last stored Position
and Forgotten
specified, into a storage::AsyncWrite
, performing only the operations necessary to
serialize the changes to the tree.
This can be more convenient than using Tree::updates
, because it is able to internally
query the storage for the last position and forgotten count, and drive the storage
operations itself.
Sourcepub fn load(
last_position: impl Into<StoredPosition>,
last_forgotten: Forgotten,
) -> LoadCommitments
pub fn load( last_position: impl Into<StoredPosition>, last_forgotten: Forgotten, ) -> LoadCommitments
Deserialize a tree using externally driven iteration, without checking for internal consistency.
Reconstructing a Tree
using this method requires stepping through a series of states, as
follows:
Tree::load
returns an objectLoadCommitments
which can be used toinsert
positioned commitments.- When all commitments have been inserted, call
.load_hashes()
to get an objectLoadHashes
. LoadHashes
can be used toinsert
positioned, heighted hashes.- Finally, call
.finish()
on theLoadHashes
to get theTree
.
⚠️ WARNING: Do not deserialize trees you did not serialize yourself, or risk violating internal invariants. You must insert all the commitments and hashes corresponding to the stored tree, or the reconstructed tree will not match what was serialized, and further, it may have internal inconsistencies that will mean that the proofs it produces will not verify.
ℹ️ NOTE: You may prefer to use from_reader
or
from_async_reader
, which drive the iteration over the
underlying storage internally rather than requiring the caller to drive the iteration.
Tree::load
is predominanly useful in circumstances when this inversion of control does
not make sense.
Sourcepub fn updates(
&self,
last_position: impl Into<StoredPosition>,
last_forgotten: Forgotten,
) -> impl Iterator<Item = Update> + Send + Sync + '_
pub fn updates( &self, last_position: impl Into<StoredPosition>, last_forgotten: Forgotten, ) -> impl Iterator<Item = Update> + Send + Sync + '_
Serialize the tree incrementally from the last stored Position
and Forgotten
specified, into an iterator of storage::Update
s.
This returns only the operations necessary to serialize the changes to the tree, synchronizing the in-memory representation with what is stored.
The iterator of updates may be .collect()
ed into a
storage::Updates
, which is more compact in-memory than
.collect()
ing into a Vec<Update>
.
ℹ️ NOTE: You may prefer to use to_writer
or
to_async_writer
, which drive the operations on the underlying
storage internally rather than requiring the caller to drive iteration. Tree::updates
is predominantly useful in circumstances when this inversion of control does not make sense.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Tree
impl<'de> Deserialize<'de> for Tree
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Tree
Auto Trait Implementations§
impl Freeze for Tree
impl !RefUnwindSafe for Tree
impl Send for Tree
impl Sync for Tree
impl Unpin for Tree
impl !UnwindSafe for Tree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.