Skip to content

[dont merge] fix: re-evaluate queued txs when USDC balance slots change#379

Draft
drappi-ai wants to merge 24 commits intoseismicfrom
cdai__codex/fix-usdc-queued-reload
Draft

[dont merge] fix: re-evaluate queued txs when USDC balance slots change#379
drappi-ai wants to merge 24 commits intoseismicfrom
cdai__codex/fix-usdc-queued-reload

Conversation

@drappi-ai
Copy link
Copy Markdown
Contributor

@drappi-ai drappi-ai commented Apr 14, 2026

Problem

When a block changes a sender's USDC predeploy balance, queued transactions from that sender need to be re-evaluated — their effective balance changed, so they may now be promotable (or demotable). Today the pool only re-evaluates senders whose native account state changed, so USDC-only balance updates are silently ignored and queued txs stay stuck.

Solution

Extend the ChangedAccountsHook trait with a new method, extend_reload_queued_senders, that lets the Seismic hook inspect the ExecutionOutcome and flag additional senders as dirty. The implementation:

  1. Scans the USDC contract's changed storage slots in both the old and new execution outcomes (covers commits and reorgs).
  2. For each currently-queued sender, checks whether their _balances[address] slot (keccak of the mapping key) is in that changed set.
  3. Adds only those senders to the dirty set — no unnecessary reloads for unrelated accounts.

Changes

Commit 1 — fix: reload queued senders on USDC storage changes

File What changed
crates/transaction-pool/src/maintain.rs Added extend_reload_queued_senders to the ChangedAccountsHook trait (default no-op). Call it after both commit and reorg paths, passing the queued-sender set and execution outcomes. Added queued_senders() helper.
crates/seismic/txpool/src/maintain.rs Implemented extend_reload_queued_senders on SeismicBalanceHook. Added queued_senders_with_changed_usdc_slots and changed_usdc_storage_slots helpers.
crates/seismic/txpool/src/usdc.rs Made usdc_balance_storage_key pub(crate) so the hook can compute expected slot keys.

Commit 2 — test: add tests for queued-sender USDC slot reload logic

File What changed
crates/seismic/txpool/src/maintain.rs Two unit tests: (1) only the sender whose USDC slot changed is flagged dirty, not unrelated queued senders; (2) changed slots from both old and new outcomes are unioned (reorg coverage).

@drappi-ai drappi-ai requested a review from cdrappi as a code owner April 14, 2026 20:37
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

Adds queued sender reloading when USDC balance storage slots change in transaction pool maintenance.

LGTM

@drappi-ai drappi-ai force-pushed the cdai__codex/fix-usdc-queued-reload branch from 7e93e48 to 4af1931 Compare April 14, 2026 20:48
## Summary

- **Bug:** `SeismicBalanceHook` was calling `self.client.latest()` to
read USDC balances, while the maintenance loop loaded native
balance/nonce from a historical block snapshot
(`history_by_block_hash`). This caused mixed-state reconciliation where
nonce and native balance came from block B but USDC balance came from
the chain tip, which could be a different block.
- **Impact:** False promotions (tx appears fundable using future USDC)
and false demotions (tx appears unfunded using stale USDC) during reorgs
and dirty-account reloads.
- **Fix:** Pass the same `StateProvider` the maintenance loop already
opened into the `ChangedAccountsHook::transform` method. The Seismic
hook no longer owns a client or opens its own state — it reads USDC
storage from the snapshot it receives.

### Changes

- `ChangedAccountsHook::transform` now takes `&dyn StateProvider` as its
first argument
- All 3 call sites in `maintain_transaction_pool_with_hook` open the
correct historical state and pass it through
- `SeismicBalanceHook` becomes a unit struct — no generic, no client
field, no `latest()` call
- No-op `()` impl updated to match the new signature

## Test plan

- [x] `cargo check -p reth-transaction-pool -p reth-seismic-txpool -p
reth-seismic-node` passes
- [ ] Existing txpool tests pass
- [ ] Manual verification: submit tx from USDC-funded account, trigger
reorg, confirm pool state is consistent
@drappi-ai drappi-ai force-pushed the cdai__codex/fix-usdc-queued-reload branch 3 times, most recently from a248354 to f4d287b Compare April 14, 2026 21:04
@drappi-ai drappi-ai changed the title txpool reload queued senders on usdc storage changes fix: re-evaluate queued txs when USDC balance slots change Apr 14, 2026
When USDC predeploy storage slots change in a canonical update, queued
transactions whose senders have affected balance slots must be
re-evaluated. This adds extend_reload_queued_senders to the
ChangedAccountsHook trait and implements it in SeismicBalanceHook to
detect USDC slot mutations and mark the corresponding queued senders
as dirty.
@drappi-ai drappi-ai force-pushed the cdai__codex/fix-usdc-queued-reload branch from f4d287b to 036567b Compare April 14, 2026 21:09
@cdrappi cdrappi marked this pull request as draft April 14, 2026 22:34
@cdrappi cdrappi changed the title fix: re-evaluate queued txs when USDC balance slots change [dont merge] fix: re-evaluate queued txs when USDC balance slots change Apr 14, 2026
Base automatically changed from d/usdc-predeploy to seismic April 14, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants