Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
feat(prover): cancel proof if it becomes verified (#207)
Browse files Browse the repository at this point in the history
Co-authored-by: David <david@taiko.xyz>
  • Loading branch information
cyberhorsey and davidtaikocha authored May 5, 2023
1 parent b5dc5c5 commit 74d1729
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 41 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ jobs:
with:
repository: taikoxyz/taiko-mono
path: ${{ env.TAIKO_MONO_DIR }}
ref: get_oracle_prover

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
Expand Down
2 changes: 1 addition & 1 deletion bindings/.githead
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b27d42cc59e26a8ff451692febfc4d1d71da66db
ec477de46f543339e71d4aa8453b62f44c32b32f
33 changes: 1 addition & 32 deletions bindings/gen_taiko_l1.go

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion cmd/flags/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ var (
Name: "oracleProver",
Usage: "Set whether prover should use oracle prover or not",
Category: proverCategory,
Value: false,
}
OracleProverPrivateKey = &cli.BoolFlag{
Name: "oracleProverPrivateKey",
Usage: "Private key of oracle prover",
Category: proverCategory,
}
Graffiti = &cli.StringFlag{
Name: "graffiti",
Expand All @@ -80,5 +84,6 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{
Dummy,
RandomDummyProofDelay,
OracleProver,
OracleProverPrivateKey,
Graffiti,
})
1 change: 1 addition & 0 deletions metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var (
ProverSentValidProofCounter = metrics.NewRegisteredCounter("prover/proof/valid/sent", nil)
ProverSentInvalidProofCounter = metrics.NewRegisteredCounter("prover/proof/invalid/sent", nil)
ProverReceivedProposedBlockGauge = metrics.NewRegisteredGauge("prover/proposed/received", nil)
ProverReceivedProvenBlockGauge = metrics.NewRegisteredGauge("prover/proven/received", nil)
)

// Serve starts the metrics server on the given address, will be closed when the given
Expand Down
16 changes: 16 additions & 0 deletions prover/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Config struct {
MaxConcurrentProvingJobs uint
Dummy bool
OracleProver bool
OracleProverPrivateKey *ecdsa.PrivateKey
Graffiti string
RandomDummyProofDelayLowerBound *time.Duration
RandomDummyProofDelayUpperBound *time.Duration
Expand All @@ -42,6 +43,20 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
return nil, fmt.Errorf("invalid L1 prover private key: %w", err)
}

var oracleProverPrivKey *ecdsa.PrivateKey
if c.IsSet(flags.OracleProver.Name) {
if !c.IsSet(flags.OracleProverPrivateKey.Name) {
return nil, fmt.Errorf("oracleProver flag set without oracleProverPrivateKey set")
}

oracleProverPrivKeyStr := c.String(flags.OracleProverPrivateKey.Name)

oracleProverPrivKey, err = crypto.ToECDSA(common.Hex2Bytes(oracleProverPrivKeyStr))
if err != nil {
return nil, fmt.Errorf("invalid oracle private key: %w", err)
}
}

var (
randomDummyProofDelayLowerBound *time.Duration
randomDummyProofDelayUpperBound *time.Duration
Expand Down Expand Up @@ -90,6 +105,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
MaxConcurrentProvingJobs: c.Uint(flags.MaxConcurrentProvingJobs.Name),
Dummy: c.Bool(flags.Dummy.Name),
OracleProver: c.Bool(flags.OracleProver.Name),
OracleProverPrivateKey: oracleProverPrivKey,
Graffiti: c.String(flags.Graffiti.Name),
RandomDummyProofDelayLowerBound: randomDummyProofDelayLowerBound,
RandomDummyProofDelayUpperBound: randomDummyProofDelayUpperBound,
Expand Down
51 changes: 51 additions & 0 deletions prover/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() {
&cli.BoolFlag{Name: flags.Dummy.Name},
&cli.StringFlag{Name: flags.RandomDummyProofDelay.Name},
&cli.BoolFlag{Name: flags.OracleProver.Name},
&cli.StringFlag{Name: flags.OracleProverPrivateKey.Name},
&cli.StringFlag{Name: flags.Graffiti.Name},
}
app.Action = func(ctx *cli.Context) error {
Expand All @@ -49,6 +50,10 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() {
s.Equal(time.Hour, *c.RandomDummyProofDelayUpperBound)
s.True(c.Dummy)
s.True(c.OracleProver)
s.Equal(
crypto.PubkeyToAddress(s.p.cfg.OracleProverPrivateKey.PublicKey),
crypto.PubkeyToAddress(c.OracleProverPrivateKey.PublicKey),
)
s.Equal("", c.Graffiti)
s.Nil(new(Prover).InitFromCli(context.Background(), ctx))

Expand All @@ -67,6 +72,52 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() {
"-" + flags.Dummy.Name,
"-" + flags.RandomDummyProofDelay.Name, "30m-1h",
"-" + flags.OracleProver.Name,
"-" + flags.OracleProverPrivateKey.Name, os.Getenv("L1_PROVER_PRIVATE_KEY"),
"-" + flags.Graffiti.Name, "",
}))
}

func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProverError() {
l1WsEndpoint := os.Getenv("L1_NODE_WS_ENDPOINT")
l1HttpEndpoint := os.Getenv("L1_NODE_HTTP_ENDPOINT")
l2WsEndpoint := os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT")
l2HttpEndpoint := os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT")
taikoL1 := os.Getenv("TAIKO_L1_ADDRESS")
taikoL2 := os.Getenv("TAIKO_L2_ADDRESS")

app := cli.NewApp()
app.Flags = []cli.Flag{
&cli.StringFlag{Name: flags.L1WSEndpoint.Name},
&cli.StringFlag{Name: flags.L1HTTPEndpoint.Name},
&cli.StringFlag{Name: flags.L2WSEndpoint.Name},
&cli.StringFlag{Name: flags.L2HTTPEndpoint.Name},
&cli.StringFlag{Name: flags.TaikoL1Address.Name},
&cli.StringFlag{Name: flags.TaikoL2Address.Name},
&cli.StringFlag{Name: flags.L1ProverPrivKey.Name},
&cli.BoolFlag{Name: flags.Dummy.Name},
&cli.StringFlag{Name: flags.RandomDummyProofDelay.Name},
&cli.BoolFlag{Name: flags.OracleProver.Name},
&cli.StringFlag{Name: flags.OracleProverPrivateKey.Name},
&cli.StringFlag{Name: flags.Graffiti.Name},
}
app.Action = func(ctx *cli.Context) error {
_, err := NewConfigFromCliContext(ctx)
s.NotNil(err)
return err
}

s.ErrorContains(app.Run([]string{
"TestNewConfigFromCliContext",
"-" + flags.L1WSEndpoint.Name, l1WsEndpoint,
"-" + flags.L1HTTPEndpoint.Name, l1HttpEndpoint,
"-" + flags.L2WSEndpoint.Name, l2WsEndpoint,
"-" + flags.L2HTTPEndpoint.Name, l2HttpEndpoint,
"-" + flags.TaikoL1Address.Name, taikoL1,
"-" + flags.TaikoL2Address.Name, taikoL2,
"-" + flags.L1ProverPrivKey.Name, os.Getenv("L1_PROVER_PRIVATE_KEY"),
"-" + flags.Dummy.Name,
"-" + flags.RandomDummyProofDelay.Name, "30m-1h",
"-" + flags.OracleProver.Name,
"-" + flags.Graffiti.Name, "",
}), "oracleProver flag set without oracleProverPrivateKey set")
}
5 changes: 5 additions & 0 deletions prover/proof_producer/dummy_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,8 @@ func (d *DummyProofProducer) proofDelay() time.Duration {

return delay
}

// Cancel cancels an existing proof generation.
func (d *DummyProofProducer) Cancel(ctx context.Context, blockID *big.Int) error {
return nil
}
17 changes: 17 additions & 0 deletions prover/proof_producer/oracle_proof_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package producer
import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
"time"
Expand All @@ -17,6 +18,10 @@ import (
anchorTxValidator "github.com/taikoxyz/taiko-client/prover/anchor_tx_validator"
)

var (
errProtocolAddressMismatch = errors.New("oracle prover private key does not match protocol setting")
)

// OracleProducer is responsible for generating a fake "zkproof" consisting
// of a signature of the evidence.
type OracleProducer struct {
Expand All @@ -32,7 +37,13 @@ func NewOracleProducer(
proverPrivKey *ecdsa.PrivateKey,
taikoL2Address common.Address,
proofTimeTarget time.Duration,
protocolOracleProverAddress common.Address,
) (*OracleProducer, error) {
proverAddress := crypto.PubkeyToAddress(proverPrivKey.PublicKey)
if proverAddress != protocolOracleProverAddress {
return nil, errProtocolAddressMismatch
}

anchorValidator, err := anchorTxValidator.New(taikoL2Address, rpc.L2ChainID, rpc)
if err != nil {
return nil, err
Expand Down Expand Up @@ -138,3 +149,9 @@ func hashAndSignForOracleProof(

return sig, v, nil
}

// Cancel cancels an existing proof generation.
// Since Oracle proofs are not "real" proofs, there is nothing to cancel.
func (d *OracleProducer) Cancel(ctx context.Context, blockID *big.Int) error {
return nil
}
1 change: 1 addition & 0 deletions prover/proof_producer/proof_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type ProofProducer interface {
header *types.Header,
resultCh chan *ProofWithHeader,
) error
Cancel(ctx context.Context, blockID *big.Int) error
}

func DegreeToCircuitsIdx(degree uint64) (uint16, error) {
Expand Down
8 changes: 8 additions & 0 deletions prover/proof_producer/zkevm_cmd_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,11 @@ func (d *ZkevmCmdProducer) outputToCalldata(output *ProverCmdOutput) []byte {

return calldata[:bufLen]
}

// Cancel cancels an existing proof generation.
// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof
// with the current zkevm software.
func (d *ZkevmCmdProducer) Cancel(ctx context.Context, blockID *big.Int) error {
log.Info("Cancel proof generation for block ", "blockId", blockID)
return nil
}
8 changes: 8 additions & 0 deletions prover/proof_producer/zkevm_rpcd_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,11 @@ func (d *ZkevmRpcdProducer) requestProof(opts *ProofRequestOptions) (*RpcdOutput

return output.Result, nil
}

// Cancel cancels an existing proof generation.
// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof
// with the current zkevm software.
func (d *ZkevmRpcdProducer) Cancel(ctx context.Context, blockID *big.Int) error {
log.Info("Cancel proof generation for block ", "blockId", blockID)
return nil
}
2 changes: 2 additions & 0 deletions prover/proof_submitter/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package submitter

import (
"context"
"math/big"

"github.com/taikoxyz/taiko-client/bindings"
proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer"
Expand All @@ -10,4 +11,5 @@ import (
type ProofSubmitter interface {
RequestProof(ctx context.Context, event *bindings.TaikoL1ClientBlockProposed) error
SubmitProof(ctx context.Context, proofWithHeader *proofProducer.ProofWithHeader) error
CancelProof(ctx context.Context, blockID *big.Int) error
}
8 changes: 8 additions & 0 deletions prover/proof_submitter/valid_proof_submitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
"sync"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -231,3 +232,10 @@ func (s *ValidProofSubmitter) SubmitProof(

return nil
}

// CancelProof cancels an existing proof generation.
// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof
// with the current zkevm software.
func (s *ValidProofSubmitter) CancelProof(ctx context.Context, blockID *big.Int) error {
return s.proofProducer.Cancel(ctx, blockID)
}
14 changes: 14 additions & 0 deletions prover/proof_submitter/valid_proof_submitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,20 @@ func (s *ProofSubmitterTestSuite) TestValidSubmitProofs() {
}
}

func (s *ProofSubmitterTestSuite) TestValidProofSubmitterRequestProofCancelled() {
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.AfterFunc(2*time.Second, func() {
cancel()
})
}()

s.ErrorContains(
s.validProofSubmitter.RequestProof(
ctx, &bindings.TaikoL1ClientBlockProposed{Id: common.Big256}), "context canceled",
)
}

func TestProofSubmitterTestSuite(t *testing.T) {
suite.Run(t, new(ProofSubmitterTestSuite))
}
Loading

0 comments on commit 74d1729

Please sign in to comment.