From 81cf6120c1610f7a8edaa183eb9a0fbbeb45b5f1 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 12 May 2023 03:19:37 +0800 Subject: [PATCH] feat(prover): update `ZkevmRpcdProducer` to integrate new circuits (#217) --- cmd/flags/driver.go | 7 -- driver/config.go | 2 - driver/config_test.go | 4 -- driver/driver.go | 10 ++- proposer/proposer.go | 2 +- prover/proof_producer/proof_producer.go | 10 +++ prover/proof_producer/zkevm_rpcd_producer.go | 68 +++++++++++++------ .../proof_submitter/valid_proof_submitter.go | 56 +++++++++++++-- 8 files changed, 118 insertions(+), 41 deletions(-) diff --git a/cmd/flags/driver.go b/cmd/flags/driver.go index fb6240a45..2b9b48c6e 100644 --- a/cmd/flags/driver.go +++ b/cmd/flags/driver.go @@ -18,12 +18,6 @@ var ( Required: true, Category: driverCategory, } - SignalServiceAddress = &cli.StringFlag{ - Name: "l1.signalService", - Usage: "L1 singal service contract address", - Required: true, - Category: driverCategory, - } ) // Optional flags used by driver. @@ -53,7 +47,6 @@ var ( var DriverFlags = MergeFlags(CommonFlags, []cli.Flag{ L2WSEndpoint, L2AuthEndpoint, - SignalServiceAddress, JWTSecret, P2PSyncVerifiedBlocks, P2PSyncTimeout, diff --git a/driver/config.go b/driver/config.go index ff3636a23..79098f381 100644 --- a/driver/config.go +++ b/driver/config.go @@ -19,7 +19,6 @@ type Config struct { L2CheckPoint string TaikoL1Address common.Address TaikoL2Address common.Address - SignalServiceAddress common.Address JwtSecret string P2PSyncVerifiedBlocks bool P2PSyncTimeout time.Duration @@ -49,7 +48,6 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { L2CheckPoint: l2CheckPoint, TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)), TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)), - SignalServiceAddress: common.HexToAddress(c.String(flags.SignalServiceAddress.Name)), JwtSecret: string(jwtSecret), P2PSyncVerifiedBlocks: p2pSyncVerifiedBlocks, P2PSyncTimeout: time.Duration(int64(time.Second) * int64(c.Uint(flags.P2PSyncTimeout.Name))), diff --git a/driver/config_test.go b/driver/config_test.go index e3714cb1b..8ec0781e5 100644 --- a/driver/config_test.go +++ b/driver/config_test.go @@ -15,7 +15,6 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { l2EngineEndpoint := os.Getenv("L2_EXECUTION_ENGINE_AUTH_ENDPOINT") taikoL1 := os.Getenv("TAIKO_L1_ADDRESS") taikoL2 := os.Getenv("TAIKO_L2_ADDRESS") - l1SignalService := os.Getenv("L1_SIGNAL_SERVICE_CONTRACT_ADDRESS") app := cli.NewApp() app.Flags = []cli.Flag{ @@ -24,7 +23,6 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { &cli.StringFlag{Name: flags.L2AuthEndpoint.Name}, &cli.StringFlag{Name: flags.TaikoL1Address.Name}, &cli.StringFlag{Name: flags.TaikoL2Address.Name}, - &cli.StringFlag{Name: flags.SignalServiceAddress.Name}, &cli.StringFlag{Name: flags.JWTSecret.Name}, &cli.UintFlag{Name: flags.P2PSyncTimeout.Name}, } @@ -36,7 +34,6 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { s.Equal(l2EngineEndpoint, c.L2EngineEndpoint) s.Equal(taikoL1, c.TaikoL1Address.String()) s.Equal(taikoL2, c.TaikoL2Address.String()) - s.Equal(l1SignalService, c.SignalServiceAddress.String()) s.Equal(120*time.Second, c.P2PSyncTimeout) s.NotEmpty(c.JwtSecret) s.Nil(new(Driver).InitFromCli(context.Background(), ctx)) @@ -51,7 +48,6 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { "-" + flags.L2AuthEndpoint.Name, l2EngineEndpoint, "-" + flags.TaikoL1Address.Name, taikoL1, "-" + flags.TaikoL2Address.Name, taikoL2, - "-" + flags.SignalServiceAddress.Name, l1SignalService, "-" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"), "-" + flags.P2PSyncTimeout.Name, "120", })) diff --git a/driver/driver.go b/driver/driver.go index 27871c9e6..a52b73e1f 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -77,13 +77,21 @@ func InitFromConfig(ctx context.Context, d *Driver, cfg *Config) (err error) { log.Warn("P2P syncing verified blocks enabled, but no connected peer found in L2 execution engine") } + var signalServiceNameBytes [32]byte + copy(signalServiceNameBytes[:], []byte("signal_service")) + + signalServiceAddress, err := d.rpc.TaikoL1.Resolve0(nil, signalServiceNameBytes, false) + if err != nil { + return err + } + if d.l2ChainSyncer, err = chainSyncer.New( d.ctx, d.rpc, d.state, cfg.P2PSyncVerifiedBlocks, cfg.P2PSyncTimeout, - cfg.SignalServiceAddress, + signalServiceAddress, ); err != nil { return err } diff --git a/proposer/proposer.go b/proposer/proposer.go index 03027969b..642110e1c 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -163,7 +163,7 @@ func (p *Proposer) ProposeOp(ctx context.Context) error { return p.CustomProposeOpHook() } - log.Info("Comparing proposer TKO balance to block fee") + log.Info("Comparing proposer TKO balance to block fee", "proposer", p.l1ProposerAddress.Hex()) if err := p.checkTaikoTokenBalance(); err != nil { return fmt.Errorf("failed to check Taiko token balance: %w", err) diff --git a/prover/proof_producer/proof_producer.go b/prover/proof_producer/proof_producer.go index e7faa78a9..936b9ae24 100644 --- a/prover/proof_producer/proof_producer.go +++ b/prover/proof_producer/proof_producer.go @@ -23,6 +23,16 @@ type ProofRequestOptions struct { Height *big.Int // the block number ProverAddress common.Address ProposeBlockTxHash common.Hash + L1SignalService common.Address + L2SignalService common.Address + TaikoL2 common.Address + MetaHash common.Hash + BlockHash common.Hash + ParentHash common.Hash + SignalRoot common.Hash + Graffiti string + GasUsed uint64 + ParentGasUsed uint64 } type ProofWithHeader struct { diff --git a/prover/proof_producer/zkevm_rpcd_producer.go b/prover/proof_producer/zkevm_rpcd_producer.go index 30fdeb291..2719d1452 100644 --- a/prover/proof_producer/zkevm_rpcd_producer.go +++ b/prover/proof_producer/zkevm_rpcd_producer.go @@ -42,17 +42,25 @@ type RequestProofBody struct { // RequestProofBody represents the JSON body of RequestProofBody's `param` field. type RequestProofBodyParam struct { - Circuit string `json:"circuit"` - Block *big.Int `json:"block"` - L1RPC string `json:"l1_rpc"` - L2RPC string `json:"l2_rpc"` - ProposeBlockTxHash string `json:"propose_tx_hash"` - Retry bool `json:"retry"` - Param string `json:"param"` - VerifyProof bool `json:"verify_proof"` - Mock bool `json:"mock"` - Aggregate bool `json:"aggregate"` - Prover string `json:"prover"` + Circuit string `json:"circuit"` + Block *big.Int `json:"block"` + L2RPC string `json:"l2_rpc"` + Retry bool `json:"retry"` + Param string `json:"param"` + VerifyProof bool `json:"verify_proof"` + Mock bool `json:"mock"` + Aggregate bool `json:"aggregate"` + Prover string `json:"prover"` + L1SignalService string `json:"l1_signal_service"` + L2SignalService string `json:"l2_signal_service"` + TaikoL2 string `json:"l2_contract"` + MetaHash string `json:"meta_hash"` + BlockHash string `json:"block_hash"` + ParentHash string `json:"parent_hash"` + SignalRoot string `json:"signal_root"` + Graffiti string `json:"graffiti"` + GasUsed uint64 `json:"gas_used"` + ParentGasUsed uint64 `json:"parent_gas_used"` } // RequestProofBodyResponse represents the JSON body of the response of the proof requests. @@ -60,6 +68,10 @@ type RequestProofBodyResponse struct { JsonRPC string `json:"jsonrpc"` ID *big.Int `json:"id"` Result *RpcdOutput `json:"result"` + Error *struct { + Code *big.Int `json:"code"` + Message string `json:"message"` + } `json:"error,omitempty"` } // RpcdOutput represents the JSON body of RequestProofBodyResponse's `result` field. @@ -169,17 +181,25 @@ func (p *ZkevmRpcdProducer) requestProof(opts *ProofRequestOptions) (*RpcdOutput ID: common.Big1, Method: "proof", Params: []*RequestProofBodyParam{{ - Circuit: "pi", - Block: opts.Height, - L1RPC: p.L1Endpoint, - L2RPC: p.L2Endpoint, - Retry: true, - Param: p.Param, - VerifyProof: true, - Mock: false, - Aggregate: false, - Prover: opts.ProverAddress.Hex()[2:], - ProposeBlockTxHash: opts.ProposeBlockTxHash.Hex()[2:], + Circuit: "pi", + Block: opts.Height, + L2RPC: p.L2Endpoint, + Retry: true, + Param: p.Param, + VerifyProof: true, + Mock: false, + Aggregate: false, + Prover: opts.ProverAddress.Hex()[2:], + L1SignalService: opts.L1SignalService.Hex()[2:], + L2SignalService: opts.L2SignalService.Hex()[2:], + TaikoL2: opts.TaikoL2.Hex()[2:], + MetaHash: opts.MetaHash.Hex()[2:], + BlockHash: opts.BlockHash.Hex()[2:], + ParentHash: opts.ParentHash.Hex()[2:], + SignalRoot: opts.SignalRoot.Hex()[2:], + Graffiti: opts.Graffiti, + GasUsed: opts.GasUsed, + ParentGasUsed: opts.ParentGasUsed, }}, } @@ -208,6 +228,10 @@ func (p *ZkevmRpcdProducer) requestProof(opts *ProofRequestOptions) (*RpcdOutput return nil, err } + if output.Error != nil { + return nil, errors.New(output.Error.Message) + } + return output.Result, nil } diff --git a/prover/proof_submitter/valid_proof_submitter.go b/prover/proof_submitter/valid_proof_submitter.go index ecc0e4d79..456a7f6d0 100644 --- a/prover/proof_submitter/valid_proof_submitter.go +++ b/prover/proof_submitter/valid_proof_submitter.go @@ -31,6 +31,9 @@ type ValidProofSubmitter struct { anchorTxValidator *anchorTxValidator.AnchorTxValidator proverPrivKey *ecdsa.PrivateKey proverAddress common.Address + taikoL2Address common.Address + l1SignalService common.Address + l2SignalService common.Address mutex *sync.Mutex isOracleProver bool isSystemProver bool @@ -54,6 +57,19 @@ func NewValidProofSubmitter( return nil, err } + var signalServiceNameBytes [32]byte + copy(signalServiceNameBytes[:], []byte("signal_service")) + + l1SignalService, err := rpc.TaikoL1.Resolve0(nil, signalServiceNameBytes, false) + if err != nil { + return nil, err + } + + l2SignalService, err := rpc.TaikoL2.Resolve0(nil, signalServiceNameBytes, false) + if err != nil { + return nil, err + } + var graffitiBytes [32]byte copy(graffitiBytes[:], []byte(graffiti)) @@ -64,6 +80,9 @@ func NewValidProofSubmitter( anchorTxValidator: anchorValidator, proverPrivKey: proverPrivKey, proverAddress: crypto.PubkeyToAddress(proverPrivKey.PublicKey), + l1SignalService: l1SignalService, + l2SignalService: l2SignalService, + taikoL2Address: taikoL2Address, mutex: mutex, isOracleProver: isOracleProver, isSystemProver: isSystemProver, @@ -79,19 +98,48 @@ func (s *ValidProofSubmitter) RequestProof(ctx context.Context, event *bindings. } // Get the header of the block to prove from L2 execution engine. - header, err := s.rpc.L2.HeaderByHash(ctx, l1Origin.L2BlockHash) + block, err := s.rpc.L2.BlockByHash(ctx, l1Origin.L2BlockHash) + if err != nil { + return err + } + + parent, err := s.rpc.L2.BlockByHash(ctx, block.ParentHash()) + if err != nil { + return err + } + + blockInfo, err := s.rpc.TaikoL1.GetBlock(nil, event.Id) + if err != nil { + return err + } + + if block.Transactions().Len() == 0 { + return errors.New("no transaction in block") + } + + signalRoot, err := s.anchorTxValidator.GetAnchoredSignalRoot(ctx, block.Transactions()[0]) if err != nil { return err } // Request proof. opts := &proofProducer.ProofRequestOptions{ - Height: header.Number, + Height: block.Number(), ProverAddress: s.proverAddress, ProposeBlockTxHash: event.Raw.TxHash, + L1SignalService: s.l1SignalService, + L2SignalService: s.l2SignalService, + TaikoL2: s.taikoL2Address, + MetaHash: blockInfo.MetaHash, + BlockHash: block.Hash(), + ParentHash: block.ParentHash(), + SignalRoot: signalRoot, + Graffiti: common.Bytes2Hex(s.graffiti[:]), + GasUsed: block.GasUsed(), + ParentGasUsed: parent.GasUsed(), } - if err := s.proofProducer.RequestProof(ctx, opts, event.Id, &event.Meta, header, s.resultCh); err != nil { + if err := s.proofProducer.RequestProof(ctx, opts, event.Id, &event.Meta, block.Header(), s.resultCh); err != nil { return err } @@ -112,7 +160,7 @@ func (s *ValidProofSubmitter) SubmitProof( "beneficiary", proofWithHeader.Meta.Beneficiary, "hash", proofWithHeader.Header.Hash(), "proof", common.Bytes2Hex(proofWithHeader.ZkProof), - "graffiti", string(s.graffiti[:]), + "graffiti", common.Bytes2Hex(s.graffiti[:]), ) var ( blockID = proofWithHeader.BlockID