#[non_exhaustive]pub struct ResourceCommitment {
pub layout: ChunkLayout,
pub total_length: u64,
pub root: Option<String>,
pub inclusion_proof: Option<String>,
}Expand description
The trusted per-resource metadata a download verifies every range against: the chunk boundaries,
the total length, the chain-anchored generation root, and (for a resource, not a capsule) the
whole-resource inclusion_proof.
Established from the first frame of the first fetched range (or an availability answer + the first frame). Immutable for the life of the download: a range whose first-frame metadata disagrees with this commitment is rejected as a different/forged generation.
§Adoption is NOT verification
Every gate available when a layout is adopted — the root match against the caller’s content id, and the
chunk_lens-sums-to-total_length consistency check — is satisfiable by a holder that lies consistently,
because both compare fields the SAME untrusted holder supplied. Only Verifier::verify_resource_leaf
binds the layout to the chain, and it cannot run until the whole resource has been fetched against that
layout. So a commitment is a HYPOTHESIS about the resource’s shape, and a holder positioned first in the
provider order can therefore deny a read by declaring a short but self-consistent layout for the correct
root (#1670, OPEN).
That denial is not fixable from here. Attributing the later refutation to the holder that supplied the layout requires distinguishing “the shape was wrong” from “the bytes were wrong”, and nothing in the system can: per-range verification is length and alignment only, with no per-chunk hash. Three successive attempts to stand a vote over peer DECLARATIONS in for that missing evidence each produced a cheaper denial than the one they replaced, because those declarations are optional wire fields that cost an attacker a keypair to forge and that honest holders legitimately omit. #1670 is re-scoped onto per-chunk attribution, which is the only thing that can name a bad holder.
#[non_exhaustive]: the adoption path is expected to gain provenance once that evidence exists. Build one
with from_first_frame or
from_first_frame_bounded.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.layout: ChunkLayoutThe chunk boundaries (chunk_lens → offsets).
total_length: u64The full resource ciphertext length.
root: Option<String>The chain-anchored generation root (64-hex) every range verifies against. None only for a
self-verifying capsule fetch that carries no per-resource root.
inclusion_proof: Option<String>The whole-resource merkle inclusion proof (base64), relayed verbatim from the first frame;
None for a capsule: true fetch (the capsule self-verifies on install).
Implementations§
Source§impl ResourceCommitment
impl ResourceCommitment
Sourcepub fn from_first_frame(
total_length: u64,
chunk_lens: Vec<u64>,
root: Option<String>,
inclusion_proof: Option<String>,
) -> Result<Self, VerifyError>
pub fn from_first_frame( total_length: u64, chunk_lens: Vec<u64>, root: Option<String>, inclusion_proof: Option<String>, ) -> Result<Self, VerifyError>
Build a commitment from first-frame verification metadata, bounded by
DEFAULT_MAX_RESOURCE_SIZE.
Equivalent to from_first_frame_bounded with the default
ceiling — see it for what the bound defends against.
Sourcepub fn from_first_frame_bounded(
total_length: u64,
chunk_lens: Vec<u64>,
root: Option<String>,
inclusion_proof: Option<String>,
max_resource_size: u64,
) -> Result<Self, VerifyError>
pub fn from_first_frame_bounded( total_length: u64, chunk_lens: Vec<u64>, root: Option<String>, inclusion_proof: Option<String>, max_resource_size: u64, ) -> Result<Self, VerifyError>
Build a commitment from first-frame verification metadata, refusing a declared
total_length above max_resource_size.
Validates that chunk_lens sums to total_length with CHECKED arithmetic (a peer reporting
inconsistent metadata is rejected up front) — and, BEFORE that, that the declared length is
within the ceiling.
The ceiling is load-bearing, not hygiene. total_length and the individual chunk_lens come
from the first frame of a peer that has not proven anything yet, and they SIZE the download: a
single chunk becomes at least one whole Range regardless of the window,
and the range assembler then buffers up to that length. So an unbounded declared length is a
one-frame memory-exhaustion primitive: a peer answering the metadata probe with
total_length: 2^40, chunk_lens: [2^40] makes the client try to buffer a terabyte. Bounding it
here — before any layout or plan exists — is what keeps that a rejection instead of an
allocation. (The range assembler’s own reservation is additionally FALLIBLE, so even a
within-ceiling length that this host cannot hold is a recoverable error rather than an
uncatchable abort.)
Sourcepub fn check_consistent(
&self,
total_length: Option<u64>,
chunk_lens: Option<&[u64]>,
root: Option<&str>,
) -> Result<(), VerifyError>
pub fn check_consistent( &self, total_length: Option<u64>, chunk_lens: Option<&[u64]>, root: Option<&str>, ) -> Result<(), VerifyError>
Check that a range’s declared first-frame metadata is consistent with this commitment (same
chunk_lens, total_length, and root). Used when a later range’s first frame arrives to
reject a source serving a different generation.
Trait Implementations§
Source§impl Clone for ResourceCommitment
impl Clone for ResourceCommitment
Source§fn clone(&self) -> ResourceCommitment
fn clone(&self) -> ResourceCommitment
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ResourceCommitment
impl Debug for ResourceCommitment
impl Eq for ResourceCommitment
Source§impl PartialEq for ResourceCommitment
impl PartialEq for ResourceCommitment
impl StructuralPartialEq for ResourceCommitment
Auto Trait Implementations§
impl Freeze for ResourceCommitment
impl RefUnwindSafe for ResourceCommitment
impl Send for ResourceCommitment
impl Sync for ResourceCommitment
impl Unpin for ResourceCommitment
impl UnsafeUnpin for ResourceCommitment
impl UnwindSafe for ResourceCommitment
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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.Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§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 moreSource§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 moreSource§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
Source§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
Source§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.Source§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.Source§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> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.