From 85adc04dceabd6218afee72f748e17d69182d81d Mon Sep 17 00:00:00 2001
From: David <david@taiko.xyz>
Date: Tue, 18 Jul 2023 10:43:30 +0800
Subject: [PATCH] feat(prover): add `--oracleProofSubmissionDelay` flag (#320)

---
 cmd/flags/prover.go                           |  6 ++++++
 prover/config.go                              |  2 ++
 .../proof_producer/special_proof_producer.go  | 20 ++++++++++++-------
 prover/prover.go                              |  1 +
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/cmd/flags/prover.go b/cmd/flags/prover.go
index 88550090b..46812b069 100644
--- a/cmd/flags/prover.go
+++ b/cmd/flags/prover.go
@@ -63,6 +63,12 @@ var (
 		Usage:    "Private key of oracle prover",
 		Category: proverCategory,
 	}
+	OracleProofSubmissionDelay = &cli.Uint64Flag{
+		Name:     "oracleProofSubmissionDelay",
+		Usage:    "Oracle proof submission delay in seconds",
+		Value:    0,
+		Category: proverCategory,
+	}
 	Graffiti = &cli.StringFlag{
 		Name:     "graffiti",
 		Usage:    "When string is passed, adds additional graffiti info to proof evidence",
diff --git a/prover/config.go b/prover/config.go
index 8409fb906..5a0ec9482 100644
--- a/prover/config.go
+++ b/prover/config.go
@@ -30,6 +30,7 @@ type Config struct {
 	Dummy                           bool
 	OracleProver                    bool
 	OracleProverPrivateKey          *ecdsa.PrivateKey
+	OracleProofSubmissionDelay      time.Duration
 	Graffiti                        string
 	RandomDummyProofDelayLowerBound *time.Duration
 	RandomDummyProofDelayUpperBound *time.Duration
@@ -114,6 +115,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
 		Dummy:                           c.Bool(flags.Dummy.Name),
 		OracleProver:                    c.Bool(flags.OracleProver.Name),
 		OracleProverPrivateKey:          oracleProverPrivKey,
+		OracleProofSubmissionDelay:      time.Duration(c.Uint64(flags.OracleProofSubmissionDelay.Name)) * time.Second,
 		Graffiti:                        c.String(flags.Graffiti.Name),
 		RandomDummyProofDelayLowerBound: randomDummyProofDelayLowerBound,
 		RandomDummyProofDelayUpperBound: randomDummyProofDelayUpperBound,
diff --git a/prover/proof_producer/special_proof_producer.go b/prover/proof_producer/special_proof_producer.go
index a55d5f189..d71743f51 100644
--- a/prover/proof_producer/special_proof_producer.go
+++ b/prover/proof_producer/special_proof_producer.go
@@ -6,6 +6,7 @@ import (
 	"errors"
 	"fmt"
 	"math/big"
+	"time"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
@@ -28,6 +29,7 @@ type SpecialProofProducer struct {
 	proverPrivKey     *ecdsa.PrivateKey
 	anchorTxValidator *anchorTxValidator.AnchorTxValidator
 	graffiti          [32]byte
+	delay             time.Duration
 }
 
 // NewSpecialProofProducer creates a new NewSpecialProofProducer instance, which can be either
@@ -38,6 +40,7 @@ func NewSpecialProofProducer(
 	taikoL2Address common.Address,
 	protocolSpecialProverAddress common.Address,
 	graffiti string,
+	delay time.Duration,
 ) (*SpecialProofProducer, error) {
 	proverAddress := crypto.PubkeyToAddress(proverPrivKey.PublicKey)
 	if proverAddress != protocolSpecialProverAddress {
@@ -54,6 +57,7 @@ func NewSpecialProofProducer(
 		proverPrivKey,
 		anchorValidator,
 		rpc.StringToBytes32(graffiti),
+		delay,
 	}, nil
 }
 
@@ -123,13 +127,15 @@ func (p *SpecialProofProducer) RequestProof(
 		return fmt.Errorf("failed to sign evidence: %w", err)
 	}
 
-	resultCh <- &ProofWithHeader{
-		BlockID: blockID,
-		Header:  header,
-		Meta:    meta,
-		ZkProof: proof,
-		Opts:    opts,
-	}
+	time.AfterFunc(p.delay, func() {
+		resultCh <- &ProofWithHeader{
+			BlockID: blockID,
+			Header:  header,
+			Meta:    meta,
+			ZkProof: proof,
+			Opts:    opts,
+		}
+	})
 
 	return nil
 }
diff --git a/prover/prover.go b/prover/prover.go
index 5d3647413..f5751fad4 100644
--- a/prover/prover.go
+++ b/prover/prover.go
@@ -177,6 +177,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) {
 			p.cfg.TaikoL2Address,
 			specialProverAddress,
 			p.cfg.Graffiti,
+			p.cfg.OracleProofSubmissionDelay,
 		); err != nil {
 			return err
 		}