Skip to content

[MEL] - Pt.2 Integration of Message Extraction Across Arbnode Behind Feature Flag#4402

Merged
eljobe merged 24 commits intomasterfrom
raul/mel-pr2-core
Mar 8, 2026
Merged

[MEL] - Pt.2 Integration of Message Extraction Across Arbnode Behind Feature Flag#4402
eljobe merged 24 commits intomasterfrom
raul/mel-pr2-core

Conversation

@rauljordan
Copy link
Copy Markdown
Contributor

@rauljordan rauljordan commented Feb 18, 2026

This PR integrates MessageExtraction across the Nitro node gated behind the MEL feature flag configuration, allowing us to run a MEL-enabled node safely. Some of the changes are refactoring of certain variables to other packages to support MEL, but most changes are straightforward.

Depends on #4398

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 18, 2026

❌ 10 Tests Failed:

Tests completed Failed Passed Skipped
4322 10 4312 0
View the top 3 failed tests by shortest run time
TestValidationInputsAtWithWasmTarget
Stack Traces | 4.520s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [03-06|21:49:29.409] Submitted transaction                    hash=0x0f285a55355bb04a15367b1203ee042c5fac673ee70c63bc0b86f39dac143477 from=0x26E554a8acF9003b83495c7f45F06edCB803d4e3 nonce=17 recipient=0x457b1BA688E9854BDbed2f473F7510C476A3dA09 value=0
INFO [03-06|21:49:29.409] Updated payload                          id=0x03bcc7c52140a5df number=38 hash=f19df6..5e731f txs=1  withdrawals=0 gas=146,581    fees=7.32905e-06    root=18a78b..bfb725 elapsed=1.347ms
INFO [03-06|21:49:29.409] Waiting background transaction indexer to exit
INFO [03-06|21:49:29.409] Stopping work on payload                 id=0x03bcc7c52140a5df reason=delivery
INFO [03-06|21:49:29.410] Writing cached state to disk             block=7  hash=ea30c2..51c349 root=c897a4..75e99e
INFO [03-06|21:49:29.410] Persisted trie from memory database      nodes=108 flushnodes=0 size=13.30KiB  flushsize=0.00B time="501.135µs"  flushtime=0s gcnodes=0 gcsize=0.00B gctime="6.421µs"  livenodes=128 livesize=22.78KiB
INFO [03-06|21:49:29.410] Writing cached state to disk             block=6  hash=7ef3a0..16ba04 root=19b71e..6fa838
INFO [03-06|21:49:29.410] Persisted trie from memory database      nodes=23  flushnodes=0 size=4.09KiB   flushsize=0.00B time="149.399µs"  flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=105 livesize=18.69KiB
INFO [03-06|21:49:29.411] Writing cached state to disk             block=1  hash=e9e1f4..b6dcc0 root=b669dc..b48437
INFO [03-06|21:49:29.411] Persisted trie from memory database      nodes=25  flushnodes=0 size=4.38KiB   flushsize=0.00B time="149.83µs"   flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=80  livesize=14.31KiB
INFO [03-06|21:49:29.411] Writing snapshot state to disk           root=ccd625..e41f9d
INFO [03-06|21:49:29.411] Persisted trie from memory database      nodes=0   flushnodes=0 size=0.00B     flushsize=0.00B time="1.523µs"    flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=80  livesize=14.31KiB
INFO [03-06|21:49:29.411] Imported new potential chain segment     number=38 hash=f19df6..5e731f blocks=1  txs=1  mgas=0.147  elapsed=1.611ms     mgasps=90.948   triediffs=190.74KiB triedirty=0.00B
INFO [03-06|21:49:29.411] Submitted transaction                    hash=0xcd18c51593a596cb13e7f9e6ff699891c772012286193865a19b6debae944c17 from=0xaF24Ca6c2831f4d4F629418b50C227DF0885613A nonce=29 recipient=0x83Be5D4253572c11A975bcDF6998B9d4DB53c3E3 value=200,003
INFO [03-06|21:49:29.411] Chain head was updated                   number=38 hash=f19df6..5e731f root=18a78b..bfb725 elapsed="179.445µs"
INFO [03-06|21:49:29.411] Blockchain stopped
INFO [03-06|21:49:29.412] Ethereum protocol stopped
INFO [03-06|21:49:29.412] Transaction pool stopped
INFO [03-06|21:49:29.412] Persisting dirty state                   head=35 root=ab236b..138edd layers=35
--- FAIL: TestValidationInputsAtWithWasmTarget (4.52s)
TestVersion30
Stack Traces | 5.320s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
    precompile_inclusion_test.go:94: goroutine 602012 [running]:
        runtime/debug.Stack()
        	/opt/hostedtoolcache/go/1.25.7/x64/src/runtime/debug/stack.go:26 +0x5e
        github.com/offchainlabs/nitro/util/testhelpers.RequireImpl({0x4114550, 0xc0b4050fc0}, {0x40d0920, 0xc0e8add7d0}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/system_tests.Require(0xc0b4050fc0, {0x40d0920, 0xc0e8add7d0}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/system_tests/common_test.go:2080 +0x5d
        github.com/offchainlabs/nitro/system_tests.testPrecompiles(0xc0b4050fc0, 0x1e, {0xc0aca59db0, 0x6, 0xc01d8e7c10?})
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:94 +0x371
        github.com/offchainlabs/nitro/system_tests.TestVersion30(0xc0b4050fc0?)
        	/home/runner/work/nitro/nitro/system_tests/precompile_inclusion_test.go:67 +0x798
        testing.tRunner(0xc0b4050fc0, 0x3d48988)
        	/opt/hostedtoolcache/go/1.25.7/x64/src/testing/testing.go:1934 +0xea
        created by testing.(*T).Run in goroutine 1
        	/opt/hostedtoolcache/go/1.25.7/x64/src/testing/testing.go:1997 +0x465
        
INFO [03-06|21:49:30.780] Starting work on payload                 id=0x03c482cb8ef6244a
    precompile_inclusion_test.go:94: �[31;1m [] execution aborted (timeout = 5s) �[0;0m
INFO [03-06|21:49:30.780] Imported new potential chain segment     number=17  hash=892170..5aae02 blocks=1  txs=1  mgas=4.235  elapsed=3.705ms     mgasps=1143.004 triediffs=59.59KiB  triedirty=0.00B
--- FAIL: TestVersion30 (5.32s)
TestVersion40
Stack Traces | 5.890s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
INFO [03-06|21:49:30.784] Persisted trie from memory database      nodes=0   flushnodes=0 size=0.00B     flushsize=0.00B time="1.393µs"    flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=0   livesize=0.00B
INFO [03-06|21:49:30.783] Stopping work on payload                 id=0x03c482cb8ef6244a reason=delivery
INFO [03-06|21:49:30.784] Chain head was updated                   number=8   hash=d9bce7..d87a45 root=60854f..bade44 elapsed="348.941µs"
INFO [03-06|21:49:30.785] Submitted contract creation              hash=0xc74d2f72e2d850f371756c1cc1246abebde5bd9c8c9e399b9d1570917c0e5012 from=0x57Ff0F473737a1c161bfF9efDF016F7991585088 nonce=13 contract=0xc917c6b60239C48bd6C7155A6BEeFF79978C8cBd value=0
INFO [03-06|21:49:30.785] Deploying ospMem
INFO [03-06|21:49:30.785] Imported new potential chain segment     number=14  hash=7cd87f..348b9d blocks=1  txs=1  mgas=2.308  elapsed=3.039ms     mgasps=759.352  triediffs=41.73KiB  triedirty=0.00B
INFO [03-06|21:49:30.784] Writing snapshot state to disk           root=6b754c..7398ca
INFO [03-06|21:49:30.786] Persisted trie from memory database      nodes=0   flushnodes=0 size=0.00B     flushsize=0.00B time="1.743µs"    flushtime=0s gcnodes=0 gcsize=0.00B gctime=0s         livenodes=0   livesize=0.00B
INFO [03-06|21:49:30.786] Starting work on payload                 id=0x033a63e105524802
INFO [03-06|21:49:30.786] Blockchain stopped
INFO [03-06|21:49:30.786] Starting work on payload                 id=0x035be9aed1d0427a
INFO [03-06|21:49:30.784] Deploying edge challenge manager
INFO [03-06|21:49:30.783] Starting work on payload                 id=0x03f16c5ac57f4dc1
INFO [03-06|21:49:30.784] Writing cached state to disk             block=1  hash=475405..151e71 root=d45d64..4e7811
INFO [03-06|21:49:30.785] Deploying upgrade executor mock
INFO [03-06|21:49:30.785] Chain head was updated                   number=14  hash=7cd87f..348b9d root=8daaf9..adac47 elapsed="262.71µs"
INFO [03-06|21:49:30.785] Imported new potential chain segment     number=22  hash=d8824b..3e2927 blocks=1  txs=1  mgas=4.884  elapsed=2.240ms     mgasps=2180.203 triediffs=77.96KiB  triedirty=0.00B
INFO [03-06|21:49:30.786] Deploying rollup creator contract
INFO [03-06|21:49:30.787] Updated payload                          id=0x033a63e105524802 number=18  hash=f3f785..028167 txs=1  withdrawals=0 gas=3,035,067  fees=3.035067e-06   root=e1de72..ce6460 elapsed="873.77µs"
--- FAIL: TestVersion40 (5.89s)

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

@rauljordan rauljordan marked this pull request as ready for review February 20, 2026 21:12
@rauljordan rauljordan requested review from diegoximenes, eljobe and tsahee and removed request for tsahee February 20, 2026 21:12
@rauljordan rauljordan changed the title [MEL] - Integration of Message Extraction Across Arbnode Behind Feature Flag [MEL] - Pt.2 Integration of Message Extraction Across Arbnode Behind Feature Flag Feb 20, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 39.31452% with 301 lines in your changes missing coverage. Please review.
✅ Project coverage is 33.53%. Comparing base (3a9bb93) to head (981a8e6).
⚠️ Report is 25 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4402      +/-   ##
==========================================
+ Coverage   32.71%   33.53%   +0.81%     
==========================================
  Files         494      494              
  Lines       58386    58612     +226     
==========================================
+ Hits        19101    19654     +553     
+ Misses      35941    35477     -464     
- Partials     3344     3481     +137     

Base automatically changed from raul/mel-pr1-core to master February 24, 2026 12:38
Comment thread arbnode/batch_poster.go Outdated
Comment thread arbnode/consensus_execution_syncer.go Outdated
Comment thread arbnode/delayed_sequencer.go
Comment thread arbnode/node.go Outdated
Comment thread arbnode/sync_monitor.go Outdated
Comment thread arbnode/sync_monitor.go Outdated
Comment thread arbnode/transaction_streamer.go Outdated
s.delayedBridge = delayedBridge
}

func (s *TransactionStreamer) SetMsgExtractor(msgExtractor *melrunner.MessageExtractor) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Setter injection makes me nervous.

  1. Why can't we have the TransactionStreamer be correct by construction?
  2. It "seems" like there is an assumption later in the code that if inboxTracker is not nil, then it will be used. So, if a TransactionStreamer is constructed with an inboxTracker, and then, later SetMsgExtractor is set, the non-nil inboxTracker would mask the msgExtractor on line 1188. (Maybe this setter should also set the inboxTracker to nil, or error out if it's not nil?
  3. I really hate panics. Isn't there some other way to handle this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still curious about this one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just pushed some changes to this. I was able to remove the panics and use error checks to ensure correctness, but it is not possible to make both mel and tx streamer correct by construction because it would require a reordering of dependencies in the arbnode/node.go initialization logic, which feels dangerous to me because of how many functions would need to be reordered. I think the new approach is a decent compromise. What do you think?

@eljobe eljobe assigned rauljordan and unassigned eljobe Feb 24, 2026
@rauljordan
Copy link
Copy Markdown
Contributor Author

Amazing feedback and helpful comments @eljobe ! Thank you. I'll take care of this soon

@rauljordan rauljordan assigned eljobe and unassigned rauljordan Mar 2, 2026
Comment thread arbnode/transaction_streamer.go Outdated
s.delayedBridge = delayedBridge
}

func (s *TransactionStreamer) SetMsgExtractor(msgExtractor *melrunner.MessageExtractor) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still curious about this one.

@eljobe eljobe assigned rauljordan and unassigned eljobe Mar 3, 2026
@rauljordan rauljordan assigned eljobe and unassigned rauljordan Mar 3, 2026
@eljobe eljobe assigned rauljordan and unassigned eljobe Mar 6, 2026
@rauljordan rauljordan requested a review from eljobe March 6, 2026 21:31
@rauljordan rauljordan assigned eljobe and unassigned rauljordan Mar 6, 2026
@eljobe eljobe added this pull request to the merge queue Mar 8, 2026
Merged via the queue into master with commit 18d1bf1 Mar 8, 2026
42 of 43 checks passed
@eljobe eljobe deleted the raul/mel-pr2-core branch March 8, 2026 10:43
joshuacolvin0 added a commit that referenced this pull request Mar 9, 2026
- Return ErrDelayedMessageNotYetFinalized instead of (nil, _, nil) when
  MEL database doesn't have the parent chain block indexed yet, preventing
  nil message dereference in delayed sequencer
- Remove incorrect waitingForFinalizedBlock assignment that stored a
  message position where a parent chain block number was expected
- Add config validation rejecting BatchPoster + MEL enabled together,
  since MessageExtractor doesn't implement BatchMetadataFetcher
- Remove unused msgExtractor param from getBatchPoster
- Fix getDelayedSequencer check ordering so non-sequencer nodes without
  parent chain reader still return gracefully
- Fix grammatical error in delayed sequencer error message

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-merge-queue Bot pushed a commit that referenced this pull request Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants