From 9b12c2ffe9c4f3c18155c9ee181d18c6231ff2f1 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 29 Apr 2024 15:49:45 +0800 Subject: [PATCH] feat(prover): introduce `TierGuardianMinority` --- bindings/encoding/struct.go | 14 +++++++----- cmd/flags/prover.go | 19 +++++++++++----- proposer/proposer.go | 2 +- prover/config.go | 10 +++++---- prover/config_test.go | 4 ++-- prover/event_handler/block_proposed.go | 14 ++++++------ prover/event_handler/util_test.go | 2 +- prover/init.go | 2 +- prover/proof_producer/guardian_producer.go | 2 +- .../proof_producer/guardian_producer_test.go | 4 ++-- prover/proof_submitter/proof_submitter.go | 2 +- .../proof_submitter/proof_submitter_test.go | 2 +- prover/prover.go | 8 +++---- prover/prover_test.go | 22 +++++++++---------- prover/server/api.go | 2 +- 15 files changed, 61 insertions(+), 48 deletions(-) diff --git a/bindings/encoding/struct.go b/bindings/encoding/struct.go index 1cfe974bf..e230bb94e 100644 --- a/bindings/encoding/struct.go +++ b/bindings/encoding/struct.go @@ -10,15 +10,17 @@ import ( // Tier IDs defined in protocol. var ( - TierOptimisticID uint16 = 100 - TierSgxID uint16 = 200 - TierSgxAndZkVMID uint16 = 300 - TierGuardianID uint16 = 1000 - ProtocolTiers = []uint16{ + TierOptimisticID uint16 = 100 + TierSgxID uint16 = 200 + TierSgxAndZkVMID uint16 = 300 + TierGuardianMinorityID uint16 = 900 + TierGuardianMajorityID uint16 = 1000 + ProtocolTiers = []uint16{ TierOptimisticID, TierSgxID, TierSgxAndZkVMID, - TierGuardianID, + TierGuardianMinorityID, + TierGuardianMajorityID, } GoldenTouchPrivKey = "92954368afd3caa1f3ce3ead0069c1af414054aefe1ef9aeacc1bf426222ce38" ) diff --git a/cmd/flags/prover.go b/cmd/flags/prover.go index 0e533270f..f8d9b861e 100644 --- a/cmd/flags/prover.go +++ b/cmd/flags/prover.go @@ -3,6 +3,7 @@ package flags import ( "time" + "github.com/taikoxyz/taiko-client/pkg/rpc" "github.com/urfave/cli/v2" ) @@ -164,11 +165,18 @@ var ( EnvVars: []string{"PROVER_GUARDIAN_PROVER_HEALTH_CHECK_SERVER_ENDPOINT"}, } // Guardian prover specific flag - GuardianProver = &cli.StringFlag{ - Name: "guardianProver", - Usage: "GuardianProver contract `address`", + GuardianProverMinority = &cli.StringFlag{ + Name: "guardianProverMinority", + Usage: "GuardianProverMinority contract `address`", + Value: rpc.ZeroAddress.Hex(), Category: proverCategory, - EnvVars: []string{"GUARDIAN_PROVER"}, + EnvVars: []string{"GUARDIAN_PROVER_MINORITY"}, + } + GuardianProverMajority = &cli.StringFlag{ + Name: "guardianProverMajority", + Usage: "GuardianProverMajority contract `address`", + Category: proverCategory, + EnvVars: []string{"GUARDIAN_PROVER_MAJORITY"}, } GuardianProofSubmissionDelay = &cli.DurationFlag{ Name: "guardian.submissionDelay", @@ -224,7 +232,8 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{ MinTaikoTokenBalance, StartingBlockID, Dummy, - GuardianProver, + GuardianProverMinority, + GuardianProverMajority, GuardianProofSubmissionDelay, GuardianProverHealthCheckServerEndpoint, Graffiti, diff --git a/proposer/proposer.go b/proposer/proposer.go index cbbcbf6fd..bbd0e1c2e 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -433,7 +433,7 @@ func (p *Proposer) initTierFees() error { p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: p.OptimisticTierFee}) case encoding.TierSgxID: p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: p.SgxTierFee}) - case encoding.TierGuardianID: + case encoding.TierGuardianMajorityID: // Guardian prover should not charge any fee. p.tierFees = append(p.tierFees, encoding.TierFee{Tier: tier.ID, Fee: common.Big0}) default: diff --git a/prover/config.go b/prover/config.go index fc3150a0f..ddc1cc096 100644 --- a/prover/config.go +++ b/prover/config.go @@ -33,7 +33,8 @@ type Config struct { L1ProverPrivKey *ecdsa.PrivateKey StartingBlockID *big.Int Dummy bool - GuardianProverAddress common.Address + GuardianProverMinorityAddress common.Address + GuardianProverMajorityAddress common.Address GuardianProofSubmissionDelay time.Duration Graffiti string BackOffMaxRetries uint64 @@ -101,7 +102,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { } // If we are running a guardian prover, we need to prove unassigned blocks and run in contester mode by default. - if c.IsSet(flags.GuardianProver.Name) { + if c.IsSet(flags.GuardianProverMajority.Name) { if err := c.Set(flags.ProveUnassignedBlocks.Name, "true"); err != nil { return nil, err } @@ -119,7 +120,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { } // If we are not running a guardian prover, a raiko host endpoint is required. - if !c.IsSet(flags.GuardianProver.Name) && !c.IsSet(flags.RaikoHostEndpoint.Name) { + if !c.IsSet(flags.GuardianProverMajority.Name) && !c.IsSet(flags.RaikoHostEndpoint.Name) { return nil, errors.New("raiko host not provided") } @@ -180,7 +181,8 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { RaikoL2Endpoint: raikoL2Endpoint, StartingBlockID: startingBlockID, Dummy: c.Bool(flags.Dummy.Name), - GuardianProverAddress: common.HexToAddress(c.String(flags.GuardianProver.Name)), + GuardianProverMinorityAddress: common.HexToAddress(c.String(flags.GuardianProverMinority.Name)), + GuardianProverMajorityAddress: common.HexToAddress(c.String(flags.GuardianProverMajority.Name)), GuardianProofSubmissionDelay: c.Duration(flags.GuardianProofSubmissionDelay.Name), GuardianProverHealthCheckServerEndpoint: guardianProverHealthCheckServerEndpoint, Graffiti: c.String(flags.Graffiti.Name), diff --git a/prover/config_test.go b/prover/config_test.go index 3d8da7f1d..69d6dff72 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -84,7 +84,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContextGuardianProver() { "--" + flags.MinOptimisticTierFee.Name, fmt.Sprint(minTierFee), "--" + flags.MinSgxTierFee.Name, fmt.Sprint(minTierFee), "--" + flags.ProverCapacity.Name, "8", - "--" + flags.GuardianProver.Name, os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS"), + "--" + flags.GuardianProverMajority.Name, os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS"), "--" + flags.AssignmentHookAddress.Name, os.Getenv("ASSIGNMENT_HOOK_ADDRESS"), "--" + flags.Graffiti.Name, "", "--" + flags.ProveUnassignedBlocks.Name, @@ -117,7 +117,7 @@ func (s *ProverTestSuite) SetupApp() *cli.App { &cli.StringFlag{Name: flags.L1ProverPrivKey.Name}, &cli.Uint64Flag{Name: flags.StartingBlockID.Name}, &cli.BoolFlag{Name: flags.Dummy.Name}, - &cli.StringFlag{Name: flags.GuardianProver.Name}, + &cli.StringFlag{Name: flags.GuardianProverMajority.Name}, &cli.StringFlag{Name: flags.Graffiti.Name}, &cli.BoolFlag{Name: flags.ProveUnassignedBlocks.Name}, &cli.DurationFlag{Name: flags.RPCTimeout.Name}, diff --git a/prover/event_handler/block_proposed.go b/prover/event_handler/block_proposed.go index 7192be5a2..492180d51 100644 --- a/prover/event_handler/block_proposed.go +++ b/prover/event_handler/block_proposed.go @@ -43,8 +43,9 @@ type BlockProposedEventHandler struct { backOffMaxRetrys uint64 contesterMode bool proveUnassignedBlocks bool - tierToOverride uint16 - submissionDelay time.Duration + // Guardian prover related. + isGuardian bool + submissionDelay time.Duration } // NewBlockProposedEventHandlerOps is the options for creating a new BlockProposedEventHandler. @@ -79,7 +80,7 @@ func NewBlockProposedEventHandler(opts *NewBlockProposedEventHandlerOps) *BlockP opts.BackOffMaxRetrys, opts.ContesterMode, opts.ProveUnassignedBlocks, - 0, + false, opts.SubmissionDelay, } } @@ -347,8 +348,8 @@ func (h *BlockProposedEventHandler) checkExpirationAndSubmitProof( return err } - if h.tierToOverride != 0 { - tier = h.tierToOverride + if h.isGuardian { + tier = encoding.TierGuardianMinorityID } log.Info( @@ -388,8 +389,7 @@ func NewBlockProposedEventGuardianHandler( opts *NewBlockProposedGuardianEventHandlerOps, ) *BlockProposedGuaridanEventHandler { blockProposedEventHandler := NewBlockProposedEventHandler(opts.NewBlockProposedEventHandlerOps) - // For guardian provers, we only send top tier proofs. - blockProposedEventHandler.tierToOverride = encoding.TierGuardianID + blockProposedEventHandler.isGuardian = true return &BlockProposedGuaridanEventHandler{ BlockProposedEventHandler: blockProposedEventHandler, diff --git a/prover/event_handler/util_test.go b/prover/event_handler/util_test.go index 3e34b5d35..5c2e19965 100644 --- a/prover/event_handler/util_test.go +++ b/prover/event_handler/util_test.go @@ -20,7 +20,7 @@ type ProverEventHandlerTestSuite struct { func (s *ProverEventHandlerTestSuite) TestGetProvingWindowNotFound() { _, err := getProvingWindow(&bindings.TaikoL1ClientBlockProposed{ Meta: bindings.TaikoDataBlockMetadata{ - MinTier: encoding.TierGuardianID + 1, + MinTier: encoding.TierGuardianMajorityID + 1, }, }, []*rpc.TierProviderTierWithID{}) s.ErrorIs(err, errTierNotFound) diff --git a/prover/init.go b/prover/init.go index 45c8244b8..872bca02e 100644 --- a/prover/init.go +++ b/prover/init.go @@ -112,7 +112,7 @@ func (p *Prover) initProofSubmitters( L2Endpoint: p.cfg.RaikoL2Endpoint, Dummy: p.cfg.Dummy, } - case encoding.TierGuardianID: + case encoding.TierGuardianMajorityID: producer = proofProducer.NewGuardianProofProducer(p.cfg.EnableLivenessBondProof) default: return fmt.Errorf("unsupported tier: %d", tier.ID) diff --git a/prover/proof_producer/guardian_producer.go b/prover/proof_producer/guardian_producer.go index d638ef1da..2d79e76d4 100644 --- a/prover/proof_producer/guardian_producer.go +++ b/prover/proof_producer/guardian_producer.go @@ -56,5 +56,5 @@ func (g *GuardianProofProducer) RequestProof( // Tier implements the ProofProducer interface. func (g *GuardianProofProducer) Tier() uint16 { - return encoding.TierGuardianID + return encoding.TierGuardianMajorityID } diff --git a/prover/proof_producer/guardian_producer_test.go b/prover/proof_producer/guardian_producer_test.go index a6e6b6d86..665b20684 100644 --- a/prover/proof_producer/guardian_producer_test.go +++ b/prover/proof_producer/guardian_producer_test.go @@ -47,7 +47,7 @@ func TestGuardianProducerRequestProof(t *testing.T) { require.Equal(t, res.BlockID, blockID) require.Equal(t, res.Header, header) - require.Equal(t, res.Tier, encoding.TierGuardianID) + require.Equal(t, res.Tier, encoding.TierGuardianMajorityID) require.NotEmpty(t, res.Proof) } @@ -84,7 +84,7 @@ func TestGuardianProducerRequestProofReturnLivenessBond(t *testing.T) { require.Equal(t, res.BlockID, blockID) require.Equal(t, res.Header, header) - require.Equal(t, res.Tier, encoding.TierGuardianID) + require.Equal(t, res.Tier, encoding.TierGuardianMajorityID) require.NotEmpty(t, res.Proof) require.Equal(t, res.Proof, crypto.Keccak256([]byte("RETURN_LIVENESS_BOND"))) } diff --git a/prover/proof_submitter/proof_submitter.go b/prover/proof_submitter/proof_submitter.go index c8b015d9f..699081c84 100644 --- a/prover/proof_submitter/proof_submitter.go +++ b/prover/proof_submitter/proof_submitter.go @@ -170,7 +170,7 @@ func (s *ProofSubmitter) SubmitProof( Tier: proofWithHeader.Tier, Data: proofWithHeader.Proof, }, - proofWithHeader.Tier == encoding.TierGuardianID, + proofWithHeader.Tier == encoding.TierGuardianMajorityID, ), ); err != nil { if err.Error() == transaction.ErrUnretryableSubmission.Error() { diff --git a/prover/proof_submitter/proof_submitter_test.go b/prover/proof_submitter/proof_submitter_test.go index f6d8413f8..bec106b32 100644 --- a/prover/proof_submitter/proof_submitter_test.go +++ b/prover/proof_submitter/proof_submitter_test.go @@ -192,7 +192,7 @@ func (s *ProofSubmitterTestSuite) TestGuardianSubmitProofs() { for _, e := range events { s.Nil(s.submitter.RequestProof(context.Background(), e)) proofWithHeader := <-s.proofCh - proofWithHeader.Tier = encoding.TierGuardianID + proofWithHeader.Tier = encoding.TierGuardianMajorityID s.Nil(s.submitter.SubmitProof(context.Background(), proofWithHeader)) } } diff --git a/prover/prover.go b/prover/prover.go index d630a115d..e67f4240c 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -110,7 +110,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { TaikoL1Address: cfg.TaikoL1Address, TaikoL2Address: cfg.TaikoL2Address, TaikoTokenAddress: cfg.TaikoTokenAddress, - GuardianProverAddress: cfg.GuardianProverAddress, + GuardianProverAddress: cfg.GuardianProverMajorityAddress, Timeout: cfg.RPCTimeout, }); err != nil { return err @@ -143,7 +143,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { } p.sharedState.SetTiers(tiers) - txBuilder := transaction.NewProveBlockTxBuilder(p.rpc, p.cfg.TaikoL1Address, p.cfg.GuardianProverAddress) + txBuilder := transaction.NewProveBlockTxBuilder(p.rpc, p.cfg.TaikoL1Address, p.cfg.GuardianProverMajorityAddress) if p.txmgr, err = txmgr.NewSimpleTxManager( "prover", @@ -375,7 +375,7 @@ func (p *Prover) contestProofOp(req *proofProducer.ContestRequestBody) error { // requestProofOp requests a new proof generation operation. func (p *Prover) requestProofOp(e *bindings.TaikoL1ClientBlockProposed, minTier uint16) error { if p.IsGuardianProver() { - minTier = encoding.TierGuardianID + minTier = encoding.TierGuardianMajorityID } if submitter := p.selectSubmitter(minTier); submitter != nil { if err := submitter.RequestProof(p.ctx, e); err != nil { @@ -453,7 +453,7 @@ func (p *Prover) getSubmitterByTier(tier uint16) proofSubmitter.Submitter { // IsGuardianProver returns true if the current prover is a guardian prover. func (p *Prover) IsGuardianProver() bool { - return p.cfg.GuardianProverAddress != common.Address{} + return p.cfg.GuardianProverMajorityAddress != common.Address{} } // ProverAddress returns the current prover account address. diff --git a/prover/prover_test.go b/prover/prover_test.go index 10f5f05a2..0b14e6dfa 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -298,14 +298,14 @@ func (s *ProverTestSuite) TestContestWrongBlocks() { s.Nil(s.p.transitionContestedHandler.Handle(context.Background(), contestedEvent)) - s.p.cfg.GuardianProverAddress = common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")) + s.p.cfg.GuardianProverMajorityAddress = common.HexToAddress(os.Getenv("GUARDIAN_PROVER_CONTRACT_ADDRESS")) s.True(s.p.IsGuardianProver()) - txBuilder := transaction.NewProveBlockTxBuilder(s.p.rpc, s.p.cfg.TaikoL1Address, s.p.cfg.GuardianProverAddress) + txBuilder := transaction.NewProveBlockTxBuilder(s.p.rpc, s.p.cfg.TaikoL1Address, s.p.cfg.GuardianProverMajorityAddress) s.p.proofSubmitters = nil s.Nil(s.p.initProofSubmitters(s.p.txmgr, txBuilder)) - s.p.rpc.GuardianProver, err = bindings.NewGuardianProver(s.p.cfg.GuardianProverAddress, s.p.rpc.L1) + s.p.rpc.GuardianProver, err = bindings.NewGuardianProver(s.p.cfg.GuardianProverMajorityAddress, s.p.rpc.L1) s.Nil(err) approvedSink := make(chan *bindings.GuardianProverGuardianApproval) @@ -319,7 +319,7 @@ func (s *ProverTestSuite) TestContestWrongBlocks() { }() req = <-s.p.proofSubmissionCh s.Nil(s.p.requestProofOp(req.Event, req.Tier)) - s.Nil(s.p.selectSubmitter(encoding.TierGuardianID).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) + s.Nil(s.p.selectSubmitter(encoding.TierGuardianMajorityID).SubmitProof(context.Background(), <-s.p.proofGenerationCh)) approvedEvent := <-approvedSink s.Equal(header.Number.Uint64(), approvedEvent.BlockId.Uint64()) @@ -340,7 +340,7 @@ func (s *ProverTestSuite) TestProveExpiredUnassignedBlock() { }() e.AssignedProver = common.BytesToAddress(testutils.RandomHash().Bytes()) - s.p.cfg.GuardianProverAddress = common.Address{} + s.p.cfg.GuardianProverMajorityAddress = common.Address{} s.Nil(s.p.assignmentExpiredHandler.Handle(context.Background(), e)) req := <-s.p.proofSubmissionCh s.Nil(s.p.requestProofOp(req.Event, req.Tier)) @@ -353,21 +353,21 @@ func (s *ProverTestSuite) TestProveExpiredUnassignedBlock() { } func (s *ProverTestSuite) TestSelectSubmitter() { - submitter := s.p.selectSubmitter(encoding.TierGuardianID - 1) + submitter := s.p.selectSubmitter(encoding.TierGuardianMajorityID - 1) s.NotNil(submitter) - s.Equal(encoding.TierGuardianID, submitter.Tier()) + s.Equal(encoding.TierGuardianMajorityID, submitter.Tier()) } func (s *ProverTestSuite) TestSelectSubmitterNotFound() { - submitter := s.p.selectSubmitter(encoding.TierGuardianID + 1) + submitter := s.p.selectSubmitter(encoding.TierGuardianMajorityID + 1) s.Nil(submitter) } func (s *ProverTestSuite) TestGetSubmitterByTier() { - submitter := s.p.getSubmitterByTier(encoding.TierGuardianID) + submitter := s.p.getSubmitterByTier(encoding.TierGuardianMajorityID) s.NotNil(submitter) - s.Equal(encoding.TierGuardianID, submitter.Tier()) - s.Nil(s.p.getSubmitterByTier(encoding.TierGuardianID + 1)) + s.Equal(encoding.TierGuardianMajorityID, submitter.Tier()) + s.Nil(s.p.getSubmitterByTier(encoding.TierGuardianMajorityID + 1)) } func (s *ProverTestSuite) TestProveOp() { diff --git a/prover/server/api.go b/prover/server/api.go index be35869ac..664d14cc1 100644 --- a/prover/server/api.go +++ b/prover/server/api.go @@ -148,7 +148,7 @@ func (s *ProverServer) CreateAssignment(c echo.Context) error { // 4. Check if the proof fee meets prover's minimum requirement for each tier. for _, tier := range req.TierFees { - if tier.Tier == encoding.TierGuardianID { + if tier.Tier == encoding.TierGuardianMajorityID { continue }