Skip to content

Conversation

@mfw78
Copy link
Collaborator

@mfw78 mfw78 commented Dec 26, 2025

Checklist

  • I have read the coding guide.
  • My change requires a documentation update, and I have done it.
  • I have added tests to cover my changes.
  • I have filled out the description and linked the related issues.

Description

Fixes a race condition in pkg/transaction/monitor.go that causes fatal error: concurrent map iteration and map write panics.

The checkPending() function was iterating over watchesByNonce without holding the lock, while WatchTransaction() could concurrently modify the map. Classic Go map concurrency footgun. 🔫

Solution: Snapshot-based approach that minimizes lock contention:

  1. Phase 1 (lock held): Snapshot transaction data needed for RPC calls
  2. Phase 2 (lock released): Make slow RPC calls (TransactionReceipt, NonceAt)
  3. Phase 3 (lock held): Notify subscribers and cleanup

This avoids blocking WatchTransaction() callers during potentially slow (100-500ms) RPC operations.

Open API Spec Version Changes (if applicable)

N/A

Motivation and Context

Discovered while running Bee nodes in a Kurtosis test environment. The panic occurred during chequebook deployment when transaction monitoring was active.

fatal error: concurrent map iteration and map write

goroutine 182 [running]:
github.com/ethersphere/bee/v2/pkg/transaction.(*transactionMonitor).checkPending(0x4000ab8d00, 0xd46)
        /app/pkg/transaction/monitor.go:198 +0x334

Related Issue (Optional)

N/A

Screenshots (if appropriate):

N/A

@mfw78 mfw78 force-pushed the fix/transaction-monitor-race-condition branch from 52325e9 to 6396e4b Compare December 26, 2025 16:34
@mfw78 mfw78 force-pushed the fix/transaction-monitor-race-condition branch from 6396e4b to a17e3a9 Compare December 26, 2025 16:37
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.

1 participant