diff --git a/cmd/flags/proposer.go b/cmd/flags/proposer.go index 04d7c7287..ff7fdc037 100644 --- a/cmd/flags/proposer.go +++ b/cmd/flags/proposer.go @@ -50,6 +50,11 @@ var ( Usage: "Minimal block gasLimit when proposing a block", Category: proposerCategory, } + MaxProposedTxListsPerEpoch = &cli.Uint64Flag{ + Name: "maxProposedTxListsPerEpoch", + Value: 1, + Category: proposerCategory, + } ) // All proposer flags. @@ -62,4 +67,5 @@ var ProposerFlags = MergeFlags(CommonFlags, []cli.Flag{ TxPoolLocals, ProposeEmptyBlocksInterval, MinBlockGasLimit, + MaxProposedTxListsPerEpoch, }) diff --git a/driver/chain_syncer/calldata/syncer_test.go b/driver/chain_syncer/calldata/syncer_test.go index 9a703f61c..7de07aab5 100644 --- a/driver/chain_syncer/calldata/syncer_test.go +++ b/driver/chain_syncer/calldata/syncer_test.go @@ -46,13 +46,14 @@ func (s *CalldataSyncerTestSuite) SetupTest() { s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, + MaxProposedTxListsPerEpoch: 1, }))) s.p = prop diff --git a/driver/driver_test.go b/driver/driver_test.go index 08636d716..ad5c53852 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -52,13 +52,14 @@ func (s *DriverTestSuite) SetupTest() { proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), p, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, }))) s.p = p } diff --git a/proposer/config.go b/proposer/config.go index 7ccf8f969..7e0aac6dc 100644 --- a/proposer/config.go +++ b/proposer/config.go @@ -25,6 +25,7 @@ type Config struct { LocalAddresses []common.Address ProposeEmptyBlocksInterval *time.Duration MinBlockGasLimit uint64 + MaxProposedTxListsPerEpoch uint64 } // NewConfigFromCliContext initializes a Config instance from @@ -83,5 +84,6 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { LocalAddresses: localAddresses, ProposeEmptyBlocksInterval: proposeEmptyBlocksInterval, MinBlockGasLimit: c.Uint64(flags.MinBlockGasLimit.Name), + MaxProposedTxListsPerEpoch: c.Uint64(flags.MaxProposedTxListsPerEpoch.Name), }, nil } diff --git a/proposer/proposer.go b/proposer/proposer.go index 94398af93..91b73dd9e 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -47,6 +47,7 @@ type Proposer struct { commitSlot uint64 locals []common.Address minBlockGasLimit *uint64 + maxProposedTxListsPerEpoch uint64 // Protocol configurations protocolConfigs *bindings.TaikoDataConfig @@ -79,6 +80,7 @@ func InitFromConfig(ctx context.Context, p *Proposer, cfg *Config) (err error) { p.wg = sync.WaitGroup{} p.locals = cfg.LocalAddresses p.commitSlot = cfg.CommitSlot + p.maxProposedTxListsPerEpoch = cfg.MaxProposedTxListsPerEpoch p.ctx = ctx // RPC clients @@ -226,6 +228,10 @@ func (p *Proposer) ProposeOp(ctx context.Context) error { for i, txs := range txLists { func(i int, txs types.Transactions) { g.Go(func() error { + if i >= int(p.maxProposedTxListsPerEpoch) { + return nil + } + txListBytes, err := rlp.EncodeToBytes(txs) if err != nil { return fmt.Errorf("failed to encode transactions: %w", err) diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index a9afd1df4..38b1574fc 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -32,13 +32,14 @@ func (s *ProposerTestSuite) SetupTest() { ctx, cancel := context.WithCancel(context.Background()) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(InitFromConfig(ctx, p, (&Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, + MaxProposedTxListsPerEpoch: 1, }))) s.p = p diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index abdef2834..858e2fc3c 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -73,13 +73,14 @@ func (s *ProofSubmitterTestSuite) SetupTest() { s.Nil(err) proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, }))) s.proposer = prop diff --git a/prover/prover_test.go b/prover/prover_test.go index 35527f259..d02a9540d 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -75,13 +75,14 @@ func (s *ProverTestSuite) SetupTest() { proposeInterval := 1024 * time.Hour // No need to periodically propose transactions list in unit tests s.Nil(proposer.InitFromConfig(context.Background(), prop, (&proposer.Config{ - L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), - L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), - TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), - TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), - L1ProposerPrivKey: l1ProposerPrivKey, - L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), - ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + L1Endpoint: os.Getenv("L1_NODE_WS_ENDPOINT"), + L2Endpoint: os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT"), + TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), + TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), + L1ProposerPrivKey: l1ProposerPrivKey, + L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), + ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests + MaxProposedTxListsPerEpoch: 1, }))) s.proposer = prop