@@ -18,7 +18,6 @@ import (
1818 "github.com/ethereum/go-ethereum/core/rawdb"
1919 "github.com/ethereum/go-ethereum/core/types"
2020 "github.com/ethereum/go-ethereum/log"
21- "github.com/ethereum/go-ethereum/metrics"
2221 "github.com/ethereum/go-ethereum/params"
2322 "github.com/ethereum/go-ethereum/rpc"
2423
@@ -29,46 +28,49 @@ import (
2928 "github.com/offchainlabs/nitro/bold/containers/fsm"
3029 "github.com/offchainlabs/nitro/cmd/chaininfo"
3130 "github.com/offchainlabs/nitro/daprovider"
31+ "github.com/offchainlabs/nitro/staker"
3232 "github.com/offchainlabs/nitro/util/headerreader"
3333 "github.com/offchainlabs/nitro/util/stopwaiter"
3434)
3535
36- var (
37- stuckFSMIndicatingGauge = metrics .NewRegisteredGauge ("arb/mel/stuck" , nil ) // 1-stuck, 0-not_stuck
38- )
39-
4036type MessageExtractionConfig struct {
41- Enable bool `koanf:"enable"`
42- RetryInterval time.Duration `koanf:"retry-interval"`
43- BlocksToPrefetch uint64 `koanf:"blocks-to-prefetch"`
44- ReadMode string `koanf:"read-mode"`
45- StallTolerance uint64 `koanf:"stall-tolerance"`
37+ Enable bool `koanf:"enable"`
38+ RetryInterval time.Duration `koanf:"retry-interval"`
39+ BlocksToPrefetch uint64 `koanf:"blocks-to-prefetch"`
40+ ReadMode string `koanf:"read-mode"`
41+ StallTolerance uint64 `koanf:"stall-tolerance"`
42+ LogExtractionStatusFrequencyBlocks uint64 `koanf:"log-extraction-status-frequency-blocks"`
4643}
4744
4845func (c * MessageExtractionConfig ) Validate () error {
4946 c .ReadMode = strings .ToLower (c .ReadMode )
5047 if c .ReadMode != "latest" && c .ReadMode != "safe" && c .ReadMode != "finalized" {
5148 return fmt .Errorf ("inbox reader read-mode is invalid, want: latest or safe or finalized, got: %s" , c .ReadMode )
5249 }
50+ if c .LogExtractionStatusFrequencyBlocks == 0 {
51+ return errors .New ("log-extraction-status-frequency-blocks must be greater than 0" )
52+ }
5353 return nil
5454}
5555
5656var DefaultMessageExtractionConfig = MessageExtractionConfig {
5757 Enable : false ,
5858 // The retry interval for the message extractor FSM. After each tick of the FSM,
5959 // the extractor service stop waiter will wait for this duration before trying to act again.
60- RetryInterval : time .Millisecond * 500 ,
61- BlocksToPrefetch : 499 , // 500 is the eth_getLogs block range limit
62- ReadMode : "latest" ,
63- StallTolerance : 10 ,
60+ RetryInterval : time .Millisecond * 500 ,
61+ BlocksToPrefetch : 499 , // 500 is the eth_getLogs block range limit
62+ ReadMode : "latest" ,
63+ StallTolerance : 10 ,
64+ LogExtractionStatusFrequencyBlocks : 100 ,
6465}
6566
6667var TestMessageExtractionConfig = MessageExtractionConfig {
67- Enable : false ,
68- RetryInterval : time .Millisecond * 10 ,
69- BlocksToPrefetch : 499 ,
70- ReadMode : "latest" ,
71- StallTolerance : 10 ,
68+ Enable : false ,
69+ RetryInterval : time .Millisecond * 10 ,
70+ BlocksToPrefetch : 499 ,
71+ ReadMode : "latest" ,
72+ StallTolerance : 10 ,
73+ LogExtractionStatusFrequencyBlocks : 100 ,
7274}
7375
7476func MessageExtractionConfigAddOptions (prefix string , f * pflag.FlagSet ) {
@@ -77,6 +79,7 @@ func MessageExtractionConfigAddOptions(prefix string, f *pflag.FlagSet) {
7779 f .Uint64 (prefix + ".blocks-to-prefetch" , DefaultMessageExtractionConfig .BlocksToPrefetch , "the number of blocks to prefetch relevant logs from. Recommend using max allowed range for eth_getLogs rpc query" )
7880 f .String (prefix + ".read-mode" , DefaultMessageExtractionConfig .ReadMode , "mode to only read latest or safe or finalized L1 blocks. Enabling safe or finalized disables feed input and output. Defaults to latest. Takes string input, valid strings- latest, safe, finalized" )
7981 f .Uint64 (prefix + ".stall-tolerance" , DefaultMessageExtractionConfig .StallTolerance , "max times the MEL fsm is allowed to be stuck without logging error" )
82+ f .Uint64 (prefix + ".log-extraction-status-frequency-blocks" , DefaultMessageExtractionConfig .LogExtractionStatusFrequencyBlocks , "frequency of logging message extraction status in terms of number of blocks processed" )
8083}
8184
8285// SequencerBatchCountFetcher queries the on-chain sequencer inbox batch count at a given parent chain block.
@@ -321,6 +324,17 @@ func (m *MessageExtractor) GetMsgCount() (arbutil.MessageIndex, error) {
321324 return arbutil .MessageIndex (headState .MsgCount ), nil
322325}
323326
327+ func (m * MessageExtractor ) GetDelayedMessageBytes (ctx context.Context , seqNum uint64 ) ([]byte , error ) {
328+ msg , err := m .GetDelayedMessage (seqNum )
329+ if err != nil {
330+ return nil , err
331+ }
332+ if msg .Message == nil {
333+ return nil , fmt .Errorf ("message at seqNum %d has nil Message field" , seqNum )
334+ }
335+ return msg .Message .Serialize ()
336+ }
337+
324338func (m * MessageExtractor ) GetDelayedMessage (index uint64 ) (* mel.DelayedInboxMessage , error ) {
325339 headState , err := m .melDB .GetHeadMelState ()
326340 if err != nil {
@@ -519,6 +533,10 @@ func (m *MessageExtractor) FindInboxBatchContainingMessage(pos arbutil.MessageIn
519533 }
520534}
521535
536+ func (m * MessageExtractor ) SetBlockValidator (_ * staker.BlockValidator ) {
537+ log .Info ("MEL does not support block validation registration; SetBlockValidator is a no-op" )
538+ }
539+
522540func (m * MessageExtractor ) GetBatchCount () (uint64 , error ) {
523541 headState , err := m .melDB .GetHeadMelState ()
524542 if err != nil {
@@ -527,6 +545,14 @@ func (m *MessageExtractor) GetBatchCount() (uint64, error) {
527545 return headState .BatchCount , nil
528546}
529547
548+ func (m * MessageExtractor ) GetBatchAcc (seqNum uint64 ) (common.Hash , error ) {
549+ metadata , err := m .GetBatchMetadata (seqNum )
550+ if err != nil {
551+ return common.Hash {}, err
552+ }
553+ return metadata .Accumulator , nil
554+ }
555+
530556func (m * MessageExtractor ) CaughtUp () chan struct {} {
531557 return m .caughtUpChan
532558}
@@ -549,13 +575,15 @@ func (m *MessageExtractor) Act(ctx context.Context) (time.Duration, error) {
549575 // from the parent chain block. The FSM will transition to the `SavingMessages`
550576 // state after successfully extracting messages.
551577 case ProcessingNextBlock :
578+ fsmBlocksProcessedCounter .Inc (1 )
552579 return m .processNextBlock (ctx , current )
553580 // `SavingMessages` is the state responsible for saving the extracted messages
554581 // and delayed messages to the database. It stores data in the node's consensus database
555582 // and runs after the `ProcessingNextBlock` state.
556583 // After data is stored, the FSM will then transition to the `ProcessingNextBlock` state
557584 // yet again.
558585 case SavingMessages :
586+ fsmSaveMessagesCounter .Inc (1 )
559587 return m .saveMessages (ctx , current )
560588 // `Reorging` is the state responsible for handling reorgs in the parent chain.
561589 // It is triggered when a reorg occurs, and it will revert the MEL state being processed to the
0 commit comments