Trait Call
pub trait Call: LoadState + SpawnBlockingwhere
Self::Evm: ConfigureEvm,
<Self::Evm as ConfigureEvm>::Primitives: NodePrimitives<BlockHeader = <Self::Provider as HeaderProvider>::Header, SignedTx = <Self::Provider as TransactionsProvider>::Transaction>,
Self::Error: FromEvmError<Self::Evm>,{
// Required methods
fn call_gas_limit(&self) -> u64;
fn max_simulate_blocks(&self) -> u64;
fn create_txn_env(
&self,
evm_env: &EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: impl Database>,
) -> Result<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx, Self::Error>
where <impl Database as Database>::Error: Into<EthApiError>;
// Provided methods
fn with_state_at_block<F, R>(
&self,
at: BlockId,
f: F,
) -> Result<R, Self::Error>
where F: FnOnce(StateProviderTraitObjWrapper<'_>) -> Result<R, Self::Error> { ... }
fn transact<DB>(
&self,
db: DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx,
) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>
where DB: Database<Error = ProviderError> { ... }
fn transact_with_inspector<DB, I>(
&self,
db: DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx,
inspector: I,
) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>
where DB: Database<Error = ProviderError>,
I: InspectorFor<Self::Evm, DB> { ... }
fn transact_call_at(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
) -> impl Future<Output = Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>> + Send
where Self: LoadPendingBlock { ... }
fn spawn_with_state_at_block<F, R>(
&self,
at: BlockId,
f: F,
) -> impl Future<Output = Result<R, Self::Error>> + Send
where F: FnOnce(StateProviderTraitObjWrapper<'_>) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static { ... }
fn spawn_with_call_at<F, R>(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
f: F,
) -> impl Future<Output = Result<R, Self::Error>> + Send
where Self: LoadPendingBlock,
F: FnOnce(StateCacheDbRefMutWrapper<'_, '_>, EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static { ... }
fn spawn_replay_transaction<F, R>(
&self,
hash: FixedBytes<32>,
f: F,
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
where Self: LoadBlock + LoadTransaction,
F: FnOnce(TransactionInfo, ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'_>>>) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static { ... }
fn replay_transactions_until<'a, DB, I>(
&self,
db: &mut DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
transactions: I,
target_tx_hash: FixedBytes<32>,
) -> Result<usize, Self::Error>
where DB: Database<Error = ProviderError> + DatabaseCommit,
I: IntoIterator<Item = Recovered<&'a <Self::Provider as TransactionsProvider>::Transaction>> { ... }
fn prepare_call_env<DB>(
&self,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: &mut CacheDB<DB>,
overrides: EvmOverrides,
) -> Result<(EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx), Self::Error>
where DB: DatabaseRef,
EthApiError: From<<DB as DatabaseRef>::Error> { ... }
}
rpc
only.Expand description
Executes code on state.
Required Methods§
fn call_gas_limit(&self) -> u64
fn call_gas_limit(&self) -> u64
Returns default gas limit to use for eth_call
and tracing RPC methods.
Data access in default trait method implementations.
fn max_simulate_blocks(&self) -> u64
fn max_simulate_blocks(&self) -> u64
Returns the maximum number of blocks accepted for eth_simulateV1
.
fn create_txn_env(
&self,
evm_env: &EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: impl Database>,
) -> Result<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx, Self::Error>where
<impl Database as Database>::Error: Into<EthApiError>,
fn create_txn_env(
&self,
evm_env: &EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: impl Database>,
) -> Result<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx, Self::Error>where
<impl Database as Database>::Error: Into<EthApiError>,
Configures a new TxEnv
for the TransactionRequest
All TxEnv
fields are derived from the given TransactionRequest
, if fields are
None
, they fall back to the EvmEnv
’s settings.
Provided Methods§
fn with_state_at_block<F, R>(&self, at: BlockId, f: F) -> Result<R, Self::Error>
fn with_state_at_block<F, R>(&self, at: BlockId, f: F) -> Result<R, Self::Error>
Executes the closure with the state that corresponds to the given BlockId
.
fn transact<DB>(
&self,
db: DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx,
) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>where
DB: Database<Error = ProviderError>,
fn transact<DB>(
&self,
db: DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx,
) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>where
DB: Database<Error = ProviderError>,
Executes the TxEnv
against the given [Database] without committing state
changes.
fn transact_with_inspector<DB, I>(
&self,
db: DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx,
inspector: I,
) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>
fn transact_with_inspector<DB, I>( &self, db: DB, evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, tx_env: <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx, inspector: I, ) -> Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>
Executes the EvmEnv
against the given [Database] without committing state
changes.
fn transact_call_at(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
) -> impl Future<Output = Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>> + Sendwhere
Self: LoadPendingBlock,
fn transact_call_at(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
) -> impl Future<Output = Result<(ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, (EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx)), Self::Error>> + Sendwhere
Self: LoadPendingBlock,
Executes the call request at the given BlockId
.
fn spawn_with_state_at_block<F, R>(
&self,
at: BlockId,
f: F,
) -> impl Future<Output = Result<R, Self::Error>> + Send
fn spawn_with_state_at_block<F, R>( &self, at: BlockId, f: F, ) -> impl Future<Output = Result<R, Self::Error>> + Send
Executes the closure with the state that corresponds to the given BlockId
on a new task
fn spawn_with_call_at<F, R>(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
f: F,
) -> impl Future<Output = Result<R, Self::Error>> + Sendwhere
Self: LoadPendingBlock,
F: FnOnce(StateCacheDbRefMutWrapper<'_, '_>, EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static,
fn spawn_with_call_at<F, R>(
&self,
request: TransactionRequest,
at: BlockId,
overrides: EvmOverrides,
f: F,
) -> impl Future<Output = Result<R, Self::Error>> + Sendwhere
Self: LoadPendingBlock,
F: FnOnce(StateCacheDbRefMutWrapper<'_, '_>, EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static,
Prepares the state and env for the given TransactionRequest
at the given BlockId
and
executes the closure on a new task returning the result of the closure.
This returns the configured EvmEnv
for the given TransactionRequest
at
the given BlockId
and with configured call settings: prepare_call_env
.
This is primarily used by eth_call
.
§Blocking behaviour
This assumes executing the call is relatively more expensive on IO than CPU because it
transacts a single transaction on an empty in memory database. Because eth_call
s are
usually allowed to consume a lot of gas, this also allows a lot of memory operations so
we assume this is not primarily CPU bound and instead spawn the call on a regular tokio task
instead, where blocking IO is less problematic.
fn spawn_replay_transaction<F, R>(
&self,
hash: FixedBytes<32>,
f: F,
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Sendwhere
Self: LoadBlock + LoadTransaction,
F: FnOnce(TransactionInfo, ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'_>>>) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static,
fn spawn_replay_transaction<F, R>(
&self,
hash: FixedBytes<32>,
f: F,
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Sendwhere
Self: LoadBlock + LoadTransaction,
F: FnOnce(TransactionInfo, ResultAndState<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::HaltReason>, CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'_>>>) -> Result<R, Self::Error> + Send + 'static,
R: Send + 'static,
Retrieves the transaction if it exists and executes it.
Before the transaction is executed, all previous transaction in the block are applied to the
state by executing them first.
The callback f
is invoked with the [ResultAndState
] after the transaction was executed
and the database that points to the beginning of the transaction.
Note: Implementers should use a threadpool where blocking is allowed, such as
BlockingTaskPool
.
fn replay_transactions_until<'a, DB, I>(
&self,
db: &mut DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
transactions: I,
target_tx_hash: FixedBytes<32>,
) -> Result<usize, Self::Error>where
DB: Database<Error = ProviderError> + DatabaseCommit,
I: IntoIterator<Item = Recovered<&'a <Self::Provider as TransactionsProvider>::Transaction>>,
fn replay_transactions_until<'a, DB, I>(
&self,
db: &mut DB,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
transactions: I,
target_tx_hash: FixedBytes<32>,
) -> Result<usize, Self::Error>where
DB: Database<Error = ProviderError> + DatabaseCommit,
I: IntoIterator<Item = Recovered<&'a <Self::Provider as TransactionsProvider>::Transaction>>,
Replays all the transactions until the target transaction is found.
All transactions before the target transaction are executed and their changes are written to
the runtime db ([CacheDB
]).
Note: This assumes the target transaction is in the given iterator. Returns the index of the target transaction in the given iterator.
fn prepare_call_env<DB>(
&self,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: &mut CacheDB<DB>,
overrides: EvmOverrides,
) -> Result<(EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx), Self::Error>where
DB: DatabaseRef,
EthApiError: From<<DB as DatabaseRef>::Error>,
fn prepare_call_env<DB>(
&self,
evm_env: EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>,
request: TransactionRequest,
db: &mut CacheDB<DB>,
overrides: EvmOverrides,
) -> Result<(EvmEnv<<<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Spec>, <<<Self::Evm as ConfigureEvm>::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory as EvmFactory>::Tx), Self::Error>where
DB: DatabaseRef,
EthApiError: From<<DB as DatabaseRef>::Error>,
Prepares the EvmEnv
for execution of calls.
Does not commit any changes to the underlying database.
§EVM settings
This modifies certain EVM settings to mirror geth’s SkipAccountChecks
when transacting requests, see also: https://github.com/ethereum/go-ethereum/blob/380688c636a654becc8f114438c2a5d93d2db032/core/state_transition.go#L145-L148:
disable_eip3607
is set totrue
disable_base_fee
is set totrue
nonce
is set toNone
In addition, this changes the block’s gas limit to the configured Self::call_gas_limit
.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.