From 3c7951b638a6be7e5f624315d76cf21b0fa6aa6f Mon Sep 17 00:00:00 2001 From: Jeffery Walsh Date: Tue, 1 Aug 2023 11:03:47 -0700 Subject: [PATCH 1/5] configurable wait receipt timeouts --- cmd/flags/common.go | 7 +++++++ proposer/config.go | 2 ++ proposer/config_test.go | 3 +++ proposer/proposer.go | 6 ++++-- prover/config.go | 2 ++ prover/config_test.go | 5 +++++ prover/proof_submitter/util.go | 6 +++++- prover/proof_submitter/valid_proof_submitter.go | 4 ++++ 8 files changed, 32 insertions(+), 3 deletions(-) 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/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/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/config_test.go b/prover/config_test.go index 386987730..ce87e5fdf 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -27,6 +27,7 @@ var testFlags = []cli.Flag{ &cli.Uint64Flag{Name: flags.CheckProofWindowExpiredInterval.Name}, &cli.BoolFlag{Name: flags.ProveUnassignedBlocks.Name}, &cli.Uint64Flag{Name: flags.RPCTimeout.Name}, + &cli.Uint64Flag{Name: flags.WaitReceiptTimeout.Name}, } func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { @@ -37,6 +38,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { taikoL1 := os.Getenv("TAIKO_L1_ADDRESS") taikoL2 := os.Getenv("TAIKO_L2_ADDRESS") taikoProverPoolL1 := os.Getenv("TAIKO_PROVER_POOL_L1_ADDRESS") + waitReceiptTimeout := 10 * time.Second app := cli.NewApp() app.Flags = testFlags @@ -65,6 +67,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { s.Equal("", c.Graffiti) s.Equal(30*time.Second, c.CheckProofWindowExpiredInterval) s.Equal(true, c.ProveUnassignedBlocks) + s.Equal(10*time.Second, c.WaitReceiptTimeout) s.Nil(c.RPCTimeout) s.Nil(new(Prover).InitFromCli(context.Background(), ctx)) @@ -88,6 +91,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { "-" + flags.Graffiti.Name, "", "-" + flags.CheckProofWindowExpiredInterval.Name, "30", "-" + flags.ProveUnassignedBlocks.Name, "true", + "-" + flags.WaitReceiptTimeout.Name, "10", })) } @@ -123,5 +127,6 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProverError() { "-" + flags.OracleProver.Name, "-" + flags.Graffiti.Name, "", "-" + flags.RPCTimeout.Name, "5", + "-" + flags.WaitReceiptTimeout.Name, "10", }), "oracleProver flag set without oracleProverPrivateKey set") } 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/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 From d6dea4d95471061f059ec9b86c13218203dbad90 Mon Sep 17 00:00:00 2001 From: Jeffery Walsh Date: Tue, 1 Aug 2023 11:04:17 -0700 Subject: [PATCH 2/5] tests --- prover/config_test.go | 1 - prover/proof_submitter/valid_proof_submitter_test.go | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/prover/config_test.go b/prover/config_test.go index ce87e5fdf..7f6e2f6c9 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -38,7 +38,6 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { taikoL1 := os.Getenv("TAIKO_L1_ADDRESS") taikoL2 := os.Getenv("TAIKO_L2_ADDRESS") taikoProverPoolL1 := os.Getenv("TAIKO_PROVER_POOL_L1_ADDRESS") - waitReceiptTimeout := 10 * time.Second app := cli.NewApp() app.Flags = testFlags diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index 7974e4558..db78ab5a6 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) From 404ba9da7a4695886f44d552a9dd83a8ec95ac6d Mon Sep 17 00:00:00 2001 From: Jeffery Walsh Date: Tue, 1 Aug 2023 11:15:06 -0700 Subject: [PATCH 3/5] lints --- prover/proof_submitter/util_test.go | 2 ++ prover/prover.go | 1 + 2 files changed, 3 insertions(+) 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/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 } From bcb557de734433cf5cc09c4a96e836326808e475 Mon Sep 17 00:00:00 2001 From: Jeffery Walsh Date: Tue, 1 Aug 2023 13:24:37 -0700 Subject: [PATCH 4/5] tests --- driver/chain_syncer/calldata/syncer_test.go | 1 + driver/driver_test.go | 1 + proposer/proposer_test.go | 1 + prover/proof_submitter/valid_proof_submitter_test.go | 1 + prover/prover_test.go | 1 + 5 files changed, 5 insertions(+) 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/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/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index db78ab5a6..35c9a3214 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -83,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_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 From 6bea57bb7b21d12b5d3f85fac01129829fb582ed Mon Sep 17 00:00:00 2001 From: Jeffery Walsh Date: Tue, 1 Aug 2023 13:56:44 -0700 Subject: [PATCH 5/5] rm prover test --- prover/config_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/prover/config_test.go b/prover/config_test.go index 7f6e2f6c9..386987730 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -27,7 +27,6 @@ var testFlags = []cli.Flag{ &cli.Uint64Flag{Name: flags.CheckProofWindowExpiredInterval.Name}, &cli.BoolFlag{Name: flags.ProveUnassignedBlocks.Name}, &cli.Uint64Flag{Name: flags.RPCTimeout.Name}, - &cli.Uint64Flag{Name: flags.WaitReceiptTimeout.Name}, } func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { @@ -66,7 +65,6 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { s.Equal("", c.Graffiti) s.Equal(30*time.Second, c.CheckProofWindowExpiredInterval) s.Equal(true, c.ProveUnassignedBlocks) - s.Equal(10*time.Second, c.WaitReceiptTimeout) s.Nil(c.RPCTimeout) s.Nil(new(Prover).InitFromCli(context.Background(), ctx)) @@ -90,7 +88,6 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProver() { "-" + flags.Graffiti.Name, "", "-" + flags.CheckProofWindowExpiredInterval.Name, "30", "-" + flags.ProveUnassignedBlocks.Name, "true", - "-" + flags.WaitReceiptTimeout.Name, "10", })) } @@ -126,6 +123,5 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProverError() { "-" + flags.OracleProver.Name, "-" + flags.Graffiti.Name, "", "-" + flags.RPCTimeout.Name, "5", - "-" + flags.WaitReceiptTimeout.Name, "10", }), "oracleProver flag set without oracleProverPrivateKey set") }