forge::backend

Trait DatabaseExt

Source
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§

Source

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.

Source

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.

Source

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.

Source

fn delete_state_snapshots(&mut self)

Deletes all state snapshots.

Source

fn create_fork(&mut self, fork: CreateFork) -> Result<Uint<256, 4>, Report>

Creates a new fork but does not select it

Source

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

Source

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

Source

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.

Source

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.

Source

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

Source

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

Source

fn active_fork_id(&self) -> Option<Uint<256, 4>>

Returns the ForkId that’s currently used in the database, if fork mode is on

Source

fn active_fork_url(&self) -> Option<String>

Returns the Fork url that’s currently used in the database, if fork mode is on

Source

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

Source

fn ensure_fork_id(&self, id: Uint<256, 4>) -> Result<&ForkId, Report>

Ensures that a corresponding ForkId exists for the given local id

Source

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

Source

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.

Source

fn clone_account( &mut self, source: &GenesisAccount, target: &Address, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>

Copies bytecode, storage, nonce and balance from the given genesis account to the target address.

Returns Ok if data was successfully inserted into the journal, Err otherwise.

Source

fn is_persistent(&self, acc: &Address) -> bool

Returns true if the given account is currently marked as persistent.

Source

fn remove_persistent_account(&mut self, account: &Address) -> bool

Revokes persistent status from the given account.

Source

fn add_persistent_account(&mut self, account: Address) -> bool

Marks the given account as persistent.

Source

fn allow_cheatcode_access(&mut self, account: Address) -> bool

Grants cheatcode access for the given account

Returns true if the account already has access

Source

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

Source

fn has_cheatcode_access(&self, account: &Address) -> bool

Returns true if the given account is allowed to execute cheatcodes

Source

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 for
  • hash - 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§

Source

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

Source

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

Source

fn is_forked_mode(&self) -> bool

Whether the database is currently in forked mode.

Source

fn remove_persistent_accounts( &mut self, accounts: impl IntoIterator<Item = Address>, )
where Self: Sized,

Removes persistent status from all given accounts.

Source

fn extend_persistent_accounts( &mut self, accounts: impl IntoIterator<Item = Address>, )
where Self: Sized,

Extends the persistent accounts with the accounts the iterator yields.

Source

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

Source

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

§

fn initialize_interp( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called before the interpreter is initialized. Read more
§

fn step( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called on each step of the interpreter. Read more
§

fn step_end( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called after 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, )

Called when a log is emitted.
§

fn call( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, inputs: &mut CallInputs, ) -> Option<CallOutcome>

Called whenever a call to a contract is about to start. Read more
§

fn call_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &CallInputs, outcome: CallOutcome, ) -> CallOutcome

Called when a call to a contract has concluded. Read more
§

fn create( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &mut CreateInputs, ) -> Option<CreateOutcome>

Called when a contract is about to be created. Read more
§

fn create_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, _call: &CreateInputs, outcome: CreateOutcome, ) -> CreateOutcome

Called when a contract has been created. Read more
§

fn eofcreate( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &mut EOFCreateInputs, ) -> Option<CreateOutcome>

Called when EOF creating is called. Read more
§

fn eofcreate_end( &mut self, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, _call: &EOFCreateInputs, outcome: CreateOutcome, ) -> CreateOutcome

Called when eof creating has ended.
§

fn selfdestruct( &mut self, contract: Address, target: Address, value: Uint<256, 4>, )

Called when a contract has been self-destructed with funds transferred to target.
Source§

impl Inspector<&mut dyn DatabaseExt<Error = DatabaseError>> for InspectorStack

Source§

fn step( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called on each step of the interpreter. Read more
Source§

fn step_end( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called after step when the instruction has been executed. Read more
Source§

fn call( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, inputs: &mut CallInputs, ) -> Option<CallOutcome>

Called whenever a call to a contract is about to start. Read more
Source§

fn call_end( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, inputs: &CallInputs, outcome: CallOutcome, ) -> CallOutcome

Called when a call to a contract has concluded. Read more
Source§

fn create( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, create: &mut CreateInputs, ) -> Option<CreateOutcome>

Called when a contract is about to be created. Read more
Source§

fn create_end( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &CreateInputs, outcome: CreateOutcome, ) -> CreateOutcome

Called when a contract has been created. Read more
Source§

fn eofcreate( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, create: &mut EOFCreateInputs, ) -> Option<CreateOutcome>

Called when EOF creating is called. Read more
Source§

fn eofcreate_end( &mut self, context: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, call: &EOFCreateInputs, outcome: CreateOutcome, ) -> CreateOutcome

Called when eof creating has ended.
Source§

fn initialize_interp( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, )

Called before the interpreter is initialized. Read more
Source§

fn log( &mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<&mut dyn DatabaseExt<Error = DatabaseError>>, log: &Log, )

Called when a log is emitted.
Source§

fn selfdestruct( &mut self, contract: Address, target: Address, value: Uint<256, 4>, )

Called when a contract has been self-destructed with funds transferred to target.

Implementations on Foreign Types§

Source§

impl<'a, T> DatabaseExt for &'a mut T

Source§

fn snapshot_state( &mut self, journaled_state: &JournaledState, env: &Env, ) -> Uint<256, 4>

Source§

fn revert_state( &mut self, id: Uint<256, 4>, journaled_state: &JournaledState, env: &mut Env, action: RevertStateSnapshotAction, ) -> Option<JournaledState>

Source§

fn delete_state_snapshot(&mut self, id: Uint<256, 4>) -> bool

Source§

fn delete_state_snapshots(&mut self)

Source§

fn create_select_fork( &mut self, fork: CreateFork, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<Uint<256, 4>, Report>

Source§

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>

Source§

fn create_fork(&mut self, fork: CreateFork) -> Result<Uint<256, 4>, Report>

Source§

fn create_fork_at_transaction( &mut self, fork: CreateFork, transaction: FixedBytes<32>, ) -> Result<Uint<256, 4>, Report>

Source§

fn select_fork( &mut self, id: Uint<256, 4>, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>

Source§

fn roll_fork( &mut self, id: Option<Uint<256, 4>>, block_number: u64, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>

Source§

fn roll_fork_to_transaction( &mut self, id: Option<Uint<256, 4>>, transaction: FixedBytes<32>, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<(), Report>

Source§

fn transact( &mut self, id: Option<Uint<256, 4>>, transaction: FixedBytes<32>, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<(), Report>

Source§

fn transact_from_tx( &mut self, transaction: &TransactionRequest, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<(), Report>

Source§

fn active_fork_id(&self) -> Option<Uint<256, 4>>

Source§

fn active_fork_url(&self) -> Option<String>

Source§

fn is_forked_mode(&self) -> bool

Source§

fn ensure_fork(&self, id: Option<Uint<256, 4>>) -> Result<Uint<256, 4>, Report>

Source§

fn ensure_fork_id(&self, id: Uint<256, 4>) -> Result<&ForkId, Report>

Source§

fn diagnose_revert( &self, callee: Address, journaled_state: &JournaledState, ) -> Option<RevertDiagnostic>

Source§

fn load_allocs( &mut self, allocs: &BTreeMap<Address, GenesisAccount>, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>

Source§

fn clone_account( &mut self, source: &GenesisAccount, target: &Address, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>

Source§

fn is_persistent(&self, acc: &Address) -> bool

Source§

fn remove_persistent_account(&mut self, account: &Address) -> bool

Source§

fn add_persistent_account(&mut self, account: Address) -> bool

Source§

fn allow_cheatcode_access(&mut self, account: Address) -> bool

Source§

fn revoke_cheatcode_access(&mut self, account: &Address) -> bool

Source§

fn has_cheatcode_access(&self, account: &Address) -> bool

Source§

fn ensure_cheatcode_access(&self, account: &Address) -> Result<(), BackendError>

Source§

fn ensure_cheatcode_access_forking_mode( &self, account: &Address, ) -> Result<(), BackendError>

Source§

fn set_blockhash( &mut self, block_number: Uint<256, 4>, block_hash: FixedBytes<32>, )

Implementors§