Skip to main content

AppendOnlyTree

Struct AppendOnlyTree 

Source
pub struct AppendOnlyTree<L> { /* private fields */ }
Expand description

Append-only Merkle transparency log over any L: Serialize leaf.

Each Self::append serializes the leaf with postcard and pushes the resulting bytes into a ct_merkle::MemoryBackedTree<Sha256, _>. The original L is not stored; the tree retains the serialized bytes plus the internal Merkle nodes.

The empty tree’s root is RFC 6962’s deterministic zero-leaf root — SHA-256("") paired with num_leaves = 0. After n appends, Self::root returns the SHA-256 Merkle Tree Hash of the n leaves with num_leaves = n. Two trees built from the same Serialize sequence in the same order produce the same root.

§The leaf encoding is a FROZEN WIRE CONTRACT

Leaves are hashed via their postcard encoding, which is derived entirely from L’s shape: fields, field declaration order, and enum variant declaration order. Once leaves of L exist in a persisted or published tree, that shape must never change — reordering or adding fields, or reordering enum variants, silently alters the bytes of historical leaves, so every previously published root and proof stops verifying with no error and no version signal. Schema evolution requires a new versioned leaf type or an explicitly versioned envelope. When long-lived verifiability matters, prefer a leaf type that pins the payload as pre-encoded bytes (e.g. a struct holding Vec<u8>) so the hashed bytes are under explicit consumer control. See the leaf module docs for the full contract.

Implementations§

Source§

impl<L> AppendOnlyTree<L>

Source

pub fn new() -> Self

Builds a new empty tree.

The empty tree’s Self::root is the deterministic zero-leaf root (SHA-256("") with num_leaves = 0) defined by RFC 6962 and implemented by ct-merkle.

Source

pub fn len(&self) -> u64

Returns the number of leaves in the tree.

Source

pub fn is_empty(&self) -> bool

Returns true if no leaves have been appended.

Source

pub fn root(&self) -> RootHash

Returns the current root hash, capturing both the SHA-256 Merkle Tree Hash and the current leaf count.

Source

pub fn prove_inclusion(&self, leaf_index: u64) -> TrustResult<InclusionProof>

Builds an inclusion proof for the leaf at leaf_index.

§Errors

Returns TrustError::MerkleTree if leaf_index is greater than or equal to the current tree length, or if the index does not fit in a usize on this target. Both conditions are pre-checked so the underlying ct-merkle call (which would otherwise panic) is never made with an invalid argument.

Source

pub fn prove_consistency( &self, old_size: u64, new_size: u64, ) -> TrustResult<ConsistencyProof>

Builds a consistency proof showing that the tree of size old_size is a prefix of the current tree (which must be exactly new_size leaves).

§Errors

Returns TrustError::MerkleTree if new_size does not equal the current tree length, old_size is zero, old_size exceeds new_size, or the resulting num_additions does not fit in a usize. These checks ensure the underlying ct-merkle call (which would otherwise panic when num_additions >= self.len()) is never made with an invalid argument.

Source§

impl AppendOnlyTree<RawLeaf>

Source

pub fn append_raw(&mut self, leaf_bytes: &[u8]) -> u64

Appends raw bytes verbatim and returns the new tree size.

The bytes are hashed exactly as supplied — no postcard, no length prefix — so the RFC 6962 leaf hash is SHA-256(0x00 ‖ leaf_bytes) (see raw_leaf_hash). Infallible: there is no serialization step to fail.

Source

pub fn reconstruct_from_raw_leaves<I>(leaves: I) -> Self
where I: IntoIterator, I::Item: AsRef<[u8]>,

Rebuilds a raw-leaf tree from leaves in their original append order.

The reconstruction path for restart and prefix rebuilds, mirroring AppendOnlyTree::reconstruct_from_leaves for the raw encoding. Because it reuses Self::append_raw, the rebuilt tree reproduces the original root bit-for-bit.

Source§

impl<L: Serialize> AppendOnlyTree<L>

Source

pub fn append(&mut self, leaf: L) -> TrustResult<u64>

Appends leaf to the tree and returns the new tree size.

The leaf is serialized via postcard before being hashed into the tree. The first append returns 1, the next 2, and so on.

§Errors

Returns TrustError::MerkleTree if the leaf cannot be serialized. No other failure modes exist at this scale of tree (ct-merkle’s internal limits are well beyond practical use).

Source

pub fn reconstruct_from_leaves(leaves: Vec<L>) -> TrustResult<Self>

Rebuilds a tree from a sequence of leaves in their original append order.

This is the mechanism for reconstructing in-memory tree state from persistent storage on restart. Because reconstruction reuses Self::append, it goes through the same serialization path and therefore reproduces the original root hash bit-for-bit.

§Errors

Returns TrustError::MerkleTree if any leaf fails to serialize.

Trait Implementations§

Source§

impl<L> Debug for AppendOnlyTree<L>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<L> Default for AppendOnlyTree<L>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<L> Freeze for AppendOnlyTree<L>
where PhantomData<fn(L)>: Freeze,

§

impl<L> RefUnwindSafe for AppendOnlyTree<L>

§

impl<L> Send for AppendOnlyTree<L>
where PhantomData<fn(L)>: Send,

§

impl<L> Sync for AppendOnlyTree<L>
where PhantomData<fn(L)>: Sync,

§

impl<L> Unpin for AppendOnlyTree<L>
where PhantomData<fn(L)>: Unpin,

§

impl<L> UnsafeUnpin for AppendOnlyTree<L>

§

impl<L> UnwindSafe for AppendOnlyTree<L>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more