From 095c5c8128f0772d65cedeed22b3df381c3334c6 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 10 Jun 2024 17:13:59 -0300 Subject: [PATCH 1/7] replay fills batchcost inside msg --- cmd/replay/main.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/cmd/replay/main.go b/cmd/replay/main.go index 5723b4a030..0fe56eb4c9 100644 --- a/cmd/replay/main.go +++ b/cmd/replay/main.go @@ -203,6 +203,13 @@ func main() { panic(fmt.Sprintf("Error opening state db: %v", err.Error())) } + batchFetcher := func(batchNum uint64) ([]byte, error) { + currentBatch := wavmio.GetInboxPosition() + if batchNum > currentBatch { + return nil, fmt.Errorf("invalid batch fetch request %d, max %d", batchNum, currentBatch) + } + return wavmio.ReadInboxMessage(batchNum), nil + } readMessage := func(dasEnabled bool) *arbostypes.MessageWithMetadata { var delayedMessagesRead uint64 if lastBlockHeader != nil { @@ -232,6 +239,10 @@ func main() { panic(fmt.Sprintf("Error reading from inbox multiplexer: %v", err.Error())) } + err = message.Message.FillInBatchGasCost(batchFetcher) + if err != nil { + message.Message = arbostypes.InvalidL1Message + } return message } @@ -280,14 +291,10 @@ func main() { message := readMessage(chainConfig.ArbitrumChainParams.DataAvailabilityCommittee) chainContext := WavmChainContext{} - batchFetcher := func(batchNum uint64) ([]byte, error) { - return wavmio.ReadInboxMessage(batchNum), nil - } - newBlock, _, err = arbos.ProduceBlock(message.Message, message.DelayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, batchFetcher, false) + newBlock, _, err = arbos.ProduceBlock(message.Message, message.DelayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, false) if err != nil { panic(err) } - } else { // Initialize ArbOS with this init message and create the genesis block. From 4ca023e185d2f2768a0baae9f6a5172994fa590d Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 10 Jun 2024 17:28:45 -0300 Subject: [PATCH 2/7] ProduceBlock doesn't needs to fetch batch --- arbos/block_processor.go | 20 +------------------- arbos/incomingmessage_test.go | 2 +- arbos/parse_l2.go | 13 +++++-------- execution/gethexec/block_recorder.go | 5 ++++- execution/gethexec/executionengine.go | 9 +-------- gethhook/geth_test.go | 2 +- system_tests/retryable_test.go | 2 +- system_tests/state_fuzz_test.go | 7 ++++++- 8 files changed, 20 insertions(+), 40 deletions(-) diff --git a/arbos/block_processor.go b/arbos/block_processor.go index 9d6c420a57..b180405c43 100644 --- a/arbos/block_processor.go +++ b/arbos/block_processor.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" @@ -144,26 +143,9 @@ func ProduceBlock( statedb *state.StateDB, chainContext core.ChainContext, chainConfig *params.ChainConfig, - batchFetcher arbostypes.FallibleBatchFetcher, isMsgForPrefetch bool, ) (*types.Block, types.Receipts, error) { - var batchFetchErr error - txes, err := ParseL2Transactions(message, chainConfig.ChainID, func(batchNum uint64, batchHash common.Hash) []byte { - data, err := batchFetcher(batchNum) - if err != nil { - batchFetchErr = err - return nil - } - dataHash := crypto.Keccak256Hash(data) - if dataHash != batchHash { - batchFetchErr = fmt.Errorf("expecting batch %v hash %v but got data with hash %v", batchNum, batchHash, dataHash) - return nil - } - return data - }) - if batchFetchErr != nil { - return nil, nil, batchFetchErr - } + txes, err := ParseL2Transactions(message, chainConfig.ChainID) if err != nil { log.Warn("error parsing incoming message", "err", err) txes = types.Transactions{} diff --git a/arbos/incomingmessage_test.go b/arbos/incomingmessage_test.go index 14726a419f..2933f6a719 100644 --- a/arbos/incomingmessage_test.go +++ b/arbos/incomingmessage_test.go @@ -36,7 +36,7 @@ func TestSerializeAndParseL1Message(t *testing.T) { if err != nil { t.Error(err) } - txes, err := ParseL2Transactions(newMsg, chainId, nil) + txes, err := ParseL2Transactions(newMsg, chainId) if err != nil { t.Error(err) } diff --git a/arbos/parse_l2.go b/arbos/parse_l2.go index d2df3bdf89..06722e4063 100644 --- a/arbos/parse_l2.go +++ b/arbos/parse_l2.go @@ -17,9 +17,7 @@ import ( "github.com/offchainlabs/nitro/util/arbmath" ) -type InfallibleBatchFetcher func(batchNum uint64, batchHash common.Hash) []byte - -func ParseL2Transactions(msg *arbostypes.L1IncomingMessage, chainId *big.Int, batchFetcher InfallibleBatchFetcher) (types.Transactions, error) { +func ParseL2Transactions(msg *arbostypes.L1IncomingMessage, chainId *big.Int) (types.Transactions, error) { if len(msg.L2msg) > arbostypes.MaxL2MessageSize { // ignore the message if l2msg is too large return nil, errors.New("message too large") @@ -71,7 +69,7 @@ func ParseL2Transactions(msg *arbostypes.L1IncomingMessage, chainId *big.Int, ba log.Debug("ignoring rollup event message") return types.Transactions{}, nil case arbostypes.L1MessageType_BatchPostingReport: - tx, err := parseBatchPostingReportMessage(bytes.NewReader(msg.L2msg), chainId, msg.BatchGasCost, batchFetcher) + tx, err := parseBatchPostingReportMessage(bytes.NewReader(msg.L2msg), chainId, msg.BatchGasCost) if err != nil { return nil, err } @@ -370,8 +368,8 @@ func parseSubmitRetryableMessage(rd io.Reader, header *arbostypes.L1IncomingMess return types.NewTx(tx), err } -func parseBatchPostingReportMessage(rd io.Reader, chainId *big.Int, msgBatchGasCost *uint64, batchFetcher InfallibleBatchFetcher) (*types.Transaction, error) { - batchTimestamp, batchPosterAddr, batchHash, batchNum, l1BaseFee, extraGas, err := arbostypes.ParseBatchPostingReportMessageFields(rd) +func parseBatchPostingReportMessage(rd io.Reader, chainId *big.Int, msgBatchGasCost *uint64) (*types.Transaction, error) { + batchTimestamp, batchPosterAddr, _, batchNum, l1BaseFee, extraGas, err := arbostypes.ParseBatchPostingReportMessageFields(rd) if err != nil { return nil, err } @@ -379,8 +377,7 @@ func parseBatchPostingReportMessage(rd io.Reader, chainId *big.Int, msgBatchGasC if msgBatchGasCost != nil { batchDataGas = *msgBatchGasCost } else { - batchData := batchFetcher(batchNum, batchHash) - batchDataGas = arbostypes.ComputeBatchGasCost(batchData) + return nil, errors.New("cannot compute batch gas cost") } batchDataGas = arbmath.SaturatingUAdd(batchDataGas, extraGas) diff --git a/execution/gethexec/block_recorder.go b/execution/gethexec/block_recorder.go index 5b509b97fc..f4f4a4d415 100644 --- a/execution/gethexec/block_recorder.go +++ b/execution/gethexec/block_recorder.go @@ -137,6 +137,10 @@ func (r *BlockRecorder) RecordBlockCreation( // Re-fetch the batch instead of using our cached cost, // as the replay binary won't have the cache populated. msg.Message.BatchGasCost = nil + err := msg.Message.FillInBatchGasCost(batchFetcher) + if err != nil { + return nil, err + } block, _, err := arbos.ProduceBlock( msg.Message, msg.DelayedMessagesRead, @@ -144,7 +148,6 @@ func (r *BlockRecorder) RecordBlockCreation( recordingdb, chaincontext, chainConfig, - batchFetcher, false, ) if err != nil { diff --git a/execution/gethexec/executionengine.go b/execution/gethexec/executionengine.go index 95b865df5a..d8a592736c 100644 --- a/execution/gethexec/executionengine.go +++ b/execution/gethexec/executionengine.go @@ -355,8 +355,7 @@ func (s *ExecutionEngine) resequenceReorgedMessages(messages []*arbostypes.Messa log.Warn("skipping non-standard sequencer message found from reorg", "header", header) continue } - // We don't need a batch fetcher as this is an L2 message - txes, err := arbos.ParseL2Transactions(msg.Message, s.bc.Config().ChainID, nil) + txes, err := arbos.ParseL2Transactions(msg.Message, s.bc.Config().ChainID) if err != nil { log.Warn("failed to parse sequencer message found from reorg", "err", err) continue @@ -625,11 +624,6 @@ func (s *ExecutionEngine) createBlockFromNextMessage(msg *arbostypes.MessageWith statedb.StartPrefetcher("TransactionStreamer") defer statedb.StopPrefetcher() - batchFetcher := func(num uint64) ([]byte, error) { - data, _, err := s.consensus.FetchBatch(s.GetContext(), num) - return data, err - } - block, receipts, err := arbos.ProduceBlock( msg.Message, msg.DelayedMessagesRead, @@ -637,7 +631,6 @@ func (s *ExecutionEngine) createBlockFromNextMessage(msg *arbostypes.MessageWith statedb, s.bc, s.bc.Config(), - batchFetcher, isMsgForPrefetch, ) diff --git a/gethhook/geth_test.go b/gethhook/geth_test.go index 99bfa4ae1c..57ce2ddec0 100644 --- a/gethhook/geth_test.go +++ b/gethhook/geth_test.go @@ -123,7 +123,7 @@ func RunMessagesThroughAPI(t *testing.T, msgs [][]byte, statedb *state.StateDB) if err != nil { t.Error(err) } - txes, err := arbos.ParseL2Transactions(msg, chainId, nil) + txes, err := arbos.ParseL2Transactions(msg, chainId) if err != nil { t.Error(err) } diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 8f9507aea2..339346efc0 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -75,7 +75,7 @@ func retryableSetup(t *testing.T, modifyNodeConfig ...func(*NodeBuilder)) ( if !msgTypes[message.Message.Header.Kind] { continue } - txs, err := arbos.ParseL2Transactions(message.Message, params.ArbitrumDevTestChainConfig().ChainID, nil) + txs, err := arbos.ParseL2Transactions(message.Message, params.ArbitrumDevTestChainConfig().ChainID) Require(t, err) for _, tx := range txs { if txTypes[tx.Type()] { diff --git a/system_tests/state_fuzz_test.go b/system_tests/state_fuzz_test.go index 713aefcfba..24140e480d 100644 --- a/system_tests/state_fuzz_test.go +++ b/system_tests/state_fuzz_test.go @@ -57,8 +57,13 @@ func BuildBlock( batchFetcher := func(uint64) ([]byte, error) { return seqBatch, nil } + err = l1Message.FillInBatchGasCost(batchFetcher) + if err != nil { + return nil, err + } + block, _, err := arbos.ProduceBlock( - l1Message, delayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, batchFetcher, false, + l1Message, delayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, false, ) return block, err } From 3fca09b8b86f24cdcbe8f930c270ddea84259768 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 10 Jun 2024 17:50:55 -0300 Subject: [PATCH 3/7] block recorder doesn't supply batch info --- execution/gethexec/block_recorder.go | 22 --------------- execution/interface.go | 2 -- staker/block_validator.go | 19 ------------- staker/stateless_block_validator.go | 41 +++++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/execution/gethexec/block_recorder.go b/execution/gethexec/block_recorder.go index f4f4a4d415..8879c90702 100644 --- a/execution/gethexec/block_recorder.go +++ b/execution/gethexec/block_recorder.go @@ -16,7 +16,6 @@ import ( "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/execution" - "github.com/offchainlabs/nitro/validator" ) // BlockRecorder uses a separate statedatabase from the blockchain. @@ -120,27 +119,7 @@ func (r *BlockRecorder) RecordBlockCreation( } var blockHash common.Hash - var readBatchInfo []validator.BatchInfo if msg != nil { - batchFetcher := func(batchNum uint64) ([]byte, error) { - data, blockHash, err := r.execEngine.consensus.FetchBatch(ctx, batchNum) - if err != nil { - return nil, err - } - readBatchInfo = append(readBatchInfo, validator.BatchInfo{ - Number: batchNum, - BlockHash: blockHash, - Data: data, - }) - return data, nil - } - // Re-fetch the batch instead of using our cached cost, - // as the replay binary won't have the cache populated. - msg.Message.BatchGasCost = nil - err := msg.Message.FillInBatchGasCost(batchFetcher) - if err != nil { - return nil, err - } block, _, err := arbos.ProduceBlock( msg.Message, msg.DelayedMessagesRead, @@ -175,7 +154,6 @@ func (r *BlockRecorder) RecordBlockCreation( Pos: pos, BlockHash: blockHash, Preimages: preimages, - BatchInfo: readBatchInfo, UserWasms: recordingdb.UserWasms(), }, err } diff --git a/execution/interface.go b/execution/interface.go index ddf30b4b2a..a3e9fb2c20 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -9,7 +9,6 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/offchainlabs/nitro/arbos/arbostypes" "github.com/offchainlabs/nitro/arbutil" - "github.com/offchainlabs/nitro/validator" ) type MessageResult struct { @@ -21,7 +20,6 @@ type RecordResult struct { Pos arbutil.MessageIndex BlockHash common.Hash Preimages map[common.Hash][]byte - BatchInfo []validator.BatchInfo UserWasms state.UserWasms } diff --git a/staker/block_validator.go b/staker/block_validator.go index bfb7c24ac6..89b82f7988 100644 --- a/staker/block_validator.go +++ b/staker/block_validator.go @@ -509,25 +509,6 @@ func (v *BlockValidator) SetCurrentWasmModuleRoot(hash common.Hash) error { ) } -func (v *BlockValidator) readBatch(ctx context.Context, batchNum uint64) (bool, []byte, common.Hash, arbutil.MessageIndex, error) { - batchCount, err := v.inboxTracker.GetBatchCount() - if err != nil { - return false, nil, common.Hash{}, 0, err - } - if batchCount <= batchNum { - return false, nil, common.Hash{}, 0, nil - } - batchMsgCount, err := v.inboxTracker.GetBatchMessageCount(batchNum) - if err != nil { - return false, nil, common.Hash{}, 0, err - } - batch, batchBlockHash, err := v.inboxReader.GetSequencerMessageBytes(ctx, batchNum) - if err != nil { - return false, nil, common.Hash{}, 0, err - } - return true, batch, batchBlockHash, batchMsgCount, nil -} - func (v *BlockValidator) createNextValidationEntry(ctx context.Context) (bool, error) { v.reorgMutex.RLock() defer v.reorgMutex.RUnlock() diff --git a/staker/stateless_block_validator.go b/staker/stateless_block_validator.go index ec235c4bf5..a0d008e862 100644 --- a/staker/stateless_block_validator.go +++ b/staker/stateless_block_validator.go @@ -231,6 +231,25 @@ func NewStatelessBlockValidator( }, nil } +func (v *StatelessBlockValidator) readBatch(ctx context.Context, batchNum uint64) (bool, []byte, common.Hash, arbutil.MessageIndex, error) { + batchCount, err := v.inboxTracker.GetBatchCount() + if err != nil { + return false, nil, common.Hash{}, 0, err + } + if batchCount <= batchNum { + return false, nil, common.Hash{}, 0, nil + } + batchMsgCount, err := v.inboxTracker.GetBatchMessageCount(batchNum) + if err != nil { + return false, nil, common.Hash{}, 0, err + } + batch, batchBlockHash, err := v.inboxReader.GetSequencerMessageBytes(ctx, batchNum) + if err != nil { + return false, nil, common.Hash{}, 0, err + } + return true, batch, batchBlockHash, batchMsgCount, nil +} + func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e *validationEntry) error { if e.Stage != ReadyForRecord { return fmt.Errorf("validation entry should be ReadyForRecord, is: %v", e.Stage) @@ -244,7 +263,27 @@ func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e * if recording.BlockHash != e.End.BlockHash { return fmt.Errorf("recording failed: pos %d, hash expected %v, got %v", e.Pos, e.End.BlockHash, recording.BlockHash) } - e.BatchInfo = append(e.BatchInfo, recording.BatchInfo...) + // record any additional batch fetching + batchFetcher := func(batchNum uint64) ([]byte, error) { + found, data, hash, _, err := v.readBatch(ctx, batchNum) + if err != nil { + return nil, err + } + if !found { + return nil, errors.New("batch not found") + } + e.BatchInfo = append(e.BatchInfo, validator.BatchInfo{ + Number: batchNum, + BlockHash: hash, + Data: data, + }) + return data, nil + } + e.msg.Message.BatchGasCost = nil + err = e.msg.Message.FillInBatchGasCost(batchFetcher) + if err != nil { + return err + } if recording.Preimages != nil { e.Preimages[arbutil.Keccak256PreimageType] = recording.Preimages From c6bd24adda18add217d1c6a1e41eac0db1e943ad Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 10 Jun 2024 17:54:48 -0300 Subject: [PATCH 4/7] remove FetchBatch from consensus --- arbnode/delayed_sequencer.go | 9 +++++++++ arbnode/node.go | 4 ---- arbnode/transaction_streamer.go | 12 ++++++++++++ execution/interface.go | 1 - 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/arbnode/delayed_sequencer.go b/arbnode/delayed_sequencer.go index 8cbb094c16..13cd5af11f 100644 --- a/arbnode/delayed_sequencer.go +++ b/arbnode/delayed_sequencer.go @@ -26,6 +26,7 @@ type DelayedSequencer struct { l1Reader *headerreader.HeaderReader bridge *DelayedBridge inbox *InboxTracker + reader *InboxReader exec execution.ExecutionSequencer coordinator *SeqCoordinator waitingForFinalizedBlock uint64 @@ -68,6 +69,7 @@ func NewDelayedSequencer(l1Reader *headerreader.HeaderReader, reader *InboxReade l1Reader: l1Reader, bridge: reader.DelayedBridge(), inbox: reader.Tracker(), + reader: reader, coordinator: coordinator, exec: exec, config: config, @@ -165,6 +167,13 @@ func (d *DelayedSequencer) sequenceWithoutLockout(ctx context.Context, lastBlock } } lastDelayedAcc = acc + err = msg.FillInBatchGasCost(func(batchNum uint64) ([]byte, error) { + data, _, err := d.reader.GetSequencerMessageBytes(ctx, batchNum) + return data, err + }) + if err != nil { + return err + } messages = append(messages, msg) pos++ } diff --git a/arbnode/node.go b/arbnode/node.go index ac18a6c7d4..e235ef9839 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -990,10 +990,6 @@ func (n *Node) StopAndWait() { } } -func (n *Node) FetchBatch(ctx context.Context, batchNum uint64) ([]byte, common.Hash, error) { - return n.InboxReader.GetSequencerMessageBytes(ctx, batchNum) -} - func (n *Node) FindInboxBatchContainingMessage(message arbutil.MessageIndex) (uint64, bool, error) { return n.InboxTracker.FindInboxBatchContainingMessage(message) } diff --git a/arbnode/transaction_streamer.go b/arbnode/transaction_streamer.go index 116092383a..90e7feddc6 100644 --- a/arbnode/transaction_streamer.go +++ b/arbnode/transaction_streamer.go @@ -432,6 +432,18 @@ func (s *TransactionStreamer) GetMessage(seqNum arbutil.MessageIndex) (*arbostyp return nil, err } + err = message.Message.FillInBatchGasCost(func(batchNum uint64) ([]byte, error) { + ctx, err := s.GetContextSafe() + if err != nil { + return nil, err + } + data, _, err := s.inboxReader.GetSequencerMessageBytes(ctx, batchNum) + return data, err + }) + if err != nil { + return nil, err + } + return &message, nil } diff --git a/execution/interface.go b/execution/interface.go index a3e9fb2c20..2a3d79c697 100644 --- a/execution/interface.go +++ b/execution/interface.go @@ -75,7 +75,6 @@ type FullExecutionClient interface { // not implemented in execution, used as input // BatchFetcher is required for any execution node type BatchFetcher interface { - FetchBatch(ctx context.Context, batchNum uint64) ([]byte, common.Hash, error) FindInboxBatchContainingMessage(message arbutil.MessageIndex) (uint64, bool, error) GetBatchParentChainBlock(seqNum uint64) (uint64, error) } From 89fd178233932265da2580f35944da23252f2cfb Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 17 Jun 2024 18:18:13 -0300 Subject: [PATCH 5/7] FillInBatchGasCost in legacyGetDelayedMessageAndAccumulator and GetDelayedMessageAccumulatorAndParentChainBlockNumber --- arbnode/delayed_sequencer.go | 2 +- arbnode/inbox_reader.go | 12 +++++++---- arbnode/inbox_tracker.go | 33 ++++++++++++++++++++++------- staker/stateless_block_validator.go | 4 ++-- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/arbnode/delayed_sequencer.go b/arbnode/delayed_sequencer.go index 13cd5af11f..4f18531a76 100644 --- a/arbnode/delayed_sequencer.go +++ b/arbnode/delayed_sequencer.go @@ -146,7 +146,7 @@ func (d *DelayedSequencer) sequenceWithoutLockout(ctx context.Context, lastBlock var lastDelayedAcc common.Hash var messages []*arbostypes.L1IncomingMessage for pos < dbDelayedCount { - msg, acc, parentChainBlockNumber, err := d.inbox.GetDelayedMessageAccumulatorAndParentChainBlockNumber(pos) + msg, acc, parentChainBlockNumber, err := d.inbox.GetDelayedMessageAccumulatorAndParentChainBlockNumber(ctx, pos) if err != nil { return err } diff --git a/arbnode/inbox_reader.go b/arbnode/inbox_reader.go index 78b4db1929..77a0b6e7a2 100644 --- a/arbnode/inbox_reader.go +++ b/arbnode/inbox_reader.go @@ -143,7 +143,11 @@ func (r *InboxReader) Start(ctxIn context.Context) error { break } // Validate the init message matches our L2 blockchain - message, err := r.tracker.GetDelayedMessage(0) + ctx, err := r.StopWaiter.GetContextSafe() + if err != nil { + return err + } + message, err := r.tracker.GetDelayedMessage(ctx, 0) if err != nil { return err } @@ -226,7 +230,7 @@ func (r *InboxReader) CaughtUp() chan struct{} { func (r *InboxReader) run(ctx context.Context, hadError bool) error { readMode := r.config().ReadMode - from, err := r.getNextBlockToRead() + from, err := r.getNextBlockToRead(ctx) if err != nil { return err } @@ -584,7 +588,7 @@ func (r *InboxReader) getPrevBlockForReorg(from *big.Int) (*big.Int, error) { return newFrom, nil } -func (r *InboxReader) getNextBlockToRead() (*big.Int, error) { +func (r *InboxReader) getNextBlockToRead(ctx context.Context) (*big.Int, error) { delayedCount, err := r.tracker.GetDelayedCount() if err != nil { return nil, err @@ -592,7 +596,7 @@ func (r *InboxReader) getNextBlockToRead() (*big.Int, error) { if delayedCount == 0 { return new(big.Int).Set(r.firstMessageBlock), nil } - _, _, parentChainBlockNumber, err := r.tracker.GetDelayedMessageAccumulatorAndParentChainBlockNumber(delayedCount - 1) + _, _, parentChainBlockNumber, err := r.tracker.GetDelayedMessageAccumulatorAndParentChainBlockNumber(ctx, delayedCount-1) if err != nil { return nil, err } diff --git a/arbnode/inbox_tracker.go b/arbnode/inbox_tracker.go index b950c1e1ef..b621b12650 100644 --- a/arbnode/inbox_tracker.go +++ b/arbnode/inbox_tracker.go @@ -316,7 +316,7 @@ func (t *InboxTracker) PopulateFeedBacklog(broadcastServer *broadcaster.Broadcas return nil } -func (t *InboxTracker) legacyGetDelayedMessageAndAccumulator(seqNum uint64) (*arbostypes.L1IncomingMessage, common.Hash, error) { +func (t *InboxTracker) legacyGetDelayedMessageAndAccumulator(ctx context.Context, seqNum uint64) (*arbostypes.L1IncomingMessage, common.Hash, error) { key := dbKey(legacyDelayedMessagePrefix, seqNum) data, err := t.db.Get(key) if err != nil { @@ -328,17 +328,26 @@ func (t *InboxTracker) legacyGetDelayedMessageAndAccumulator(seqNum uint64) (*ar var acc common.Hash copy(acc[:], data[:32]) msg, err := arbostypes.ParseIncomingL1Message(bytes.NewReader(data[32:]), nil) + if err != nil { + return nil, common.Hash{}, err + } + + err = msg.FillInBatchGasCost(func(batchNum uint64) ([]byte, error) { + data, _, err := t.txStreamer.inboxReader.GetSequencerMessageBytes(ctx, batchNum) + return data, err + }) + return msg, acc, err } -func (t *InboxTracker) GetDelayedMessageAccumulatorAndParentChainBlockNumber(seqNum uint64) (*arbostypes.L1IncomingMessage, common.Hash, uint64, error) { +func (t *InboxTracker) GetDelayedMessageAccumulatorAndParentChainBlockNumber(ctx context.Context, seqNum uint64) (*arbostypes.L1IncomingMessage, common.Hash, uint64, error) { delayedMessageKey := dbKey(rlpDelayedMessagePrefix, seqNum) exists, err := t.db.Has(delayedMessageKey) if err != nil { return nil, common.Hash{}, 0, err } if !exists { - msg, acc, err := t.legacyGetDelayedMessageAndAccumulator(seqNum) + msg, acc, err := t.legacyGetDelayedMessageAndAccumulator(ctx, seqNum) return msg, acc, 0, err } data, err := t.db.Get(delayedMessageKey) @@ -356,6 +365,14 @@ func (t *InboxTracker) GetDelayedMessageAccumulatorAndParentChainBlockNumber(seq return msg, acc, 0, err } + err = msg.FillInBatchGasCost(func(batchNum uint64) ([]byte, error) { + data, _, err := t.txStreamer.inboxReader.GetSequencerMessageBytes(ctx, batchNum) + return data, err + }) + if err != nil { + return msg, acc, 0, err + } + parentChainBlockNumberKey := dbKey(parentChainBlockNumberPrefix, seqNum) exists, err = t.db.Has(parentChainBlockNumberKey) if err != nil { @@ -373,13 +390,13 @@ func (t *InboxTracker) GetDelayedMessageAccumulatorAndParentChainBlockNumber(seq } -func (t *InboxTracker) GetDelayedMessage(seqNum uint64) (*arbostypes.L1IncomingMessage, error) { - msg, _, _, err := t.GetDelayedMessageAccumulatorAndParentChainBlockNumber(seqNum) +func (t *InboxTracker) GetDelayedMessage(ctx context.Context, seqNum uint64) (*arbostypes.L1IncomingMessage, error) { + msg, _, _, err := t.GetDelayedMessageAccumulatorAndParentChainBlockNumber(ctx, seqNum) return msg, err } -func (t *InboxTracker) GetDelayedMessageBytes(seqNum uint64) ([]byte, error) { - msg, err := t.GetDelayedMessage(seqNum) +func (t *InboxTracker) GetDelayedMessageBytes(ctx context.Context, seqNum uint64) ([]byte, error) { + msg, err := t.GetDelayedMessage(ctx, seqNum) if err != nil { return nil, err } @@ -617,7 +634,7 @@ func (b *multiplexerBackend) ReadDelayedInbox(seqNum uint64) (*arbostypes.L1Inco if len(b.batches) == 0 || seqNum >= b.batches[0].AfterDelayedCount { return nil, errors.New("attempted to read past end of sequencer batch delayed messages") } - return b.inbox.GetDelayedMessage(seqNum) + return b.inbox.GetDelayedMessage(b.ctx, seqNum) } var delayedMessagesMismatch = errors.New("sequencer batch delayed messages missing or different") diff --git a/staker/stateless_block_validator.go b/staker/stateless_block_validator.go index a0d008e862..9fad900f63 100644 --- a/staker/stateless_block_validator.go +++ b/staker/stateless_block_validator.go @@ -49,7 +49,7 @@ type BlockValidatorRegistrer interface { type InboxTrackerInterface interface { BlockValidatorRegistrer - GetDelayedMessageBytes(uint64) ([]byte, error) + GetDelayedMessageBytes(context.Context, uint64) ([]byte, error) GetBatchMessageCount(seqNum uint64) (arbutil.MessageIndex, error) GetBatchAcc(seqNum uint64) (common.Hash, error) GetBatchCount() (uint64, error) @@ -291,7 +291,7 @@ func (v *StatelessBlockValidator) ValidationEntryRecord(ctx context.Context, e * e.UserWasms = recording.UserWasms } if e.HasDelayedMsg { - delayedMsg, err := v.inboxTracker.GetDelayedMessageBytes(e.DelayedMsgNr) + delayedMsg, err := v.inboxTracker.GetDelayedMessageBytes(ctx, e.DelayedMsgNr) if err != nil { log.Error( "error while trying to read delayed msg for proving", From 17d04ecf6cd0fc117b4824f89e0051aeae56c970 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 17 Jun 2024 19:22:15 -0300 Subject: [PATCH 6/7] Skips L1MessageType_BatchPostingReport when resequencing delayed messages --- execution/gethexec/executionengine.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/execution/gethexec/executionengine.go b/execution/gethexec/executionengine.go index d8a592736c..9f928719c8 100644 --- a/execution/gethexec/executionengine.go +++ b/execution/gethexec/executionengine.go @@ -343,6 +343,10 @@ func (s *ExecutionEngine) resequenceReorgedMessages(messages []*arbostypes.Messa log.Info("not resequencing delayed message due to unexpected index", "expected", nextDelayedSeqNum, "found", delayedSeqNum) continue } + if header.Kind == arbostypes.L1MessageType_BatchPostingReport { + log.Debug("skipping L1MessageType_BatchPostingReport message", "header", header) + continue + } _, err := s.sequenceDelayedMessageWithBlockMutex(msg.Message, delayedSeqNum) if err != nil { log.Error("failed to re-sequence old delayed message removed by reorg", "err", err) From 4b71218b646200d6dfd35622d3c723eb19d9b3d4 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 26 Jul 2024 12:49:11 -0300 Subject: [PATCH 7/7] Revert "Skips L1MessageType_BatchPostingReport when resequencing delayed messages" This reverts commit 17d04ecf6cd0fc117b4824f89e0051aeae56c970. --- execution/gethexec/executionengine.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/execution/gethexec/executionengine.go b/execution/gethexec/executionengine.go index 9f928719c8..d8a592736c 100644 --- a/execution/gethexec/executionengine.go +++ b/execution/gethexec/executionengine.go @@ -343,10 +343,6 @@ func (s *ExecutionEngine) resequenceReorgedMessages(messages []*arbostypes.Messa log.Info("not resequencing delayed message due to unexpected index", "expected", nextDelayedSeqNum, "found", delayedSeqNum) continue } - if header.Kind == arbostypes.L1MessageType_BatchPostingReport { - log.Debug("skipping L1MessageType_BatchPostingReport message", "header", header) - continue - } _, err := s.sequenceDelayedMessageWithBlockMutex(msg.Message, delayedSeqNum) if err != nil { log.Error("failed to re-sequence old delayed message removed by reorg", "err", err)