Trait DatabaseExt
pub trait DatabaseExt: Database<Error = DatabaseError> + DatabaseCommit {
Show 32 methods
// Required methods
fn snapshot_state(
&mut self,
journaled_state: &JournaledState,
env: &Env,
) -> Uint<256, 4>;
fn revert_state(
&mut self,
id: Uint<256, 4>,
journaled_state: &JournaledState,
env: &mut Env,
action: RevertStateSnapshotAction,
) -> Option<JournaledState>;
fn delete_state_snapshot(&mut self, id: Uint<256, 4>) -> bool;
fn delete_state_snapshots(&mut self);
fn create_fork(&mut self, fork: CreateFork) -> Result<Uint<256, 4>, Report>;
fn create_fork_at_transaction(
&mut self,
fork: CreateFork,
transaction: FixedBytes<32>,
) -> Result<Uint<256, 4>, Report>;
fn select_fork(
&mut self,
id: Uint<256, 4>,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>;
fn roll_fork(
&mut self,
id: Option<Uint<256, 4>>,
block_number: u64,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>;
fn roll_fork_to_transaction(
&mut self,
id: Option<Uint<256, 4>>,
transaction: FixedBytes<32>,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>;
fn transact(
&mut self,
id: Option<Uint<256, 4>>,
transaction: FixedBytes<32>,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<(), Report>;
fn transact_from_tx(
&mut self,
transaction: &TransactionRequest,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<(), Report>;
fn active_fork_id(&self) -> Option<Uint<256, 4>>;
fn active_fork_url(&self) -> Option<String>;
fn ensure_fork(
&self,
id: Option<Uint<256, 4>>,
) -> Result<Uint<256, 4>, Report>;
fn ensure_fork_id(&self, id: Uint<256, 4>) -> Result<&ForkId, Report>;
fn diagnose_revert(
&self,
callee: Address,
journaled_state: &JournaledState,
) -> Option<RevertDiagnostic>;
fn load_allocs(
&mut self,
allocs: &BTreeMap<Address, GenesisAccount>,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>;
fn clone_account(
&mut self,
source: &GenesisAccount,
target: &Address,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>;
fn is_persistent(&self, acc: &Address) -> bool;
fn remove_persistent_account(&mut self, account: &Address) -> bool;
fn add_persistent_account(&mut self, account: Address) -> bool;
fn allow_cheatcode_access(&mut self, account: Address) -> bool;
fn revoke_cheatcode_access(&mut self, account: &Address) -> bool;
fn has_cheatcode_access(&self, account: &Address) -> bool;
fn set_blockhash(
&mut self,
block_number: Uint<256, 4>,
block_hash: FixedBytes<32>,
);
// Provided methods
fn create_select_fork(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<Uint<256, 4>, Report> { ... }
fn create_select_fork_at_transaction(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
transaction: FixedBytes<32>,
) -> Result<Uint<256, 4>, Report> { ... }
fn is_forked_mode(&self) -> bool { ... }
fn remove_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)
where Self: Sized { ... }
fn extend_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)
where Self: Sized { ... }
fn ensure_cheatcode_access(
&self,
account: &Address,
) -> Result<(), BackendError> { ... }
fn ensure_cheatcode_access_forking_mode(
&self,
account: &Address,
) -> Result<(), BackendError> { ... }
}
Expand description
An extension trait that allows us to easily extend the revm::Inspector
capabilities
Required Methods§
fn snapshot_state(
&mut self,
journaled_state: &JournaledState,
env: &Env,
) -> Uint<256, 4>
fn snapshot_state( &mut self, journaled_state: &JournaledState, env: &Env, ) -> Uint<256, 4>
Creates a new state snapshot at the current point of execution.
A state snapshot is associated with a new unique id that’s created for the snapshot. State snapshots can be reverted: DatabaseExt::revert_state, however, depending on the RevertStateSnapshotAction, it will keep the snapshot alive or delete it.
fn revert_state(
&mut self,
id: Uint<256, 4>,
journaled_state: &JournaledState,
env: &mut Env,
action: RevertStateSnapshotAction,
) -> Option<JournaledState>
fn revert_state( &mut self, id: Uint<256, 4>, journaled_state: &JournaledState, env: &mut Env, action: RevertStateSnapshotAction, ) -> Option<JournaledState>
Reverts the snapshot if it exists
Returns true
if the snapshot was successfully reverted, false
if no snapshot for that id
exists.
N.B. While this reverts the state of the evm to the snapshot, it keeps new logs made
since the snapshots was created. This way we can show logs that were emitted between
snapshot and its revert.
This will also revert any changes in the Env
and replace it with the captured Env
of
Self::snapshot_state
.
Depending on RevertStateSnapshotAction it will keep the snapshot alive or delete it.
fn delete_state_snapshot(&mut self, id: Uint<256, 4>) -> bool
fn delete_state_snapshot(&mut self, id: Uint<256, 4>) -> bool
Deletes the state snapshot with the given id
Returns true
if the snapshot was successfully deleted, false
if no snapshot for that id
exists.
fn delete_state_snapshots(&mut self)
fn delete_state_snapshots(&mut self)
Deletes all state snapshots.
fn create_fork(&mut self, fork: CreateFork) -> Result<Uint<256, 4>, Report>
fn create_fork(&mut self, fork: CreateFork) -> Result<Uint<256, 4>, Report>
Creates a new fork but does not select it
fn create_fork_at_transaction(
&mut self,
fork: CreateFork,
transaction: FixedBytes<32>,
) -> Result<Uint<256, 4>, Report>
fn create_fork_at_transaction( &mut self, fork: CreateFork, transaction: FixedBytes<32>, ) -> Result<Uint<256, 4>, Report>
Creates a new fork but does not select it
fn select_fork(
&mut self,
id: Uint<256, 4>,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>
fn select_fork( &mut self, id: Uint<256, 4>, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>
Selects the fork’s state
This will also modify the current Env
.
Note: this does not change the local state, but swaps the remote state
§Errors
Returns an error if no fork with the given id
exists
fn roll_fork(
&mut self,
id: Option<Uint<256, 4>>,
block_number: u64,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>
fn roll_fork( &mut self, id: Option<Uint<256, 4>>, block_number: u64, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>
Updates the fork to given block number.
This will essentially create a new fork at the given block height.
§Errors
Returns an error if not matching fork was found.
fn roll_fork_to_transaction(
&mut self,
id: Option<Uint<256, 4>>,
transaction: FixedBytes<32>,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<(), Report>
fn roll_fork_to_transaction( &mut self, id: Option<Uint<256, 4>>, transaction: FixedBytes<32>, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>
Updates the fork to given transaction hash
This will essentially create a new fork at the block this transaction was mined and replays all transactions up until the given transaction.
§Errors
Returns an error if not matching fork was found.
fn transact(
&mut self,
id: Option<Uint<256, 4>>,
transaction: FixedBytes<32>,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<(), Report>
fn transact( &mut self, id: Option<Uint<256, 4>>, transaction: FixedBytes<32>, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<(), Report>
Fetches the given transaction for the fork and executes it, committing the state in the DB
fn transact_from_tx(
&mut self,
transaction: &TransactionRequest,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<(), Report>
fn transact_from_tx( &mut self, transaction: &TransactionRequest, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<(), Report>
Executes a given TransactionRequest, commits the new state to the DB
fn active_fork_id(&self) -> Option<Uint<256, 4>>
fn active_fork_id(&self) -> Option<Uint<256, 4>>
Returns the ForkId
that’s currently used in the database, if fork mode is on
fn active_fork_url(&self) -> Option<String>
fn active_fork_url(&self) -> Option<String>
Returns the Fork url that’s currently used in the database, if fork mode is on
fn ensure_fork(&self, id: Option<Uint<256, 4>>) -> Result<Uint<256, 4>, Report>
fn ensure_fork(&self, id: Option<Uint<256, 4>>) -> Result<Uint<256, 4>, Report>
Ensures that an appropriate fork exists
If id
contains a requested Fork
this will ensure it exists.
Otherwise, this returns the currently active fork.
§Errors
Returns an error if the given id
does not match any forks
Returns an error if no fork exists
fn ensure_fork_id(&self, id: Uint<256, 4>) -> Result<&ForkId, Report>
fn ensure_fork_id(&self, id: Uint<256, 4>) -> Result<&ForkId, Report>
Ensures that a corresponding ForkId
exists for the given local id
fn diagnose_revert(
&self,
callee: Address,
journaled_state: &JournaledState,
) -> Option<RevertDiagnostic>
fn diagnose_revert( &self, callee: Address, journaled_state: &JournaledState, ) -> Option<RevertDiagnostic>
Handling multiple accounts/new contracts in a multifork environment can be challenging since every fork has its own standalone storage section. So this can be a common error to run into:
function testCanDeploy() public {
vm.selectFork(mainnetFork);
// contract created while on `mainnetFork`
DummyContract dummy = new DummyContract();
// this will succeed
dummy.hello();
vm.selectFork(optimismFork);
vm.expectRevert();
// this will revert since `dummy` contract only exists on `mainnetFork`
dummy.hello();
}
If this happens (dummy.hello()
), or more general, a call on an address that’s not a
contract, revm will revert without useful context. This call will check in this context if
address(dummy)
belongs to an existing contract and if not will check all other forks if
the contract is deployed there.
Returns a more useful error message if that’s the case
fn load_allocs(
&mut self,
allocs: &BTreeMap<Address, GenesisAccount>,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>
fn load_allocs( &mut self, allocs: &BTreeMap<Address, GenesisAccount>, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>
Loads the account allocs from the given allocs
map into the passed JournaledState.
Returns Ok if all accounts were successfully inserted into the journal, Err otherwise.
fn clone_account(
&mut self,
source: &GenesisAccount,
target: &Address,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>
fn clone_account( &mut self, source: &GenesisAccount, target: &Address, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>
fn is_persistent(&self, acc: &Address) -> bool
fn is_persistent(&self, acc: &Address) -> bool
Returns true if the given account is currently marked as persistent.
fn remove_persistent_account(&mut self, account: &Address) -> bool
fn remove_persistent_account(&mut self, account: &Address) -> bool
Revokes persistent status from the given account.
fn add_persistent_account(&mut self, account: Address) -> bool
fn add_persistent_account(&mut self, account: Address) -> bool
Marks the given account as persistent.
fn allow_cheatcode_access(&mut self, account: Address) -> bool
fn allow_cheatcode_access(&mut self, account: Address) -> bool
Grants cheatcode access for the given account
Returns true if the account
already has access
fn revoke_cheatcode_access(&mut self, account: &Address) -> bool
fn revoke_cheatcode_access(&mut self, account: &Address) -> bool
Revokes cheatcode access for the given account
Returns true if the account
was previously allowed cheatcode access
fn has_cheatcode_access(&self, account: &Address) -> bool
fn has_cheatcode_access(&self, account: &Address) -> bool
Returns true
if the given account is allowed to execute cheatcodes
fn set_blockhash(
&mut self,
block_number: Uint<256, 4>,
block_hash: FixedBytes<32>,
)
fn set_blockhash( &mut self, block_number: Uint<256, 4>, block_hash: FixedBytes<32>, )
Set the blockhash for a given block number.
§Arguments
number
- The block number to set the blockhash forhash
- The blockhash to set
§Note
This function mimics the EVM limits of the blockhash
operation:
- It sets the blockhash for blocks where
block.number - 256 <= number < block.number
- Setting a blockhash for the current block (number == block.number) has no effect
- Setting a blockhash for future blocks (number > block.number) has no effect
- Setting a blockhash for blocks older than
block.number - 256
has no effect
Provided Methods§
fn create_select_fork(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<Uint<256, 4>, Report>
fn create_select_fork( &mut self, fork: CreateFork, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<Uint<256, 4>, Report>
Creates and also selects a new fork
This is basically create_fork
+ select_fork
fn create_select_fork_at_transaction(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
transaction: FixedBytes<32>,
) -> Result<Uint<256, 4>, Report>
fn create_select_fork_at_transaction( &mut self, fork: CreateFork, env: &mut Env, journaled_state: &mut JournaledState, transaction: FixedBytes<32>, ) -> Result<Uint<256, 4>, Report>
Creates and also selects a new fork
This is basically create_fork
+ select_fork
fn is_forked_mode(&self) -> bool
fn is_forked_mode(&self) -> bool
Whether the database is currently in forked mode.
fn remove_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
fn remove_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
Removes persistent status from all given accounts.
fn extend_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
fn extend_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
Extends the persistent accounts with the accounts the iterator yields.
fn ensure_cheatcode_access(&self, account: &Address) -> Result<(), BackendError>
fn ensure_cheatcode_access(&self, account: &Address) -> Result<(), BackendError>
Ensures that account
is allowed to execute cheatcodes
Returns an error if Self::has_cheatcode_access
returns false
fn ensure_cheatcode_access_forking_mode(
&self,
account: &Address,
) -> Result<(), BackendError>
fn ensure_cheatcode_access_forking_mode( &self, account: &Address, ) -> Result<(), BackendError>
Same as Self::ensure_cheatcode_access()
but only enforces it if the backend is currently
in forking mode
Trait Implementations§
§impl Inspector<&mut dyn DatabaseExt<Error = DatabaseError>> for Cheatcodes
impl Inspector<&mut dyn DatabaseExt<Error = DatabaseError>> for Cheatcodes
§fn initialize_interp(
&mut self,
interpreter: &mut Interpreter,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
)
fn initialize_interp( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )
§fn step(
&mut self,
interpreter: &mut Interpreter,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
)
fn step( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )
§fn step_end(
&mut self,
interpreter: &mut Interpreter,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
)
fn step_end( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )
step
when the instruction has been executed. Read more§fn log(
&mut self,
interpreter: &mut Interpreter,
_ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
log: &Log,
)
fn log( &mut self, interpreter: &mut Interpreter, _ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, log: &Log, )
§fn call(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
inputs: &mut CallInputs,
) -> Option<CallOutcome>
fn call( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, inputs: &mut CallInputs, ) -> Option<CallOutcome>
§fn call_end(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
call: &CallInputs,
outcome: CallOutcome,
) -> CallOutcome
fn call_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &CallInputs, outcome: CallOutcome, ) -> CallOutcome
§fn create(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
call: &mut CreateInputs,
) -> Option<CreateOutcome>
fn create( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &mut CreateInputs, ) -> Option<CreateOutcome>
§fn create_end(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
_call: &CreateInputs,
outcome: CreateOutcome,
) -> CreateOutcome
fn create_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, _call: &CreateInputs, outcome: CreateOutcome, ) -> CreateOutcome
§fn eofcreate(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
call: &mut EOFCreateInputs,
) -> Option<CreateOutcome>
fn eofcreate( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &mut EOFCreateInputs, ) -> Option<CreateOutcome>
§fn eofcreate_end(
&mut self,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
_call: &EOFCreateInputs,
outcome: CreateOutcome,
) -> CreateOutcome
fn eofcreate_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, _call: &EOFCreateInputs, outcome: CreateOutcome, ) -> CreateOutcome
§fn selfdestruct(
&mut self,
contract: Address,
target: Address,
value: Uint<256, 4>,
)
fn selfdestruct( &mut self, contract: Address, target: Address, value: Uint<256, 4>, )
§impl Inspector<&mut dyn DatabaseExt<Error = DatabaseError>> for InspectorStack
impl Inspector<&mut dyn DatabaseExt<Error = DatabaseError>> for InspectorStack
§fn step(
&mut self,
interpreter: &mut Interpreter,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
)
fn step( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )
§fn step_end(
&mut self,
interpreter: &mut Interpreter,
ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>,
)
fn step_end( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )
step
when the instruction has been executed. Read more