diff --git a/cmd/flags/prover.go b/cmd/flags/prover.go index fc909a83f..1661fbb69 100644 --- a/cmd/flags/prover.go +++ b/cmd/flags/prover.go @@ -24,16 +24,17 @@ var ( Category: proverCategory, EnvVars: []string{"PROVER_CAPACITY"}, } -) - -// Optional flags used by prover. -var ( RaikoHostEndpoint = &cli.StringFlag{ Name: "raiko.host", Usage: "RPC endpoint of a Raiko host service", + Required: true, Category: proverCategory, EnvVars: []string{"RAIKO_HOST"}, } +) + +// Optional flags used by prover. +var ( RaikoL1Endpoint = &cli.StringFlag{ Name: "raiko.l1", Usage: "L1 RPC endpoint which will be sent to the Raiko service", diff --git a/prover/config.go b/prover/config.go index ddc1cc096..6f30d6e68 100644 --- a/prover/config.go +++ b/prover/config.go @@ -117,13 +117,12 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { if !c.IsSet(flags.L2NodeVersion.Name) { return nil, errors.New("--prover.l2NodeVersion flag is required if guardian prover is set") } - } - // If we are not running a guardian prover, a raiko host endpoint is required. - if !c.IsSet(flags.GuardianProverMajority.Name) && !c.IsSet(flags.RaikoHostEndpoint.Name) { - return nil, errors.New("raiko host not provided") + // If we are running a guardian prover, a raiko host endpoint is required. + if !c.IsSet(flags.RaikoHostEndpoint.Name) { + return nil, errors.New("raiko host not provided") + } } - var ( raikoL1Endpoint = c.String(flags.RaikoL1Endpoint.Name) raikoL1BeaconEndpoint = c.String(flags.RaikoL1BeaconEndpoint.Name) diff --git a/prover/config_test.go b/prover/config_test.go index 18956ed4c..6175cbba6 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -93,6 +93,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContextGuardianProver() { "--" + flags.Allowance.Name, fmt.Sprint(allowance), "--" + flags.L1NodeVersion.Name, l1NodeVersion, "--" + flags.L2NodeVersion.Name, l2NodeVersion, + "--" + flags.RaikoHostEndpoint.Name, "https://dummy.raiko.xyz", })) } @@ -132,6 +133,7 @@ func (s *ProverTestSuite) SetupApp() *cli.App { &cli.StringFlag{Name: flags.ContesterMode.Name}, &cli.StringFlag{Name: flags.L1NodeVersion.Name}, &cli.StringFlag{Name: flags.L2NodeVersion.Name}, + &cli.StringFlag{Name: flags.RaikoHostEndpoint.Name}, } app.Flags = append(app.Flags, flags.TxmgrFlags...) app.Action = func(ctx *cli.Context) error { diff --git a/prover/init.go b/prover/init.go index 3a8ae804a..354ddfaa9 100644 --- a/prover/init.go +++ b/prover/init.go @@ -110,12 +110,27 @@ func (p *Prover) initProofSubmitters( L1Endpoint: p.cfg.RaikoL1Endpoint, L1BeaconEndpoint: p.cfg.RaikoL1BeaconEndpoint, L2Endpoint: p.cfg.RaikoL2Endpoint, + ProofType: proofProducer.ProofTypeSgx, Dummy: p.cfg.Dummy, } case encoding.TierGuardianMinorityID: - producer = proofProducer.NewMinorityGuardianProofProducer(p.cfg.EnableLivenessBondProof) + producer = proofProducer.NewMinorityGuardianProofProducer(&proofProducer.SGXProofProducer{ + RaikoHostEndpoint: p.cfg.RaikoHostEndpoint, + L1Endpoint: p.cfg.RaikoL1Endpoint, + L1BeaconEndpoint: p.cfg.RaikoL1BeaconEndpoint, + L2Endpoint: p.cfg.RaikoL2Endpoint, + ProofType: proofProducer.ProofTypeCPU, + Dummy: p.cfg.Dummy, + }, p.cfg.EnableLivenessBondProof) case encoding.TierGuardianMajorityID: - producer = proofProducer.NewGuardianProofProducer(p.cfg.EnableLivenessBondProof) + producer = proofProducer.NewGuardianProofProducer(&proofProducer.SGXProofProducer{ + RaikoHostEndpoint: p.cfg.RaikoHostEndpoint, + L1Endpoint: p.cfg.RaikoL1Endpoint, + L1BeaconEndpoint: p.cfg.RaikoL1BeaconEndpoint, + L2Endpoint: p.cfg.RaikoL2Endpoint, + ProofType: proofProducer.ProofTypeCPU, + Dummy: p.cfg.Dummy, + }, 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 f4521e58b..5ac243681 100644 --- a/prover/proof_producer/guardian_producer.go +++ b/prover/proof_producer/guardian_producer.go @@ -15,30 +15,35 @@ import ( // GuardianProofProducer always returns an optimistic (dummy) proof. type GuardianProofProducer struct { returnLivenessBond bool - DummyProofProducer + *SGXProofProducer } // MinorityGuardianProofProducer always returns an optimistic (dummy) proof. type MinorityGuardianProofProducer struct { returnLivenessBond bool - DummyProofProducer + *SGXProofProducer } -func NewGuardianProofProducer(returnLivenessBond bool) *GuardianProofProducer { +func NewGuardianProofProducer(sgxProofProducer *SGXProofProducer, returnLivenessBond bool) *GuardianProofProducer { return &GuardianProofProducer{ + SGXProofProducer: sgxProofProducer, returnLivenessBond: returnLivenessBond, } } -func NewMinorityGuardianProofProducer(returnLivenessBond bool) *MinorityGuardianProofProducer { +func NewMinorityGuardianProofProducer( + sgxProofProducer *SGXProofProducer, + returnLivenessBond bool, +) *MinorityGuardianProofProducer { return &MinorityGuardianProofProducer{ + SGXProofProducer: sgxProofProducer, returnLivenessBond: returnLivenessBond, } } // RequestProof implements the ProofProducer interface. func (g *GuardianProofProducer) RequestProof( - _ context.Context, + ctx context.Context, opts *ProofRequestOptions, blockID *big.Int, meta *bindings.TaikoDataBlockMetadata, @@ -63,11 +68,18 @@ func (g *GuardianProofProducer) RequestProof( }, nil } + // Each guardian prover should check the block hash with raiko at first, + // before submitting the guardian proof, if raiko can return a proof without + // any error, which means the block hash is valid. + if _, err := g.SGXProofProducer.RequestProof(ctx, opts, blockID, meta, header); err != nil { + return nil, err + } + return g.DummyProofProducer.RequestProof(opts, blockID, meta, header, g.Tier()) } func (m *MinorityGuardianProofProducer) RequestProof( - _ context.Context, + ctx context.Context, opts *ProofRequestOptions, blockID *big.Int, meta *bindings.TaikoDataBlockMetadata, @@ -92,6 +104,10 @@ func (m *MinorityGuardianProofProducer) RequestProof( }, nil } + if _, err := m.SGXProofProducer.RequestProof(ctx, opts, blockID, meta, header); err != nil { + return nil, err + } + return m.DummyProofProducer.RequestProof(opts, blockID, meta, header, m.Tier()) } diff --git a/prover/proof_producer/guardian_producer_test.go b/prover/proof_producer/guardian_producer_test.go index 665b20684..d012d0565 100644 --- a/prover/proof_producer/guardian_producer_test.go +++ b/prover/proof_producer/guardian_producer_test.go @@ -33,7 +33,7 @@ func TestGuardianProducerRequestProof(t *testing.T) { } var ( - producer = NewGuardianProofProducer(false) + producer = NewGuardianProofProducer(&SGXProofProducer{Dummy: true}, false) blockID = common.Big32 ) res, err := producer.RequestProof( @@ -70,7 +70,7 @@ func TestGuardianProducerRequestProofReturnLivenessBond(t *testing.T) { } var ( - producer = NewGuardianProofProducer(true) + producer = NewGuardianProofProducer(&SGXProofProducer{Dummy: true}, true) blockID = common.Big32 ) res, err := producer.RequestProof( diff --git a/prover/proof_producer/minority_guardian_producer_test.go b/prover/proof_producer/minority_guardian_producer_test.go index 2f7825d98..9d506b708 100644 --- a/prover/proof_producer/minority_guardian_producer_test.go +++ b/prover/proof_producer/minority_guardian_producer_test.go @@ -34,7 +34,7 @@ func TestRequestProof(t *testing.T) { } var ( - producer = NewMinorityGuardianProofProducer(false) + producer = NewMinorityGuardianProofProducer(&SGXProofProducer{Dummy: true}, false) blockID = common.Big32 ) res, err := producer.RequestProof( @@ -71,7 +71,7 @@ func TestRequestProofReturnLivenessBond(t *testing.T) { } var ( - producer = NewMinorityGuardianProofProducer(true) + producer = NewMinorityGuardianProofProducer(&SGXProofProducer{Dummy: true}, true) blockID = common.Big32 ) res, err := producer.RequestProof( diff --git a/prover/proof_producer/sgx_producer.go b/prover/proof_producer/sgx_producer.go index f306a8dfa..a4068b8fa 100644 --- a/prover/proof_producer/sgx_producer.go +++ b/prover/proof_producer/sgx_producer.go @@ -21,12 +21,18 @@ import ( "github.com/taikoxyz/taiko-client/internal/metrics" ) +const ( + ProofTypeSgx = "sgx" + ProofTypeCPU = "native" +) + // SGXProofProducer generates a SGX proof for the given block. type SGXProofProducer struct { RaikoHostEndpoint string // a proverd RPC endpoint L1Endpoint string // a L1 node RPC endpoint L1BeaconEndpoint string // a L1 beacon node RPC endpoint L2Endpoint string // a L2 execution engine's RPC endpoint + ProofType string // Proof type Dummy bool DummyProofProducer } @@ -161,7 +167,7 @@ func (s *SGXProofProducer) requestProof(opts *ProofRequestOptions) (*RaikoHostOu ID: common.Big1, Method: "proof", Params: []*SGXRequestProofBodyParam{{ - Type: "sgx", + Type: s.ProofType, Block: opts.BlockID, L2RPC: s.L2Endpoint, L1RPC: s.L1Endpoint,