Skip to content

Speed up BOLD challenge protocol tests#4405

Draft
hkalodner wants to merge 10 commits intomasterfrom
hkalodner/challenge-test-improvements
Draft

Speed up BOLD challenge protocol tests#4405
hkalodner wants to merge 10 commits intomasterfrom
hkalodner/challenge-test-improvements

Conversation

@hkalodner
Copy link
Copy Markdown
Contributor

Summary

  • Fix race condition in event producer: replace receiver-side close(events) + blanket recover() with a producer-owned stopped channel that cleanly unblocks both in-flight broadcast goroutines and subscribers on shutdown
  • Speed up BOLD challenge protocol test (~186s to ~24s) via subscription-based watcher triggering, execution run caching across subchallenge levels, and subscription-based WaitMined
  • Extract shared helpers for BOLD challenge test node creation and challenge tail to eliminate ~700 lines of duplication across test files
  • Deduplicate L3 BOLD challenge test by reusing the shared helpers
  • Cache execution runs in Redis validation consumer to avoid re-creating machines for consecutive requests with the same input

Test plan

  • go test ./bold/containers/events/... -v passes
  • go test -run TestChallengeProtocolBOLD -tags challengetest ./system_tests/ -v
  • CI passes

🤖 Generated with Claude Code

@hkalodner hkalodner marked this pull request as draft February 18, 2026 22:45
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 18, 2026

Codecov Report

❌ Patch coverage is 43.71585% with 103 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.97%. Comparing base (d29fc5c) to head (87668dc).
⚠️ Report is 3 commits behind head on hkalodner/waitfortx-subscriptions.

Additional details and impacted files
@@                          Coverage Diff                          @@
##           hkalodner/waitfortx-subscriptions    #4405      +/-   ##
=====================================================================
- Coverage                              34.73%   32.97%   -1.76%     
=====================================================================
  Files                                    489      490       +1     
  Lines                                  58064    58188     +124     
=====================================================================
- Hits                                   20170    19190     -980     
- Misses                                 34307    35717    +1410     
+ Partials                                3587     3281     -306     

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 18, 2026

❌ 9 Tests Failed:

Tests completed Failed Passed Skipped
4278 9 4269 0
View the top 3 failed tests by shortest run time
TestSequencerInboxReader
Stack Traces | 4.240s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=1ac326..1ef269 parent=b72d24..c8ecbe id=136                block=135
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=1e9426..605353 parent=1ac326..1ef269 id=137                block=136
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=237aa8..4c9a78 parent=1e9426..605353 id=138                block=137
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=f542b7..b492ad parent=237aa8..4c9a78 id=139                block=138
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=401b31..858300 parent=f542b7..b492ad id=140                block=139
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=cd17ab..20937b parent=401b31..858300 id=141                block=140
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=790e7e..5158e9 parent=cd17ab..20937b id=142                block=141
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=979dfd..26d497 parent=790e7e..5158e9 id=143                block=142
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=d51c64..79d1af parent=979dfd..26d497 id=144                block=143
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=4e5187..50290c parent=d51c64..79d1af id=145                block=144
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=011b82..f65f92 parent=4e5187..50290c id=146                block=145
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=75b60c..8b4708 parent=011b82..f65f92 id=147                block=146
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=0a8df9..d01740 parent=75b60c..8b4708 id=148                block=147
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=27caa2..b918f1 parent=0a8df9..d01740 id=149                block=148
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=0fb9d9..ad0a67 parent=27caa2..b918f1 id=150                block=149
DEBUG[02-20|02:21:58.893] Journaled pathdb diff layer              root=8b8cf3..b21db2 parent=0fb9d9..ad0a67 id=151                block=150
INFO [02-20|02:21:58.893] Persisted dirty state to disk            size=626.04KiB elapsed=4.547ms
INFO [02-20|02:21:58.893] Blockchain stopped
TRACE[02-20|02:21:58.893] P2P networking is spinning down
--- FAIL: TestSequencerInboxReader (4.24s)
TestVersion30
Stack Traces | 5.470s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
        github.com/offchainlabs/nitro/system_tests.testPrecompiles(0xc05a877180, 0x1e, {0xc0a9ff5db0, 0x6, 0x0?})
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:94 +0x371
        github.com/offchainlabs/nitro/system_tests.TestVersion30(0xc05a877180?)
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:67 +0x798
        testing.tRunner(0xc05a877180, 0x3d2bfa0)
        	/opt/hostedtoolcache/go/1.25.6/x64/src/testing/testing.go:1934 +0xea
        created by testing.(*T).Run in goroutine 1
        	/opt/hostedtoolcache/go/1.25.6/x64/src/testing/testing.go:1997 +0x465
        
    precompile_inclusion_test.go:94: �[31;1m [] execution aborted (timeout = 5s) �[0;0m
INFO [02-20|02:16:44.704] Stopping work on payload                 id=0x03cf34d10746256b reason=delivery
INFO [02-20|02:16:44.704] Writing cached state to disk             block=1  hash=06a85e..f8dbb5 root=8448b4..050cee
INFO [02-20|02:16:44.704] Persisted trie from memory database      nodes=20  flushnodes=0 size=3.26KiB   flushsize=0.00B time="101.859µs" flushtime=0s gcnodes=0 gcsize=0.00B gctime="1.674µs"  livenodes=0   livesize=0.00B
INFO [02-20|02:16:44.704] Writing cached state to disk             block=1  hash=06a85e..f8dbb5 root=8448b4..050cee
INFO [02-20|02:16:44.704] Persisted trie from memory database      nodes=0   flushnodes=0 size=0.00B     flushsize=0.00B time=581ns       flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=0   livesize=0.00B
INFO [02-20|02:16:44.704] Writing snapshot state to disk           root=6b754c..7398ca
INFO [02-20|02:16:44.704] Persisted trie from memory database      nodes=0   flushnodes=0 size=0.00B     flushsize=0.00B time=451ns       flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=0   livesize=0.00B
INFO [02-20|02:16:44.704] Blockchain stopped
INFO [02-20|02:16:44.705] Imported new potential chain segment     number=14  hash=9c4cd6..f5439a blocks=1  txs=1  mgas=1.691  elapsed=2.173ms      mgasps=777.977  triediffs=48.27KiB  triedirty=0.00B
--- FAIL: TestVersion30 (5.47s)
TestVersion40
Stack Traces | 5.980s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [02-20|02:16:44.717]  - Homestead:                   #0       
INFO [02-20|02:16:44.717]  - Tangerine Whistle (EIP 150): #0       
INFO [02-20|02:16:44.717]  - Spurious Dragon/1 (EIP 155): #0       
INFO [02-20|02:16:44.717]  - Spurious Dragon/2 (EIP 158): #0       
INFO [02-20|02:16:44.717]  - Byzantium:                   #0       
INFO [02-20|02:16:44.717]  - Constantinople:              #0       
INFO [02-20|02:16:44.717]  - Petersburg:                  #0       
INFO [02-20|02:16:44.717]  - Istanbul:                    #0       
INFO [02-20|02:16:44.717]  - Muir Glacier:                #0       
INFO [02-20|02:16:44.717]  - Berlin:                      #0       
INFO [02-20|02:16:44.717]  - London:                      #0       
INFO [02-20|02:16:44.717] 
INFO [02-20|02:16:44.717] Merge configured:
INFO [02-20|02:16:44.717]  - Total terminal difficulty:  <nil>
INFO [02-20|02:16:44.717] 
INFO [02-20|02:16:44.717] Post-Merge hard forks (timestamp based):
INFO [02-20|02:16:44.717] Starting work on payload                 id=0x032f6a65a903735e
INFO [02-20|02:16:44.717] Starting work on payload                 id=0x03de35e889d76abe
INFO [02-20|02:16:44.713] Deploying challenge factory contracts
INFO [02-20|02:16:44.718] Deploying osp0

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

hkalodner and others added 10 commits February 19, 2026 20:41
WaitForTx previously relied on bind.WaitMined which polls for
transaction receipts every 1 second. For setup.DeployRollup, which
sends 5 sequential transactions, this added ~5 seconds of pure polling
latency to every test that deploys a rollup.

When the backend supports SubscribeNewHead (ethclient.Client,
protocol.ChainBackend), use head subscriptions for near-instant
notification instead. Falls back to bind.WaitMined for backends
without subscription support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test used a hardcoded sleep of MaxEmptyBatchDelay + 15s, which was
insufficient because the simulated beacon's block timestamps race ahead
of wall clock time (each block gets lastBlockTime+1 when mined faster
than 1/second). After ~27 blocks during setup, L1 timestamps are ~27s
ahead, but the batch poster compares against time.Now().

Replace the hardcoded sleep with a dynamic calculation based on the
actual L1 head timestamp offset, and use the lighter legacy deployment
path to reduce setup blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The receiver (Subscription.Next) was closing the events channel on
context cancellation, while sender goroutines from Broadcast could
still be mid-send — causing panics caught by a blanket recover().

Replace that with a stopped channel owned by the producer. When the
producer shuts down, closing stopped unblocks both in-flight Broadcast
goroutines and any Next calls whose context outlives the producer.
This eliminates the race without masking other panics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add subscription-based watcher triggering, headerProvider in tests,
execution run caching across subchallenge levels, and subscription-based
WaitMined to eliminate polling latency from bisection round-trips.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lenge tail

Extract createSecondL2Node from the duplicated node-creation logic in
create2ndNodeWithConfigForBoldProtocol and createNodeBWithSharedContracts.
This also fixes a bug in createNodeBWithSharedContracts where the L1 chain
ID was hardcoded as big.NewInt(1337) instead of queried from the client.

Simplify create2ndNodeWithConfigForBoldProtocol: remove unused stackConfig
parameter (always nil), remove dead assertion chain creation code (caller
discarded it), and delegate to createSecondL2Node for the shared core.

Delete createNodeBWithSharedContracts entirely, replacing its single call
site with a direct call to createSecondL2Node.

Extract runFastChallengeAndAssertHonestWin from the identical challenge-run
tail in both low-level tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the L3-specific `startL3BoldChallengeManager` with the shared
`startBoldChallengeManager` via `boldChallengeManagerParams`, and replace
the inline OSP wait loop with `waitForHonestOSPWin`. Removes ~150 lines
of duplicated code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When an edge tracker's Act() call fails (e.g., an evil validator's
one-step proof reverts), sleep 5 seconds before retrying. Without this,
failing trackers retry on every block notification, flooding the
simulated backend with RPC calls and starving block production. This
caused TestEndToEnd_ManyEvilValidators to time out in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hkalodner hkalodner force-pushed the hkalodner/challenge-test-improvements branch from 33e6cb8 to 87668dc Compare February 20, 2026 01:59
Base automatically changed from hkalodner/waitfortx-subscriptions to master February 20, 2026 08:45
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