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

fix(anvil): set best_number to state.block.number if greater #9543

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
Loading