Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(anvil): reset to non fork #7500

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/anvil/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1587,17 +1587,17 @@ impl EthApi {

/// Reset the fork to a fresh forked state, and optionally update the fork config.
///
/// If `forking` is `None` then this will disable forking entirely.
/// If `forking` is `None` then this will disable forking entirely and reset to a fresh state.
///
/// Handler for RPC call: `anvil_reset`
pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
node_info!("anvil_reset");
self.reset_instance_id();
if let Some(forking) = forking {
// if we're resetting the fork we need to reset the instance id
self.reset_instance_id();
self.backend.reset_fork(forking).await
} else {
Err(BlockchainError::RpcUnimplemented)
self.backend.reset_to_non_fork().await
}
}

Expand Down
43 changes: 41 additions & 2 deletions crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
validate::TransactionValidator,
},
error::{BlockchainError, ErrDetail, InvalidTransactionError},
fees::{FeeDetails, FeeManager},
fees::{FeeDetails, FeeManager, INITIAL_BASE_FEE, INITIAL_GAS_PRICE},
macros::node_info,
pool::transactions::PoolTransaction,
util::get_precompiles_for,
Expand Down Expand Up @@ -58,7 +58,7 @@ use anvil_core::{
};
use anvil_rpc::error::RpcError;
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use foundry_common::types::ToAlloy;
use foundry_common::{types::ToAlloy, DEV_CHAIN_ID};
use foundry_evm::{
backend::{DatabaseError, DatabaseResult, RevertSnapshotAction},
constants::DEFAULT_CREATE2_DEPLOYER_RUNTIME_CODE,
Expand Down Expand Up @@ -468,6 +468,45 @@ impl Backend {
}
}

/// Reset to fresh state
pub async fn reset_to_non_fork(&self) -> Result<(), BlockchainError> {
// Reset fork
*self.fork.write() = None;

// Clear env
{
let mut env = self.env.write();
env.clear();

// Set default anvil chain_id
env.cfg.chain_id = DEV_CHAIN_ID;

// Reset time
self.time.reset(env.block.timestamp.to::<u64>());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't entirely accurate, what we need to consider here is that the node can be in two modes here, forked or mem only.

if mem only we need to reset to the genesis block

if in forked, we need to entirely reinitialize the node block env like this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattsse So if the node is in mem mode, we just clear the env like env.clear()?


// reset fees
self.fees.set_base_fee(U256::from(INITIAL_BASE_FEE));
self.fees.set_gas_price(U256::from(INITIAL_GAS_PRICE));
// Clear the state
*self.blockchain.storage.write() = BlockchainStorage::empty();
self.states.write().clear();

let mut db = self.db.write().await;

// clear database
db.clear();

// genesis accounts
for (account, info) in self.genesis.account_infos() {
db.insert_account(account, info);
}

// Reset genensis alloc
self.genesis.apply_genesis_json_alloc(db)?;

Ok(())
}
/// Returns the `TimeManager` responsible for timestamps
pub fn time(&self) -> &TimeManager {
&self.time
Expand Down