From 4771437745af7dc105662527cca48a8059f6e88f Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:02:34 +0200 Subject: [PATCH 1/8] Fix bug sequencer submission strategy and log commit price --- .../internal/controller/relayer/l2_relayer.go | 20 ++++++++++++++----- .../controller/relayer/l2_relayer_metrics.go | 5 +++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 418762a470..0f3f4b6d50 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -104,10 +104,15 @@ type StrategyParams struct { } // bestParams maps your 2h/5h/12h windows to their best rules. +// Timeouts are in seconds, 2, 5 and 12 hours (and same + 20 mins to account for +// time to create batch currently roughly, as time is measured from block creation) var bestParams = map[uint64]StrategyParams{ - 2 * 3600: {BaselineType: PctMin, BaselineParam: 0.10, Gamma: 0.4, Beta: 8, RelaxType: Exponential}, - 5 * 3600: {BaselineType: PctMin, BaselineParam: 0.30, Gamma: 0.6, Beta: 20, RelaxType: Sigmoid}, - 12 * 3600: {BaselineType: PctMin, BaselineParam: 0.50, Gamma: 0.5, Beta: 20, RelaxType: Sigmoid}, + 7200: {BaselineType: PctMin, BaselineParam: 0.10, Gamma: 0.4, Beta: 8, RelaxType: Exponential}, + 8400: {BaselineType: PctMin, BaselineParam: 0.10, Gamma: 0.4, Beta: 8, RelaxType: Exponential}, + 18000: {BaselineType: PctMin, BaselineParam: 0.30, Gamma: 0.6, Beta: 20, RelaxType: Sigmoid}, + 19200: {BaselineType: PctMin, BaselineParam: 0.30, Gamma: 0.6, Beta: 20, RelaxType: Sigmoid}, + 42800: {BaselineType: PctMin, BaselineParam: 0.50, Gamma: 0.5, Beta: 20, RelaxType: Sigmoid}, + 44400: {BaselineType: PctMin, BaselineParam: 0.50, Gamma: 0.5, Beta: 20, RelaxType: Sigmoid}, } // NewLayer2Relayer will return a new instance of Layer2RelayerClient @@ -147,6 +152,11 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm. return nil, fmt.Errorf("invalid service type for l2_relayer: %v", serviceType) } + strategy, ok := bestParams[uint64(cfg.BatchSubmission.TimeoutSec)] + if !ok { + return nil, fmt.Errorf("invalid timeout for batch submission: %v", cfg.BatchSubmission.TimeoutSec) + } + layer2Relayer := &Layer2Relayer{ ctx: ctx, db: db, @@ -164,7 +174,7 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm. l1RollupABI: bridgeAbi.ScrollChainABI, l2GasOracleABI: bridgeAbi.L2GasPriceOracleABI, - batchStrategy: bestParams[uint64(cfg.BatchSubmission.TimeoutSec)], + batchStrategy: strategy, cfg: cfg, chainCfg: chainCfg, } @@ -508,7 +518,6 @@ func (r *Layer2Relayer) ProcessPendingBatches() { r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Add(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerProcessBatchesPerTxCount.Set(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerCommitLatency.Set(time.Since(oldestBlockTimestamp).Seconds()) - log.Info("Sent the commitBatches tx to layer1", "batches count", len(batchesToSubmit), "start index", firstBatch.Index, "start hash", firstBatch.Hash, "end index", lastBatch.Index, "end hash", lastBatch.Hash, "tx hash", txHash.String()) } @@ -1118,6 +1127,7 @@ func (r *Layer2Relayer) skipSubmitByFee(oldest time.Time, metrics *l2RelayerMetr ) } + r.metrics.rollupL2RelayerCommitPrice.Set(target) // otherwise proceed with submission return false, nil } diff --git a/rollup/internal/controller/relayer/l2_relayer_metrics.go b/rollup/internal/controller/relayer/l2_relayer_metrics.go index 00e550588f..b6c883ceaa 100644 --- a/rollup/internal/controller/relayer/l2_relayer_metrics.go +++ b/rollup/internal/controller/relayer/l2_relayer_metrics.go @@ -31,6 +31,7 @@ type l2RelayerMetrics struct { rollupL2RelayerTargetBlobPrice prometheus.Gauge rollupL2RelayerCommitLatency prometheus.Gauge rollupL2RelayerBacklogCounts prometheus.Gauge + rollupL2RelayerCommitPrice prometheus.Gauge } var ( @@ -125,6 +126,10 @@ func initL2RelayerMetrics(reg prometheus.Registerer) *l2RelayerMetrics { Name: "rollup_l2_relayer_backlog_counts", Help: "The number of pending batches in the backlog", }), + rollupL2RelayerCommitPrice: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ + Name: "rollup_l2_relayer_commit_price", + Help: "The commit price for the L2 relayer's submission strategy", + }), } }) return l2RelayerMetric From 65fa2be45f3e620608772206597f61f01a5b2560 Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:07:34 +0200 Subject: [PATCH 2/8] log current price not target when committing --- rollup/internal/controller/relayer/l2_relayer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 0f3f4b6d50..b651da190e 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -1127,7 +1127,7 @@ func (r *Layer2Relayer) skipSubmitByFee(oldest time.Time, metrics *l2RelayerMetr ) } - r.metrics.rollupL2RelayerCommitPrice.Set(target) + r.metrics.rollupL2RelayerCommitPrice.Set(currentFloat) // otherwise proceed with submission return false, nil } From 8856ba6e69f374a1d4de29efda2a0587c1440de6 Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:15:30 +0200 Subject: [PATCH 3/8] Log commit price if forced submission too --- rollup/internal/controller/relayer/l2_relayer.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index b651da190e..015785d446 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -518,6 +518,12 @@ func (r *Layer2Relayer) ProcessPendingBatches() { r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Add(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerProcessBatchesPerTxCount.Set(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerCommitLatency.Set(time.Since(oldestBlockTimestamp).Seconds()) + if len(r.feeHistory) != 0 { + current := r.feeHistory[len(r.feeHistory)-1] + currentFloat, _ := current.Float64() + r.metrics.rollupL2RelayerCommitPrice.Set(float64(currentFloat)) + } + log.Info("Sent the commitBatches tx to layer1", "batches count", len(batchesToSubmit), "start index", firstBatch.Index, "start hash", firstBatch.Hash, "end index", lastBatch.Index, "end hash", lastBatch.Hash, "tx hash", txHash.String()) } @@ -1127,7 +1133,6 @@ func (r *Layer2Relayer) skipSubmitByFee(oldest time.Time, metrics *l2RelayerMetr ) } - r.metrics.rollupL2RelayerCommitPrice.Set(currentFloat) // otherwise proceed with submission return false, nil } From 8b5c670a185a2afa444adb057599d0444b0cb56d Mon Sep 17 00:00:00 2001 From: ranchalp Date: Fri, 23 May 2025 08:16:28 +0000 Subject: [PATCH 4/8] =?UTF-8?q?chore:=20auto=20version=20bump=E2=80=89[bot?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/version/version.go b/common/version/version.go index cb1ff7acc6..419c8716ad 100644 --- a/common/version/version.go +++ b/common/version/version.go @@ -5,7 +5,7 @@ import ( "runtime/debug" ) -var tag = "v4.5.16" +var tag = "v4.5.17" var commit = func() string { if info, ok := debug.ReadBuildInfo(); ok { From 48ce121f8a4342886a2a69c4ba22ad024288e449 Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:35:13 +0200 Subject: [PATCH 5/8] Log actual blob base fee on submission --- .../internal/controller/relayer/l1_relayer.go | 6 ++--- .../internal/controller/relayer/l2_relayer.go | 18 ++++++--------- rollup/internal/controller/sender/sender.go | 22 +++++++++---------- .../internal/controller/sender/sender_test.go | 20 ++++++++--------- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/rollup/internal/controller/relayer/l1_relayer.go b/rollup/internal/controller/relayer/l1_relayer.go index 0088b14102..63fa741f56 100644 --- a/rollup/internal/controller/relayer/l1_relayer.go +++ b/rollup/internal/controller/relayer/l1_relayer.go @@ -179,13 +179,13 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() { return } - hash, err := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, data, nil) + txHash, err, _ := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, data, nil) if err != nil { log.Error("Failed to send gas oracle update tx to layer2", "block.Hash", block.Hash, "block.Height", block.Number, "block.BaseFee", baseFee, "block.BlobBaseFee", blobBaseFee, "err", err) return } - err = r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, block.Hash, types.GasOracleImporting, hash.String()) + err = r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, block.Hash, types.GasOracleImporting, txHash.String()) if err != nil { log.Error("UpdateGasOracleStatusAndOracleTxHash failed", "block.Hash", block.Hash, "block.Height", block.Number, "err", err) return @@ -195,7 +195,7 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() { r.lastBlobBaseFee = blobBaseFee r.metrics.rollupL1RelayerLatestBaseFee.Set(float64(r.lastBaseFee)) r.metrics.rollupL1RelayerLatestBlobBaseFee.Set(float64(r.lastBlobBaseFee)) - log.Info("Update l1 base fee", "txHash", hash.String(), "baseFee", baseFee, "blobBaseFee", blobBaseFee) + log.Info("Update l1 base fee", "txHash", txHash.String(), "baseFee", baseFee, "blobBaseFee", blobBaseFee) } } } diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 015785d446..093ec21de2 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -281,11 +281,11 @@ func (r *Layer2Relayer) commitGenesisBatch(batchHash string, batchHeader []byte, } // submit genesis batch to L1 rollup contract - txHash, err := r.commitSender.SendTransaction(batchHash, &r.cfg.RollupContractAddress, calldata, nil) + txHash, err, _ := r.commitSender.SendTransaction(batchHash, &r.cfg.RollupContractAddress, calldata, nil) if err != nil { return fmt.Errorf("failed to send import genesis batch tx to L1, error: %v", err) } - log.Info("importGenesisBatch transaction sent", "contract", r.cfg.RollupContractAddress, "txHash", txHash.String(), "batchHash", batchHash) + log.Info("importGenesisBatch transaction sent", "contract", r.cfg.RollupContractAddress, "txHash", txHash, "batchHash", batchHash) // wait for confirmation // we assume that no other transactions are sent before initializeGenesis completes @@ -346,12 +346,12 @@ func (r *Layer2Relayer) ProcessPendingBatches() { var forceSubmit bool startChunk, err := r.chunkOrm.GetChunkByIndex(r.ctx, dbBatches[0].StartChunkIndex) - oldestBlockTimestamp := time.Unix(int64(startChunk.StartBlockTime), 0) if err != nil { log.Error("failed to get first chunk", "err", err, "batch index", dbBatches[0].Index, "chunk index", dbBatches[0].StartChunkIndex) return } - + oldestBlockTimestamp := time.Unix(int64(startChunk.StartBlockTime), 0) + // if the batch with the oldest index is too old, we force submit all batches that we have so far in the next step if r.cfg.BatchSubmission.TimeoutSec > 0 && time.Since(oldestBlockTimestamp) > time.Duration(r.cfg.BatchSubmission.TimeoutSec)*time.Second { forceSubmit = true @@ -477,7 +477,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() { return } - txHash, err := r.commitSender.SendTransaction(r.contextIDFromBatches(batchesToSubmit), &r.cfg.RollupContractAddress, calldata, blobs) + txHash, err, blobBaseFee := r.commitSender.SendTransaction(r.contextIDFromBatches(batchesToSubmit), &r.cfg.RollupContractAddress, calldata, blobs) if err != nil { if errors.Is(err, sender.ErrTooManyPendingBlobTxs) { r.metrics.rollupL2RelayerProcessPendingBatchErrTooManyPendingBlobTxsTotal.Inc() @@ -518,11 +518,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() { r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Add(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerProcessBatchesPerTxCount.Set(float64(len(batchesToSubmit))) r.metrics.rollupL2RelayerCommitLatency.Set(time.Since(oldestBlockTimestamp).Seconds()) - if len(r.feeHistory) != 0 { - current := r.feeHistory[len(r.feeHistory)-1] - currentFloat, _ := current.Float64() - r.metrics.rollupL2RelayerCommitPrice.Set(float64(currentFloat)) - } + r.metrics.rollupL2RelayerCommitPrice.Set(float64(blobBaseFee)) log.Info("Sent the commitBatches tx to layer1", "batches count", len(batchesToSubmit), "start index", firstBatch.Index, "start hash", firstBatch.Hash, "end index", lastBatch.Index, "end hash", lastBatch.Hash, "tx hash", txHash.String()) } @@ -706,7 +702,7 @@ func (r *Layer2Relayer) finalizeBundle(bundle *orm.Bundle, withProof bool) error return fmt.Errorf("unsupported codec version in finalizeBundle, bundle index: %v, version: %d", bundle.Index, bundle.CodecVersion) } - txHash, err := r.finalizeSender.SendTransaction("finalizeBundle-"+bundle.Hash, &r.cfg.RollupContractAddress, calldata, nil) + txHash, err, _ := r.finalizeSender.SendTransaction("finalizeBundle-"+bundle.Hash, &r.cfg.RollupContractAddress, calldata, nil) if err != nil { log.Error("finalizeBundle in layer1 failed", "with proof", withProof, "index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, diff --git a/rollup/internal/controller/sender/sender.go b/rollup/internal/controller/sender/sender.go index 1b8ccd3aa2..338b746519 100644 --- a/rollup/internal/controller/sender/sender.go +++ b/rollup/internal/controller/sender/sender.go @@ -171,7 +171,7 @@ func (s *Sender) getFeeData(target *common.Address, data []byte, sidecar *gethTy } // SendTransaction send a signed L2tL1 transaction. -func (s *Sender) SendTransaction(contextID string, target *common.Address, data []byte, blobs []*kzg4844.Blob) (common.Hash, error) { +func (s *Sender) SendTransaction(contextID string, target *common.Address, data []byte, blobs []*kzg4844.Blob) (common.Hash, error, uint64) { s.metrics.sendTransactionTotal.WithLabelValues(s.service, s.name).Inc() var ( feeData *FeeData @@ -190,37 +190,37 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data numPendingTransactions, err = s.pendingTransactionOrm.GetCountPendingTransactionsBySenderType(s.ctx, s.senderType) if err != nil { log.Error("failed to count pending transactions", "err: %w", err) - return common.Hash{}, fmt.Errorf("failed to count pending transactions, err: %w", err) + return nil, fmt.Errorf("failed to count pending transactions, err: %w", err) } if numPendingTransactions >= s.config.MaxPendingBlobTxs { - return common.Hash{}, ErrTooManyPendingBlobTxs + return nil, ErrTooManyPendingBlobTxs } } sidecar, err = makeSidecar(blobs) if err != nil { log.Error("failed to make sidecar for blob transaction", "error", err) - return common.Hash{}, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err) + return nil, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err) } } blockNumber, baseFee, blobBaseFee, err := s.getBlockNumberAndBaseFeeAndBlobFee(s.ctx) if err != nil { log.Error("failed to get block number and base fee", "error", err) - return common.Hash{}, fmt.Errorf("failed to get block number and base fee, err: %w", err) + return nil, fmt.Errorf("failed to get block number and base fee, err: %w", err) } if feeData, err = s.getFeeData(target, data, sidecar, baseFee, blobBaseFee); err != nil { s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc() log.Error("failed to get fee data", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err) + return nil, fmt.Errorf("failed to get fee data, err: %w", err) } signedTx, err := s.createTx(feeData, target, data, sidecar, s.transactionSigner.GetNonce()) if err != nil { s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc() log.Error("failed to create signed tx (non-resubmit case)", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to create signed transaction, err: %w", err) + return nil, fmt.Errorf("failed to create signed transaction, err: %w", err) } // Insert the transaction into the pending transaction table. @@ -228,14 +228,14 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data // This case will be handled by the checkPendingTransaction function. if err = s.pendingTransactionOrm.InsertPendingTransaction(s.ctx, contextID, s.getSenderMeta(), signedTx, blockNumber); err != nil { log.Error("failed to insert transaction", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to insert transaction, err: %w", err) + return nil, fmt.Errorf("failed to insert transaction, err: %w", err) } if err := s.client.SendTransaction(s.ctx, signedTx); err != nil { // Delete the transaction from the pending transaction table if it fails to send. if updateErr := s.pendingTransactionOrm.DeleteTransactionByTxHash(s.ctx, signedTx.Hash()); updateErr != nil { log.Error("failed to delete transaction", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", updateErr) - return common.Hash{}, fmt.Errorf("failed to delete transaction, err: %w", updateErr) + return nil, fmt.Errorf("failed to delete transaction, err: %w", updateErr) } log.Error("failed to send tx", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", err) @@ -244,12 +244,12 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data if strings.Contains(err.Error(), "nonce too low") { s.resetNonce(context.Background()) } - return common.Hash{}, fmt.Errorf("failed to send transaction, err: %w", err) + return nil, fmt.Errorf("failed to send transaction, err: %w", err) } s.transactionSigner.SetNonce(signedTx.Nonce() + 1) - return signedTx.Hash(), nil + return signedTx.Hash(), nil, blobBaseFee } func (s *Sender) createTx(feeData *FeeData, target *common.Address, data []byte, sidecar *gethTypes.BlobTxSidecar, nonce uint64) (*gethTypes.Transaction, error) { diff --git a/rollup/internal/controller/sender/sender_test.go b/rollup/internal/controller/sender/sender_test.go index 80164170a0..2eb56d572d 100644 --- a/rollup/internal/controller/sender/sender_test.go +++ b/rollup/internal/controller/sender/sender_test.go @@ -187,7 +187,7 @@ func testSendAndRetrieveTransaction(t *testing.T) { if txBlob[i] != nil { blobs = []*kzg4844.Blob{txBlob[i]} } - hash, err := s.SendTransaction("0", &common.Address{}, nil, blobs) + hash, err, _ := s.SendTransaction("0", &common.Address{}, nil, blobs) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) assert.NoError(t, err) @@ -545,10 +545,10 @@ func testResubmitNonceGappedTransaction(t *testing.T) { if txBlob[i] != nil { blobs = []*kzg4844.Blob{txBlob[i]} } - _, err = s.SendTransaction("test-1", &common.Address{}, nil, blobs) + _, err, _ = s.SendTransaction("test-1", &common.Address{}, nil, blobs) assert.NoError(t, err) - _, err = s.SendTransaction("test-2", &common.Address{}, nil, blobs) + _, err, _ = s.SendTransaction("test-2", &common.Address{}, nil, blobs) assert.NoError(t, err) s.checkPendingTransaction() @@ -589,7 +589,7 @@ func testCheckPendingTransactionTxConfirmed(t *testing.T) { return nil }) - _, err = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + _, err, _ = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -631,7 +631,7 @@ func testCheckPendingTransactionResubmitTxConfirmed(t *testing.T) { return nil }) - originTxHash, err := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + originTxHash, err, _ := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -691,7 +691,7 @@ func testCheckPendingTransactionReplacedTxConfirmed(t *testing.T) { return nil }) - txHash, err := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + txHash, err, _ := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -761,7 +761,7 @@ func testCheckPendingTransactionTxMultipleTimesWithOnlyOneTxPending(t *testing.T return nil }) - _, err = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + _, err, _ = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -835,7 +835,7 @@ func testBlobTransactionWithBlobhashOpContractCall(t *testing.T) { assert.NoError(t, err) defer s.Stop() - _, err = s.SendTransaction("0", &testContractsAddress, data, blobs) + _, err, _ = s.SendTransaction("0", &testContractsAddress, data, blobs) assert.NoError(t, err) var txHash common.Hash @@ -893,10 +893,10 @@ func testSendBlobCarryingTxOverLimit(t *testing.T) { assert.NoError(t, err) for i := 0; i < int(cfgCopy.MaxPendingBlobTxs); i++ { - _, err = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) + _, err, _ = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) } - _, err = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) + _, err, _ = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) assert.ErrorIs(t, err, ErrTooManyPendingBlobTxs) s.Stop() } From ae2bcb904bf426b5faaa48ce8aa8f413487b5c4b Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:39:04 +0200 Subject: [PATCH 6/8] Fix not returning 3 arguments on errors --- rollup/internal/controller/sender/sender.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rollup/internal/controller/sender/sender.go b/rollup/internal/controller/sender/sender.go index 338b746519..63cdbeb534 100644 --- a/rollup/internal/controller/sender/sender.go +++ b/rollup/internal/controller/sender/sender.go @@ -190,37 +190,37 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data numPendingTransactions, err = s.pendingTransactionOrm.GetCountPendingTransactionsBySenderType(s.ctx, s.senderType) if err != nil { log.Error("failed to count pending transactions", "err: %w", err) - return nil, fmt.Errorf("failed to count pending transactions, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to count pending transactions, err: %w", err), 0 } if numPendingTransactions >= s.config.MaxPendingBlobTxs { - return nil, ErrTooManyPendingBlobTxs + return common.Hash{}, ErrTooManyPendingBlobTxs, 0 } } sidecar, err = makeSidecar(blobs) if err != nil { log.Error("failed to make sidecar for blob transaction", "error", err) - return nil, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err), 0 } } blockNumber, baseFee, blobBaseFee, err := s.getBlockNumberAndBaseFeeAndBlobFee(s.ctx) if err != nil { log.Error("failed to get block number and base fee", "error", err) - return nil, fmt.Errorf("failed to get block number and base fee, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to get block number and base fee, err: %w", err), 0 } if feeData, err = s.getFeeData(target, data, sidecar, baseFee, blobBaseFee); err != nil { s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc() log.Error("failed to get fee data", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return nil, fmt.Errorf("failed to get fee data, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err), 0 } signedTx, err := s.createTx(feeData, target, data, sidecar, s.transactionSigner.GetNonce()) if err != nil { s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc() log.Error("failed to create signed tx (non-resubmit case)", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return nil, fmt.Errorf("failed to create signed transaction, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to create signed transaction, err: %w", err), 0 } // Insert the transaction into the pending transaction table. @@ -228,14 +228,14 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data // This case will be handled by the checkPendingTransaction function. if err = s.pendingTransactionOrm.InsertPendingTransaction(s.ctx, contextID, s.getSenderMeta(), signedTx, blockNumber); err != nil { log.Error("failed to insert transaction", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return nil, fmt.Errorf("failed to insert transaction, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to insert transaction, err: %w", err), 0 } if err := s.client.SendTransaction(s.ctx, signedTx); err != nil { // Delete the transaction from the pending transaction table if it fails to send. if updateErr := s.pendingTransactionOrm.DeleteTransactionByTxHash(s.ctx, signedTx.Hash()); updateErr != nil { log.Error("failed to delete transaction", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", updateErr) - return nil, fmt.Errorf("failed to delete transaction, err: %w", updateErr) + return common.Hash{}, fmt.Errorf("failed to delete transaction, err: %w", updateErr), 0 } log.Error("failed to send tx", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", err) @@ -244,7 +244,7 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data if strings.Contains(err.Error(), "nonce too low") { s.resetNonce(context.Background()) } - return nil, fmt.Errorf("failed to send transaction, err: %w", err) + return common.Hash{}, fmt.Errorf("failed to send transaction, err: %w", err), 0 } s.transactionSigner.SetNonce(signedTx.Nonce() + 1) From f5700adb23ca3346c5df6325e8ec357a470b0331 Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:48:46 +0200 Subject: [PATCH 7/8] Make lint happy --- .../internal/controller/relayer/l1_relayer.go | 2 +- .../internal/controller/relayer/l2_relayer.go | 8 ++++---- rollup/internal/controller/sender/sender.go | 4 ++-- .../internal/controller/sender/sender_test.go | 20 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/rollup/internal/controller/relayer/l1_relayer.go b/rollup/internal/controller/relayer/l1_relayer.go index 63fa741f56..d9f0835d52 100644 --- a/rollup/internal/controller/relayer/l1_relayer.go +++ b/rollup/internal/controller/relayer/l1_relayer.go @@ -179,7 +179,7 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() { return } - txHash, err, _ := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, data, nil) + txHash, _, err := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, data, nil) if err != nil { log.Error("Failed to send gas oracle update tx to layer2", "block.Hash", block.Hash, "block.Height", block.Number, "block.BaseFee", baseFee, "block.BlobBaseFee", blobBaseFee, "err", err) return diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 093ec21de2..8c74418fad 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -281,7 +281,7 @@ func (r *Layer2Relayer) commitGenesisBatch(batchHash string, batchHeader []byte, } // submit genesis batch to L1 rollup contract - txHash, err, _ := r.commitSender.SendTransaction(batchHash, &r.cfg.RollupContractAddress, calldata, nil) + txHash, _, err := r.commitSender.SendTransaction(batchHash, &r.cfg.RollupContractAddress, calldata, nil) if err != nil { return fmt.Errorf("failed to send import genesis batch tx to L1, error: %v", err) } @@ -351,7 +351,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() { return } oldestBlockTimestamp := time.Unix(int64(startChunk.StartBlockTime), 0) - + // if the batch with the oldest index is too old, we force submit all batches that we have so far in the next step if r.cfg.BatchSubmission.TimeoutSec > 0 && time.Since(oldestBlockTimestamp) > time.Duration(r.cfg.BatchSubmission.TimeoutSec)*time.Second { forceSubmit = true @@ -477,7 +477,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() { return } - txHash, err, blobBaseFee := r.commitSender.SendTransaction(r.contextIDFromBatches(batchesToSubmit), &r.cfg.RollupContractAddress, calldata, blobs) + txHash, blobBaseFee, err := r.commitSender.SendTransaction(r.contextIDFromBatches(batchesToSubmit), &r.cfg.RollupContractAddress, calldata, blobs) if err != nil { if errors.Is(err, sender.ErrTooManyPendingBlobTxs) { r.metrics.rollupL2RelayerProcessPendingBatchErrTooManyPendingBlobTxsTotal.Inc() @@ -702,7 +702,7 @@ func (r *Layer2Relayer) finalizeBundle(bundle *orm.Bundle, withProof bool) error return fmt.Errorf("unsupported codec version in finalizeBundle, bundle index: %v, version: %d", bundle.Index, bundle.CodecVersion) } - txHash, err, _ := r.finalizeSender.SendTransaction("finalizeBundle-"+bundle.Hash, &r.cfg.RollupContractAddress, calldata, nil) + txHash, _, err := r.finalizeSender.SendTransaction("finalizeBundle-"+bundle.Hash, &r.cfg.RollupContractAddress, calldata, nil) if err != nil { log.Error("finalizeBundle in layer1 failed", "with proof", withProof, "index", bundle.Index, "start batch index", bundle.StartBatchIndex, "end batch index", bundle.EndBatchIndex, diff --git a/rollup/internal/controller/sender/sender.go b/rollup/internal/controller/sender/sender.go index 63cdbeb534..189fafb65a 100644 --- a/rollup/internal/controller/sender/sender.go +++ b/rollup/internal/controller/sender/sender.go @@ -171,7 +171,7 @@ func (s *Sender) getFeeData(target *common.Address, data []byte, sidecar *gethTy } // SendTransaction send a signed L2tL1 transaction. -func (s *Sender) SendTransaction(contextID string, target *common.Address, data []byte, blobs []*kzg4844.Blob) (common.Hash, error, uint64) { +func (s *Sender) SendTransaction(contextID string, target *common.Address, data []byte, blobs []*kzg4844.Blob) (common.Hash, uint64, error) { s.metrics.sendTransactionTotal.WithLabelValues(s.service, s.name).Inc() var ( feeData *FeeData @@ -249,7 +249,7 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data s.transactionSigner.SetNonce(signedTx.Nonce() + 1) - return signedTx.Hash(), nil, blobBaseFee + return signedTx.Hash(), blobBaseFee, nil } func (s *Sender) createTx(feeData *FeeData, target *common.Address, data []byte, sidecar *gethTypes.BlobTxSidecar, nonce uint64) (*gethTypes.Transaction, error) { diff --git a/rollup/internal/controller/sender/sender_test.go b/rollup/internal/controller/sender/sender_test.go index 2eb56d572d..7ca8da5c8d 100644 --- a/rollup/internal/controller/sender/sender_test.go +++ b/rollup/internal/controller/sender/sender_test.go @@ -187,7 +187,7 @@ func testSendAndRetrieveTransaction(t *testing.T) { if txBlob[i] != nil { blobs = []*kzg4844.Blob{txBlob[i]} } - hash, err, _ := s.SendTransaction("0", &common.Address{}, nil, blobs) + hash, _, err := s.SendTransaction("0", &common.Address{}, nil, blobs) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) assert.NoError(t, err) @@ -545,10 +545,10 @@ func testResubmitNonceGappedTransaction(t *testing.T) { if txBlob[i] != nil { blobs = []*kzg4844.Blob{txBlob[i]} } - _, err, _ = s.SendTransaction("test-1", &common.Address{}, nil, blobs) + _, _, err = s.SendTransaction("test-1", &common.Address{}, nil, blobs) assert.NoError(t, err) - _, err, _ = s.SendTransaction("test-2", &common.Address{}, nil, blobs) + _, _, err = s.SendTransaction("test-2", &common.Address{}, nil, blobs) assert.NoError(t, err) s.checkPendingTransaction() @@ -589,7 +589,7 @@ func testCheckPendingTransactionTxConfirmed(t *testing.T) { return nil }) - _, err, _ = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + _, _, err = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -631,7 +631,7 @@ func testCheckPendingTransactionResubmitTxConfirmed(t *testing.T) { return nil }) - originTxHash, err, _ := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + originTxHash, _, err := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -691,7 +691,7 @@ func testCheckPendingTransactionReplacedTxConfirmed(t *testing.T) { return nil }) - txHash, err, _ := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + txHash, _, err := s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -761,7 +761,7 @@ func testCheckPendingTransactionTxMultipleTimesWithOnlyOneTxPending(t *testing.T return nil }) - _, err, _ = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) + _, _, err = s.SendTransaction("test", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) txs, err := s.pendingTransactionOrm.GetPendingOrReplacedTransactionsBySenderType(context.Background(), s.senderType, 1) @@ -835,7 +835,7 @@ func testBlobTransactionWithBlobhashOpContractCall(t *testing.T) { assert.NoError(t, err) defer s.Stop() - _, err, _ = s.SendTransaction("0", &testContractsAddress, data, blobs) + _, _, err = s.SendTransaction("0", &testContractsAddress, data, blobs) assert.NoError(t, err) var txHash common.Hash @@ -893,10 +893,10 @@ func testSendBlobCarryingTxOverLimit(t *testing.T) { assert.NoError(t, err) for i := 0; i < int(cfgCopy.MaxPendingBlobTxs); i++ { - _, err, _ = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) + _, _, err = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) assert.NoError(t, err) } - _, err, _ = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) + _, _, err = s.SendTransaction("0", &common.Address{}, nil, randBlobs(1)) assert.ErrorIs(t, err, ErrTooManyPendingBlobTxs) s.Stop() } From d1a18932c91fd0de72cf00dc32d8e104f3c433fc Mon Sep 17 00:00:00 2001 From: Alejandro Ranchal-Pedrosa Date: Fri, 23 May 2025 10:52:43 +0200 Subject: [PATCH 8/8] Make lint happy II --- rollup/internal/controller/sender/sender.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rollup/internal/controller/sender/sender.go b/rollup/internal/controller/sender/sender.go index 189fafb65a..d5a4db5d3b 100644 --- a/rollup/internal/controller/sender/sender.go +++ b/rollup/internal/controller/sender/sender.go @@ -190,37 +190,37 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data numPendingTransactions, err = s.pendingTransactionOrm.GetCountPendingTransactionsBySenderType(s.ctx, s.senderType) if err != nil { log.Error("failed to count pending transactions", "err: %w", err) - return common.Hash{}, fmt.Errorf("failed to count pending transactions, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to count pending transactions, err: %w", err) } if numPendingTransactions >= s.config.MaxPendingBlobTxs { - return common.Hash{}, ErrTooManyPendingBlobTxs, 0 + return common.Hash{}, 0, ErrTooManyPendingBlobTxs } } sidecar, err = makeSidecar(blobs) if err != nil { log.Error("failed to make sidecar for blob transaction", "error", err) - return common.Hash{}, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to make sidecar for blob transaction, err: %w", err) } } blockNumber, baseFee, blobBaseFee, err := s.getBlockNumberAndBaseFeeAndBlobFee(s.ctx) if err != nil { log.Error("failed to get block number and base fee", "error", err) - return common.Hash{}, fmt.Errorf("failed to get block number and base fee, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to get block number and base fee, err: %w", err) } if feeData, err = s.getFeeData(target, data, sidecar, baseFee, blobBaseFee); err != nil { s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc() log.Error("failed to get fee data", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to get fee data, err: %w", err) } signedTx, err := s.createTx(feeData, target, data, sidecar, s.transactionSigner.GetNonce()) if err != nil { s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc() log.Error("failed to create signed tx (non-resubmit case)", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to create signed transaction, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to create signed transaction, err: %w", err) } // Insert the transaction into the pending transaction table. @@ -228,14 +228,14 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data // This case will be handled by the checkPendingTransaction function. if err = s.pendingTransactionOrm.InsertPendingTransaction(s.ctx, contextID, s.getSenderMeta(), signedTx, blockNumber); err != nil { log.Error("failed to insert transaction", "from", s.transactionSigner.GetAddr().String(), "nonce", s.transactionSigner.GetNonce(), "err", err) - return common.Hash{}, fmt.Errorf("failed to insert transaction, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to insert transaction, err: %w", err) } if err := s.client.SendTransaction(s.ctx, signedTx); err != nil { // Delete the transaction from the pending transaction table if it fails to send. if updateErr := s.pendingTransactionOrm.DeleteTransactionByTxHash(s.ctx, signedTx.Hash()); updateErr != nil { log.Error("failed to delete transaction", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", updateErr) - return common.Hash{}, fmt.Errorf("failed to delete transaction, err: %w", updateErr), 0 + return common.Hash{}, 0, fmt.Errorf("failed to delete transaction, err: %w", updateErr) } log.Error("failed to send tx", "tx hash", signedTx.Hash().String(), "from", s.transactionSigner.GetAddr().String(), "nonce", signedTx.Nonce(), "err", err) @@ -244,7 +244,7 @@ func (s *Sender) SendTransaction(contextID string, target *common.Address, data if strings.Contains(err.Error(), "nonce too low") { s.resetNonce(context.Background()) } - return common.Hash{}, fmt.Errorf("failed to send transaction, err: %w", err), 0 + return common.Hash{}, 0, fmt.Errorf("failed to send transaction, err: %w", err) } s.transactionSigner.SetNonce(signedTx.Nonce() + 1)