Skip to content

Conversation

ganeshvanahalli
Copy link
Contributor

@ganeshvanahalli ganeshvanahalli commented Oct 14, 2025

Previously system_tests used NodeBuilder's nodeConfig and execConfig to create consensus and execution nodes directly, meaning if the test wanted to change any config fields- it would end up changing behavior of the nodes already started as well, sometimes unintentionally! As the NodeBuilder's configs are to be used for building multiple nodes with different configurations.

To facilitate this we introduce commonConfigFetcher that can take in both consensus and execution config- clone the config and store the new config atomically in its local atomic.Pointer filed and return a ConfigFetcher interface implemented by both kinds of nodes. And tests planning to changing the config fields after the node has started should use respective configfetchers of consensus and execution nodes available in the TestClient object to make changes and use Set() method to update the configs atomically.

Resolves NIT-3815

Copy link

github-actions bot commented Oct 14, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
2141 2 2139 0
View the top 2 failed tests by shortest run time
TestConsumeNextBid_DuplicateHandling
Stack Traces | 16.059s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [10-17|15:11:26.445] Starting work on payload                 id=0x03d08462eb89ebb0
INFO [10-17|15:11:26.446] Updated payload                          id=0x03d08462eb89ebb0                      number=16 hash=6c3544..f921cb txs=1 withdrawals=0 gas=979,249   fees=9.79249e-07 root=79542c..d6e68c elapsed="765.976µs"
INFO [10-17|15:11:26.446] Stopping work on payload                 id=0x03d08462eb89ebb0                      reason=delivery
INFO [10-17|15:11:26.447] Imported new potential chain segment     number=16 hash=6c3544..f921cb blocks=1 txs=1 mgas=0.979 elapsed="953.387µs" mgasps=1027.126 triediffs=39.18KiB triedirty=0.00B
INFO [10-17|15:11:26.448] Chain head was updated                   number=16 hash=6c3544..f921cb root=79542c..d6e68c elapsed="76.755µs"
    auctioneer_bid_consumption_test.go:278: 
        	Error Trace:	/home/runner/work/nitro/nitro/timeboost/auctioneer_bid_consumption_test.go:278
        	Error:      	Received unexpected error:
        	            	invalid length, need 256 bits
        	            	opening wallet
        	            	github.com/offchainlabs/nitro/timeboost.NewAuctioneerServer
        	            		/home/runner/work/nitro/nitro/timeboost/auctioneer.go:207
        	            	github.com/offchainlabs/nitro/timeboost.TestConsumeNextBid_DuplicateHandling
        	            		/home/runner/work/nitro/nitro/timeboost/auctioneer_bid_consumption_test.go:277
        	            	testing.tRunner
        	            		/opt/hostedtoolcache/go/1.25.3/x64/src/testing/testing.go:1934
        	            	runtime.goexit
        	            		/opt/hostedtoolcache/go/1.25.3/x64/src/runtime/asm_amd64.s:1693
        	Test:       	TestConsumeNextBid_DuplicateHandling
--- FAIL: TestConsumeNextBid_DuplicateHandling (16.06s)
TestTimeboostAuctionResolutionDuringATie
Stack Traces | 18.520s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=250ns       gcnodes=534  gcsize=99.49KiB   gctime=1.914538ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=210ns       gcnodes=534  gcsize=99.49KiB   gctime=1.914638ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=190ns       gcnodes=534  gcsize=99.49KiB   gctime=1.914728ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=191ns       gcnodes=534  gcsize=99.49KiB   gctime=1.914828ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=231ns       gcnodes=534  gcsize=99.49KiB   gctime=1.914948ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=210ns       gcnodes=534  gcsize=99.49KiB   gctime=1.915058ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=0   size=0.00B     time=190ns       gcnodes=534  gcsize=99.49KiB   gctime=1.915138ms  livenodes=128   livesize=25.63KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=16  size=3.18KiB   time="62.016µs"  gcnodes=550  gcsize=102.67KiB  gctime=1.976944ms  livenodes=112   livesize=22.46KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=16  size=3.22KiB   time="43.111µs"  gcnodes=566  gcsize=105.89KiB  gctime=2.019885ms  livenodes=96    livesize=19.23KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=17  size=3.29KiB   time="42.65µs"   gcnodes=583  gcsize=109.18KiB  gctime=2.062424ms  livenodes=79    livesize=15.94KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=16  size=3.22KiB   time="43.351µs"  gcnodes=599  gcsize=112.41KiB  gctime=2.105675ms  livenodes=63    livesize=12.72KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=16  size=3.22KiB   time="32.35µs"   gcnodes=615  gcsize=115.63KiB  gctime=2.137905ms  livenodes=47    livesize=9.50KiB
DEBUG[10-17|15:16:24.303] Dereferenced trie from memory database   nodes=15  size=3.08KiB   time="34.755µs"  gcnodes=630  gcsize=118.71KiB  gctime=2.17253ms   livenodes=32    livesize=6.42KiB
DEBUG[10-17|15:16:24.304] Dereferenced trie from memory database   nodes=16  size=3.21KiB   time="36.599µs"  gcnodes=646  gcsize=121.92KiB  gctime=2.209019ms  livenodes=16    livesize=3.21KiB
DEBUG[10-17|15:16:24.304] Dereferenced trie from memory database   nodes=16  size=3.21KiB   time="37.711µs"  gcnodes=662  gcsize=125.13KiB  gctime=2.24663ms   livenodes=0     livesize=0.00B
DEBUG[10-17|15:16:24.304] Dereferenced trie from memory database   nodes=0   size=0.00B     time=180ns       gcnodes=662  gcsize=125.13KiB  gctime=2.24671ms   livenodes=0     livesize=0.00B
DEBUG[10-17|15:16:24.304] Dereferenced trie from memory database   nodes=0   size=0.00B     time=130ns       gcnodes=662  gcsize=125.13KiB  gctime=2.24676ms   livenodes=0     livesize=0.00B
INFO [10-17|15:16:24.304] Blockchain stopped
TRACE[10-17|15:16:24.310] P2P networking is spinning down
--- FAIL: TestTimeboostAuctionResolutionDuringATie (18.52s)

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

Comment on lines 577 to +578
builder.nodeConfig.BatchPoster.MaxDelay = 0
builder.L2.ConsensusConfigFetcher.Set(builder.nodeConfig)
Copy link
Member

Choose a reason for hiding this comment

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

given that Set always occurs in this pattern: (1) change config (2) set config, we might actually change the fetcher API from Set() to Update(func (*T))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for some reason git didnt post my reply to your comment! my bad.
Regarding Update instead of Set I think Set makes more sense like suggested in the ticket https://linear.app/offchain-labs/issue/NIT-3815/system-tests-avoid-races-for-tests-changing-config because what does Update even mean? does it mean we call func on the existing config var stored in the atomic pointer? realize that we arent using mutexs here (to make the process of changing configs fast and efficient we use atomic.Pointer) so changing that config basically means introducing race again.

Copy link
Member

Choose a reason for hiding this comment

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

nah, the intention was to perform field reassignments on some temp copy and then use atomic.Pointer as we currently do

my motivation was to wrap the 2-instruction pattern within the fetcher API, but maybe it doesn't make that much sense here; waiving

Copy link
Member

@pmikolajczyk41 pmikolajczyk41 left a comment

Choose a reason for hiding this comment

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

I maintain my suggestion about wrapping the pattern with Update instead of Set; wdyt @gligneul ?

Copy link
Member

@pmikolajczyk41 pmikolajczyk41 left a comment

Choose a reason for hiding this comment

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

given that @gligneul agrees, I would convert my suggestion with change request - please convert this pattern:

config.field = value
actual_config.Set(config)

with

actual_config.Update(func (config) {
  config.field = value
})

it should make us a bit safer

@ganeshvanahalli
Copy link
Contributor Author

given that @gligneul agrees, I would convert my suggestion with change request - please convert this pattern:

config.field = value
actual_config.Set(config)

with

actual_config.Update(func (config) {
  config.field = value
})

it should make us a bit safer

I dont know if you read my response here #3829 (comment), Update is redundant in our case.

@ganeshvanahalli ganeshvanahalli removed their assignment Oct 17, 2025
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.

5 participants