Skip to content

Commit

Permalink
fix(anvil): reset cache path during anvil_reset without fork url (#9729)
Browse files Browse the repository at this point in the history
* reset cache path during anvil_reset without fork url

* refactor

* comment typo

* fix base fee update

* fix test on windows, fmt

* abstract block number reset logic

* fix test deadlock

* update foundry-fork-db

* clippy

---------

Co-authored-by: grandizzy <[email protected]>
Co-authored-by: grandizzy <[email protected]>
  • Loading branch information
3 people authored Feb 25, 2025
1 parent 1bfde08 commit 4974a08
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ foundry-linking = { path = "crates/linking" }
# solc & compilation utilities
foundry-block-explorers = { version = "0.11.0", default-features = false }
foundry-compilers = { version = "0.13.3", default-features = false }
foundry-fork-db = "0.11.0"
foundry-fork-db = "0.11.1"
solang-parser = "=0.3.3"
solar-parse = { version = "=0.1.1", default-features = false }

Expand Down
42 changes: 30 additions & 12 deletions crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,19 +529,17 @@ impl Backend {
// update all settings related to the forked block
{
if let Some(fork_url) = forking.json_rpc_url {
// Set the fork block number
let mut node_config = self.node_config.write().await;
node_config.fork_choice = Some(ForkChoice::Block(fork_block_number));

let mut env = self.env.read().clone();
let (forked_db, client_fork_config) =
node_config.setup_fork_db_config(fork_url, &mut env, &self.fees).await?;

*self.db.write().await = Box::new(forked_db);
let fork = ClientFork::new(client_fork_config, Arc::clone(&self.db));
*self.fork.write() = Some(fork);
*self.env.write() = env;
self.reset_block_number(fork_url, fork_block_number).await?;
} else {
// If rpc url is unspecified, then update the fork with the new block number and
// existing rpc url, this updates the cache path
{
let maybe_fork_url = { self.node_config.read().await.eth_rpc_url.clone() };
if let Some(fork_url) = maybe_fork_url {
self.reset_block_number(fork_url, fork_block_number).await?;
}
}

let gas_limit = self.node_config.read().await.fork_gas_limit(&fork_block);
let mut env = self.env.write();

Expand Down Expand Up @@ -592,6 +590,26 @@ impl Backend {
}
}

async fn reset_block_number(
&self,
fork_url: String,
fork_block_number: u64,
) -> Result<(), BlockchainError> {
let mut node_config = self.node_config.write().await;
node_config.fork_choice = Some(ForkChoice::Block(fork_block_number));

let mut env = self.env.read().clone();
let (forked_db, client_fork_config) =
node_config.setup_fork_db_config(fork_url, &mut env, &self.fees).await?;

*self.db.write().await = Box::new(forked_db);
let fork = ClientFork::new(client_fork_config, Arc::clone(&self.db));
*self.fork.write() = Some(fork);
*self.env.write() = env;

Ok(())
}

/// Returns the `TimeManager` responsible for timestamps
pub fn time(&self) -> &TimeManager {
&self.time
Expand Down
36 changes: 36 additions & 0 deletions crates/anvil/tests/it/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,42 @@ async fn test_reset_dev_account_nonce() {
assert!(receipt.status());
}

#[tokio::test(flavor = "multi_thread")]
async fn test_reset_updates_cache_path_when_rpc_url_not_provided() {
let config: NodeConfig = fork_config();

let (mut api, _handle) = spawn(config).await;
let info = api.anvil_node_info().await.unwrap();
let number = info.fork_config.fork_block_number.unwrap();
assert_eq!(number, BLOCK_NUMBER);

async fn get_block_from_cache_path(api: &mut EthApi) -> u64 {
let db = api.backend.get_db().read().await;
let cache_path = db.maybe_inner().unwrap().cache().cache_path().unwrap();
cache_path
.parent()
.expect("must have filename")
.file_name()
.expect("must have block number as dir name")
.to_str()
.expect("must be valid string")
.parse::<u64>()
.expect("must be valid number")
}

assert_eq!(BLOCK_NUMBER, get_block_from_cache_path(&mut api).await);

// Reset to older block without specifying a new rpc url
api.anvil_reset(Some(Forking {
json_rpc_url: None,
block_number: Some(BLOCK_NUMBER - 1_000_000),
}))
.await
.unwrap();

assert_eq!(BLOCK_NUMBER - 1_000_000, get_block_from_cache_path(&mut api).await);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_fork_get_account() {
let (_api, handle) = spawn(fork_config()).await;
Expand Down

0 comments on commit 4974a08

Please sign in to comment.