Skip to content

Commit

Permalink
feat: add ChunkProof message (scroll-tech#688)
Browse files Browse the repository at this point in the history
Co-authored-by: HAOYUatHZ <[email protected]>
Co-authored-by: HAOYUatHZ <[email protected]>
  • Loading branch information
3 people authored Jul 30, 2023
1 parent 20e1344 commit df54d51
Show file tree
Hide file tree
Showing 18 changed files with 93 additions and 78 deletions.
2 changes: 1 addition & 1 deletion bridge/internal/controller/relayer/l2_relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) {

err = batchOrm.UpdateRollupStatus(context.Background(), batch.Hash, types.RollupCommitted)
assert.NoError(t, err)
proof := &message.AggProof{
proof := &message.BatchProof{
Proof: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
FinalPair: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
}
Expand Down
6 changes: 3 additions & 3 deletions bridge/internal/orm/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (o *Batch) GetBatchCount(ctx context.Context) (uint64, error) {
}

// GetVerifiedProofByHash retrieves the verified aggregate proof for a batch with the given hash.
func (o *Batch) GetVerifiedProofByHash(ctx context.Context, hash string) (*message.AggProof, error) {
func (o *Batch) GetVerifiedProofByHash(ctx context.Context, hash string) (*message.BatchProof, error) {
db := o.db.WithContext(ctx)
db = db.Model(&Batch{})
db = db.Select("proof")
Expand All @@ -119,7 +119,7 @@ func (o *Batch) GetVerifiedProofByHash(ctx context.Context, hash string) (*messa
return nil, fmt.Errorf("Batch.GetVerifiedProofByHash error: %w, batch hash: %v", err, hash)
}

var proof message.AggProof
var proof message.BatchProof
if err := json.Unmarshal(batch.Proof, &proof); err != nil {
return nil, fmt.Errorf("Batch.GetVerifiedProofByHash error: %w, batch hash: %v", err, hash)
}
Expand Down Expand Up @@ -392,7 +392,7 @@ func (o *Batch) UpdateFinalizeTxHashAndRollupStatus(ctx context.Context, hash st

// UpdateProofByHash updates the batch proof by hash.
// for unit test.
func (o *Batch) UpdateProofByHash(ctx context.Context, hash string, proof *message.AggProof, proofTimeSec uint64) error {
func (o *Batch) UpdateProofByHash(ctx context.Context, hash string, proof *message.BatchProof, proofTimeSec uint64) error {
proofBytes, err := json.Marshal(proof)
if err != nil {
return fmt.Errorf("Batch.UpdateProofByHash error: %w, batch hash: %v", err, hash)
Expand Down
2 changes: 1 addition & 1 deletion bridge/tests/rollup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
assert.Equal(t, types.RollupCommitted, statuses[0])

// add dummy proof
proof := &message.AggProof{
proof := &message.BatchProof{
Proof: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
FinalPair: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
}
Expand Down
32 changes: 22 additions & 10 deletions common/types/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,18 @@ type TaskMsg struct {
// For decentralization, basic provers will get block hashes from the coordinator. So that they can refer to the block hashes and fetch traces locally. Only applicable for basic provers.
BlockHashes []common.Hash `json:"block_hashes,omitempty"`
// Only applicable for aggregator provers.
SubProofs []*AggProof `json:"sub_proofs,omitempty"`
SubProofs []*ChunkProof `json:"sub_proofs,omitempty"`
}

// ProofDetail is the message received from provers that contains zk proof, the status of
// the proof generation succeeded, and an error message if proof generation failed.
type ProofDetail struct {
ID string `json:"id"`
Type ProofType `json:"type,omitempty"`
Status RespStatus `json:"status"`
Proof *AggProof `json:"proof"`
Error string `json:"error,omitempty"`
ID string `json:"id"`
Type ProofType `json:"type,omitempty"`
Status RespStatus `json:"status"`
ChunkProof *ChunkProof `json:"chunk_proof,omitempty"`
BatchProof *BatchProof `json:"batch_proof,omitempty"`
Error string `json:"error,omitempty"`
}

// Hash return proofMsg content hash.
Expand All @@ -231,18 +232,29 @@ func (z *ProofDetail) Hash() ([]byte, error) {
return hash[:], nil
}

// AggProof includes the proof and public input that are required to verification and rollup.
type AggProof struct {
// ChunkProof includes the proof info that are required for chunk verification and rollup.
type ChunkProof struct {
StorageTrace []byte `json:"storage_trace"`
Protocol []byte `json:"protocol"`
Proof []byte `json:"proof"`
Instance []byte `json:"instance"`
FinalPair []byte `json:"final_pair"`
Vk []byte `json:"vk"`
BlockCount uint `json:"block_count"`
}

// BatchProof includes the proof info that are required for batch verification and rollup.
type BatchProof struct {
Proof []byte `json:"proof"`
Instance []byte `json:"instance"`
FinalPair []byte `json:"final_pair"`
Vk []byte `json:"vk"`
BlockCount uint `json:"block_count"`
}

// SanityCheck checks whether an AggProof is in a legal format
// SanityCheck checks whether an BatchProof is in a legal format
// TODO: change to check Proof&Instance when upgrading to snark verifier v0.4
func (ap *AggProof) SanityCheck() error {
func (ap *BatchProof) SanityCheck() error {
if ap == nil {
return errors.New("agg_proof is nil")
}
Expand Down
8 changes: 4 additions & 4 deletions common/types/message/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestProofMessageSignVerifyPublicKey(t *testing.T) {
ID: "testID",
Type: ProofTypeChunk,
Status: StatusOk,
Proof: &AggProof{
ChunkProof: &ChunkProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Expand Down Expand Up @@ -95,7 +95,7 @@ func TestProofDetailHash(t *testing.T) {
ID: "testID",
Type: ProofTypeChunk,
Status: StatusOk,
Proof: &AggProof{
ChunkProof: &ChunkProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Expand All @@ -106,7 +106,7 @@ func TestProofDetailHash(t *testing.T) {
}
hash, err := proofDetail.Hash()
assert.NoError(t, err)
expectedHash := "8ad894c2047166a98b1a389b716b06b01dc1bd29e950e2687ffbcb3c328edda5"
expectedHash := "f7c02bb8b9ff58a5ba61bb76a8b1fb76a023df9da2982d073d20e67f5e72df47"
assert.Equal(t, expectedHash, hex.EncodeToString(hash))
}

Expand All @@ -130,7 +130,7 @@ func TestProofMsgPublicKey(t *testing.T) {
ID: "testID",
Type: ProofTypeChunk,
Status: StatusOk,
Proof: &AggProof{
ChunkProof: &ChunkProof{
Proof: []byte("testProof"),
Instance: []byte("testInstance"),
FinalPair: []byte("testFinalPair"),
Expand Down
2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v4.0.32"
var tag = "v4.0.33"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down
22 changes: 11 additions & 11 deletions coordinator/internal/controller/api/prover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ func TestProver_SubmitProof(t *testing.T) {
id := "provers_info_test"
tmpProof := &message.ProofMsg{
ProofDetail: &message.ProofDetail{
Type: message.ProofTypeChunk,
ID: id,
Status: message.StatusOk,
Proof: &message.AggProof{},
Type: message.ProofTypeChunk,
ID: id,
Status: message.StatusOk,
ChunkProof: &message.ChunkProof{},
},
}
assert.NoError(t, tmpProof.Sign(prvKey))
Expand Down Expand Up @@ -212,15 +212,15 @@ func TestProver_SubmitProof(t *testing.T) {
})

var chunkOrm *orm.Chunk
patchGuard.ApplyMethodFunc(chunkOrm, "UpdateProofByHash", func(context.Context, string, *message.AggProof, uint64, ...*gorm.DB) error {
patchGuard.ApplyMethodFunc(chunkOrm, "UpdateProofByHash", func(context.Context, string, *message.BatchProof, uint64, ...*gorm.DB) error {
return nil
})
patchGuard.ApplyMethodFunc(chunkOrm, "UpdateProvingStatus", func(ctx context.Context, hash string, status types.ProvingStatus, dbTX ...*gorm.DB) error {
return nil
})

var batchOrm *orm.Batch
patchGuard.ApplyMethodFunc(batchOrm, "UpdateProofByHash", func(ctx context.Context, hash string, proof *message.AggProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
patchGuard.ApplyMethodFunc(batchOrm, "UpdateProofByHash", func(ctx context.Context, hash string, proof *message.BatchProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
return nil
})
patchGuard.ApplyMethodFunc(batchOrm, "UpdateProvingStatus", func(ctx context.Context, hash string, status types.ProvingStatus, dbTX ...*gorm.DB) error {
Expand All @@ -233,9 +233,9 @@ func TestProver_SubmitProof(t *testing.T) {
})
tmpProof1 := &message.ProofMsg{
ProofDetail: &message.ProofDetail{
ID: "10001",
Status: message.StatusOk,
Proof: &message.AggProof{},
ID: "10001",
Status: message.StatusOk,
ChunkProof: &message.ChunkProof{},
},
}
privKey, err := crypto.GenerateKey()
Expand Down Expand Up @@ -284,14 +284,14 @@ func TestProver_SubmitProof(t *testing.T) {
var tmpVerifier *verifier.Verifier
convey.Convey("verifier proof failure", t, func() {
targetErr := errors.New("verify proof failure")
patchGuard.ApplyMethodFunc(tmpVerifier, "VerifyProof", func(proof *message.AggProof) (bool, error) {
patchGuard.ApplyMethodFunc(tmpVerifier, "VerifyProof", func(proof *message.BatchProof) (bool, error) {
return false, targetErr
})
err1 := proverController.SubmitProof(tmpProof)
assert.Nil(t, err1)
})

patchGuard.ApplyMethodFunc(tmpVerifier, "VerifyProof", func(proof *message.AggProof) (bool, error) {
patchGuard.ApplyMethodFunc(tmpVerifier, "VerifyProof", func(proof *message.BatchProof) (bool, error) {
return true, nil
})

Expand Down
2 changes: 1 addition & 1 deletion coordinator/internal/logic/collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (b *BaseCollector) checkAttemptsExceeded(hash string, taskType message.Proo
return true
}

func (b *BaseCollector) sendTask(proveType message.ProofType, hash string, blockHashes []common.Hash, subProofs []*message.AggProof) ([]*coordinatorType.ProverStatus, error) {
func (b *BaseCollector) sendTask(proveType message.ProofType, hash string, blockHashes []common.Hash, subProofs []*message.ChunkProof) ([]*coordinatorType.ProverStatus, error) {
sendMsg := &message.TaskMsg{
ID: hash,
Type: proveType,
Expand Down
7 changes: 4 additions & 3 deletions coordinator/internal/logic/proof/proof_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (m *ZKProofReceiver) HandleZkProof(ctx context.Context, proofMsg *message.P
switch proofMsg.Type {
case message.ProofTypeChunk:
storeProofErr = m.db.Transaction(func(tx *gorm.DB) error {
if dbErr := m.chunkOrm.UpdateProofByHash(ctx, proofMsg.ID, proofMsg.Proof, proofTimeSec, tx); dbErr != nil {
if dbErr := m.chunkOrm.UpdateProofByHash(ctx, proofMsg.ID, proofMsg.ChunkProof, proofTimeSec, tx); dbErr != nil {
return fmt.Errorf("failed to store chunk proof into db, err:%w", dbErr)
}
if dbErr := m.chunkOrm.UpdateProvingStatus(ctx, proofMsg.ID, types.ProvingTaskProved, tx); dbErr != nil {
Expand All @@ -105,7 +105,7 @@ func (m *ZKProofReceiver) HandleZkProof(ctx context.Context, proofMsg *message.P
})
case message.ProofTypeBatch:
storeProofErr = m.db.Transaction(func(tx *gorm.DB) error {
if dbErr := m.batchOrm.UpdateProofByHash(ctx, proofMsg.ID, proofMsg.Proof, proofTimeSec, tx); dbErr != nil {
if dbErr := m.batchOrm.UpdateProofByHash(ctx, proofMsg.ID, proofMsg.BatchProof, proofTimeSec, tx); dbErr != nil {
return fmt.Errorf("failed to store batch proof into db, error:%w", dbErr)
}
if dbErr := m.batchOrm.UpdateProvingStatus(ctx, proofMsg.ID, types.ProvingTaskProved, tx); dbErr != nil {
Expand All @@ -122,7 +122,8 @@ func (m *ZKProofReceiver) HandleZkProof(ctx context.Context, proofMsg *message.P

coordinatorProofsReceivedTotalCounter.Inc(1)

success, verifyErr := m.verifier.VerifyProof(proofMsg.Proof)
// TODO: add switch case for ChunkProof & BatchProof
success, verifyErr := m.verifier.VerifyProof(proofMsg.BatchProof)
if verifyErr != nil || !success {
if verifyErr != nil {
// TODO: this is only a temp workaround for testnet, we should return err in real cases
Expand Down
2 changes: 1 addition & 1 deletion coordinator/internal/logic/verifier/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func NewVerifier(_ *config.VerifierConfig) (*Verifier, error) {
}

// VerifyProof always return true
func (v *Verifier) VerifyProof(proof *message.AggProof) (bool, error) {
func (v *Verifier) VerifyProof(proof *message.BatchProof) (bool, error) {
if string(proof.Proof) == InvalidTestProof {
return false, nil
}
Expand Down
8 changes: 4 additions & 4 deletions coordinator/internal/logic/verifier/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
}

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

aggProofStr := C.CString(string(buf))
proofStr := C.CString(string(buf))
defer func() {
C.free(unsafe.Pointer(aggProofStr))
C.free(unsafe.Pointer(proofStr))
}()

log.Info("Start to verify proof ...")
verified := C.verify_agg_proof(aggProofStr)
verified := C.verify_agg_proof(proofStr)
return verified != 0, nil
}
6 changes: 3 additions & 3 deletions coordinator/internal/logic/verifier/verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ func TestFFI(t *testing.T) {
as.NoError(err)
byt, err := io.ReadAll(f)
as.NoError(err)
aggProof := &message.AggProof{}
as.NoError(json.Unmarshal(byt, aggProof))
proof := &message.BatchProof{}
as.NoError(json.Unmarshal(byt, proof))

ok, err := v.VerifyProof(aggProof)
ok, err := v.VerifyProof(proof)
as.NoError(err)
as.True(ok)
}
2 changes: 1 addition & 1 deletion coordinator/internal/orm/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func (o *Batch) UpdateProvingStatus(ctx context.Context, hash string, status typ
}

// UpdateProofByHash updates the batch proof by hash.
func (o *Batch) UpdateProofByHash(ctx context.Context, hash string, proof *message.AggProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
func (o *Batch) UpdateProofByHash(ctx context.Context, hash string, proof *message.BatchProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
db := o.db
if len(dbTX) > 0 && dbTX[0] != nil {
db = dbTX[0]
Expand Down
10 changes: 5 additions & 5 deletions coordinator/internal/orm/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ func (o *Chunk) GetUnassignedChunks(ctx context.Context, limit int) ([]*Chunk, e
}

// GetProofsByBatchHash retrieves the proofs associated with a specific batch hash.
// It returns a slice of decoded proofs (message.AggProof) obtained from the database.
// It returns a slice of decoded proofs (message.ChunkProof) obtained from the database.
// The returned proofs are sorted in ascending order by their associated chunk index.
func (o *Chunk) GetProofsByBatchHash(ctx context.Context, batchHash string) ([]*message.AggProof, error) {
func (o *Chunk) GetProofsByBatchHash(ctx context.Context, batchHash string) ([]*message.ChunkProof, error) {
db := o.db.WithContext(ctx)
db = db.Model(&Chunk{})
db = db.Where("batch_hash", batchHash)
Expand All @@ -100,9 +100,9 @@ func (o *Chunk) GetProofsByBatchHash(ctx context.Context, batchHash string) ([]*
return nil, fmt.Errorf("Chunk.GetProofsByBatchHash error: %w, batch hash: %v", err, batchHash)
}

var proofs []*message.AggProof
var proofs []*message.ChunkProof
for _, chunk := range chunks {
var proof message.AggProof
var proof message.ChunkProof
if err := json.Unmarshal(chunk.Proof, &proof); err != nil {
return nil, fmt.Errorf("Chunk.GetProofsByBatchHash error: %w, batch hash: %v, chunk hash: %v", err, batchHash, chunk.Hash)
}
Expand Down Expand Up @@ -287,7 +287,7 @@ func (o *Chunk) UpdateProvingStatus(ctx context.Context, hash string, status typ
}

// UpdateProofByHash updates the chunk proof by hash.
func (o *Chunk) UpdateProofByHash(ctx context.Context, hash string, proof *message.AggProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
func (o *Chunk) UpdateProofByHash(ctx context.Context, hash string, proof *message.ChunkProof, proofTimeSec uint64, dbTX ...*gorm.DB) error {
db := o.db
if len(dbTX) > 0 && dbTX[0] != nil {
db = dbTX[0]
Expand Down
12 changes: 7 additions & 5 deletions coordinator/test/mock_prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,18 @@ func (r *mockProver) loop(t *testing.T, client *client2.Client, proofTime time.D
}
proof := &message.ProofMsg{
ProofDetail: &message.ProofDetail{
ID: task.ID,
Type: r.proofType,
Status: message.StatusOk,
Proof: &message.AggProof{},
ID: task.ID,
Type: r.proofType,
Status: message.StatusOk,
ChunkProof: &message.ChunkProof{},
BatchProof: &message.BatchProof{},
},
}
if proofStatus == generatedFailed {
proof.Status = message.StatusProofError
} else if proofStatus == verifiedFailed {
proof.ProofDetail.Proof.Proof = []byte(verifier.InvalidTestProof)
proof.ProofDetail.ChunkProof.Proof = []byte(verifier.InvalidTestProof)
proof.ProofDetail.BatchProof.Proof = []byte(verifier.InvalidTestProof)
}
assert.NoError(t, proof.Sign(r.privKey))
assert.NoError(t, client.SubmitProof(context.Background(), proof))
Expand Down
4 changes: 2 additions & 2 deletions prover/core/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ func NewProverCore(cfg *config.ProverCoreConfig) (*ProverCore, error) {
}

// Prove call rust ffi to generate proof, if first failed, try again.
func (p *ProverCore) Prove(taskID string, traces []*types.BlockTrace) (*message.AggProof, error) {
func (p *ProverCore) Prove(taskID string, traces []*types.BlockTrace) (*message.ChunkProof, error) {
_empty := common.BigToHash(big.NewInt(0))
return &message.AggProof{
return &message.ChunkProof{
Proof: _empty[:],
Instance: _empty[:],
FinalPair: _empty[:],
Expand Down
4 changes: 2 additions & 2 deletions prover/core/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func NewProverCore(cfg *config.ProverCoreConfig) (*ProverCore, error) {
}

// Prove call rust ffi to generate proof, if first failed, try again.
func (p *ProverCore) Prove(taskID string, traces []*types.BlockTrace) (*message.AggProof, error) {
func (p *ProverCore) Prove(taskID string, traces []*types.BlockTrace) (*message.ChunkProof, error) {
var proofByt []byte
if p.cfg.ProofType == message.ProofTypeChunk {
tracesByt, err := json.Marshal(traces)
Expand All @@ -69,7 +69,7 @@ func (p *ProverCore) Prove(taskID string, traces []*types.BlockTrace) (*message.
log.Error("Dump proof failed", "task-id", taskID, "error", err)
}

zkProof := &message.AggProof{}
zkProof := &message.ChunkProof{}
return zkProof, json.Unmarshal(proofByt, zkProof)
}

Expand Down
Loading

0 comments on commit df54d51

Please sign in to comment.