pub enum Header {
V1(Header),
V2(Header),
V3(Header),
V99(Header),
}
Expand description
Each variant represents a specific minor version header.
Variants§
Implementations§
Source§impl Header
impl Header
pub fn version(&self) -> Version
pub(crate) fn create( chain_config: ChainConfig, height: u64, timestamp: u64, l1_head: u64, l1_finalized: Option<L1BlockInfo>, payload_commitment: VidCommitment, builder_commitment: BuilderCommitment, ns_table: NsTable, fee_merkle_tree_root: FeeMerkleCommitment, block_merkle_tree_root: BlockMerkleCommitment, reward_merkle_tree_root: Option<RewardMerkleCommitment>, fee_info: Vec<FeeInfo>, builder_signature: Vec<BuilderSignature>, version: Version, ) -> Self
Source§impl Header
impl Header
fn from_info( payload_commitment: VidCommitment, builder_commitment: BuilderCommitment, ns_table: NsTable, parent_leaf: &Leaf2, l1: L1Snapshot, l1_deposits: &[FeeInfo], builder_fee: Vec<BuilderFee<SeqTypes>>, view_number: u64, timestamp: u64, state: ValidatedState, chain_config: ChainConfig, version: Version, auction_results: Option<SolverAuctionResults>, validator: Option<Validator<BLSPubKey>>, ) -> Result<Self>
async fn get_chain_config( validated_state: &ValidatedState, instance_state: &NodeState, ) -> Result<ChainConfig>
Source§impl Header
impl Header
Sourcepub fn chain_config(&self) -> ResolvableChainConfig
pub fn chain_config(&self) -> ResolvableChainConfig
A commitment to a ChainConfig or a full ChainConfig.
pub fn height(&self) -> u64
pub fn height_mut(&mut self) -> &mut u64
pub fn timestamp(&self) -> u64
pub fn timestamp_mut(&mut self) -> &mut u64
Sourcepub fn l1_head(&self) -> u64
pub fn l1_head(&self) -> u64
The Espresso block header includes a reference to the current head of the L1 chain.
Rollups can use this to facilitate bridging between the L1 and L2 in a deterministic way. This field deterministically associates an L2 block with a recent L1 block the instant the L2 block is sequenced. Rollups can then define the L2 state after this block as the state obtained by executing all the transactions in this block plus all the L1 deposits up to the given L1 block number. Since there is no need to wait for the L2 block to be reflected on the L1, this bridge design retains the low confirmation latency of HotShot.
This block number indicates the unsafe head of the L1 chain, so it is subject to reorgs. For
this reason, the Espresso header does not include any information that might change in a
reorg, such as the L1 block timestamp or hash. It includes only the L1 block number, which
will always refer to some block after a reorg: if the L1 head at the time this block was
sequenced gets reorged out, the L1 chain will eventually (and probably quickly) grow to the
same height once again, and a different block will exist with the same height. In this way,
Espresso does not have to handle L1 reorgs, and the Espresso blockchain will always be
reflective of the current state of the L1 blockchain. Rollups that use this block number
do have to handle L1 reorgs, but each rollup and each rollup client can decide how many
confirmations they want to wait for on top of this l1_head
before they consider an L2
block finalized. This offers a tradeoff between low-latency L1-L2 bridges and finality.
Rollups that want a stronger guarantee of finality, or that want Espresso to attest to data
from the L1 block that might change in reorgs, can instead use the latest L1 finalized
block at the time this L2 block was sequenced: Self::l1_finalized
.
pub fn l1_head_mut(&mut self) -> &mut u64
Sourcepub fn l1_finalized(&self) -> Option<L1BlockInfo>
pub fn l1_finalized(&self) -> Option<L1BlockInfo>
The Espresso block header includes information about the latest finalized L1 block.
Similar to l1_head
, rollups can use this information to implement a
bridge between the L1 and L2 while retaining the finality of low-latency block confirmations
from HotShot. Since this information describes the finalized L1 block, a bridge using this
L1 block will have much higher latency than a bridge using l1_head
. In
exchange, rollups that use the finalized block do not have to worry about L1 reorgs, and can
inject verifiable attestations to the L1 block metadata (such as its timestamp or hash) into
their execution layers, since Espresso replicas will sign this information for the finalized
L1 block.
This block may be None
in the rare case where Espresso has started shortly after the
genesis of the L1, and the L1 has yet to finalize a block. In all other cases it will be
Some
.
pub fn l1_finalized_mut(&mut self) -> &mut Option<L1BlockInfo>
pub fn payload_commitment(&self) -> VidCommitment
pub fn payload_commitment_mut(&mut self) -> &mut VidCommitment
pub fn builder_commitment(&self) -> &BuilderCommitment
pub fn builder_commitment_mut(&mut self) -> &mut BuilderCommitment
pub fn ns_table(&self) -> &NsTable
Sourcepub fn block_merkle_tree_root(&self) -> BlockMerkleCommitment
pub fn block_merkle_tree_root(&self) -> BlockMerkleCommitment
Root Commitment of Block Merkle Tree
pub fn block_merkle_tree_root_mut(&mut self) -> &mut BlockMerkleCommitment
Sourcepub fn fee_merkle_tree_root(&self) -> FeeMerkleCommitment
pub fn fee_merkle_tree_root(&self) -> FeeMerkleCommitment
Root Commitment of FeeMerkleTree
pub fn fee_merkle_tree_root_mut(&mut self) -> &mut FeeMerkleCommitment
Sourcepub fn reward_merkle_tree_root(&self) -> RewardMerkleCommitment
pub fn reward_merkle_tree_root(&self) -> RewardMerkleCommitment
Fee paid by the block builder
Sourcepub fn builder_signature(&self) -> Vec<BuilderSignature>
pub fn builder_signature(&self) -> Vec<BuilderSignature>
Account (etheruem address) of builder
This signature is not considered formally part of the header; it is just evidence proving
that other parts of the header (fee_info
) are correct. It exists in the
header so that it is available to all nodes to be used during validation. But since it is
checked during consensus, any downstream client who has a proof of consensus finality of a
header can trust that fee_info
is correct without relying on the
signature. Thus, this signature is not included in the header commitment.
Trait Implementations§
Source§impl BlockHeader<SeqTypes> for Header
impl BlockHeader<SeqTypes> for Header
Source§fn get_auction_results(&self) -> Option<SolverAuctionResults>
fn get_auction_results(&self) -> Option<SolverAuctionResults>
Get the results of the auction for this Header. Only used in post-marketplace versions
Source§async fn new_marketplace(
parent_state: &<SeqTypes as NodeType>::ValidatedState,
instance_state: &<<SeqTypes as NodeType>::ValidatedState as ValidatedState<SeqTypes>>::Instance,
parent_leaf: &Leaf2<SeqTypes>,
payload_commitment: VidCommitment,
builder_commitment: BuilderCommitment,
metadata: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata,
builder_fee: Vec<BuilderFee<SeqTypes>>,
view_number: u64,
auction_results: Option<SolverAuctionResults>,
version: Version,
) -> Result<Self, Self::Error>
async fn new_marketplace( parent_state: &<SeqTypes as NodeType>::ValidatedState, instance_state: &<<SeqTypes as NodeType>::ValidatedState as ValidatedState<SeqTypes>>::Instance, parent_leaf: &Leaf2<SeqTypes>, payload_commitment: VidCommitment, builder_commitment: BuilderCommitment, metadata: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata, builder_fee: Vec<BuilderFee<SeqTypes>>, view_number: u64, auction_results: Option<SolverAuctionResults>, version: Version, ) -> Result<Self, Self::Error>
Build a header with the parent validate state, instance-level state, parent leaf, payload commitment, metadata, and auction results. This is only used in post-marketplace versions
Source§fn builder_commitment(&self) -> BuilderCommitment
fn builder_commitment(&self) -> BuilderCommitment
Commit over fee_amount, payload_commitment and metadata
Source§type Error = InvalidBlockHeader
type Error = InvalidBlockHeader
Source§async fn new_legacy(
parent_state: &ValidatedState,
instance_state: &NodeState,
parent_leaf: &Leaf2,
payload_commitment: VidCommitment,
builder_commitment: BuilderCommitment,
metadata: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata,
builder_fee: BuilderFee<SeqTypes>,
version: Version,
view_number: u64,
) -> Result<Self, Self::Error>
async fn new_legacy( parent_state: &ValidatedState, instance_state: &NodeState, parent_leaf: &Leaf2, payload_commitment: VidCommitment, builder_commitment: BuilderCommitment, metadata: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata, builder_fee: BuilderFee<SeqTypes>, version: Version, view_number: u64, ) -> Result<Self, Self::Error>
Source§fn genesis(
instance_state: &NodeState,
payload_commitment: VidCommitment,
builder_commitment: BuilderCommitment,
ns_table: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata,
) -> Self
fn genesis( instance_state: &NodeState, payload_commitment: VidCommitment, builder_commitment: BuilderCommitment, ns_table: <<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata, ) -> Self
Source§fn block_number(&self) -> u64
fn block_number(&self) -> u64
Source§fn payload_commitment(&self) -> VidCommitment
fn payload_commitment(&self) -> VidCommitment
Source§fn metadata(
&self,
) -> &<<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata
fn metadata( &self, ) -> &<<SeqTypes as NodeType>::BlockPayload as BlockPayload<SeqTypes>>::Metadata
Source§fn get_light_client_state(
&self,
view: <SeqTypes as NodeType>::View,
) -> Result<LightClientState>
fn get_light_client_state( &self, view: <SeqTypes as NodeType>::View, ) -> Result<LightClientState>
Source§impl<'de> Deserialize<'de> for Header
impl<'de> Deserialize<'de> for Header
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>,
Source§impl ExplorerHeader<SeqTypes> for Header
impl ExplorerHeader<SeqTypes> for Header
Source§fn reward_balance(&self) -> Self::BalanceAmount
fn reward_balance(&self) -> Self::BalanceAmount
reward_balance at the moment is only implemented as a stub, as block rewards have not yet been implemented.
TODO: update implementation when rewards have been created / supported. Issue: https://github.com/EspressoSystems/espresso-sequencer/issues/1453
Source§type BalanceAmount = FeeAmount
type BalanceAmount = FeeAmount
Source§type WalletAddress = Vec<FeeAccount>
type WalletAddress = Vec<FeeAccount>
Source§type ProposerId = Vec<FeeAccount>
type ProposerId = Vec<FeeAccount>
Source§type NamespaceId = NamespaceId
type NamespaceId = NamespaceId
Source§fn proposer_id(&self) -> Self::ProposerId
fn proposer_id(&self) -> Self::ProposerId
Source§fn fee_info_account(&self) -> Self::WalletAddress
fn fee_info_account(&self) -> Self::WalletAddress
Source§fn fee_info_balance(&self) -> Self::BalanceAmount
fn fee_info_balance(&self) -> Self::BalanceAmount
Source§fn namespace_ids(&self) -> Vec<Self::NamespaceId>
fn namespace_ids(&self) -> Vec<Self::NamespaceId>
impl Eq for Header
impl StructuralPartialEq for Header
Auto Trait Implementations§
impl Freeze for Header
impl RefUnwindSafe for Header
impl Send for Header
impl Sync for Header
impl Unpin for Header
impl UnwindSafe for Header
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> 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<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> Resolvable<T> for Twhere
T: Committable,
impl<T> Resolvable<T> for Twhere
T: Committable,
§fn try_resolve(self) -> Result<T, T>
fn try_resolve(self) -> Result<T, T>
§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.