pub struct NsTable {
    pub(crate) bytes: Vec<u8>,
}Expand description
Raw binary data for a namespace table.
Any sequence of bytes is a valid NsTable.
§Binary format of a namespace table
Byte lengths for the different items that could appear in a namespace table
are specified in local private constants NUM_NSS_BYTE_LEN,
NS_OFFSET_BYTE_LEN, NS_ID_BYTE_LEN.
§Number of entries in the namespace table
The first NUM_NSS_BYTE_LEN bytes of the namespace table indicate the
number n of entries in the table as a little-endian unsigned integer. If
the entire table length is smaller than NUM_NSS_BYTE_LEN then the
missing bytes are zero-padded.
The bytes in the namespace table beyond the first NUM_NSS_BYTE_LEN bytes
encode table entries. Each entry consumes exactly NS_ID_BYTE_LEN +
NS_OFFSET_BYTE_LEN bytes.
The number n could be anything, including a number much larger than the
number of entries that could fit in the namespace table. As such, the actual
number of entries in the table is defined as the minimum of n and the
maximum number of whole entries that could fit in the table.
See Self::in_bounds for clarification.
§Namespace table entry
§Namespace ID
The first NS_ID_BYTE_LEN bytes of each table entry indicate the
[NamespaceId] for this namespace. Any table entry whose [NamespaceId] is
a duplicate of a previous entry is ignored. A correct count of the number of
unique (non-ignored) entries is given by NsTable::iter().count().
§Namespace offset
The next NS_OFFSET_BYTE_LEN bytes of each table entry indicate the
end-index of a namespace in the block payload bytes
Payload. This end-index is a little-endian
unsigned integer.
§How to deduce a namespace’s byte range
In order to extract the payload bytes of a single namespace N from the
block payload one needs both the start- and end-indices for N.
See Self::ns_range for clarification. What follows is a description of
what’s implemented in Self::ns_range.
If N occupies the ith entry in the namespace table for i>0 then the
start-index for N is defined as the end-index of the (i-1)th entry in
the table.
Even if the (i-1)the entry would otherwise be ignored (due to a duplicate
[NamespaceId] or any other reason), that entry’s end-index still defines
the start-index of N. This rule guarantees that both start- and
end-indices for any namespace N can be read from a constant-size byte
range in the namespace table, and it eliminates the need to traverse an
unbounded number of previous entries of the namespace table looking for a
previous non-ignored entry.
The start-index of the 0th entry in the table is implicitly defined to be
0.
The start- and end-indices (declared_start, declared_end) declared in the
namespace table could be anything. As such, the actual start- and
end-indices (start, end) are defined so as to ensure that the byte range
is well-defined and in-bounds for the block payload:
end = min(declared_end, block_payload_byte_length)
start = min(declared_start, end)In a “honestly-prepared” namespace table the end-index of the final namespace equals the byte length of the block payload. (Otherwise the block payload might have bytes that are not included in any namespace.)
It is possible that a namespace table could indicate two distinct namespaces whose byte ranges overlap, though no “honestly-prepared” namespace table would do this.
TODO prefer NsTable to be a newtype like this
#[repr(transparent)]
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
#[serde(transparent)]
pub struct NsTable(#[serde(with = "base64_bytes")] Vec<u8>);but we need to maintain serialization compatibility. https://github.com/EspressoSystems/espresso-sequencer/issues/1575
Fields§
§bytes: Vec<u8>Implementations§
Source§impl NsTable
 
impl NsTable
Sourcepub fn find_ns_id(&self, ns_id: &NamespaceId) -> Option<NsIndex>
 
pub fn find_ns_id(&self, ns_id: &NamespaceId) -> Option<NsIndex>
Search the namespace table for the ns_index belonging to ns_id.
Sourcepub fn len(&self) -> NumNss
 
pub fn len(&self) -> NumNss
Number of entries in the namespace table.
Defined as the maximum number of entries that could fit in the namespace table, ignoring what’s declared in the table header.
Sourcepub fn iter(&self) -> impl Iterator<Item = NsIndex> + '_
 
pub fn iter(&self) -> impl Iterator<Item = NsIndex> + '_
Iterator over all unique namespaces in the namespace table.
Sourcepub fn read_ns_id(&self, index: &NsIndex) -> Option<NamespaceId>
 
pub fn read_ns_id(&self, index: &NsIndex) -> Option<NamespaceId>
Read the namespace id from the indexth entry from the namespace table.
Returns None if index is out of bounds.
TODO I want to restrict visibility to pub(crate) or lower but this
method is currently used in nasty-client.
Sourcepub fn read_ns_id_unchecked(&self, index: &NsIndex) -> NamespaceId
 
pub fn read_ns_id_unchecked(&self, index: &NsIndex) -> NamespaceId
Like Self::read_ns_id except index is not checked. Use Self::in_bounds as needed.
Sourcepub fn in_bounds(&self, index: &NsIndex) -> bool
 
pub fn in_bounds(&self, index: &NsIndex) -> bool
Does the indexth entry exist in the namespace table?
Sourcepub fn from_bytes_unchecked(bytes: &[u8]) -> NsTable
 
pub fn from_bytes_unchecked(bytes: &[u8]) -> NsTable
Instantiate an NsTable from a byte slice.
Sourcepub fn validate(
    &self,
    payload_byte_len: &PayloadByteLen,
) -> Result<(), NsTableValidationError>
 
pub fn validate( &self, payload_byte_len: &PayloadByteLen, ) -> Result<(), NsTableValidationError>
Are the bytes of this NsTable uncorrupted?
§Checks
- Byte length must hold a whole number of entries.
 - All offsets must increase monotonically. Offsets must be nonzero. Namespace IDs must be unique.
 - Header consistent with byte length. (Obsolete after https://github.com/EspressoSystems/espresso-sequencer/issues/1604.)
 - Final offset must equal 
payload_byte_len. (Obsolete after https://github.com/EspressoSystems/espresso-sequencer/issues/1604.) If the namespace table is empty thenpayload_byte_lenmust be 0. 
Sourcepub fn ns_range(
    &self,
    index: &NsIndex,
    payload_byte_len: &PayloadByteLen,
) -> NsPayloadRange
 
pub fn ns_range( &self, index: &NsIndex, payload_byte_len: &PayloadByteLen, ) -> NsPayloadRange
Read subslice range for the indexth namespace from the namespace
table.
Sourcefn read_num_nss(&self) -> usize
 
fn read_num_nss(&self) -> usize
Read the number of namespaces declared in the namespace table. THIS
QUANTITY IS NEVER USED. Instead use NsTable::len.
TODO Delete this method after https://github.com/EspressoSystems/espresso-sequencer/issues/1604
Sourcefn read_ns_offset_unchecked(&self, index: &NsIndex) -> usize
 
fn read_ns_offset_unchecked(&self, index: &NsIndex) -> usize
Read the namespace offset from the indexth entry from the namespace table.
Sourcefn validate_deserialization_invariants(
    &self,
) -> Result<(), NsTableValidationError>
 
fn validate_deserialization_invariants( &self, ) -> Result<(), NsTableValidationError>
Helper for NsTable::validate, used in our custom serde
implementation.
Checks conditions 1-3 of NsTable::validate. Those conditions can be
checked by looking only at the contents of the NsTable.
Source§impl<'de> NsTable
 
impl<'de> NsTable
pub fn deserialize<__D>(__deserializer: __D) -> Result<NsTable, __D::Error>where
    __D: Deserializer<'de>,
Trait Implementations§
Source§impl<'de> Deserialize<'de> for NsTable
 
impl<'de> Deserialize<'de> for NsTable
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 NsTable
impl StructuralPartialEq for NsTable
Auto Trait Implementations§
impl Freeze for NsTable
impl RefUnwindSafe for NsTable
impl Send for NsTable
impl Sync for NsTable
impl Unpin for NsTable
impl UnwindSafe for NsTable
Blanket Implementations§
§impl<T> ArchivePointee for T
 
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
 
type ArchivedMetadata = ()
§fn pointer_metadata(
    _: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
 
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
    T: 'a,
 
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
    T: 'a,
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
    T: 'a,
 
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
    T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
    T: 'a,
 
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
    T: 'a,
§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<T> CallHasher for T
 
impl<T> CallHasher for 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<F, W, T, D> Deserialize<With<T, W>, D> for F
 
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
§fn deserialize(
    &self,
    deserializer: &mut D,
) -> Result<With<T, W>, <D as Fallible>::Error>
 
fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>
§impl<T> Downcast for Twhere
    T: Any,
 
impl<T> Downcast for Twhere
    T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
 
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
 
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
 
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
 
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
 
impl<T> DowncastSync 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
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
§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> 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> 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 more§impl<T> LayoutRaw for T
 
impl<T> LayoutRaw for T
§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
 
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
§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> PolicyExt for Twhere
    T: ?Sized,
 
impl<T> PolicyExt for Twhere
    T: ?Sized,
Source§impl<T> Resolvable<T> for Twhere
    T: Committable,
 
impl<T> Resolvable<T> for Twhere
    T: Committable,
Source§fn try_resolve(self) -> Result<T, T>
 
fn try_resolve(self) -> Result<T, T>
Source§fn commitment(&self) -> Commitment<T>
 
fn commitment(&self) -> Commitment<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.