Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(taiko-client): introduce zk #17831

Merged
merged 57 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
1b68a41
feat(protocol): temporary change the conf in devnet
YoGhurt111 Jul 15, 2024
5487962
feat(protocol): introduce `RiscZeroVerifier`
YoGhurt111 Jul 15, 2024
3f2a880
feat(taiko-client): introduce zk proof
YoGhurt111 Jul 17, 2024
8f26e21
feat: add risc0 receipt verifier and connect to tier verifier
smtmfft Jul 17, 2024
5ba8fe7
trigger cicd to push image
YoGhurt111 Jul 18, 2024
6e1fd33
use risc0 origin interface definition
YoGhurt111 Jul 18, 2024
d7402d0
fix
YoGhurt111 Jul 18, 2024
0a4d208
keep nonce order
YoGhurt111 Jul 18, 2024
f893da3
fix
YoGhurt111 Jul 22, 2024
2ec881c
fix
YoGhurt111 Jul 22, 2024
dc0dec5
Revert "feat(protocol): temporary change the conf in devnet"
YoGhurt111 Jul 22, 2024
526214c
fix
YoGhurt111 Jul 22, 2024
e0041d3
revert to main
YoGhurt111 Jul 22, 2024
a535269
fix
YoGhurt111 Jul 22, 2024
ac4fec2
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 23, 2024
24d9789
fix
YoGhurt111 Jul 23, 2024
b6d393c
fix path
YoGhurt111 Jul 23, 2024
96481f7
fix lint
YoGhurt111 Jul 23, 2024
175fb7b
fix typo config
YoGhurt111 Jul 23, 2024
2ff1f41
fix
YoGhurt111 Jul 23, 2024
48e0bd7
add type ignore
YoGhurt111 Jul 23, 2024
0ee427a
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 25, 2024
eb3be2b
fix
YoGhurt111 Jul 26, 2024
3b37afb
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 26, 2024
e1dc8cd
fix
YoGhurt111 Jul 26, 2024
e9bfc1f
Merge branch 'main' into feature/introduce-zk2
mask-pp Jul 27, 2024
49befe4
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 29, 2024
6208b85
update risc0 test
smtmfft Jul 29, 2024
35cb4c8
forge fmt & update contract layout table
smtmfft Jul 29, 2024
ea3ebee
match raiko proof format
smtmfft Jul 29, 2024
2ad8dbc
Merge branch 'feature/introduce-zk2' of https://github.com/taikoxyz/t…
smtmfft Jul 29, 2024
6bfe52c
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 29, 2024
3cd08eb
build image
YoGhurt111 Jul 29, 2024
cab6d56
build image
YoGhurt111 Jul 29, 2024
87c7535
random tier
YoGhurt111 Jul 29, 2024
6f6b006
forge fmt & update contract layout table
YoGhurt111 Jul 29, 2024
faec5d0
fix
YoGhurt111 Jul 29, 2024
fc94909
Merge branch 'feature/introduce-zk2' of github.com:taikoxyz/taiko-mon…
YoGhurt111 Jul 29, 2024
b062b38
fix
YoGhurt111 Jul 30, 2024
5073569
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Jul 30, 2024
73101e6
Revert "Merge branch 'main' into feature/introduce-zk2"
YoGhurt111 Jul 30, 2024
4b63331
build
YoGhurt111 Jul 30, 2024
ec04f44
change timeout to 90 mins
YoGhurt111 Aug 1, 2024
5b52d35
Update .github/workflows/taiko-client--docker.yml
YoGhurt111 Aug 2, 2024
816e627
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Aug 2, 2024
c404464
Reapply "Merge branch 'main' into feature/introduce-zk2"
YoGhurt111 Aug 2, 2024
7362164
fix
YoGhurt111 Aug 2, 2024
7c8510e
Update calldata.go
YoGhurt111 Aug 2, 2024
b070fc7
Update TaikoL1.sol
YoGhurt111 Aug 2, 2024
39dfd03
Merge branch 'main' into feature/introduce-zk2
YoGhurt111 Aug 5, 2024
4646064
Merge branch 'feature/zk-protocol' into feature/introduce-zk2
YoGhurt111 Aug 5, 2024
e215629
Merge branch 'feature/zk-protocol' into feature/introduce-zk2
YoGhurt111 Aug 5, 2024
2dafb0e
fix
YoGhurt111 Aug 5, 2024
1b4a25e
fix based on comment
YoGhurt111 Aug 5, 2024
f2083b2
fix based on comment
YoGhurt111 Aug 5, 2024
df9e10e
fix based on comment
YoGhurt111 Aug 5, 2024
b5bea93
Merge branch 'feature/zk-protocol' into feature/introduce-zk2
YoGhurt111 Aug 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/taiko-client/prover/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ func (p *Prover) initProofSubmitters(
Dummy: p.cfg.Dummy,
RaikoRequestTimeout: p.cfg.RaikoRequestTimeout,
}
case encoding.TierSgxAndZkVMID:
producer = &proofProducer.SgxAndZKvmProofProducer{
ZKProofType: proofProducer.ZKProofTypeR0,
SGX: proofProducer.SGXProofProducer{
RaikoHostEndpoint: p.cfg.RaikoHostEndpoint,
JWT: p.cfg.RaikoJWT,
ProofType: proofProducer.ProofTypeSgx,
Dummy: p.cfg.Dummy,
RaikoRequestTimeout: p.cfg.RaikoRequestTimeout,
},
}
case encoding.TierGuardianMinorityID:
producer = proofProducer.NewGuardianProofProducer(encoding.TierGuardianMinorityID, p.cfg.EnableLivenessBondProof)
case encoding.TierGuardianMajorityID:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ func (g *GuardianProofProducer) RequestProof(
return g.DummyProofProducer.RequestProof(opts, blockID, meta, header, g.Tier())
}

func (g *GuardianProofProducer) RequestCancel(
_ context.Context,
_ *ProofRequestOptions,
) error {
return nil
}

// Tier implements the ProofProducer interface.
func (g *GuardianProofProducer) Tier() uint16 {
return g.tier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ func (o *OptimisticProofProducer) RequestProof(
return o.DummyProofProducer.RequestProof(opts, blockID, meta, header, o.Tier())
}

func (o *OptimisticProofProducer) RequestCancel(
_ context.Context,
_ *ProofRequestOptions,
) error {
return nil
}

// Tier implements the ProofProducer interface.
func (o *OptimisticProofProducer) Tier() uint16 {
return encoding.TierOptimisticID
Expand Down
4 changes: 4 additions & 0 deletions packages/taiko-client/prover/proof_producer/proof_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,9 @@ type ProofProducer interface {
meta metadata.TaikoBlockMetaData,
header *types.Header,
) (*ProofWithHeader, error)
RequestCancel(
ctx context.Context,
opts *ProofRequestOptions,
) error
Tier() uint16
}
247 changes: 247 additions & 0 deletions packages/taiko-client/prover/proof_producer/sgx_and_zkvm_producer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
package producer

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"math/big"
"net/http"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"

"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/encoding"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/metadata"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/internal/metrics"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/rpc"
)

const (
ZKProofTypeR0 = "risc0"
ZKProofTypeSP1 = "sp1"
)

var ErrProofInProgress = errors.New("work_in_progress")

// RaikoRequestProofBodyResponseV2 represents the JSON body of the response of the proof requests.
type RaikoRequestProofBodyResponseV2 struct {
Data *RaikoProofDataV2 `json:"data"`
ErrorMessage string `json:"message"`
}

type RaikoProofDataV2 struct {
Proof *ProofDataV2 `json:"proof"` //nolint:revive,stylecheck
Status string `json:"status"`
}

type ProofDataV2 struct {
KzgProof string `json:"kzg_proof"`
Proof string `json:"proof"`
Quote string `json:"quote"`
}

// SgxAndZKvmProofProducer generates a ZK proof for the given block.
type SgxAndZKvmProofProducer struct {
ZKProofType string // ZK Proof type
SGX SGXProofProducer
}

// RequestProof implements the ProofProducer interface.
func (s *SgxAndZKvmProofProducer) RequestProof(
ctx context.Context,
opts *ProofRequestOptions,
blockID *big.Int,
meta metadata.TaikoBlockMetaData,
header *types.Header,
) (*ProofWithHeader, error) {
log.Info(
"Request sgx and zk proof from raiko-host service",
"blockID", blockID,
"coinbase", meta.GetCoinbase(),
"height", header.Number,
"hash", header.Hash(),
)

if s.SGX.Dummy {
return s.SGX.DummyProofProducer.RequestProof(opts, blockID, meta, header, s.Tier())
}

proof, err := s.callProverDaemon(ctx, opts)
if err != nil {
return nil, err
}

metrics.ProverSgxProofGeneratedCounter.Add(1)

return &ProofWithHeader{
BlockID: blockID,
Header: header,
Meta: meta,
Proof: proof,
Opts: opts,
Tier: s.Tier(),
}, nil
}

func (s *SgxAndZKvmProofProducer) RequestCancel(
ctx context.Context,
opts *ProofRequestOptions,
) error {
return s.requestCancel(ctx, opts)
}

// callProverDaemon keeps polling the proverd service to get the requested proof.
func (s *SgxAndZKvmProofProducer) callProverDaemon(ctx context.Context, opts *ProofRequestOptions) ([]byte, error) {
var (
proof []byte
start = time.Now()
)

zkCtx, zkCancel := rpc.CtxWithTimeoutOrDefault(ctx, s.SGX.RaikoRequestTimeout)
defer zkCancel()

output, err := s.requestProof(zkCtx, opts)
if err != nil {
log.Error("Failed to request proof", "height", opts.BlockID, "error", err, "endpoint", s.SGX.RaikoHostEndpoint)
return nil, err
}

if output.Data.Status == ErrProofInProgress.Error() {
return nil, ErrProofInProgress
}

log.Debug("Proof generation output", "output", output)

proof = common.Hex2Bytes(output.Data.Proof.Proof[2:])
log.Info(
"Proof generated",
"height", opts.BlockID,
"time", time.Since(start),
"producer", "SgxAndZKvmProofProducer",
)

return proof, nil
}

// requestProof sends a RPC request to proverd to try to get the requested proof.
func (s *SgxAndZKvmProofProducer) requestProof(
ctx context.Context,
opts *ProofRequestOptions,
) (*RaikoRequestProofBodyResponseV2, error) {
reqBody := RaikoRequestProofBody{
Type: s.ZKProofType,
Block: opts.BlockID,
Prover: opts.ProverAddress.Hex()[2:],
Graffiti: opts.Graffiti,
RISC0: &RISC0RequestProofBodyParam{
Bonsai: true,
Snark: true,
Profile: false,
ExecutionPo2: big.NewInt(20),
},
}

client := &http.Client{}

jsonValue, err := json.Marshal(reqBody)
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, "POST", s.SGX.RaikoHostEndpoint+"/v2/proof", bytes.NewBuffer(jsonValue))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
if len(s.SGX.JWT) > 0 {
req.Header.Set("Authorization", "Bearer "+base64.StdEncoding.EncodeToString([]byte(s.SGX.JWT)))
}

res, err := client.Do(req)
if err != nil {
return nil, err
}

defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to request proof, id: %d, statusCode: %d", opts.BlockID, res.StatusCode)
}

resBytes, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

var output RaikoRequestProofBodyResponseV2
if err := json.Unmarshal(resBytes, &output); err != nil {
return nil, err
}

if len(output.ErrorMessage) > 0 {
return nil, fmt.Errorf("failed to get proof, msg: %s", output.ErrorMessage)
}

return &output, nil
}

func (s *SgxAndZKvmProofProducer) requestCancel(
ctx context.Context,
opts *ProofRequestOptions,
) error {
reqBody := RaikoRequestProofBody{
Type: s.ZKProofType,
Block: opts.BlockID,
Prover: opts.ProverAddress.Hex()[2:],
Graffiti: opts.Graffiti,
RISC0: &RISC0RequestProofBodyParam{
Bonsai: true,
Snark: true,
Profile: false,
ExecutionPo2: big.NewInt(20),
},
}

client := &http.Client{}

jsonValue, err := json.Marshal(reqBody)
if err != nil {
return err
}

req, err := http.NewRequestWithContext(
ctx,
"POST",
s.SGX.RaikoHostEndpoint+"/v2/proof/cancel",
bytes.NewBuffer(jsonValue),
)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
if len(s.SGX.JWT) > 0 {
req.Header.Set("Authorization", "Bearer "+base64.StdEncoding.EncodeToString([]byte(s.SGX.JWT)))
}

res, err := client.Do(req)
if err != nil {
return err
}

defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return fmt.Errorf("failed to cancel requesting proof, statusCode: %d", res.StatusCode)
}

return nil
}

// Tier implements the ProofProducer interface.
func (s *SgxAndZKvmProofProducer) Tier() uint16 {
return encoding.TierSgxAndZkVMID
}
24 changes: 16 additions & 8 deletions packages/taiko-client/prover/proof_producer/sgx_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ type SGXProofProducer struct {

// RaikoRequestProofBody represents the JSON body for requesting the proof.
type RaikoRequestProofBody struct {
Block *big.Int `json:"block_number"`
Prover string `json:"prover"`
Graffiti string `json:"graffiti"`
Type string `json:"proof_type"`
SGX *SGXRequestProofBodyParam `json:"sgx"`
RISC0 RISC0RequestProofBodyParam `json:"risc0"`
Block *big.Int `json:"block_number"`
Prover string `json:"prover"`
Graffiti string `json:"graffiti"`
Type string `json:"proof_type"`
SGX *SGXRequestProofBodyParam `json:"sgx"`
RISC0 *RISC0RequestProofBodyParam `json:"risc0"`
}

// SGXRequestProofBodyParam represents the JSON body of RaikoRequestProofBody's `sgx` field.
Expand All @@ -68,7 +68,8 @@ type RaikoRequestProofBodyResponse struct {
}

type RaikoProofData struct {
Proof string `json:"proof"` //nolint:revive,stylecheck
Proof string `json:"proof"` //nolint:revive,stylecheck
Status string `json:"status"`
}

// RequestProof implements the ProofProducer interface.
Expand All @@ -80,7 +81,7 @@ func (s *SGXProofProducer) RequestProof(
header *types.Header,
) (*ProofWithHeader, error) {
log.Info(
"Request proof from raiko-host service",
"Request sgx proof from raiko-host service",
"blockID", blockID,
"coinbase", meta.GetCoinbase(),
"height", header.Number,
Expand Down Expand Up @@ -108,6 +109,13 @@ func (s *SGXProofProducer) RequestProof(
}, nil
}

func (s *SGXProofProducer) RequestCancel(
_ context.Context,
_ *ProofRequestOptions,
) error {
return nil
}

// callProverDaemon keeps polling the proverd service to get the requested proof.
func (s *SGXProofProducer) callProverDaemon(ctx context.Context, opts *ProofRequestOptions) ([]byte, error) {
var (
Expand Down
11 changes: 11 additions & 0 deletions packages/taiko-client/prover/proof_submitter/proof_submitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
_ Submitter = (*ProofSubmitter)(nil)
submissionDelayRandomBumpRange float64 = 20
proofPollingInterval = 10 * time.Second
ProofTimeout = 90 * time.Minute
)

// ProofSubmitter is responsible requesting proofs for the given L2
Expand Down Expand Up @@ -128,6 +129,8 @@ func (s *ProofSubmitter) RequestProof(ctx context.Context, meta metadata.TaikoBl
opts.ProverAddress = s.proverSetAddress
}

startTime := time.Now()

// Send the generated proof.
if err := backoff.Retry(
func() error {
Expand Down Expand Up @@ -158,6 +161,14 @@ func (s *ProofSubmitter) RequestProof(ctx context.Context, meta metadata.TaikoBl
header,
)
if err != nil {
// If request proof has timed out in retry, let's cancel the proof generating and skip
if errors.Is(err, proofProducer.ErrProofInProgress) && time.Since(startTime) >= ProofTimeout {
log.Error("Request proof has timed out, start to cancel", "blockID", opts.BlockID)
if cancelErr := s.proofProducer.RequestCancel(ctx, opts); cancelErr != nil {
log.Error("Failed to request cancellation of proof", "err", cancelErr)
}
return nil
}
return fmt.Errorf("failed to request proof (id: %d): %w", meta.GetBlockID(), err)
}
s.resultCh <- result
Expand Down
Loading