Skip to content

fix: detect sponsored tx nonce conflicts using the sponsor nonce - #2698

Merged
rafa-stacks merged 2 commits into
mainfrom
sponsor-fix
Sep 29, 2026
Merged

rafa-stacks merged 2 commits into
mainfrom
sponsor-fix

Conversation

@rafa-stacks

@rafa-stacks rafa-stacks commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Replace-by-fee detection and mempool prune/restore keyed sponsored transactions by (sponsor_address, nonce). But nonce is the origin's nonce, and sponsor_nonce was never read. A sponsored tx actually uses two account nonces: (origin, nonce) and (sponsor, sponsor_nonce). The node's mempool enforces a unique constraint on each.

This PR computes conflicts per nonce slot. Each tx occupies (sender, nonce), plus (sponsor, sponsor_nonce) when it's sponsored.

@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.24242% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
migrations/1779800000026_sponsor-nonce-indexes.ts 97.22% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Independent winner selection can incorrectly prune valid transactions when sponsored nonce-slot conflicts overlap.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Corrects sponsored transaction conflict detection to use both origin and sponsor nonce slots.

Changes:

  • Reworks RBF, pruning, and restoration around nonce slots.
  • Adds sponsor-nonce indexes.
  • Adds sponsored transaction conflict and reorg tests.
File Description
src/​datastore/​pg-write-store.ts Implements slot-based conflict handling.
migrations/​1779800000026_sponsor-nonce-indexes.ts Replaces incorrect sponsor indexes.
tests/​api/​mempool/​mempool.test.ts Covers sponsored nonce conflicts and reorgs.
tests/​api/​test-builders.ts Supports sponsor nonces in fixtures.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/datastore/pg-write-store.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Winner selection and re-org restoration can still leave the mempool in an incorrect state.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Recalculate RBF ordering for restored mempool transactions

src/​datastore/​pg-write-store.ts:4283

When every orphaned transaction already has a mempool row (for example, a transaction that was pending before confirmation), this CTE restores all same-slot rows to Pending but never recalculates RBF ordering. The later block-ingestion call is keyed only by transactions in the replacement block, so an empty replacement block leaves all conflicting rows visible and overcounts mempool_tx_count. The current re-org tests avoid this by confirming a transaction that never touched the mempool, which forces the insertion path to run the recalculation. Re-run RBF for the restored IDs here as well.

Comment thread src/datastore/pg-write-store.ts
@rafa-stacks
rafa-stacks marked this pull request as ready for review September 29, 2026 19:10
@rafa-stacks
rafa-stacks merged commit f585584 into main Sep 29, 2026
27 checks passed
@rafa-stacks
rafa-stacks deleted the sponsor-fix branch September 29, 2026 19:17

This branch was successfully deployed

1 active deployment
Production — 6cf9843d Deployed Sep 29, 2026 by rafa-stacks via build-publish #3796
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants