diff --git a/cmd/flags/common.go b/cmd/flags/common.go index 5b0eafe45..4f94daeec 100644 --- a/cmd/flags/common.go +++ b/cmd/flags/common.go @@ -100,6 +100,12 @@ var ( Usage: "Timeout in seconds for RPC calls", Category: commonCategory, } + WaitReceiptTimeout = &cli.Uint64Flag{ + Name: "rpc.waitReceiptTimeout", + Usage: "Timeout in seconds for wait for receipts for RPC transactions", + Category: commonCategory, + Value: 60, + } ) // All common flags. @@ -117,6 +123,7 @@ var CommonFlags = []cli.Flag{ BackOffMaxRetrys, BackOffRetryInterval, RPCTimeout, + WaitReceiptTimeout, } // MergeFlags merges the given flag slices. diff --git a/driver/chain_syncer/calldata/syncer_test.go b/driver/chain_syncer/calldata/syncer_test.go index 18e9e6c69..3f4c5031d 100644 --- a/driver/chain_syncer/calldata/syncer_test.go +++ b/driver/chain_syncer/calldata/syncer_test.go @@ -54,6 +54,7 @@ func (s *CalldataSyncerTestSuite) SetupTest() { L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, }))) s.p = prop diff --git a/driver/driver_test.go b/driver/driver_test.go index 2537228f0..399056462 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -60,6 +60,7 @@ func (s *DriverTestSuite) SetupTest() { L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, }))) s.p = p } diff --git a/proposer/config.go b/proposer/config.go index 5cd153af5..c11c9e444 100644 --- a/proposer/config.go +++ b/proposer/config.go @@ -31,6 +31,7 @@ type Config struct { BackOffRetryInterval time.Duration ProposeBlockTxReplacementMultiplier uint64 RPCTimeout *time.Duration + WaitReceiptTimeout time.Duration } // NewConfigFromCliContext initializes a Config instance from @@ -116,5 +117,6 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { BackOffRetryInterval: time.Duration(c.Uint64(flags.BackOffRetryInterval.Name)) * time.Second, ProposeBlockTxReplacementMultiplier: proposeBlockTxReplacementMultiplier, RPCTimeout: timeout, + WaitReceiptTimeout: time.Duration(c.Uint64(flags.WaitReceiptTimeout.Name)) * time.Second, }, nil } diff --git a/proposer/config_test.go b/proposer/config_test.go index ecd7ca6e7..f964e5c30 100644 --- a/proposer/config_test.go +++ b/proposer/config_test.go @@ -40,6 +40,7 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() { &cli.StringFlag{Name: flags.TxPoolLocals.Name}, &cli.Uint64Flag{Name: flags.ProposeBlockTxReplacementMultiplier.Name}, &cli.Uint64Flag{Name: flags.RPCTimeout.Name}, + &cli.Uint64Flag{Name: flags.WaitReceiptTimeout.Name}, } app.Action = func(ctx *cli.Context) error { c, err := NewConfigFromCliContext(ctx) @@ -56,6 +57,7 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() { s.Equal(goldenTouchAddress, c.LocalAddresses[0]) s.Equal(uint64(5), c.ProposeBlockTxReplacementMultiplier) s.Equal(rpcTimeout, *c.RPCTimeout) + s.Equal(10*time.Second, c.WaitReceiptTimeout) s.Nil(new(Proposer).InitFromCli(context.Background(), ctx)) return err @@ -74,5 +76,6 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() { "-" + flags.TxPoolLocals.Name, goldenTouchAddress.Hex(), "-" + flags.ProposeBlockTxReplacementMultiplier.Name, "5", "-" + flags.RPCTimeout.Name, "5", + "-" + flags.WaitReceiptTimeout.Name, "10", })) } diff --git a/proposer/proposer.go b/proposer/proposer.go index 23f7c1533..62ab4de27 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -29,7 +29,6 @@ import ( var ( errNoNewTxs = errors.New("no new transactions") - waitReceiptTimeout = 1 * time.Minute maxSendProposeBlockTxRetry = 10 ) @@ -64,6 +63,8 @@ type Proposer struct { ctx context.Context wg sync.WaitGroup + + waitReceiptTimeout time.Duration } // New initializes the given proposer instance based on the command line flags. @@ -91,6 +92,7 @@ func InitFromConfig(ctx context.Context, p *Proposer, cfg *Config) (err error) { p.maxProposedTxListsPerEpoch = cfg.MaxProposedTxListsPerEpoch p.txReplacementTipMultiplier = cfg.ProposeBlockTxReplacementMultiplier p.ctx = ctx + p.waitReceiptTimeout = cfg.WaitReceiptTimeout // RPC clients if p.rpc, err = rpc.NewClient(p.ctx, &rpc.ClientConfig{ @@ -427,7 +429,7 @@ func (p *Proposer) ProposeTxList( return err } - ctxWithTimeout, cancel := context.WithTimeout(ctx, waitReceiptTimeout) + ctxWithTimeout, cancel := context.WithTimeout(ctx, p.waitReceiptTimeout) defer cancel() if _, err := rpc.WaitReceipt(ctxWithTimeout, p.rpc.L1, tx); err != nil { diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index 8fa7c1b19..c0cad85e3 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -43,6 +43,7 @@ func (s *ProposerTestSuite) SetupTest() { ProposeInterval: &proposeInterval, MaxProposedTxListsPerEpoch: 1, ProposeBlockTxReplacementMultiplier: 2, + WaitReceiptTimeout: 10 * time.Second, }))) s.p = p diff --git a/prover/config.go b/prover/config.go index 0a6ee2567..0eb829584 100644 --- a/prover/config.go +++ b/prover/config.go @@ -40,6 +40,7 @@ type Config struct { CheckProofWindowExpiredInterval time.Duration ProveUnassignedBlocks bool RPCTimeout *time.Duration + WaitReceiptTimeout time.Duration } // NewConfigFromCliContext creates a new config instance from command line flags. @@ -136,5 +137,6 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { ) * time.Second, ProveUnassignedBlocks: c.Bool(flags.ProveUnassignedBlocks.Name), RPCTimeout: timeout, + WaitReceiptTimeout: time.Duration(c.Uint64(flags.WaitReceiptTimeout.Name)) * time.Second, }, nil } diff --git a/prover/proof_submitter/util.go b/prover/proof_submitter/util.go index 8648df37e..d6c193f15 100644 --- a/prover/proof_submitter/util.go +++ b/prover/proof_submitter/util.go @@ -71,6 +71,7 @@ func sendTxWithBackoff( sendTxFunc func() (*types.Transaction, error), retryInterval time.Duration, maxRetry *uint64, + waitReceiptTimeout time.Duration, ) error { var ( isUnretryableError bool @@ -120,7 +121,10 @@ func sendTxWithBackoff( return nil } - if _, err := rpc.WaitReceipt(ctx, cli.L1, tx); err != nil { + ctxWithTimeout, cancel := context.WithTimeout(ctx, waitReceiptTimeout) + defer cancel() + + if _, err := rpc.WaitReceipt(ctxWithTimeout, cli.L1, tx); err != nil { log.Warn("Failed to wait till transaction executed", "blockID", blockID, "txHash", tx.Hash(), "error", err) return err } diff --git a/prover/proof_submitter/util_test.go b/prover/proof_submitter/util_test.go index 1fac8bfc4..e78521a35 100644 --- a/prover/proof_submitter/util_test.go +++ b/prover/proof_submitter/util_test.go @@ -48,6 +48,7 @@ func (s *ProofSubmitterTestSuite) TestSendTxWithBackoff() { func() (*types.Transaction, error) { return nil, errors.New("L1_TEST") }, 12*time.Second, &testMaxRetry, + 5*time.Second, )) s.Nil(sendTxWithBackoff( @@ -75,5 +76,6 @@ func (s *ProofSubmitterTestSuite) TestSendTxWithBackoff() { }, 12*time.Second, &testMaxRetry, + 5*time.Second, )) } diff --git a/prover/proof_submitter/valid_proof_submitter.go b/prover/proof_submitter/valid_proof_submitter.go index 9e113def4..afe579ab1 100644 --- a/prover/proof_submitter/valid_proof_submitter.go +++ b/prover/proof_submitter/valid_proof_submitter.go @@ -42,6 +42,7 @@ type ValidProofSubmitter struct { graffiti [32]byte submissionMaxRetry uint64 retryInterval time.Duration + waitReceiptTimeout time.Duration } // NewValidProofSubmitter creates a new ValidProofSubmitter instance. @@ -56,6 +57,7 @@ func NewValidProofSubmitter( graffiti string, submissionMaxRetry uint64, retryInterval time.Duration, + waitReceiptTimeout time.Duration, ) (*ValidProofSubmitter, error) { anchorValidator, err := anchorTxValidator.New(taikoL2Address, rpcClient.L2ChainID, rpcClient) if err != nil { @@ -87,6 +89,7 @@ func NewValidProofSubmitter( graffiti: rpc.StringToBytes32(graffiti), submissionMaxRetry: submissionMaxRetry, retryInterval: retryInterval, + waitReceiptTimeout: waitReceiptTimeout, }, nil } @@ -271,6 +274,7 @@ func (s *ValidProofSubmitter) SubmitProof( sendTx, s.retryInterval, maxRetry, + s.waitReceiptTimeout, ); err != nil { if errors.Is(err, errUnretryable) { return nil diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index 7974e4558..35c9a3214 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -50,6 +50,7 @@ func (s *ProofSubmitterTestSuite) SetupTest() { "test", 1, 12*time.Second, + 10*time.Second, ) s.Nil(err) @@ -82,6 +83,7 @@ func (s *ProofSubmitterTestSuite) SetupTest() { L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, }))) s.proposer = prop diff --git a/prover/prover.go b/prover/prover.go index 33607e96d..c08ca21bf 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -200,6 +200,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.cfg.Graffiti, p.cfg.ProofSubmissionMaxRetry, p.cfg.BackOffRetryInterval, + p.cfg.WaitReceiptTimeout, ); err != nil { return err } diff --git a/prover/prover_test.go b/prover/prover_test.go index 6354a9bdf..67594b617 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -85,6 +85,7 @@ func (s *ProverTestSuite) SetupTest() { L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")), ProposeInterval: &proposeInterval, // No need to periodically propose transactions list in unit tests MaxProposedTxListsPerEpoch: 1, + WaitReceiptTimeout: 10 * time.Second, }))) s.proposer = prop