Skip to content

Commit c808c4c

Browse files
authored
fix(anvil): get account info from db when node block > fork block (#12175)
fix(anvil): return account info from db when requested block > fork block
1 parent 91211c6 commit c808c4c

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

crates/anvil/src/eth/api.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -775,18 +775,30 @@ impl EthApi {
775775
node_info!("eth_getAccountInfo");
776776

777777
if let Some(fork) = self.get_fork() {
778+
let block_request = self.block_request(block_number).await?;
778779
// check if the number predates the fork, if in fork mode
779-
if let BlockRequest::Number(number) = self.block_request(block_number).await?
780-
&& fork.predates_fork_inclusive(number)
781-
{
782-
// if this predates the fork we need to fetch balance, nonce, code individually
783-
// because the provider might not support this endpoint
784-
let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
785-
let code = fork.get_code(address, number).map_err(BlockchainError::from);
786-
let nonce = self.get_transaction_count(address, Some(number.into()));
787-
let (balance, code, nonce) = try_join!(balance, code, nonce)?;
788-
789-
return Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code });
780+
if let BlockRequest::Number(number) = block_request {
781+
trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
782+
return if fork.predates_fork(number) {
783+
// if this predates the fork we need to fetch balance, nonce, code individually
784+
// because the provider might not support this endpoint
785+
let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
786+
let code = fork.get_code(address, number).map_err(BlockchainError::from);
787+
let nonce = self.get_transaction_count(address, Some(number.into()));
788+
let (balance, code, nonce) = try_join!(balance, code, nonce)?;
789+
790+
Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
791+
} else {
792+
// Anvil node is at the same block or higher than the fork block,
793+
// return account info from backend to reflect current state.
794+
let account_info = self.backend.get_account(address).await?;
795+
let code = self.backend.get_code(address, Some(block_request)).await?;
796+
Ok(alloy_rpc_types::eth::AccountInfo {
797+
balance: account_info.balance,
798+
nonce: account_info.nonce,
799+
code,
800+
})
801+
};
790802
}
791803
}
792804

crates/anvil/tests/it/fork.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,7 @@ async fn test_fork_get_account() {
16221622

16231623
#[tokio::test(flavor = "multi_thread")]
16241624
async fn test_fork_get_account_info() {
1625-
let (_api, handle) = spawn(fork_config()).await;
1625+
let (api, handle) = spawn(fork_config()).await;
16261626
let provider = handle.http_provider();
16271627

16281628
let info = provider
@@ -1655,6 +1655,23 @@ async fn test_fork_get_account_info() {
16551655
code: Default::default(),
16561656
}
16571657
);
1658+
1659+
// Mine and check account info at new block number, see https://github.com/foundry-rs/foundry/issues/12148
1660+
api.evm_mine(None).await.unwrap();
1661+
let info = provider
1662+
.get_account_info(address!("0x19e53a7397bE5AA7908fE9eA991B03710bdC74Fd"))
1663+
// predates fork
1664+
.number(BLOCK_NUMBER + 1)
1665+
.await
1666+
.unwrap();
1667+
assert_eq!(
1668+
info,
1669+
AccountInfo {
1670+
balance: U256::from(14352720829244098514u64),
1671+
nonce: 6690,
1672+
code: Default::default(),
1673+
}
1674+
);
16581675
}
16591676

16601677
fn assert_hardfork_config(

0 commit comments

Comments
 (0)