Skip to content

Commit

Permalink
feat(coordinator): abstract proof types behind an interface
Browse files Browse the repository at this point in the history
  • Loading branch information
omerfirmak committed Feb 6, 2025
1 parent 8f10d0f commit 08b89b1
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 131 deletions.
108 changes: 77 additions & 31 deletions common/types/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@ import (
"github.com/scroll-tech/go-ethereum/common"
)

// RespStatus represents status code from prover to scroll
type RespStatus uint32

const (
// StatusOk means generate proof success
StatusOk RespStatus = iota
// StatusProofError means generate proof failed
StatusProofError
)

// ProofType represents the type of task.
type ProofType uint8

Expand Down Expand Up @@ -51,15 +41,15 @@ type ChunkTaskDetail struct {

// BatchTaskDetail is a type containing BatchTask detail.
type BatchTaskDetail struct {
ChunkInfos []*ChunkInfo `json:"chunk_infos"`
ChunkProofs []*ChunkProof `json:"chunk_proofs"`
BatchHeader interface{} `json:"batch_header"`
BlobBytes []byte `json:"blob_bytes"`
ChunkInfos []*ChunkInfo `json:"chunk_infos"`
ChunkProofs []ChunkProof `json:"chunk_proofs"`
BatchHeader interface{} `json:"batch_header"`
BlobBytes []byte `json:"blob_bytes"`
}

// BundleTaskDetail consists of all the information required to describe the task to generate a proof for a bundle of batches.
type BundleTaskDetail struct {
BatchProofs []*BatchProof `json:"batch_proofs"`
BatchProofs []BatchProof `json:"batch_proofs"`
}

// ChunkInfo is for calculating pi_hash for chunk
Expand All @@ -79,11 +69,24 @@ type SubCircuitRowUsage struct {
RowNumber uint64 `json:"row_number"`
}

// ChunkProof includes the proof info that are required for chunk verification and rollup.
type ChunkProof struct {
// ChunkProof
type ChunkProof interface {
Proof() []byte
}

// NewChunkProof creates a new ChunkProof instance.
func NewChunkProof(hardForkName string) ChunkProof {
switch hardForkName {
default:
return &Halo2ChunkProof{}
}
}

// Halo2ChunkProof includes the proof info that are required for chunk verification and rollup.
type Halo2ChunkProof struct {
StorageTrace []byte `json:"storage_trace,omitempty"`
Protocol []byte `json:"protocol"`
Proof []byte `json:"proof"`
RawProof []byte `json:"proof"`
Instances []byte `json:"instances"`
Vk []byte `json:"vk"`
// cross-reference between cooridinator computation and prover compution
Expand All @@ -92,29 +95,53 @@ type ChunkProof struct {
RowUsages []SubCircuitRowUsage `json:"row_usages,omitempty"`
}

// BatchProof includes the proof info that are required for batch verification and rollup.
type BatchProof struct {
// Proof returns the proof bytes of a ChunkProof
func (ap *Halo2ChunkProof) Proof() []byte {
return ap.RawProof
}

// BatchProof
type BatchProof interface {
SanityCheck() error
Proof() []byte
}

// NewBatchProof creates a new BatchProof instance.
func NewBatchProof(hardForkName string) BatchProof {
switch hardForkName {
default:
return &Halo2BatchProof{}
}
}

// Halo2BatchProof includes the proof info that are required for batch verification and rollup.
type Halo2BatchProof struct {
Protocol []byte `json:"protocol"`
Proof []byte `json:"proof"`
RawProof []byte `json:"proof"`
Instances []byte `json:"instances"`
Vk []byte `json:"vk"`
// cross-reference between cooridinator computation and prover compution
BatchHash common.Hash `json:"batch_hash"`
GitVersion string `json:"git_version,omitempty"`
}

// Proof returns the proof bytes of a BatchProof
func (ap *Halo2BatchProof) Proof() []byte {
return ap.RawProof
}

// SanityCheck checks whether a BatchProof is in a legal format
func (ap *BatchProof) SanityCheck() error {
func (ap *Halo2BatchProof) SanityCheck() error {
if ap == nil {
return errors.New("agg_proof is nil")
}

if len(ap.Proof) == 0 {
if len(ap.RawProof) == 0 {
return errors.New("proof not ready")
}

if len(ap.Proof)%32 != 0 {
return fmt.Errorf("proof buffer length must be a multiple of 32, got: %d", len(ap.Proof))
if len(ap.RawProof)%32 != 0 {
return fmt.Errorf("proof buffer length must be a multiple of 32, got: %d", len(ap.RawProof))
}

if len(ap.Instances) == 0 {
Expand All @@ -128,27 +155,46 @@ func (ap *BatchProof) SanityCheck() error {
return nil
}

// BundleProof
type BundleProof interface {
SanityCheck() error
Proof() []byte
}

// NewBundleProof creates a new BundleProof instance.
func NewBundleProof(hardForkName string) BundleProof {
switch hardForkName {
default:
return &Halo2BundleProof{}
}
}

// BundleProof includes the proof info that are required for verification of a bundle of batch proofs.
type BundleProof struct {
Proof []byte `json:"proof"`
type Halo2BundleProof struct {
RawProof []byte `json:"proof"`
Instances []byte `json:"instances"`
Vk []byte `json:"vk"`
// cross-reference between cooridinator computation and prover compution
GitVersion string `json:"git_version,omitempty"`
}

// Proof returns the proof bytes of a BundleProof
func (ap *Halo2BundleProof) Proof() []byte {
return ap.RawProof
}

// SanityCheck checks whether a BundleProof is in a legal format
func (ap *BundleProof) SanityCheck() error {
func (ap *Halo2BundleProof) SanityCheck() error {
if ap == nil {
return errors.New("agg_proof is nil")
}

if len(ap.Proof) == 0 {
if len(ap.RawProof) == 0 {
return errors.New("proof not ready")
}

if len(ap.Proof)%32 != 0 {
return fmt.Errorf("proof buffer length must be a multiple of 32, got: %d", len(ap.Proof))
if len(ap.RawProof)%32 != 0 {
return fmt.Errorf("proof buffer length must be a multiple of 32, got: %d", len(ap.RawProof))
}

if len(ap.Instances) == 0 {
Expand Down
6 changes: 3 additions & 3 deletions coordinator/cmd/tool/tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ func action(ctx *cli.Context) error {
return fmt.Errorf("failed to get batch proofs for bundle task id:%s, no batch found", taskID)
}

var batchProofs []*message.BatchProof
var batchProofs []message.BatchProof
for _, batch := range batches {
var proof message.BatchProof
var proof message.BatchProof // todo: NewBatchProof
if encodeErr := json.Unmarshal(batch.Proof, &proof); encodeErr != nil {
log.Error("failed to unmarshal batch proof")
return fmt.Errorf("failed to unmarshal proof: %w, bundle hash: %v, batch hash: %v", encodeErr, taskID, batch.Hash)
}
batchProofs = append(batchProofs, &proof)
batchProofs = append(batchProofs, proof)
}

taskDetail := message.BundleTaskDetail{
Expand Down
14 changes: 8 additions & 6 deletions coordinator/internal/logic/provertask/batch_prover_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,14 @@ func (bp *BatchProverTask) formatProverTask(ctx context.Context, task *orm.Prove
return nil, fmt.Errorf("no chunk found for batch task id:%s", task.TaskID)
}

var chunkProofs []*message.ChunkProof
var chunkProofs []message.ChunkProof
var chunkInfos []*message.ChunkInfo
for _, chunk := range chunks {
var proof message.ChunkProof
proof := message.NewChunkProof(hardForkName)
if encodeErr := json.Unmarshal(chunk.Proof, &proof); encodeErr != nil {
return nil, fmt.Errorf("Chunk.GetProofsByBatchHash unmarshal proof error: %w, batch hash: %v, chunk hash: %v", encodeErr, task.TaskID, chunk.Hash)
}
chunkProofs = append(chunkProofs, &proof)
chunkProofs = append(chunkProofs, proof)

chunkInfo := message.ChunkInfo{
ChainID: bp.cfg.L2.ChainID,
Expand All @@ -232,8 +232,10 @@ func (bp *BatchProverTask) formatProverTask(ctx context.Context, task *orm.Prove
DataHash: common.HexToHash(chunk.Hash),
IsPadding: false,
}
if proof.ChunkInfo != nil {
chunkInfo.TxBytes = proof.ChunkInfo.TxBytes
if haloProot, ok := proof.(*message.Halo2ChunkProof); ok {
if haloProot.ChunkInfo != nil {
chunkInfo.TxBytes = haloProot.ChunkInfo.TxBytes
}
}
chunkInfos = append(chunkInfos, &chunkInfo)
}
Expand Down Expand Up @@ -264,7 +266,7 @@ func (bp *BatchProverTask) recoverActiveAttempts(ctx *gin.Context, batchTask *or
}
}

func (bp *BatchProverTask) getBatchTaskDetail(dbBatch *orm.Batch, chunkInfos []*message.ChunkInfo, chunkProofs []*message.ChunkProof) (*message.BatchTaskDetail, error) {
func (bp *BatchProverTask) getBatchTaskDetail(dbBatch *orm.Batch, chunkInfos []*message.ChunkInfo, chunkProofs []message.ChunkProof) (*message.BatchTaskDetail, error) {
taskDetail := &message.BatchTaskDetail{
ChunkInfos: chunkInfos,
ChunkProofs: chunkProofs,
Expand Down
6 changes: 3 additions & 3 deletions coordinator/internal/logic/provertask/bundle_prover_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ func (bp *BundleProverTask) formatProverTask(ctx context.Context, task *orm.Prov
return nil, fmt.Errorf("failed to get batch proofs for bundle task id:%s, no batch found", task.TaskID)
}

var batchProofs []*message.BatchProof
var batchProofs []message.BatchProof
for _, batch := range batches {
var proof message.BatchProof
proof := message.NewBatchProof(hardForkName)
if encodeErr := json.Unmarshal(batch.Proof, &proof); encodeErr != nil {
return nil, fmt.Errorf("failed to unmarshal proof: %w, bundle hash: %v, batch hash: %v", encodeErr, task.TaskID, batch.Hash)
}
batchProofs = append(batchProofs, &proof)
batchProofs = append(batchProofs, proof)
}

taskDetail := message.BundleTaskDetail{
Expand Down
14 changes: 7 additions & 7 deletions coordinator/internal/logic/submitproof/proof_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,23 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor

switch message.ProofType(proofParameter.TaskType) {
case message.ProofTypeChunk:
var chunkProof message.ChunkProof
chunkProof := message.NewChunkProof(hardForkName)
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &chunkProof); unmarshalErr != nil {
return unmarshalErr
}
success, verifyErr = m.verifier.VerifyChunkProof(&chunkProof, hardForkName)
success, verifyErr = m.verifier.VerifyChunkProof(chunkProof, hardForkName)
case message.ProofTypeBatch:
var batchProof message.BatchProof
batchProof := message.NewBatchProof(hardForkName)
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &batchProof); unmarshalErr != nil {
return unmarshalErr
}
success, verifyErr = m.verifier.VerifyBatchProof(&batchProof, hardForkName)
success, verifyErr = m.verifier.VerifyBatchProof(batchProof, hardForkName)
case message.ProofTypeBundle:
var bundleProof message.BundleProof
bundleProof := message.NewBundleProof(hardForkName)
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &bundleProof); unmarshalErr != nil {
return unmarshalErr
}
success, verifyErr = m.verifier.VerifyBundleProof(&bundleProof, hardForkName)
success, verifyErr = m.verifier.VerifyBundleProof(bundleProof, hardForkName)
}

if verifyErr != nil || !success {
Expand Down Expand Up @@ -265,7 +265,7 @@ func (m *ProofReceiverLogic) validator(ctx context.Context, proverTask *orm.Prov
proofTime := time.Since(proverTask.CreatedAt)
proofTimeSec := uint64(proofTime.Seconds())

if proofParameter.Status != int(message.StatusOk) {
if proofParameter.Status != int(coordinatorType.StatusOk) {
// Temporarily replace "panic" with "pa-nic" to prevent triggering the alert based on logs.
failureMsg := strings.Replace(proofParameter.FailureMsg, "panic", "pa-nic", -1)

Expand Down
12 changes: 6 additions & 6 deletions coordinator/internal/logic/verifier/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
}

// VerifyChunkProof return a mock verification result for a ChunkProof.
func (v *Verifier) VerifyChunkProof(proof *message.ChunkProof, forkName string) (bool, error) {
if string(proof.Proof) == InvalidTestProof {
func (v *Verifier) VerifyChunkProof(proof message.ChunkProof, forkName string) (bool, error) {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
}

// VerifyBatchProof return a mock verification result for a BatchProof.
func (v *Verifier) VerifyBatchProof(proof *message.BatchProof, forkName string) (bool, error) {
if string(proof.Proof) == InvalidTestProof {
func (v *Verifier) VerifyBatchProof(proof message.BatchProof, forkName string) (bool, error) {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
}

// VerifyBundleProof return a mock verification result for a BundleProof.
func (v *Verifier) VerifyBundleProof(proof *message.BundleProof, forkName string) (bool, error) {
if string(proof.Proof) == InvalidTestProof {
func (v *Verifier) VerifyBundleProof(proof message.BundleProof, forkName string) (bool, error) {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
Expand Down
12 changes: 6 additions & 6 deletions coordinator/internal/logic/verifier/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
}

// VerifyBatchProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
func (v *Verifier) VerifyBatchProof(proof *message.BatchProof, forkName string) (bool, error) {
func (v *Verifier) VerifyBatchProof(proof message.BatchProof, forkName string) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, batch verifier disabled")
if string(proof.Proof) == InvalidTestProof {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
Expand All @@ -137,10 +137,10 @@ func (v *Verifier) VerifyBatchProof(proof *message.BatchProof, forkName string)
}

// VerifyChunkProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
func (v *Verifier) VerifyChunkProof(proof *message.ChunkProof, forkName string) (bool, error) {
func (v *Verifier) VerifyChunkProof(proof message.ChunkProof, forkName string) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, verifier disabled")
if string(proof.Proof) == InvalidTestProof {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
Expand All @@ -164,10 +164,10 @@ func (v *Verifier) VerifyChunkProof(proof *message.ChunkProof, forkName string)
}

// VerifyBundleProof Verify a ZkProof for a bundle of batches, by marshaling it and verifying it via the EVM verifier.
func (v *Verifier) VerifyBundleProof(proof *message.BundleProof, forkName string) (bool, error) {
func (v *Verifier) VerifyBundleProof(proof message.BundleProof, forkName string) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, verifier disabled")
if string(proof.Proof) == InvalidTestProof {
if string(proof.Proof()) == InvalidTestProof {
return false, nil
}
return true, nil
Expand Down
Loading

0 comments on commit 08b89b1

Please sign in to comment.