Skip to content

fix(anvil): update fee history cache synchronously during mining#13784

Open
decofe wants to merge 1 commit intofoundry-rs:masterfrom
decofe:zerosnacks/fix-fee-history-race
Open

fix(anvil): update fee history cache synchronously during mining#13784
decofe wants to merge 1 commit intofoundry-rs:masterfrom
decofe:zerosnacks/fix-fee-history-race

Conversation

@decofe
Copy link
Copy Markdown
Contributor

@decofe decofe commented Mar 16, 2026

Problem

eth_feeHistory can return fewer entries than requested when called right after a block is mined.

The fee history cache is populated by FeeHistoryService, which runs as a separate Future inside NodeService::poll. The timeline looks like:

  1. do_mine_block() stores the block in BlockchainStorage
  2. do_mine_block() calls notify_on_new_block() — sends a notification on a channel
  3. ← race window: eth_feeHistory reads the cache here, before step 4 runs →
  4. FeeHistoryService::poll receives the notification and updates the cache

During step 3, the new block exists in storage (so best_number is incremented), but the cache hasn't been updated yet. eth_feeHistory sees the new block number, tries to look it up in the cache, finds nothing, silently skips it, and returns a short response.

Fix

Share the FeeHistoryCache between Backend and FeeHistoryService. Update it synchronously in do_mine_block() before notify_on_new_block(), closing the race window. The async FeeHistoryService still runs but becomes a no-op for already-cached blocks.

Closes #13680

@zerosnacks zerosnacks self-assigned this Mar 16, 2026
@zerosnacks zerosnacks marked this pull request as draft March 17, 2026 11:52
@zerosnacks zerosnacks force-pushed the zerosnacks/fix-fee-history-race branch 2 times, most recently from a90b3a5 to c73de21 Compare March 17, 2026 12:15
Fixes a race condition where eth_feeHistory returns incomplete results
when called shortly after blocks are mined. The fee history cache was
populated asynchronously by FeeHistoryService, creating a window where
RPC calls observe a stale cache.

Now the cache is updated synchronously inside do_mine_block() before
notify_on_new_block(), guaranteeing consistency with the chain head.

Closes foundry-rs#13680

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019cfba7-4986-77c6-9630-574261e9d580
@zerosnacks zerosnacks force-pushed the zerosnacks/fix-fee-history-race branch from c73de21 to 73ce3e7 Compare March 17, 2026 12:18
@zerosnacks zerosnacks marked this pull request as ready for review March 17, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

bug: Possible race condition in eth_feeHistory. Method returns incomplete results due to async cache population race

2 participants