diff --git a/op-node/rollup/derive/payload_attributes.go b/op-node/rollup/derive/payload_attributes.go index 62856e2366898..2c36b15af06af 100644 --- a/op-node/rollup/derive/payload_attributes.go +++ b/op-node/rollup/derive/payload_attributes.go @@ -226,32 +226,33 @@ func UserDeposits(receipts []*types.Receipt, depositContractAddr common.Address) return out, errs } -func BatchesFromEVMTransactions(config *rollup.Config, txLists []types.Transactions) ([]*BatchData, error) { +func BatchesFromEVMTransactions(config *rollup.Config, txLists []types.Transactions) ([]*BatchData, []error) { var out []*BatchData + var errs []error l1Signer := config.L1Signer() - for _, txs := range txLists { - for _, tx := range txs { + for i, txs := range txLists { + for j, tx := range txs { if to := tx.To(); to != nil && *to == config.BatchInboxAddress { seqDataSubmitter, err := l1Signer.Sender(tx) // optimization: only derive sender if To is correct if err != nil { - // TODO: log error + errs = append(errs, fmt.Errorf("invalid signature: tx list: %d, tx: %d, err: %w", i, j, err)) continue // bad signature, ignore } // some random L1 user might have sent a transaction to our batch inbox, ignore them if seqDataSubmitter != config.BatchSenderAddress { - // TODO: log/record metric + errs = append(errs, fmt.Errorf("unauthorized batch submitter: tx list: %d, tx: %d", i, j)) continue // not an authorized batch submitter, ignore } batches, err := DecodeBatches(config, bytes.NewReader(tx.Data())) if err != nil { - // TODO: log/record metric + errs = append(errs, fmt.Errorf("invalid batch: tx list: %d, tx: %d, err: %w", i, j, err)) continue } out = append(out, batches...) } } } - return out, nil + return out, errs } func FilterBatches(config *rollup.Config, epoch rollup.Epoch, minL2Time uint64, maxL2Time uint64, batches []*BatchData) (out []*BatchData) { diff --git a/op-node/rollup/driver/step.go b/op-node/rollup/driver/step.go index c7282e71adecb..4a1de9c746c00 100644 --- a/op-node/rollup/driver/step.go +++ b/op-node/rollup/driver/step.go @@ -198,10 +198,14 @@ func (d *outputImpl) insertEpoch(ctx context.Context, l2Head eth.L2BlockRef, l2S if err != nil { return l2Head, l2SafeHead, false, fmt.Errorf("failed to fetch transactions from %s: %v", l1Input, err) } - batches, err := derive.BatchesFromEVMTransactions(&d.Config, transactions) - if err != nil { - return l2Head, l2SafeHead, false, fmt.Errorf("failed to fetch create batches from transactions: %w", err) + batches, errs := derive.BatchesFromEVMTransactions(&d.Config, transactions) + // Some input to derive.BatchesFromEVMTransactions may be invalid and produce errors. + // We log the errors, but keep going as this process is designed to be resilient to these errors + // and we have defaults in case no valid (or partial) batches were submitted. + for i, err := range errs { + d.log.Error("Failed to decode batch", "err_idx", i, "err", err) } + // Make batches contiguous minL2Time := uint64(l2Info.Timestamp) + d.Config.BlockTime maxL2Time := l1Info.Time() + d.Config.MaxSequencerDrift