Skip to content

Commit

Permalink
chore: snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
popzxc committed Dec 18, 2024
1 parent 1876c01 commit d92ad57
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 226 deletions.
52 changes: 24 additions & 28 deletions crates/evm/core/src/backend/cow.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A wrapper around `Backend` that is clone-on-write used for fuzzing.
use super::{strategy::BackendStrategyExt, BackendError, ForkInfo};
use super::{strategy::BackendStrategy, BackendError, ForkInfo};
use crate::{
backend::{
diagnostic::RevertDiagnostic, Backend, DatabaseExt, LocalForkId, RevertStateSnapshotAction,
Expand All @@ -15,7 +15,7 @@ use foundry_fork_db::DatabaseError;
use revm::{
db::DatabaseRef,
primitives::{Account, AccountInfo, Bytecode, Env, EnvWithHandlerCfg, HashMap as Map, SpecId},
Database, DatabaseCommit, JournaledState,
Database, DatabaseCommit,
};
use std::{borrow::Cow, collections::BTreeMap};

Expand All @@ -36,24 +36,24 @@ use std::{borrow::Cow, collections::BTreeMap};
/// which would add significant overhead for large fuzz sets even if the Database is not big after
/// setup.
#[derive(Clone, Debug)]
pub struct CowBackend<'a> {
pub struct CowBackend<'a, S: BackendStrategy> {
/// The underlying `Backend`.
///
/// No calls on the `CowBackend` will ever persistently modify the `backend`'s state.
pub backend: Cow<'a, Backend>,
pub backend: Cow<'a, Backend<S>>,
/// Keeps track of whether the backed is already initialized
pub is_initialized: bool,
/// The [SpecId] of the current backend.
pub spec_id: SpecId,
}

impl<'a> CowBackend<'a> {
impl<'a, S: BackendStrategy> CowBackend<'a, S> {
/// Creates a new `CowBackend` with the given `Backend`.
pub fn new(backend: &'a Backend) -> Self {
pub fn new(backend: &'a Backend<S>) -> Self {
Self { backend: Cow::Borrowed(backend), is_initialized: false, spec_id: SpecId::LATEST }
}

pub fn new_borrowed(backend: &'a Backend) -> Self {
pub fn new_borrowed(backend: &'a Backend<S>) -> Self {
Self { backend: Cow::Borrowed(backend), is_initialized: false, spec_id: SpecId::LATEST }
}

Expand All @@ -67,7 +67,7 @@ impl<'a> CowBackend<'a> {
/// Returns a mutable instance of the Backend.
///
/// If this is the first time this is called, the backed is cloned and initialized.
fn backend_mut(&mut self, env: &Env) -> &mut Backend {
fn backend_mut(&mut self, env: &Env) -> &mut Backend<S> {
if !self.is_initialized {
let backend = self.backend.to_mut();
let env = EnvWithHandlerCfg::new_with_spec_id(Box::new(env.clone()), self.spec_id);
Expand All @@ -79,34 +79,30 @@ impl<'a> CowBackend<'a> {
}

/// Returns a mutable instance of the Backend if it is initialized.
fn initialized_backend_mut(&mut self) -> Option<&mut Backend> {
fn initialized_backend_mut(&mut self) -> Option<&mut Backend<S>> {
if self.is_initialized {
return Some(self.backend.to_mut())
}
None
}
}

impl DatabaseExt for CowBackend<'_> {
impl<S: BackendStrategy> DatabaseExt<S> for CowBackend<'_, S> {
fn get_fork_info(&mut self, id: LocalForkId) -> eyre::Result<ForkInfo> {
self.backend.to_mut().get_fork_info(id)
}

fn get_strategy(&mut self) -> &mut dyn BackendStrategyExt {
self.backend.to_mut().strategy.as_mut()
}

fn snapshot_state(&mut self, journaled_state: &JournaledState, env: &Env) -> U256 {
fn snapshot_state(&mut self, journaled_state: &S::JournaledState, env: &Env) -> U256 {
self.backend_mut(env).snapshot_state(journaled_state, env)
}

fn revert_state(
&mut self,
id: U256,
journaled_state: &JournaledState,
journaled_state: &S::JournaledState,
current: &mut Env,
action: RevertStateSnapshotAction,
) -> Option<JournaledState> {
) -> Option<S::JournaledState> {
self.backend_mut(current).revert_state(id, journaled_state, current, action)
}

Expand Down Expand Up @@ -140,7 +136,7 @@ impl DatabaseExt for CowBackend<'_> {
&mut self,
id: LocalForkId,
env: &mut Env,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
) -> eyre::Result<()> {
self.backend_mut(env).select_fork(id, env, journaled_state)
}
Expand All @@ -150,7 +146,7 @@ impl DatabaseExt for CowBackend<'_> {
id: Option<LocalForkId>,
block_number: u64,
env: &mut Env,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
) -> eyre::Result<()> {
self.backend_mut(env).roll_fork(id, block_number, env, journaled_state)
}
Expand All @@ -160,7 +156,7 @@ impl DatabaseExt for CowBackend<'_> {
id: Option<LocalForkId>,
transaction: B256,
env: &mut Env,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
) -> eyre::Result<()> {
self.backend_mut(env).roll_fork_to_transaction(id, transaction, env, journaled_state)
}
Expand All @@ -170,7 +166,7 @@ impl DatabaseExt for CowBackend<'_> {
id: Option<LocalForkId>,
transaction: B256,
env: Env,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
inspector: &mut dyn InspectorExt,
) -> eyre::Result<()> {
self.backend_mut(&env).transact(id, transaction, env, journaled_state, inspector)
Expand All @@ -180,7 +176,7 @@ impl DatabaseExt for CowBackend<'_> {
&mut self,
transaction: &TransactionRequest,
env: Env,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
inspector: &mut dyn InspectorExt,
) -> eyre::Result<()> {
self.backend_mut(&env).transact_from_tx(transaction, env, journaled_state, inspector)
Expand All @@ -205,15 +201,15 @@ impl DatabaseExt for CowBackend<'_> {
fn diagnose_revert(
&self,
callee: Address,
journaled_state: &JournaledState,
journaled_state: &S::JournaledState,
) -> Option<RevertDiagnostic> {
self.backend.diagnose_revert(callee, journaled_state)
}

fn load_allocs(
&mut self,
allocs: &BTreeMap<Address, GenesisAccount>,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
) -> Result<(), BackendError> {
self.backend_mut(&Env::default()).load_allocs(allocs, journaled_state)
}
Expand All @@ -222,7 +218,7 @@ impl DatabaseExt for CowBackend<'_> {
&mut self,
source: &GenesisAccount,
target: &Address,
journaled_state: &mut JournaledState,
journaled_state: &mut S::JournaledState,
) -> Result<(), BackendError> {
self.backend_mut(&Env::default()).clone_account(source, target, journaled_state)
}
Expand Down Expand Up @@ -264,7 +260,7 @@ impl DatabaseExt for CowBackend<'_> {
}
}

impl DatabaseRef for CowBackend<'_> {
impl<S: BackendStrategy> DatabaseRef for CowBackend<'_, S> {
type Error = DatabaseError;

fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
Expand All @@ -284,7 +280,7 @@ impl DatabaseRef for CowBackend<'_> {
}
}

impl Database for CowBackend<'_> {
impl<S: BackendStrategy> Database for CowBackend<'_, S> {
type Error = DatabaseError;

fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
Expand All @@ -304,7 +300,7 @@ impl Database for CowBackend<'_> {
}
}

impl DatabaseCommit for CowBackend<'_> {
impl<S: BackendStrategy> DatabaseCommit for CowBackend<'_, S> {
fn commit(&mut self, changes: Map<Address, Account>) {
self.backend.to_mut().commit(changes)
}
Expand Down
Loading

0 comments on commit d92ad57

Please sign in to comment.