Skip to content

Commit

Permalink
fix(anvil): set best_number to state.block.number if greater (#…
Browse files Browse the repository at this point in the history
…9543)

fix(`anvil`): set `best_number` correctly while loading state with fork activated
  • Loading branch information
yash-atreya authored Dec 12, 2024
1 parent c4fcf12 commit 539760c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
26 changes: 22 additions & 4 deletions crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -922,10 +922,28 @@ impl Backend {
let fork_num_and_hash = self.get_fork().map(|f| (f.block_number(), f.block_hash()));

if let Some((number, hash)) = fork_num_and_hash {
// If loading state file on a fork, set best number to the fork block number.
// Ref: https://github.com/foundry-rs/foundry/pull/9215#issue-2618681838
self.blockchain.storage.write().best_number = U64::from(number);
self.blockchain.storage.write().best_hash = hash;
let best_number = state.best_block_number.unwrap_or(block.number.to::<U64>());
trace!(target: "backend", state_block_number=?best_number, fork_block_number=?number);
// If the state.block_number is greater than the fork block number, set best number
// to the state block number.
// Ref: https://github.com/foundry-rs/foundry/issues/9539
if best_number.to::<u64>() > number {
self.blockchain.storage.write().best_number = best_number;
let best_hash =
self.blockchain.storage.read().hash(best_number.into()).ok_or_else(
|| {
BlockchainError::RpcError(RpcError::internal_error_with(format!(
"Best hash not found for best number {best_number}",
)))
},
)?;
self.blockchain.storage.write().best_hash = best_hash;
} else {
// If loading state file on a fork, set best number to the fork block number.
// Ref: https://github.com/foundry-rs/foundry/pull/9215#issue-2618681838
self.blockchain.storage.write().best_number = U64::from(number);
self.blockchain.storage.write().best_hash = hash;
}
} else {
let best_number = state.best_block_number.unwrap_or(block.number.to::<U64>());
self.blockchain.storage.write().best_number = best_number;
Expand Down
33 changes: 32 additions & 1 deletion crates/anvil/tests/it/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::abi::Greeter;
use alloy_network::{ReceiptResponse, TransactionBuilder};
use alloy_primitives::{address, utils::Unit, Bytes, Uint, U256};
use alloy_primitives::{address, utils::Unit, Bytes, Uint, U256, U64};
use alloy_provider::Provider;
use alloy_rpc_types::{BlockId, TransactionRequest};
use alloy_serde::WithOtherFields;
Expand Down Expand Up @@ -245,3 +245,34 @@ async fn test_fork_load_state() {

assert_eq!(balance_alice + value, latest_balance_alice);
}

// <https://github.com/foundry-rs/foundry/issues/9539>
#[tokio::test(flavor = "multi_thread")]
async fn test_fork_load_state_with_greater_state_block() {
let (api, _handle) = spawn(
NodeConfig::test()
.with_eth_rpc_url(Some(next_http_rpc_endpoint()))
.with_fork_block_number(Some(21070682u64)),
)
.await;

api.mine_one().await;

let block_number = api.block_number().unwrap();

let serialized_state = api.serialized_state(false).await.unwrap();

assert_eq!(serialized_state.best_block_number, Some(block_number.to::<U64>()));

let (api, _handle) = spawn(
NodeConfig::test()
.with_eth_rpc_url(Some(next_http_rpc_endpoint()))
.with_fork_block_number(Some(21070682u64)) // Forked chain has moved forward
.with_init_state(Some(serialized_state)),
)
.await;

let new_block_number = api.block_number().unwrap();

assert_eq!(new_block_number, block_number);
}

0 comments on commit 539760c

Please sign in to comment.