RangeProof

Struct RangeProof 

Source
pub struct RangeProof<K, V, H> {
    start_proof: Proof<H>,
    end_proof: Proof<H>,
    key_values: Box<[(K, V)]>,
}
Expand description

A range proof is a cryptographic proof that demonstrates a contiguous set of key-value pairs exists within a Merkle trie with a given root hash.

Range proofs are used to efficiently prove the presence (or absence) of multiple consecutive keys in a trie without revealing the entire trie structure. They consist of:

  • A start proof: proves the existence of the first key in the range (or the nearest key before it)
  • An end proof: proves the existence of the last key in the range (or the nearest key after it)
  • The actual key-value pairs within the range

This allows verification that:

  1. The provided key-value pairs are indeed part of the trie
  2. There are no other keys between the start and end of the range
  3. The trie has the claimed root hash

Range proofs are particularly useful in blockchain contexts for:

  • State synchronization between nodes
  • Light client verification
  • Efficient auditing of specific key ranges

Fields§

§start_proof: Proof<H>§end_proof: Proof<H>§key_values: Box<[(K, V)]>

Implementations§

Source§

impl RangeProof<Box<[u8]>, Box<[u8]>, Box<[ProofNode]>>

Source

pub fn from_slice(data: &[u8]) -> Result<Self, ReadError>

Parses a FrozenRangeProof from the given byte slice.

Currently only V0 proofs are supported. See FrozenRangeProof::write_to_vec for the serialization format.

§Errors

Returns a ReadError if the data is invalid. See the enum variants for the possible reasons.

Source§

impl<K, V, H> RangeProof<K, V, H>
where K: AsRef<[u8]>, V: AsRef<[u8]>, H: ProofCollection,

Source

pub const fn new( start_proof: Proof<H>, end_proof: Proof<H>, key_values: Box<[(K, V)]>, ) -> Self

Create a new range proof with the given start and end proofs and the key-value pairs that are included in the proof.

§Parameters
  • start_proof - A Merkle proof for the first key in the range, or if the range starts before any existing key, a proof for the nearest key that comes after the start of the range. This proof establishes the lower boundary of the range and ensures no keys exist between the range start and the first included key. May be empty if proving from the very beginning of the trie.

  • end_proof - A Merkle proof for the last key in the range, or if the range extends beyond all existing keys, a proof for the nearest key that comes before the end of the range. This proof establishes the upper boundary of the range and ensures no keys exist between the last included key and the range end. May be empty if proving to the very end of the trie.

  • key_values - The actual key-value pairs that exist within the proven range. These are the consecutive entries from the trie that fall within the boundaries established by the start and end proofs. The keys should be in lexicographic order as they appear in the trie. May be empty if proving the absence of keys in a range.

Source

pub const fn start_proof(&self) -> &Proof<H>

Returns a reference to the start proof, which may be empty.

Source

pub const fn end_proof(&self) -> &Proof<H>

Returns a reference to the end proof, which may be empty.

Source

pub const fn key_values(&self) -> &[(K, V)]

Returns the key-value pairs included in the range proof, which may be empty.

Source

pub fn is_empty(&self) -> bool

Returns true if the range proof is empty, meaning it has no start or end proof and no key-value pairs.

Source

pub fn iter(&self) -> RangeProofIter<'_, K, V>

Returns an iterator over the key-value pairs in this range proof.

The iterator yields references to the key-value pairs in the order they appear in the proof (which should be lexicographic order as they appear in the trie).

Source§

impl RangeProof<Box<[u8]>, Box<[u8]>, Box<[ProofNode]>>

Source

pub fn write_to_vec(&self, out: &mut Vec<u8>)

Serializes this proof into the provided byte vector.

§Format

The V0 serialization format for a range proof is:

  • A 32-byte Header with the proof type set to ProofType::Range.
  • The start proof, serialized as a sequence of ProofNodes
  • The end proof, serialized as a sequence of ProofNodes
  • The key-value pairs, serialized as a sequence of (key, value) tuples.

Each ProofNode is serialized as:

  • The key, serialized as a sequence of bytes where each byte is a nibble of the appropriate branching factor. E.g., if the trie has a branching factor of 16, each byte is only the lower 4 bits of the byte and the upper 4 bits are all zero.
  • A variable-length integer indicating the length of the parent’s key of the key. I.e., key[partial_len..] is the partial path of this node.
  • The value digest:
    • If there is no value for the node, a single byte with the value 0.
    • If there is a value for the node, a single byte with the value 1 followed by:
      • If the value digest is of a full value, a single byte with the value 0 followed by the value serialized as a sequence of bytes.
      • If the value digest is of a hash, a single byte with the value 1 followed by the hash serialized as exactly 32 bytes.
      • See [ValueDigest::make_hash] as to when a value digest is a hash.
  • The children bitmap, which is a fixed-size bit field where each bit indicates whether the corresponding child is present. The size of the bitmap is branching_factor / 8 bytes. E.g., if the branching factor is 16, the bitmap is 2 bytes (16 bits) and if the branching factor is 256, the bitmap is 32 bytes (256 bits). All zero bits indicate that the node is a leaf node and no children follow.
  • For each child that is present, as indicated by the bitmap, the child’s node ID is serialized.
    • If the trie is using MerkleDB hashing, the ID is a fixed 32-byte sha256 hash.
    • If the trie is using Ethereum hashing, the ID is serialized as:
      • A single byte with the value 0 if the ID is a keccak256 hash; followed by the fixed 32-byte hash.
      • A single byte with the value 1 if the ID is an RLP encoded node; followed by the RLP encoded bytes serialized as a sequence of bytes. This occurs when the hash input (RLP encoded node) is smaller than 32 bytes; in which case, the hash result is the input value unhashed.

Each sequence mentioned above is prefixed with a variable-length integer indicating the number of items in the sequence.

Variable-length integers are encoded using unsigned LEB128.

Trait Implementations§

Source§

impl<K: Debug, V: Debug, H: Debug> Debug for RangeProof<K, V, H>

Source§

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

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

impl<'a, K, V, H> IntoIterator for &'a RangeProof<K, V, H>
where K: AsRef<[u8]>, V: AsRef<[u8]>, H: ProofCollection,

Source§

type Item = &'a (K, V)

The type of the elements being iterated over.
Source§

type IntoIter = RangeProofIter<'a, K, V>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<K: PartialEq, V: PartialEq, H: PartialEq> PartialEq for RangeProof<K, V, H>

Source§

fn eq(&self, other: &RangeProof<K, V, H>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<K, V, H> StructuralPartialEq for RangeProof<K, V, H>

Auto Trait Implementations§

§

impl<K, V, H> Freeze for RangeProof<K, V, H>
where H: Freeze,

§

impl<K, V, H> RefUnwindSafe for RangeProof<K, V, H>

§

impl<K, V, H> Send for RangeProof<K, V, H>
where H: Send, K: Send, V: Send,

§

impl<K, V, H> Sync for RangeProof<K, V, H>
where H: Sync, K: Sync, V: Sync,

§

impl<K, V, H> Unpin for RangeProof<K, V, H>
where H: Unpin,

§

impl<K, V, H> UnwindSafe for RangeProof<K, V, H>
where H: UnwindSafe, K: UnwindSafe, V: UnwindSafe,

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<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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

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

§

fn vzip(self) -> V

§

impl<T> ValueSize for T

§

fn value_size(&self) -> usize

The size of this value in bytes, excluding allocated data. Read more
§

fn value_size_sum_iter<'item>(iterator: impl Iterator<Item = &'item T>) -> usize
where T: 'item,

The total sum of the sizes of all values in the given iterator, in bytes. This is default-implemented by computing [ValueSize::value_size] on every element and summing them. For Sized types, a more potentially efficient implementation using Iterator::count is provided. If you are implementing this trait manually, it is unlikely to be more efficient to provide a manual implementation here. Read more
§

fn value_size_sum_exact_size_iter<'item>( iterator: impl ExactSizeIterator<Item = &'item T>, ) -> usize
where T: 'item,

The total sum of the sizes of all values in the given exact-size-iterator, in bytes. This is default-implemented by using [ValueSize::value_size_sum_iter]. For Sized types, a usually more efficient implementation using ExactSizeIterator::len is provided. If you are implementing this trait manually, it is unlikely to be more efficient to provide a manual implementation here. Read more