pub struct ForkLocalDepot {
pub inherited_keys: BTreeSet<[u8; 32]>,
pub local_keys: BTreeSet<[u8; 32]>,
}Expand description
Fork-local storage scope for ForksHandler implementing ForkScopes.
ForkLocalDepot is the branch-local scope container used by the
fork-aware offchain execution system to track visibility of
fork-scoped storage entries across branch lineage.
It does not store the actual values themselves.
Instead, it stores only deterministic 32-byte keys ([u8; 32])
representing items written into fork-aware storage systems such as:
These keys act as stable scope references that allow the fork graph to answer:
"does this item exist on this branch or any reachable ancestor branch?"without requiring repeated traversal of historical parent branches.
§Why this exists
In fork-aware OCW execution, each branch must maintain isolated local state while still inheriting valid reachable state from its lineage.
Example:
A -> B -> C
|-- D
|-- D'Here:
DandD'must not overwrite each other- both branches must still see inherited state from
A -> B -> C
ForkLocalDepot provides that visibility layer by separating:
- current-generation writes
- inherited historical writes
instead of repeatedly walking parent branches during every lookup.
§Fork inheritance model
When a new sibling branch is created:
Parent branch:
A -> B -> C
New sibling:
|-- D'the child branch receives:
inherited_keys(child)
= inherited_keys(parent) + local_keys(parent)while starting with:
local_keys(child) = {}This ensures:
- parent state remains reachable
- new writes stay isolated to the new fork
- existence checks remain O(log n)
- no ancestry walking is required for normal reads
§Example
Original branch:
local_keys = {k1, k2}
inherited_keys = {}
After fork:
local_keys = {}
inherited_keys = {k1, k2}
New write:
local_keys = {k3}
inherited_keys = {k1, k2}The child branch can see:
{k1, k2, k3}while sibling branches remain isolated from k3.
Fields§
§inherited_keys: BTreeSet<[u8; 32]>Keys inherited from previous generations through Accrete.
These represent all reachable historical entries inherited from ancestor branches.
They are not created in the current branch generation, but remain visible because they were promoted forward during fork creation.
This allows branch-local reads to access valid ancestor state without walking parent branches repeatedly.
local_keys: BTreeSet<[u8; 32]>Keys created only in the current local generation.
These represent the newest writes belonging exclusively to the current branch path.
They are isolated to this branch until another fork occurs,
at which point they are promoted into inherited_keys of the
child branch through Accrete::accrete().
This ensures writes remain fork-local while still preserving deterministic lineage inheritance for future branches.
Trait Implementations§
Source§impl Accrete for ForkLocalDepot
impl Accrete for ForkLocalDepot
Source§type Item = Vec<u8>
type Item = Vec<u8>
The original payload used to derive deterministic keys.
Only the generated [u8; 32] key is stored internally.
Source§fn accrete(&self) -> Self
fn accrete(&self) -> Self
Create the next generation.
All current local keys are promoted into inherited history, and the returned generation starts with a fresh empty local layer.
Source§fn add_to_local(&mut self, item: Self::Item) -> [u8; 32]
fn add_to_local(&mut self, item: Self::Item) -> [u8; 32]
Insert an item’s deterministic key into the local generation.
The payload itself is not stored here, only its stable key hash.
Returns the deterministic key used for future lookups.
Source§fn exists_in_inherited(&self, key: &[u8; 32]) -> bool
fn exists_in_inherited(&self, key: &[u8; 32]) -> bool
Checks existence only in inherited generations.
Source§fn remove_from_local(&mut self, key: &[u8; 32])
fn remove_from_local(&mut self, key: &[u8; 32])
Remove a key only from the local generation.
Source§fn remove_from_inherited(&mut self, key: &[u8; 32])
fn remove_from_inherited(&mut self, key: &[u8; 32])
Remove a key only from inherited generations.
Source§impl Clone for ForkLocalDepot
impl Clone for ForkLocalDepot
Source§fn clone(&self) -> ForkLocalDepot
fn clone(&self) -> ForkLocalDepot
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ForkLocalDepot
impl Debug for ForkLocalDepot
Source§impl Decode for ForkLocalDepot
impl Decode for ForkLocalDepot
Source§fn decode<__CodecInputEdqy: Input>(
__codec_input_edqy: &mut __CodecInputEdqy,
) -> Result<Self, Error>
fn decode<__CodecInputEdqy: Input>( __codec_input_edqy: &mut __CodecInputEdqy, ) -> Result<Self, Error>
§fn decode_into<I>(
input: &mut I,
dst: &mut MaybeUninit<Self>,
) -> Result<DecodeFinished, Error>where
I: Input,
fn decode_into<I>(
input: &mut I,
dst: &mut MaybeUninit<Self>,
) -> Result<DecodeFinished, Error>where
I: Input,
§fn skip<I>(input: &mut I) -> Result<(), Error>where
I: Input,
fn skip<I>(input: &mut I) -> Result<(), Error>where
I: Input,
§fn encoded_fixed_size() -> Option<usize>
fn encoded_fixed_size() -> Option<usize>
Source§impl Default for ForkLocalDepot
impl Default for ForkLocalDepot
Source§fn default() -> ForkLocalDepot
fn default() -> ForkLocalDepot
Source§impl Encode for ForkLocalDepot
impl Encode for ForkLocalDepot
Source§fn size_hint(&self) -> usize
fn size_hint(&self) -> usize
Source§fn encode_to<__CodecOutputEdqy: Output + ?Sized>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy,
)
fn encode_to<__CodecOutputEdqy: Output + ?Sized>( &self, __codec_dest_edqy: &mut __CodecOutputEdqy, )
§fn using_encoded<R, F>(&self, f: F) -> R
fn using_encoded<R, F>(&self, f: F) -> R
§fn encoded_size(&self) -> usize
fn encoded_size(&self) -> usize
impl EncodeLike for ForkLocalDepot
Auto Trait Implementations§
impl Freeze for ForkLocalDepot
impl RefUnwindSafe for ForkLocalDepot
impl Send for ForkLocalDepot
impl Sync for ForkLocalDepot
impl Unpin for ForkLocalDepot
impl UnwindSafe for ForkLocalDepot
Blanket Implementations§
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> CheckedConversion for T
impl<T> CheckedConversion for T
§fn checked_from<T>(t: T) -> Option<Self>where
Self: TryFrom<T>,
fn checked_from<T>(t: T) -> Option<Self>where
Self: TryFrom<T>,
§fn checked_into<T>(self) -> Option<T>where
Self: TryInto<T>,
fn checked_into<T>(self) -> Option<T>where
Self: TryInto<T>,
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> DecodeAll for Twhere
T: Decode,
impl<T> DecodeAll for Twhere
T: Decode,
§fn decode_all(input: &mut &[u8]) -> Result<T, Error>
fn decode_all(input: &mut &[u8]) -> Result<T, Error>
Self and consume all of the given input data. Read more§impl<T> DecodeLimit for Twhere
T: Decode,
impl<T> DecodeLimit for Twhere
T: Decode,
§impl<T> Hashable for Twhere
T: Codec,
impl<T> Hashable for Twhere
T: Codec,
§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> 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 moreSource§impl<T, U, Tag> IntoTag<U, Tag> for Twhere
U: FromTag<T, Tag>,
Tag: DiscriminantTag,
impl<T, U, Tag> IntoTag<U, Tag> for Twhere
U: FromTag<T, Tag>,
Tag: DiscriminantTag,
§impl<Src, Dest> IntoTuple<Dest> for Srcwhere
Dest: FromTuple<Src>,
impl<Src, Dest> IntoTuple<Dest> for Srcwhere
Dest: FromTuple<Src>,
fn into_tuple(self) -> Dest
§impl<T> IsType<T> for T
impl<T> IsType<T> for T
§impl<T, Outer> IsWrappedBy<Outer> for T
impl<T, Outer> IsWrappedBy<Outer> for T
§impl<T> KeyedVec for Twhere
T: Codec,
impl<T> KeyedVec for Twhere
T: Codec,
Source§impl<T, Time> Logging<Time> for Twhere
Time: Time,
impl<T, Time> Logging<Time> for Twhere
Time: Time,
Source§const FALLBACK_TARGET: &'static str = const FALLBACK_TARGET: &'_ str = "routine";
const FALLBACK_TARGET: &'static str = const FALLBACK_TARGET: &'_ str = "routine";
Default logging target if none is provided.
Most routines, especially offchain workers or background tasks, use this target for simplicity.
It allows a consistent place to look for routine logs without requiring every call to specify a target.
Note: This target is only a conveninence and may be somewhat vague. To ensure errors can still be traced accurately, the logged messages should include additional metadata (e.g., module name, error index, or contextual info) so that the source of the error can be identified even if the target is generic.
Source§type Logger = DispatchError
type Logger = DispatchError
The type taken and returned for logging.
We simply return the same [DispatchError] that was logged,
so logging does not change control flow or error propagation.
DispatchError is used because in Substrate it encompasses all
runtime errors - including module errors, token errors, arithmetic
issues, and transactional boundaries - making it the universal
substrate-side error representation.
Source§type Level = LogLevel
type Level = LogLevel
The log level type.
We use the LogLevel enum to standardize severity levels
(Info, Warn, Error, Debug) across all routine logs.
Source§fn log(
level: <T as Logging<Time>>::Level,
err: &<T as Logging<Time>>::Logger,
timestamp: Time,
target: Option<&str>,
fmt: Option<fn(Time, &<T as Logging<Time>>::Level, &str, &str) -> String>,
) -> <T as Logging<Time>>::Logger
fn log( level: <T as Logging<Time>>::Level, err: &<T as Logging<Time>>::Logger, timestamp: Time, target: Option<&str>, fmt: Option<fn(Time, &<T as Logging<Time>>::Level, &str, &str) -> String>, ) -> <T as Logging<Time>>::Logger
Source§fn info(
err: &Self::Logger,
timestamp: Timestamp,
target: Option<&str>,
fmt: Option<LogFormatter<Timestamp, Self::Level>>,
) -> Self::Loggerwhere
Self: Sized,
fn info(
err: &Self::Logger,
timestamp: Timestamp,
target: Option<&str>,
fmt: Option<LogFormatter<Timestamp, Self::Level>>,
) -> Self::Loggerwhere
Self: Sized,
Source§fn warn(
err: &Self::Logger,
timestamp: Timestamp,
target: Option<&str>,
fmt: Option<LogFormatter<Timestamp, Self::Level>>,
) -> Self::Loggerwhere
Self: Sized,
fn warn(
err: &Self::Logger,
timestamp: Timestamp,
target: Option<&str>,
fmt: Option<LogFormatter<Timestamp, Self::Level>>,
) -> Self::Loggerwhere
Self: Sized,
§impl<T> SaturatedConversion for T
impl<T> SaturatedConversion for T
§fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
fn saturated_from<T>(t: T) -> Selfwhere
Self: UniqueSaturatedFrom<T>,
§fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
fn saturated_into<T>(self) -> Twhere
Self: UniqueSaturatedInto<T>,
T. Read more§impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
impl<T, U> TryIntoKey<U> for Twhere
U: TryFromKey<T>,
type Error = <U as TryFromKey<T>>::Error
fn try_into_key(self) -> Result<U, <U as TryFromKey<T>>::Error>
§impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
§fn unchecked_into(self) -> T
fn unchecked_into(self) -> T
unchecked_from.§impl<T, S> UniqueSaturatedInto<T> for S
impl<T, S> UniqueSaturatedInto<T> for S
§fn unique_saturated_into(self) -> T
fn unique_saturated_into(self) -> T
T.