pub struct Storage<'a, D> { /* private fields */ }Expand description
Hierarchical storage abstraction over EVM account state.
Subspaces are derived from base_key using keccak-based mixing; direct
state I/O (when available) targets account. The struct is parameterised
over the executor’s Database so the same shape can be inhabited by an
executor &'a mut State<D> or by Detached for read paths that operate
purely through a [StorageBackend].
The lifetime 'a ties the handle to the originating &mut State<D> borrow
so a Storage value cannot outlive the state it references. The state is
held as a NonNull internally (with a PhantomData for the lifetime)
so multiple disjoint subspaces over the same state can coexist; direct I/O
goes through one unsafe deref controlled by the same SAFETY invariant
described below.
§Safety
All direct I/O methods on Storage<'a, D> materialise &mut *state for the
duration of a single SLOAD/SSTORE. The executor runs each block on a single
thread and the EVM call graph is sequential, so no two such borrows overlap
at runtime. The lifetime 'a ensures the underlying State<D> cannot be
dropped while Storage handles into it are alive.
Implementations§
Source§impl<'a, D> Storage<'a, D>
impl<'a, D> Storage<'a, D>
Sourcepub fn new(state: &'a mut State<D>, base_key: B256) -> Self
pub fn new(state: &'a mut State<D>, base_key: B256) -> Self
Creates a new Storage backed by the ArbOS state account.
Sourcepub fn new_with_account(
state: &'a mut State<D>,
base_key: B256,
account: Address,
) -> Self
pub fn new_with_account( state: &'a mut State<D>, base_key: B256, account: Address, ) -> Self
Creates a new Storage backed by a specific account.
Sourcepub fn open_sub_storage(&self, sub_key: &[u8]) -> Storage<'a, D>
pub fn open_sub_storage(&self, sub_key: &[u8]) -> Storage<'a, D>
Opens a child subspace by hashing the parent key with the child ID.
Sourcepub fn open_sub_storage_with_key(&self, key: B256) -> Storage<'a, D>
pub fn open_sub_storage_with_key(&self, key: B256) -> Storage<'a, D>
Opens a child subspace using a pre-derived key, avoiding a keccak hash.
Sourcepub fn open_account(&self, account: Address, base_key: B256) -> Storage<'a, D>
pub fn open_account(&self, account: Address, base_key: B256) -> Storage<'a, D>
Opens a sibling handle bound to the same backing state but targeting a
different account and base_key. Used when constructing accessors for
well-known non-ArbOS addresses (e.g. the filtered-transactions store).
Sourcepub fn new_slot(&self, offset: u64) -> U256
pub fn new_slot(&self, offset: u64) -> U256
Creates a StorageSlot handle for a specific offset.
Sourcepub fn slot_for_key(&self, key: B256) -> U256
pub fn slot_for_key(&self, key: B256) -> U256
Computes the EVM slot for a B256-keyed entry under this subspace.
Source§impl<'a, D: Database> Storage<'a, D>
impl<'a, D: Database> Storage<'a, D>
Sourcepub fn get_by_uint64(&self, offset: u64) -> Result<B256, StorageError>
pub fn get_by_uint64(&self, offset: u64) -> Result<B256, StorageError>
Reads a 32-byte value by uint64 offset.
Sourcepub fn set_by_uint64(
&self,
offset: u64,
value: B256,
) -> Result<(), StorageError>
pub fn set_by_uint64( &self, offset: u64, value: B256, ) -> Result<(), StorageError>
Writes a 32-byte value by uint64 offset.
Sourcepub fn get_uint64_by_uint64(&self, offset: u64) -> Result<u64, StorageError>
pub fn get_uint64_by_uint64(&self, offset: u64) -> Result<u64, StorageError>
Reads a u64 by uint64 offset, truncating values that exceed u64::MAX.
Sourcepub fn set_uint64_by_uint64(
&self,
offset: u64,
value: u64,
) -> Result<(), StorageError>
pub fn set_uint64_by_uint64( &self, offset: u64, value: u64, ) -> Result<(), StorageError>
Writes a u64 by uint64 offset.
Sourcepub fn get(&self, key: B256) -> Result<B256, StorageError>
pub fn get(&self, key: B256) -> Result<B256, StorageError>
Reads a 32-byte value by B256 key using mapAddress algorithm.
Sourcepub fn set(&self, key: B256, value: B256) -> Result<(), StorageError>
pub fn set(&self, key: B256, value: B256) -> Result<(), StorageError>
Writes a 32-byte value by B256 key using mapAddress algorithm.
Source§impl<'a, D> Storage<'a, D>
impl<'a, D> Storage<'a, D>
Sourcepub unsafe fn state_mut(&self) -> &'a mut State<D>
pub unsafe fn state_mut(&self) -> &'a mut State<D>
Re-borrows the underlying state for direct State<D>-level operations
(e.g. account-level reads such as get_account_balance and writes such
as set_account_nonce/set_account_code).
The returned reference inherits the lifetime parameter 'a of the
Storage, so it is decoupled from any temporary borrow on &self.
This shape lets callers thread the same backing state through methods
that take &mut self without artificial borrow conflicts.
§Safety
arbreth’s executor runs each block on a single thread and the EVM call
graph is sequential, so no two such borrows are live at the same time
at runtime. Callers must not nest two state_mut() returns from
overlapping Storage handles.
Trait Implementations§
Source§impl<D: Database> StorageBackend for Storage<'_, D>
impl<D: Database> StorageBackend for Storage<'_, D>
Source§fn sload(&mut self, account: Address, slot: U256) -> Result<U256, StorageError>
fn sload(&mut self, account: Address, slot: U256) -> Result<U256, StorageError>
(account, slot). Reads through StorageBackend
follow the host’s normal storage path (journaled when invoked on
EvmInternals); for non-journaled reads see SystemStateBackend.Source§impl<D: Database> SystemStateBackend for Storage<'_, D>
impl<D: Database> SystemStateBackend for Storage<'_, D>
Source§type Error = StorageError
type Error = StorageError
StorageError so callers can stay uniform.Source§fn sload_system(
&mut self,
account: Address,
slot: U256,
) -> Result<U256, Self::Error>
fn sload_system( &mut self, account: Address, slot: U256, ) -> Result<U256, Self::Error>
(account, slot) without journaling.impl<D: Send> Send for Storage<'_, D>
impl<D: Sync> Sync for Storage<'_, D>
Auto Trait Implementations§
impl<'a, D> Freeze for Storage<'a, D>
impl<'a, D> RefUnwindSafe for Storage<'a, D>where
D: RefUnwindSafe,
impl<'a, D> Unpin for Storage<'a, D>
impl<'a, D> !UnwindSafe for Storage<'a, D>
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
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<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<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
impl<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
§fn from_recovered_tx(tx: &&T, sender: Address) -> TxEnv
fn from_recovered_tx(tx: &&T, sender: Address) -> TxEnv
TxEnv] from a transaction and a sender address.§impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
§fn from_encoded_tx(tx: &&T, sender: Address, encoded: Bytes) -> TxEnv
fn from_encoded_tx(tx: &&T, sender: Address, encoded: Bytes) -> TxEnv
TxEnv] from a transaction, its sender, and encoded transaction bytes.§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 more§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> 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.