From 9a8e15eccb720dda3a703937aae5c8ae3dc495c2 Mon Sep 17 00:00:00 2001 From: Gavin Yu Date: Wed, 3 Jul 2024 11:06:59 +0800 Subject: [PATCH] feat(taiko-client): add proof status check before generating proof (#17711) Co-authored-by: David --- .../prover/proof_producer/proof_producer.go | 4 +- .../prover/proof_producer/sgx_producer.go | 63 +++++++++---------- .../prover/proof_submitter/proof_submitter.go | 48 ++++++++++---- 3 files changed, 66 insertions(+), 49 deletions(-) diff --git a/packages/taiko-client/prover/proof_producer/proof_producer.go b/packages/taiko-client/prover/proof_producer/proof_producer.go index 0f1462e9cb..eefba58e2f 100644 --- a/packages/taiko-client/prover/proof_producer/proof_producer.go +++ b/packages/taiko-client/prover/proof_producer/proof_producer.go @@ -4,7 +4,6 @@ import ( "context" "errors" "math/big" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -13,8 +12,7 @@ import ( ) var ( - proofPollingInterval = 10 * time.Second - errProofGenerating = errors.New("proof is generating") + errProofGenerating = errors.New("proof is generating") ) // ProofRequestBody represents a request body to generate a proof. diff --git a/packages/taiko-client/prover/proof_producer/sgx_producer.go b/packages/taiko-client/prover/proof_producer/sgx_producer.go index 96cf6572d7..be278c2849 100644 --- a/packages/taiko-client/prover/proof_producer/sgx_producer.go +++ b/packages/taiko-client/prover/proof_producer/sgx_producer.go @@ -11,7 +11,6 @@ import ( "net/http" "time" - "github.com/cenkalti/backoff/v4" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -113,47 +112,43 @@ func (s *SGXProofProducer) callProverDaemon(ctx context.Context, opts *ProofRequ proof []byte start = time.Now() ) - if err := backoff.Retry(func() error { - if ctx.Err() != nil { - return nil - } - output, err := s.requestProof(opts) - if err != nil { - log.Error("Failed to request proof", "height", opts.BlockID, "error", err, "endpoint", s.RaikoHostEndpoint) - return err - } - - if output == nil { - log.Info( - "Proof generating", - "height", opts.BlockID, - "time", time.Since(start), - "producer", "SGXProofProducer", - ) - return errProofGenerating - } - - log.Debug("Proof generation output", "output", output) - - // Raiko returns "" as proof when proof type is native, - // so we just convert "" to bytes - if s.ProofType == ProofTypeCPU { - proof = common.Hex2Bytes(output.Data.Proof) - } else { - proof = common.Hex2Bytes(output.Data.Proof[2:]) - } + if ctx.Err() != nil { + return nil, ctx.Err() + } + output, err := s.requestProof(opts) + if err != nil { + log.Error("Failed to request proof", "height", opts.BlockID, "error", err, "endpoint", s.RaikoHostEndpoint) + return nil, err + } + + if output == nil { log.Info( - "Proof generated", + "Proof generating", "height", opts.BlockID, "time", time.Since(start), "producer", "SGXProofProducer", ) - return nil - }, backoff.WithContext(backoff.NewConstantBackOff(proofPollingInterval), ctx)); err != nil { - return nil, err + return nil, errProofGenerating } + log.Debug("Proof generation output", "output", output) + + // Raiko returns "" as proof when proof type is native, + // so we just convert "" to bytes + if s.ProofType == ProofTypeCPU { + proof = common.Hex2Bytes(output.Data.Proof) + } else { + proof = common.Hex2Bytes(output.Data.Proof[2:]) + } + + log.Info( + "Proof generated", + "height", opts.BlockID, + "time", time.Since(start), + "producer", "SGXProofProducer", + ) + return proof, nil } diff --git a/packages/taiko-client/prover/proof_submitter/proof_submitter.go b/packages/taiko-client/prover/proof_submitter/proof_submitter.go index ca6c3c1a0a..d46f7cb812 100644 --- a/packages/taiko-client/prover/proof_submitter/proof_submitter.go +++ b/packages/taiko-client/prover/proof_submitter/proof_submitter.go @@ -8,6 +8,7 @@ import ( "math/big" "time" + "github.com/cenkalti/backoff/v4" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -25,6 +26,7 @@ import ( var ( _ Submitter = (*ProofSubmitter)(nil) submissionDelayRandomBumpRange float64 = 20 + proofPollingInterval = 10 * time.Second ) // ProofSubmitter is responsible requesting proofs for the given L2 @@ -126,19 +128,41 @@ func (s *ProofSubmitter) RequestProof(ctx context.Context, event *bindings.Taiko } // Send the generated proof. - result, err := s.proofProducer.RequestProof( - ctx, - opts, - event.BlockId, - &event.Meta, - header, - ) - if err != nil { - return fmt.Errorf("failed to request proof (id: %d): %w", event.BlockId, err) + if err := backoff.Retry( + func() error { + // Check if there is a need to generate proof + proofStatus, err := rpc.GetBlockProofStatus( + ctx, + s.rpc, + opts.BlockID, + opts.ProverAddress, + s.proverSetAddress, + ) + if err != nil { + return err + } + if proofStatus.IsSubmitted && !proofStatus.Invalid { + return nil + } + + result, err := s.proofProducer.RequestProof( + ctx, + opts, + event.BlockId, + &event.Meta, + header, + ) + if err != nil { + return fmt.Errorf("failed to request proof (id: %d): %w", event.BlockId, err) + } + s.resultCh <- result + metrics.ProverQueuedProofCounter.Add(1) + return nil + }, + backoff.WithContext(backoff.NewConstantBackOff(proofPollingInterval), ctx), + ); err != nil { + log.Error("Request proof error", "error", err) } - s.resultCh <- result - - metrics.ProverQueuedProofCounter.Add(1) return nil }