diff --git a/bindings/.githead b/bindings/.githead index 58a79d30b..4ba711ae2 100644 --- a/bindings/.githead +++ b/bindings/.githead @@ -1 +1 @@ -ccecd708276bce3eca84b92c7c48c95b2156dd18 +285c756c270fa4041c10aa06d95e2067fcc1b69f diff --git a/prover/proof_producer/dummy_producer.go b/prover/proof_producer/dummy_producer.go index f6ca986df..364cadce9 100644 --- a/prover/proof_producer/dummy_producer.go +++ b/prover/proof_producer/dummy_producer.go @@ -17,6 +17,12 @@ type DummyProofProducer struct { RandomDummyProofDelayUpperBound *time.Duration } +func (d *DummyProofProducer) CalcDelay( + header *types.Header, +) time.Duration { + return time.Duration(0) +} + // RequestProof implements the ProofProducer interface. func (d *DummyProofProducer) RequestProof( ctx context.Context, diff --git a/prover/proof_producer/proof_producer.go b/prover/proof_producer/proof_producer.go index d5022129a..c16db843b 100644 --- a/prover/proof_producer/proof_producer.go +++ b/prover/proof_producer/proof_producer.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -54,6 +55,7 @@ type ProofProducer interface { resultCh chan *ProofWithHeader, ) error Cancel(ctx context.Context, blockID *big.Int) error + CalcDelay(header *types.Header) time.Duration } func DegreeToCircuitsIdx(degree uint64) (uint16, error) { diff --git a/prover/proof_producer/special_proof_producer.go b/prover/proof_producer/special_proof_producer.go index 0d85a77ad..70edbbccb 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" @@ -60,6 +61,12 @@ func NewSpecialProofProducer( }, nil } +func (p *SpecialProofProducer) CalcDelay( + header *types.Header, +) time.Duration { + return time.Duration(0) +} + // RequestProof implements the ProofProducer interface. func (p *SpecialProofProducer) RequestProof( ctx context.Context, diff --git a/prover/proof_producer/zkevm_rpcd_producer.go b/prover/proof_producer/zkevm_rpcd_producer.go index 7932adc05..17b5dfa00 100644 --- a/prover/proof_producer/zkevm_rpcd_producer.go +++ b/prover/proof_producer/zkevm_rpcd_producer.go @@ -30,6 +30,7 @@ type ZkevmRpcdProducer struct { L2Endpoint string // a L2 execution engine's RPC endpoint Retry bool // retry proof computation if error CustomProofHook func() ([]byte, uint64, error) // only for testing purposes + ProofTimeTarget uint64 // used for calculating proof delay } // RequestProofBody represents the JSON body for requesting the proof. @@ -90,16 +91,31 @@ func NewZkevmRpcdProducer( l1Endpoint string, l2Endpoint string, retry bool, + proofTimeTarget uint64, ) (*ZkevmRpcdProducer, error) { return &ZkevmRpcdProducer{ - RpcdEndpoint: rpcdEndpoint, - Param: param, - L1Endpoint: l1Endpoint, - L2Endpoint: l2Endpoint, - Retry: retry, + RpcdEndpoint: rpcdEndpoint, + Param: param, + L1Endpoint: l1Endpoint, + L2Endpoint: l2Endpoint, + Retry: retry, + ProofTimeTarget: proofTimeTarget, }, nil } +func (p *ZkevmRpcdProducer) CalcDelay( + header *types.Header, +) time.Duration { + // if > 0, delay has not yet elapsed; proof should be delayed. + // if <= 0, delay has already elapsed; proof does not need delay. + delay := ((p.ProofTimeTarget + header.Time) - uint64(time.Now().Unix())) + if delay > 0 { + return time.Duration(delay) + } else { + return time.Duration(0) + } +} + // RequestProof implements the ProofProducer interface. func (p *ZkevmRpcdProducer) RequestProof( ctx context.Context, @@ -131,14 +147,16 @@ func (p *ZkevmRpcdProducer) RequestProof( return err } - resultCh <- &ProofWithHeader{ - BlockID: blockID, - Header: header, - Meta: meta, - ZkProof: proof, - Degree: degree, - Opts: opts, - } + time.AfterFunc(p.CalcDelay(header), func() { + resultCh <- &ProofWithHeader{ + BlockID: blockID, + Header: header, + Meta: meta, + ZkProof: proof, + Degree: degree, + Opts: opts, + } + }) return nil } diff --git a/prover/proof_producer/zkevm_rpcd_producer_test.go b/prover/proof_producer/zkevm_rpcd_producer_test.go index e8e2e3ac9..41f0c9701 100644 --- a/prover/proof_producer/zkevm_rpcd_producer_test.go +++ b/prover/proof_producer/zkevm_rpcd_producer_test.go @@ -12,7 +12,7 @@ import ( ) func TestNewZkevmRpcdProducer(t *testing.T) { - dummpyZkevmRpcdProducer, err := NewZkevmRpcdProducer("http://localhost:18545", "", "", "", false) + dummpyZkevmRpcdProducer, err := NewZkevmRpcdProducer("http://localhost:18545", "", "", "", false, 0) require.Nil(t, err) dummpyZkevmRpcdProducer.CustomProofHook = func() ([]byte, uint64, error) { diff --git a/prover/prover.go b/prover/prover.go index c998533e5..7b3db27fa 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -155,6 +155,12 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { isSystemProver := cfg.SystemProver isOracleProver := cfg.OracleProver + stateVars, err := p.rpc.GetProtocolStateVariables(nil) + if err != nil { + log.Error("error retrieving protocol state variables", "error", err) + return + } + if isSystemProver || isOracleProver { var specialProverAddress common.Address var privateKey *ecdsa.PrivateKey @@ -188,6 +194,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { cfg.L1HttpEndpoint, cfg.L2HttpEndpoint, true, + stateVars.ProofTimeTarget, ); err != nil { return err }