Closed evan-gray closed 3 months ago
Able to reproduce with this test in crates/anvil/tests/it/api.rs
#[tokio::test(flavor = "multi_thread")]
async fn can_mine_while_mining() {
let (api, _) = spawn(NodeConfig::test()).await;
let total_blocks = 200;
let block_number = api
.block_by_number(BlockNumberOrTag::Latest)
.await
.unwrap()
.unwrap()
.header
.number
.unwrap();
assert_eq!(block_number, 0);
let block = api.block_by_number(BlockNumberOrTag::Number(block_number)).await.unwrap().unwrap();
assert_eq!(block.header.number.unwrap(), 0);
let result = join!(
api.anvil_mine(Some(U256::from(total_blocks / 2)), None),
api.anvil_mine(Some(U256::from(total_blocks / 2)), None)
);
result.0.unwrap();
result.1.unwrap();
tokio::time::sleep(Duration::from_millis(100)).await;
let block_number = api
.block_by_number(BlockNumberOrTag::Latest)
.await
.unwrap()
.unwrap()
.header
.number
.unwrap();
assert_eq!(block_number, total_blocks);
let block = api.block_by_number(BlockNumberOrTag::Number(block_number)).await.unwrap().unwrap();
assert_eq!(block.header.number.unwrap(), total_blocks);
}
test api::can_mine_while_mining ... FAILED
failures:
---- api::can_mine_while_mining stdout ----
thread 'api::can_mine_while_mining' panicked at crates/anvil/tests/it/api.rs:415:5:
assertion `left == right` failed
left: 162
right: 200
I see, there are actually a few race conditions in the do_mine_block impl
the best fix here imo would be to add an additional tokio mutex that is kept for the duration of the function
do you want to try this?
mining: Arc<tokio::Mutex<()>>
or perhaps add it here https://github.com/foundry-rs/foundry/blob/cce36f85c80946bd4a1868411aa99eda879a0e43/crates/anvil/src/eth/backend/mem/mod.rs#L923-L923
Was just looking into this! Will give it a shot 🙂
Thanks for the support @mattsse ! I put up a PR with a test and also tested that it fixes the issue detailed above. Let me know if there's any changes you'd want to see to it. 🤝
Component
Anvil
Have you ensured that all of these are up to date?
What version of Foundry are you on?
forge 0.2.0 (626221f 2024-08-02T00:19:31.215591698Z)
What command(s) is the bug in?
anvil
Operating System
Linux
Describe the bug
If two block mining requests overlap (either via
-b <SECONDS>
andanvil_mine
or two parallelanvil_mine
requests),eth_getBlockByNumber
returns the incorrect results for blocks following the overlap.To reproduce:
Terminal 1:
Terminal 2:
Terminal 3 (while the previous command is still running):
Afterwards:
The
anvil
output lists32768
as the last block mined, which is0x8000
.I had intermittently hit this error in integration tests that run in parallel and relied on setting
-b 1
but also usedanvil_mine 0x40
to quickly reachfinalized
depth. I'm not sure whether parallelanvil_mine
requests should be cumulative or simply ensure that at least the specified number of blocks are queued to be mined from the latest block at the time of the request, but I could find either acceptable for our use case.