Skip to content
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
3 changes: 3 additions & 0 deletions crates/anvil-polkadot/src/api_server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,9 @@ impl ApiServer {
) -> Result<sp_core::U256> {
node_info!("eth_estimateGas");

// Default to pending block, same as EDR and original Anvil
// See: https://github.com/paritytech/contract-issues/issues/261
let block = block.or(Some(BlockId::Number(BlockNumberOrTag::Pending)));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

anvil-polkadot does not currently have any special support for the pending tag (like building an intermediate block with the transactions in the pool), so I don't think this achieves anything

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for reviewing this PR, Alin!

This change enables the logic in eth-rpc and pallet-revive that is triggered when the block tag is pending.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ok, I see. So for now we only want to have the current timestamp and the block number being increased. I thought we wanted to achieve full compatibility with what a real pending block would be in upstream anvil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

shouldn't we change that inside get_block_hash_for_tag instead when block is None?

Copy link
Copy Markdown
Author

@marian-radu marian-radu Feb 2, 2026

Choose a reason for hiding this comment

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

Updating get_block_hash_for_tag could impact the behavior of several other APIs, such as eth_call and eth_getTransactionCount. Looking at the original Anvil implementation, the block is defaulted to pending (from None) only for eth_estimateGas.

let hash = self.get_block_hash_for_tag(block).await?;
let runtime_api = self.eth_rpc_client.runtime_api(hash);
let dry_run = runtime_api
Expand Down
19 changes: 10 additions & 9 deletions crates/forge/tests/it/revive/cheats_individual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ macro_rules! revive_cheat_test_with_dir {
#[case::evm(ReviveRuntimeMode::Evm)]
#[tokio::test(flavor = "multi_thread")]
async fn $test_name(#[case] runtime_mode: ReviveRuntimeMode) {
let mut filter = Filter::new(".*", ".*", &format!(".*/{}/{}.t.sol$", $dir, $file_pattern));
let mut filter =
Filter::new(".*", ".*", &format!(".*/{}/{}.t.sol$", $dir, $file_pattern));

if let Some(exclude_pattern) = $exclude_option {
filter = filter.exclude_tests(exclude_pattern);
Expand All @@ -34,7 +35,7 @@ macro_rules! revive_cheat_test {
($test_name:ident, $file_pattern:expr) => {
revive_cheat_test_with_dir!($test_name, $file_pattern, "revive", None::<&str>);
};
($test_name:ident, $file_pattern:expr, exclude: $exclude_pattern:expr) => {
($test_name:ident, $file_pattern:expr,exclude: $exclude_pattern:expr) => {
revive_cheat_test_with_dir!($test_name, $file_pattern, "revive", Some($exclude_pattern));
};
}
Expand All @@ -44,7 +45,7 @@ macro_rules! revive_cheat_test_original {
($test_name:ident, $file_pattern:expr) => {
revive_cheat_test_with_dir!($test_name, $file_pattern, "cheats", None::<&str>);
};
($test_name:ident, $file_pattern:expr, exclude: $exclude_pattern:expr) => {
($test_name:ident, $file_pattern:expr,exclude: $exclude_pattern:expr) => {
revive_cheat_test_with_dir!($test_name, $file_pattern, "cheats", Some($exclude_pattern));
};
}
Expand Down Expand Up @@ -125,8 +126,8 @@ revive_cheat_test_original!(test_read_callers, "ReadCallers");
// FAILS: State diff recording (startStateDiffRecording) doesn't capture all account accesses
// (EXTCODESIZE, EXTCODEHASH, etc.) since these opcodes execute in pallet-revive, not REVM
// revive_cheat_test_original!(test_record_account_accesses, "RecordAccountAccesses");
// FAILS: Debug trace recording doesn't capture call depth correctly when execution happens in pallet-revive
// revive_cheat_test_original!(test_record_debug_trace, "RecordDebugTrace");
// FAILS: Debug trace recording doesn't capture call depth correctly when execution happens in
// pallet-revive revive_cheat_test_original!(test_record_debug_trace, "RecordDebugTrace");
revive_cheat_test_original!(test_record_logs, "RecordLogs");
revive_cheat_test_original!(test_remember, "Remember");
revive_cheat_test_original!(test_reset_nonce, "ResetNonce");
Expand Down Expand Up @@ -155,10 +156,10 @@ revive_cheat_test_original!(test_wallet, "Wallet");
// FAILS: In Polkadot mode, vm.dumpState dumps all persistent accounts (14) instead of just the
// explicitly created ones (expected 1). Test asserts account count which differs in pallet-revive.
// revive_cheat_test_original!(test_dump_state, "dumpState");
// FAILS: vm.loadAllocs() combined with vm.revertToState() causes panic in storage_rollback_transaction()
// because vm.loadAllocs creates external accounts that get migrated to pallet-revive, and the snapshot/revert
// mechanism doesn't properly handle rolling back cross-runtime state changes
// revive_cheat_test_original!(test_load_allocs, "loadAllocs");
// FAILS: vm.loadAllocs() combined with vm.revertToState() causes panic in
// storage_rollback_transaction() because vm.loadAllocs creates external accounts that get migrated
// to pallet-revive, and the snapshot/revert mechanism doesn't properly handle rolling back
// cross-runtime state changes revive_cheat_test_original!(test_load_allocs, "loadAllocs");
revive_cheat_test_original!(test_gas_metering, "GasMetering");
revive_cheat_test!(test_custom_nonce, "Nonce");
revive_cheat_test_original!(test_nonce, "Nonce");
Expand Down
Loading