pub struct Finalized<Context, Value, Routine, Handler>(PhantomData<(Value, Context, Routine, Handler)>)
where
Context: Config,
Value: Portable,
Routine: Routines<BlockNumberFor<Context>>,
Handler: ForksHandler<Context, ForkLocalDepot>;Expand description
Marker type for finality-aware offchain storage, combining fork-aware and persistent state to derive confidence-graded values via routine-defined policies and observations.
Intended for Substrate FRAME-based runtimes only.
The Finalized storage model:
- records values speculatively using fork-aware storage,
- tracks historical observations in persistent storage,
- and exposes values only after evaluating time and observation-based finality guarantees.
Finality is determined by:
- a wall-clock time window (see
FinalizedPolicy), - and repeated successful observations.
This marker is used to specialize KeyValueStore implementations that
combine ForkAware and Persistent storage to provide confidence-graded
values (see Confidence).
§Behavioral contract
Any routine using Finalized storage must provide error policies for the
exact internal storage forms used by this model via
OffchainStorageError:
ForkAware<Context, ValueHash, Routine>, which stores speculative fork-local identity usingValueHash, andPersistent<Context, Ledger<Context, Moment<Context>, Value>, Routine>, which stores the persistent observation ledger usingLedgerand wall-clockMoment.
In addition, the routine must define:
- a
FinalizedPolicydescribing when a value becomes stable, and FinalizedOffchainStorageErrorvalues for finality-specific invariant violations.
Together, these requirements ensure that:
- fork-aware and persistent state remain consistent,
- semantic invariants are enforced at a single, centralized layer,
- and all failures are surfaced as caller-defined error signals and logged exactly once.
§Value-first semantics
This storage model is value-first: confidence is tied to the observed value, not just the key. If the same value is inserted again for the same key, its accumulated confidence is reset, as the insertion is treated as a fresh observation sequence.
Callers are therefore responsible for deciding whether repeated insertions of the same value are semantically meaningful. To avoid unintended confidence resets, routines should refrain from inserting identical values multiple times unless a reset is explicitly desired.
§Timestamp semantics
All logging and routine behavior associated with this storage model is
explicitly bound to block numbers via [BlockNumberFor<Context>].
This type does not accept a generic timestamp parameter.
Wall-clock time, when required for finality evaluation, is obtained
explicitly from [pallet_timestamp].
§Type parameters
Context: The active runtime type (i.e. a type implementing [frame_system::Config]). This binds the storage model to a specific runtime configuration.Value: The value type whose finality is being tracked.Routine: A routine type implementingRoutinesparameterized by [BlockNumberFor<Context>], allowing logging, error handling, policy evaluation, and invariant enforcement to be specialized at the type level.Handler: A type implementingForksHandlerusingForkLocalDepotthat manages the fork graph and scope tracking for this storage backend.
This type is a marker only and carries no runtime data.
Tuple Fields§
§0: PhantomData<(Value, Context, Routine, Handler)>Trait Implementations§
Source§impl<Context, Value, Routine, Handler> Clone for Finalized<Context, Value, Routine, Handler>where
Context: Config + Clone,
Value: Portable + Clone,
Routine: Routines<BlockNumberFor<Context>> + Clone,
Handler: ForksHandler<Context, ForkLocalDepot> + Clone,
impl<Context, Value, Routine, Handler> Clone for Finalized<Context, Value, Routine, Handler>where
Context: Config + Clone,
Value: Portable + Clone,
Routine: Routines<BlockNumberFor<Context>> + Clone,
Handler: ForksHandler<Context, ForkLocalDepot> + Clone,
Source§impl<Context, Value, Routine, Handler> Debug for Finalized<Context, Value, Routine, Handler>where
Context: Config + Debug,
Value: Portable + Debug,
Routine: Routines<BlockNumberFor<Context>> + Debug,
Handler: ForksHandler<Context, ForkLocalDepot> + Debug,
impl<Context, Value, Routine, Handler> Debug for Finalized<Context, Value, Routine, Handler>where
Context: Config + Debug,
Value: Portable + Debug,
Routine: Routines<BlockNumberFor<Context>> + Debug,
Handler: ForksHandler<Context, ForkLocalDepot> + Debug,
Source§impl<T, Value, Routine, Handler> KeyValueStore<Value, <<<T as Config>::Block as HeaderProvider>::HeaderT as Header>::Number> for Finalized<T, Value, Routine, Handler>where
T: Config,
Value: Portable,
Routine: FinalizedOffchainStorageError<T, Value> + FinalizedPolicy<T> + OffchainStorageError<Persistent<T, Ledger<T, Value>, Routine>> + OffchainStorageError<ForkAware<T, ValueHash, Routine, Handler>> + Routines<BlockNumberFor<T>>,
Handler: ForksHandler<T, ForkLocalDepot> + Logging<BlockNumberFor<T>, Level = LogLevel, Logger = DispatchError>,
KeyValueStore implementation for Finalized storage semantics.
impl<T, Value, Routine, Handler> KeyValueStore<Value, <<<T as Config>::Block as HeaderProvider>::HeaderT as Header>::Number> for Finalized<T, Value, Routine, Handler>where
T: Config,
Value: Portable,
Routine: FinalizedOffchainStorageError<T, Value> + FinalizedPolicy<T> + OffchainStorageError<Persistent<T, Ledger<T, Value>, Routine>> + OffchainStorageError<ForkAware<T, ValueHash, Routine, Handler>> + Routines<BlockNumberFor<T>>,
Handler: ForksHandler<T, ForkLocalDepot> + Logging<BlockNumberFor<T>, Level = LogLevel, Logger = DispatchError>,
KeyValueStore implementation for Finalized storage semantics.
This implementation materializes the behavioral contract defined by
Finalized by combining:
- fork-aware storage for speculative state,
- persistent storage for observation history,
- and routine-defined policies for finality evaluation and error signaling.
The required bounds ensure that the routine:
- defines when a value becomes stable (
FinalizedPolicy), - provides caller-defined error signals for finality invariants
(
FinalizedOffchainStorageError), - and supplies
OffchainStorageErrorerror policies for the exact storage forms used internally by this model for:
This guarantees that all storage failures and semantic violations are surfaced consistently as caller-defined errors and are logged exactly once at the correct abstraction layer.
Source§type Value = Confidence<Value>
type Value = Confidence<Value>
Return value type used when querying a key.
The value is wrapped in Confidence, representing a
confidence signal derived from the Finalized storage
model rather than a definitive truth or on-chain finality.
Source§fn insert(
key: &Self::Key,
value: &Value,
target: Option<&str>,
fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>,
) -> Result<(), Self::Logger>
fn insert( key: &Self::Key, value: &Value, target: Option<&str>, fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>, ) -> Result<(), Self::Logger>
Inserts a value speculatively under finality-aware semantics.
This operation:
- computes a stable
ValueHashfor fork-independent identity, - records the hash in fork-aware storage (speculative marker),
- and inserts or updates an
Observationin the persistent ledger.
No confidence is implied by insertion alone; this operation only records existence and initializes observation tracking.
Source§fn get(
key: &Self::Key,
target: Option<&str>,
fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>,
) -> Result<Option<Confidence<Value>>, Self::Logger>
fn get( key: &Self::Key, target: Option<&str>, fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>, ) -> Result<Option<Confidence<Value>>, Self::Logger>
Reads the value associated with the current fork and derives the
value wrapped in a Confidence signal.
Returned signals:
Confidence::Unsafe- finality window not elapsed.Confidence::Risky- time elapsed, insufficient block observations.Confidence::Safe- time and observation thresholds satisfied.
Any detected invariant violation (for example, a fork-aware hash without a ledger entry) is logged and cleaned up automatically.
Source§fn remove(
key: &Self::Key,
target: Option<&str>,
fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>,
) -> Result<Option<Value>, Self::Logger>
fn remove( key: &Self::Key, target: Option<&str>, fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>, ) -> Result<Option<Value>, Self::Logger>
Removes the value associated with the current fork.
Removal semantics:
- The fork-aware marker is always removed first.
- The corresponding persistent ledger entry is removed next.
- The ledger itself is deleted if it becomes empty.
This ensures no semantic or historical state is left behind once the value is no longer relevant.
Source§fn mutate<F>(
key: &Self::Key,
f: F,
target: Option<&str>,
fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>,
) -> Result<(), Self::Logger>
fn mutate<F>( key: &Self::Key, f: F, target: Option<&str>, fmt: Option<LogFormatter<BlockNumberFor<T>, Self::Level>>, ) -> Result<(), Self::Logger>
Mutates the value associated with a key under finality-aware semantics.
The closure f receives the current value, if any, and must return
a new value to replace it.
Replacing a value resets all finality observations: the new value is treated as freshly observed and must re-accumulate confidence.
The update is scoped to the current fork and preserves all storage invariants. Any detected invariant violation is logged once and cleaned up automatically before the error is returned.
impl<Context, Value, Routine, Handler> Copy for Finalized<Context, Value, Routine, Handler>where
Context: Config + Copy,
Value: Portable + Copy,
Routine: Routines<BlockNumberFor<Context>> + Copy,
Handler: ForksHandler<Context, ForkLocalDepot> + Copy,
Auto Trait Implementations§
impl<Context, Value, Routine, Handler> Freeze for Finalized<Context, Value, Routine, Handler>
impl<Context, Value, Routine, Handler> RefUnwindSafe for Finalized<Context, Value, Routine, Handler>
impl<Context, Value, Routine, Handler> Send for Finalized<Context, Value, Routine, Handler>
impl<Context, Value, Routine, Handler> Sync for Finalized<Context, Value, Routine, Handler>
impl<Context, Value, Routine, Handler> Unpin for Finalized<Context, Value, Routine, Handler>
impl<Context, Value, Routine, Handler> UnwindSafe for Finalized<Context, Value, Routine, Handler>
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> 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
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.