diff --git a/common/utils/flags.go b/common/utils/flags.go index e6e4f64222..a97d2b7f87 100644 --- a/common/utils/flags.go +++ b/common/utils/flags.go @@ -21,6 +21,7 @@ var ( // RollupRelayerFlags contains flags only used in rollup-relayer RollupRelayerFlags = []cli.Flag{ &ImportGenesisFlag, + &MinCodecVersionFlag, } // ConfigFileFlag load json type config file. ConfigFileFlag = cli.StringFlag{ @@ -90,4 +91,10 @@ var ( Usage: "Genesis file of the network", Value: "./conf/genesis.json", } + // MinCodecVersionFlag defines the minimum codec version required for the relayer + MinCodecVersionFlag = cli.UintFlag{ + Name: "min-codec-version", + Usage: "Minimum required codec version for the relayer", + Required: true, + } ) diff --git a/rollup/cmd/rollup_relayer/app/app.go b/rollup/cmd/rollup_relayer/app/app.go index ebaeb5723c..080f27cdf7 100644 --- a/rollup/cmd/rollup_relayer/app/app.go +++ b/rollup/cmd/rollup_relayer/app/app.go @@ -8,6 +8,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "github.com/scroll-tech/da-codec/encoding" "github.com/scroll-tech/go-ethereum/ethclient" "github.com/scroll-tech/go-ethereum/log" "github.com/urfave/cli/v2" @@ -84,9 +85,10 @@ func action(ctx *cli.Context) error { log.Crit("failed to create l2 relayer", "config file", cfgFile, "error", err) } - chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, genesis.Config, db, registry) - batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, genesis.Config, db, registry) - bundleProposer := watcher.NewBundleProposer(subCtx, cfg.L2Config.BundleProposerConfig, genesis.Config, db, registry) + minCodecVersion := encoding.CodecVersion(ctx.Uint(utils.MinCodecVersionFlag.Name)) + chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, minCodecVersion, genesis.Config, db, registry) + batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, minCodecVersion, genesis.Config, db, registry) + bundleProposer := watcher.NewBundleProposer(subCtx, cfg.L2Config.BundleProposerConfig, minCodecVersion, genesis.Config, db, registry) l2watcher := watcher.NewL2WatcherClient(subCtx, l2client, cfg.L2Config.Confirmations, cfg.L2Config.L2MessageQueueAddress, cfg.L2Config.WithdrawTrieRootSlot, genesis.Config, db, registry) diff --git a/rollup/internal/controller/watcher/batch_proposer.go b/rollup/internal/controller/watcher/batch_proposer.go index f4a5a890b8..8b69cd9c25 100644 --- a/rollup/internal/controller/watcher/batch_proposer.go +++ b/rollup/internal/controller/watcher/batch_proposer.go @@ -34,7 +34,8 @@ type BatchProposer struct { gasCostIncreaseMultiplier float64 maxUncompressedBatchBytesSize uint64 - chainCfg *params.ChainConfig + minCodecVersion encoding.CodecVersion + chainCfg *params.ChainConfig batchProposerCircleTotal prometheus.Counter proposeBatchFailureTotal prometheus.Counter @@ -58,7 +59,7 @@ type BatchProposer struct { } // NewBatchProposer creates a new BatchProposer instance. -func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *BatchProposer { +func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, minCodecVersion encoding.CodecVersion, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *BatchProposer { log.Info("new batch proposer", "maxL1CommitGasPerBatch", cfg.MaxL1CommitGasPerBatch, "maxL1CommitCalldataSizePerBatch", cfg.MaxL1CommitCalldataSizePerBatch, @@ -78,6 +79,7 @@ func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, chai batchTimeoutSec: cfg.BatchTimeoutSec, gasCostIncreaseMultiplier: cfg.GasCostIncreaseMultiplier, maxUncompressedBatchBytesSize: cfg.MaxUncompressedBatchBytesSize, + minCodecVersion: minCodecVersion, chainCfg: chainCfg, batchProposerCircleTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{ @@ -248,8 +250,8 @@ func (p *BatchProposer) proposeBatch() error { return fmt.Errorf("failed to retrieve codec for block number %v and time %v", firstUnbatchedChunk.StartBlockNumber, firstUnbatchedChunk.StartBlockTime) } - if codec.Version() < encoding.CodecV4 { - return fmt.Errorf("unsupported codec version: %v, expected at least %v", codec.Version(), encoding.CodecV4) + if codec.Version() < p.minCodecVersion { + return fmt.Errorf("unsupported codec version: %v, expected at least %v", codec.Version(), p.minCodecVersion) } maxChunksThisBatch := codec.MaxNumChunksPerBatch() diff --git a/rollup/internal/controller/watcher/batch_proposer_test.go b/rollup/internal/controller/watcher/batch_proposer_test.go index 7484d4fd36..7c426d5b10 100644 --- a/rollup/internal/controller/watcher/batch_proposer_test.go +++ b/rollup/internal/controller/watcher/batch_proposer_test.go @@ -117,7 +117,7 @@ func testBatchProposerLimitsCodecV4(t *testing.T) { ChunkTimeoutSec: 300, GasCostIncreaseMultiplier: 1.2, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, ¶ms.ChainConfig{ + }, encoding.CodecV4, ¶ms.ChainConfig{ LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), @@ -140,7 +140,7 @@ func testBatchProposerLimitsCodecV4(t *testing.T) { BatchTimeoutSec: tt.batchTimeoutSec, GasCostIncreaseMultiplier: 1.2, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, ¶ms.ChainConfig{ + }, encoding.CodecV4, ¶ms.ChainConfig{ LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), @@ -211,7 +211,7 @@ func testBatchCommitGasAndCalldataSizeEstimationCodecV4(t *testing.T) { ChunkTimeoutSec: 300, GasCostIncreaseMultiplier: 1.2, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) + }, encoding.CodecV4, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) cp.TryProposeChunk() // chunk1 contains block1 cp.TryProposeChunk() // chunk2 contains block2 @@ -228,7 +228,7 @@ func testBatchCommitGasAndCalldataSizeEstimationCodecV4(t *testing.T) { BatchTimeoutSec: 0, GasCostIncreaseMultiplier: 1.2, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) + }, encoding.CodecV4, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) bp.TryProposeBatch() batches, err := batchOrm.GetBatches(context.Background(), map[string]interface{}{}, []string{}, 0) @@ -296,7 +296,7 @@ func testBatchProposerBlobSizeLimitCodecV4(t *testing.T) { ChunkTimeoutSec: 0, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) blockHeight := int64(0) block = readBlockFromJSON(t, "../../../testdata/blockTrace_03.json") @@ -317,7 +317,7 @@ func testBatchProposerBlobSizeLimitCodecV4(t *testing.T) { BatchTimeoutSec: math.MaxUint32, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) for i := 0; i < 2; i++ { bp.TryProposeBatch() @@ -390,7 +390,7 @@ func testBatchProposerMaxChunkNumPerBatchLimitCodecV4(t *testing.T) { ChunkTimeoutSec: 0, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) block = readBlockFromJSON(t, "../../../testdata/blockTrace_03.json") for blockHeight := int64(1); blockHeight <= 60; blockHeight++ { @@ -406,7 +406,7 @@ func testBatchProposerMaxChunkNumPerBatchLimitCodecV4(t *testing.T) { BatchTimeoutSec: math.MaxUint32, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) bp.TryProposeBatch() batches, err := batchOrm.GetBatches(context.Background(), map[string]interface{}{}, []string{}, 0) diff --git a/rollup/internal/controller/watcher/bundle_proposer.go b/rollup/internal/controller/watcher/bundle_proposer.go index a71b0d998c..1a37a6265a 100644 --- a/rollup/internal/controller/watcher/bundle_proposer.go +++ b/rollup/internal/controller/watcher/bundle_proposer.go @@ -29,7 +29,8 @@ type BundleProposer struct { maxBatchNumPerBundle uint64 bundleTimeoutSec uint64 - chainCfg *params.ChainConfig + minCodecVersion encoding.CodecVersion + chainCfg *params.ChainConfig bundleProposerCircleTotal prometheus.Counter proposeBundleFailureTotal prometheus.Counter @@ -41,7 +42,7 @@ type BundleProposer struct { } // NewBundleProposer creates a new BundleProposer instance. -func NewBundleProposer(ctx context.Context, cfg *config.BundleProposerConfig, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *BundleProposer { +func NewBundleProposer(ctx context.Context, cfg *config.BundleProposerConfig, minCodecVersion encoding.CodecVersion, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *BundleProposer { log.Info("new bundle proposer", "bundleBatchesNum", cfg.MaxBatchNumPerBundle, "bundleTimeoutSec", cfg.BundleTimeoutSec) p := &BundleProposer{ @@ -52,6 +53,7 @@ func NewBundleProposer(ctx context.Context, cfg *config.BundleProposerConfig, ch bundleOrm: orm.NewBundle(db), maxBatchNumPerBundle: cfg.MaxBatchNumPerBundle, bundleTimeoutSec: cfg.BundleTimeoutSec, + minCodecVersion: minCodecVersion, chainCfg: chainCfg, bundleProposerCircleTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{ @@ -131,7 +133,7 @@ func (p *BundleProposer) proposeBundle() error { // select at most maxBlocksThisChunk blocks maxBatchesThisBundle := p.maxBatchNumPerBundle - batches, err := p.batchOrm.GetBatchesGEIndexGECodecVersion(p.ctx, firstUnbundledBatchIndex, encoding.CodecV4, int(maxBatchesThisBundle)) + batches, err := p.batchOrm.GetBatchesGEIndexGECodecVersion(p.ctx, firstUnbundledBatchIndex, p.minCodecVersion, int(maxBatchesThisBundle)) if err != nil { return err } @@ -155,8 +157,8 @@ func (p *BundleProposer) proposeBundle() error { hardforkName := encoding.GetHardforkName(p.chainCfg, firstChunk.StartBlockNumber, firstChunk.StartBlockTime) codecVersion := encoding.CodecVersion(batches[0].CodecVersion) - if codecVersion < encoding.CodecV4 { - return fmt.Errorf("unsupported codec version: %v, expected at least %v", codecVersion, encoding.CodecV4) + if codecVersion < p.minCodecVersion { + return fmt.Errorf("unsupported codec version: %v, expected at least %v", codecVersion, p.minCodecVersion) } for i := 1; i < len(batches); i++ { diff --git a/rollup/internal/controller/watcher/bundle_proposer_test.go b/rollup/internal/controller/watcher/bundle_proposer_test.go index 5f9c5a9062..4a0a4219b0 100644 --- a/rollup/internal/controller/watcher/bundle_proposer_test.go +++ b/rollup/internal/controller/watcher/bundle_proposer_test.go @@ -99,7 +99,7 @@ func testBundleProposerLimitsCodecV4(t *testing.T) { ChunkTimeoutSec: math.MaxUint32, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) bap := NewBatchProposer(context.Background(), &config.BatchProposerConfig{ MaxL1CommitGasPerBatch: math.MaxUint64, @@ -107,7 +107,7 @@ func testBundleProposerLimitsCodecV4(t *testing.T) { BatchTimeoutSec: 0, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) cp.TryProposeChunk() // chunk1 contains block1 bap.TryProposeBatch() // batch1 contains chunk1 @@ -117,7 +117,7 @@ func testBundleProposerLimitsCodecV4(t *testing.T) { bup := NewBundleProposer(context.Background(), &config.BundleProposerConfig{ MaxBatchNumPerBundle: tt.maxBatchNumPerBundle, BundleTimeoutSec: tt.bundleTimeoutSec, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) bup.TryProposeBundle() diff --git a/rollup/internal/controller/watcher/chunk_proposer.go b/rollup/internal/controller/watcher/chunk_proposer.go index 8a9d0249d9..87056e6464 100644 --- a/rollup/internal/controller/watcher/chunk_proposer.go +++ b/rollup/internal/controller/watcher/chunk_proposer.go @@ -34,7 +34,8 @@ type ChunkProposer struct { gasCostIncreaseMultiplier float64 maxUncompressedBatchBytesSize uint64 - chainCfg *params.ChainConfig + minCodecVersion encoding.CodecVersion + chainCfg *params.ChainConfig chunkProposerCircleTotal prometheus.Counter proposeChunkFailureTotal prometheus.Counter @@ -60,7 +61,7 @@ type ChunkProposer struct { } // NewChunkProposer creates a new ChunkProposer instance. -func NewChunkProposer(ctx context.Context, cfg *config.ChunkProposerConfig, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *ChunkProposer { +func NewChunkProposer(ctx context.Context, cfg *config.ChunkProposerConfig, minCodecVersion encoding.CodecVersion, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *ChunkProposer { log.Info("new chunk proposer", "maxBlockNumPerChunk", cfg.MaxBlockNumPerChunk, "maxTxNumPerChunk", cfg.MaxTxNumPerChunk, @@ -85,6 +86,7 @@ func NewChunkProposer(ctx context.Context, cfg *config.ChunkProposerConfig, chai chunkTimeoutSec: cfg.ChunkTimeoutSec, gasCostIncreaseMultiplier: cfg.GasCostIncreaseMultiplier, maxUncompressedBatchBytesSize: cfg.MaxUncompressedBatchBytesSize, + minCodecVersion: minCodecVersion, chainCfg: chainCfg, chunkProposerCircleTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{ @@ -277,8 +279,8 @@ func (p *ChunkProposer) proposeChunk() error { codecVersion := encoding.GetCodecVersion(p.chainCfg, blocks[0].Header.Number.Uint64(), blocks[0].Header.Time) - if codecVersion < encoding.CodecV4 { - return fmt.Errorf("unsupported codec version: %v, expected at least %v", codecVersion, encoding.CodecV4) + if codecVersion < p.minCodecVersion { + return fmt.Errorf("unsupported codec version: %v, expected at least %v", codecVersion, p.minCodecVersion) } // Including Curie block in a sole chunk. diff --git a/rollup/internal/controller/watcher/chunk_proposer_test.go b/rollup/internal/controller/watcher/chunk_proposer_test.go index 23733154ab..4886fbebe0 100644 --- a/rollup/internal/controller/watcher/chunk_proposer_test.go +++ b/rollup/internal/controller/watcher/chunk_proposer_test.go @@ -164,7 +164,7 @@ func testChunkProposerLimitsCodecV4(t *testing.T) { ChunkTimeoutSec: tt.chunkTimeoutSec, GasCostIncreaseMultiplier: 1.2, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) + }, encoding.CodecV4, ¶ms.ChainConfig{LondonBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), DarwinTime: new(uint64), DarwinV2Time: new(uint64)}, db, nil) cp.TryProposeChunk() chunkOrm := orm.NewChunk(db) @@ -214,7 +214,7 @@ func testChunkProposerBlobSizeLimitCodecV4(t *testing.T) { ChunkTimeoutSec: math.MaxUint32, GasCostIncreaseMultiplier: 1, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) for i := 0; i < 2; i++ { cp.TryProposeChunk() diff --git a/rollup/tests/rollup_test.go b/rollup/tests/rollup_test.go index 4a217298d2..4251aa273b 100644 --- a/rollup/tests/rollup_test.go +++ b/rollup/tests/rollup_test.go @@ -97,19 +97,19 @@ func testCommitBatchAndFinalizeBundleCodecV4(t *testing.T) { MaxRowConsumptionPerChunk: 1048319, ChunkTimeoutSec: 300, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) bap := watcher.NewBatchProposer(context.Background(), &config.BatchProposerConfig{ MaxL1CommitGasPerBatch: 50000000000, MaxL1CommitCalldataSizePerBatch: 1000000, BatchTimeoutSec: 300, MaxUncompressedBatchBytesSize: math.MaxUint64, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) bup := watcher.NewBundleProposer(context.Background(), &config.BundleProposerConfig{ MaxBatchNumPerBundle: 1000000, BundleTimeoutSec: 300, - }, chainConfig, db, nil) + }, encoding.CodecV4, chainConfig, db, nil) l2BlockOrm := orm.NewL2Block(db) err = l2BlockOrm.InsertL2Blocks(context.Background(), blocks[:5])