pub struct ReactiveRuntime<N: Network = Ethereum> { /* private fields */ }Expand description
Reactive runtime.
Implementations§
Source§impl<N: Network> ReactiveRuntime<N>
impl<N: Network> ReactiveRuntime<N>
Sourcepub fn new(config: ReactiveConfig) -> Self
pub fn new(config: ReactiveConfig) -> Self
Create an empty runtime.
Sourcepub fn track_account(&mut self, address: Address, policy: TrackingPolicy)
pub fn track_account(&mut self, address: Address, policy: TrackingPolicy)
Track address under policy for the per-block root gate (Phase-8 step 4).
Tracking is strictly opt-in: a runtime with no tracked accounts runs the
gate as a no-op. Registering an account clears any baseline it held (a
policy change re-adopts on the next probe rather than diffing against a
baseline captured under the old policy). Each RootGateCadence
firing, the gate
probes tracked WholeAccount and
Scalars accounts’ roots/fields via the
account-proof seam and, on a move no decoder covered, emits a
ReactiveReport::CoverageGap and schedules a
ResyncReason::RootMoved repair. Slots
accounts are never root-gated (spec Decision 3).
Sourcepub fn untrack_account(&mut self, address: Address) -> bool
pub fn untrack_account(&mut self, address: Address) -> bool
Stop tracking address, dropping its policy and any adopted baseline.
Returns true if the account was tracked.
Sourcepub fn set_root_gate_cadence(&mut self, cadence: RootGateCadence)
pub fn set_root_gate_cadence(&mut self, cadence: RootGateCadence)
Set how often the root gate probes tracked accounts (default:
RootGateCadence::default — every 16 canonical blocks; see the
RootGateCadence docs for why skipping blocks loses no detection).
Reconfiguring resets the gate’s window bookkeeping (the touched-address accumulator and the last-fired block), so a stale window never leaks into the new cadence: the next canonical block fires the gate.
Sourcepub fn root_gate_cadence(&self) -> RootGateCadence
pub fn root_gate_cadence(&self) -> RootGateCadence
The configured RootGateCadence.
Sourcepub fn enable_freshness_stamping(&mut self)
pub fn enable_freshness_stamping(&mut self)
Enable freshness stamping of canonical event-derived writes (opt-in).
Installs a FreshnessRegistry the runtime owns; while it is present,
applying a canonical handler storage-slot effect for a block N stamps the
touched (address, slot) as
Validity::ValidThrough(N).
The slot is therefore not volatile at N (event-maintained, no need to
re-verify) but ages to volatile once the clock passes N.
Idempotent: if a registry is already installed it is left untouched, so an existing registry (and any stamps it holds) is never clobbered.
Sourcepub fn freshness(&self) -> Option<&FreshnessRegistry>
pub fn freshness(&self) -> Option<&FreshnessRegistry>
Borrow the runtime’s freshness registry, if stamping was enabled.
Returns None unless
enable_freshness_stamping was called.
Sourcepub fn freshness_mut(&mut self) -> Option<&mut FreshnessRegistry>
pub fn freshness_mut(&mut self) -> Option<&mut FreshnessRegistry>
Mutably borrow the runtime’s freshness registry, if stamping was enabled.
Returns None unless
enable_freshness_stamping was called.
Sourcepub fn health(&self) -> CacheHealth
pub fn health(&self) -> CacheHealth
Return the current queryable CacheHealth of the runtime.
Sourcepub fn metrics(&self) -> CacheMetricsSnapshot
pub fn metrics(&self) -> CacheMetricsSnapshot
Return a point-in-time snapshot of the runtime’s observability counters.
Sourcepub fn reset_health(&mut self)
pub fn reset_health(&mut self)
Complete the caller-driven self-heal by returning health to
CacheHealth::Healthy.
A trust-loss event (a reorg deeper than the journal, or a detected missed
block range) escalates health toward CacheHealth::Unhealthy as a
“stop until rebuilt” signal that the caller must act on. Once the caller
has resynced or rebuilt the affected state, it invokes this to clear the
signal. It does not emit a ReactiveReport::Health report, since it is
called outside an ingest cycle.
Sourcepub fn register_handler(
&mut self,
handler: Arc<dyn ReactiveHandler<N>>,
) -> Result<(), RegisterError>
pub fn register_handler( &mut self, handler: Arc<dyn ReactiveHandler<N>>, ) -> Result<(), RegisterError>
Register a handler.
Sourcepub fn unregister_handler(
&mut self,
id: &HandlerId,
) -> Option<Arc<dyn ReactiveHandler<N>>>
pub fn unregister_handler( &mut self, id: &HandlerId, ) -> Option<Arc<dyn ReactiveHandler<N>>>
Remove one handler from the runtime registry without resetting runtime state.
This delegates to ReactiveRegistry::unregister_handler only. It does
not clear the reorg journal, health, metrics, hooks, pending resyncs,
tracking policy, freshness registry, or root-gate baselines, and it does
not purge EvmCache state. Callers that want cache eviction must issue
explicit StateUpdate::purge updates or use cache purge APIs separately.
Sourcepub fn contains_handler(&self, id: &HandlerId) -> bool
pub fn contains_handler(&self, id: &HandlerId) -> bool
Return true when the runtime has a registered handler with id.
Sourcepub fn handler_ids(&self) -> Vec<HandlerId>
pub fn handler_ids(&self) -> Vec<HandlerId>
Ids of all registered handlers, in registration (= routing) order.
Sourcepub fn handler_interests(
&self,
id: &HandlerId,
) -> Option<&[ReactiveInterest<N>]>
pub fn handler_interests( &self, id: &HandlerId, ) -> Option<&[ReactiveInterest<N>]>
Borrow the interests owned by one registered handler.
Sourcepub fn last_canonical_block(&self) -> Option<BlockRef>
pub fn last_canonical_block(&self) -> Option<BlockRef>
The most recently journaled canonical block, if any.
This is the runtime’s current chain position: the canonical block most
recently recorded by ingestion. Reorged blocks are dropped from the
journal during recovery, so a rolled-back head does not linger here.
ReactiveEngine::register_handler uses it as the default backfill
anchor for handlers registered mid-lifecycle. None until the first
canonical input is journaled, and always None when
ReactiveConfig::journal_depth is 0 (journaling disabled).
Sourcepub fn pending_resyncs(&self) -> &[ResyncRequest]
pub fn pending_resyncs(&self) -> &[ResyncRequest]
Queued resync requests: surfaced by handlers but not yet executed by an
ingest_batch_with_resync pass.
Callers driving resync execution themselves (plain
ingest_batch loops) can read the ledger here;
reorg recovery cancels entries whose pinned blocks were dropped, and
cancel_pending_resyncs drops entries
for torn-down accounts.
Sourcepub fn cancel_pending_resyncs(&mut self, address: Address) -> Vec<ResyncRequest>
pub fn cancel_pending_resyncs(&mut self, address: Address) -> Vec<ResyncRequest>
Cancel queued resync work that targets address, returning the
cancelled portions.
Every pending ResyncRequest target referencing address is removed;
a request reduced to zero targets is dropped entirely, while
mixed-target requests keep their other accounts queued. Each returned
request mirrors the original id/reason/block/priority and carries only
the targets that were cancelled.
This is part of the adapter-teardown recipe (see
ReactiveEngine::unregister_handler): it clears the pending ledger so
a dropped pool’s queued repairs stop occupying memory and stop
surfacing as cancellations in reorg reports. It cannot recall requests
already returned to the caller in earlier batch reports.
Sourcepub fn register_hook(
&mut self,
hook: Arc<dyn ReactiveHook<N>>,
) -> Result<(), RegisterError>
pub fn register_hook( &mut self, hook: Arc<dyn ReactiveHook<N>>, ) -> Result<(), RegisterError>
Register a hook.
Sourcepub fn interests(&self) -> Vec<ReactiveInterest<N>>
pub fn interests(&self) -> Vec<ReactiveInterest<N>>
Return all registered interests in handler registration order.
Sourcepub fn ingest_batch(
&mut self,
cache: &mut EvmCache,
batch: ReactiveInputBatch<N>,
) -> Result<ReactiveBatchReport<N>, ReactiveError>
pub fn ingest_batch( &mut self, cache: &mut EvmCache, batch: ReactiveInputBatch<N>, ) -> Result<ReactiveBatchReport<N>, ReactiveError>
Ingest a batch, apply valid direct state effects, and dispatch reports.
Sourcepub fn ingest_batch_with_resync(
&mut self,
cache: &mut EvmCache,
batch: ReactiveInputBatch<N>,
) -> Result<ReactiveBatchReport<N>, ReactiveError>
pub fn ingest_batch_with_resync( &mut self, cache: &mut EvmCache, batch: ReactiveInputBatch<N>, ) -> Result<ReactiveBatchReport<N>, ReactiveError>
Ingest a batch, then execute surfaced storage resync requests.
This entrypoint preserves ingest_batch behavior for
direct handler effects, then runs a synchronous resync phase over the
collected ResyncRequests. Storage targets are fetched through
EvmCache::storage_batch_fetcher grouped by ResyncBlock, successful
values are applied as StateUpdate::slot updates through
EvmCache::apply_updates, and unsupported or failed targets are reported
in ResyncReport::failed. It does not start subscribers, background
workers, or network transport.
Auto Trait Implementations§
impl<N = Ethereum> !Freeze for ReactiveRuntime<N>
impl<N = Ethereum> !RefUnwindSafe for ReactiveRuntime<N>
impl<N = Ethereum> !UnwindSafe for ReactiveRuntime<N>
impl<N> Send for ReactiveRuntime<N>
impl<N> Sync for ReactiveRuntime<N>
impl<N> Unpin for ReactiveRuntime<N>where
N: Unpin,
impl<N> UnsafeUnpin for ReactiveRuntime<N>
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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> 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> 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.Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
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.