Skip to content

Commit 9c8782f

Browse files
committed
fix coordinator generate validium batch
1 parent b63e247 commit 9c8782f

File tree

6 files changed

+204
-39
lines changed

6 files changed

+204
-39
lines changed

coordinator/internal/logic/provertask/batch_prover_task.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -316,32 +316,42 @@ func (bp *BatchProverTask) getBatchTaskDetail(dbBatch *orm.Batch, chunkInfos []*
316316
ForkName: hardForkName,
317317
}
318318

319-
dbBatchCodecVersion := encoding.CodecVersion(dbBatch.CodecVersion)
320-
switch dbBatchCodecVersion {
321-
case encoding.CodecV3, encoding.CodecV4, encoding.CodecV6, encoding.CodecV7, encoding.CodecV8:
322-
default:
323-
return taskDetail, nil
324-
}
325-
326-
codec, err := encoding.CodecFromVersion(encoding.CodecVersion(dbBatch.CodecVersion))
327-
if err != nil {
328-
return nil, fmt.Errorf("failed to get codec from version %d, err: %w", dbBatch.CodecVersion, err)
329-
}
330-
331-
batchHeader, decodeErr := codec.NewDABatchFromBytes(dbBatch.BatchHeader)
332-
if decodeErr != nil {
333-
return nil, fmt.Errorf("failed to decode batch header version %d: %w", dbBatch.CodecVersion, decodeErr)
334-
}
335-
taskDetail.BatchHeader = batchHeader
336319
taskDetail.BlobBytes = dbBatch.BlobBytes
337320
if !bp.validiumMode() {
321+
dbBatchCodecVersion := encoding.CodecVersion(dbBatch.CodecVersion)
322+
switch dbBatchCodecVersion {
323+
case encoding.CodecV3, encoding.CodecV4, encoding.CodecV6, encoding.CodecV7, encoding.CodecV8:
324+
default:
325+
return taskDetail, nil
326+
}
327+
328+
codec, err := encoding.CodecFromVersion(encoding.CodecVersion(dbBatch.CodecVersion))
329+
if err != nil {
330+
return nil, fmt.Errorf("failed to get codec from version %d, err: %w", dbBatch.CodecVersion, err)
331+
}
332+
333+
batchHeader, decodeErr := codec.NewDABatchFromBytes(dbBatch.BatchHeader)
334+
if decodeErr != nil {
335+
return nil, fmt.Errorf("failed to decode batch header version %d: %w", dbBatch.CodecVersion, decodeErr)
336+
}
337+
taskDetail.BatchHeader = batchHeader
338+
338339
taskDetail.ChallengeDigest = common.HexToHash(dbBatch.ChallengeDigest)
339340
// Memory layout of `BlobDataProof`: used in Codec.BlobDataProofForPointEvaluation()
340341
// | z | y | kzg_commitment | kzg_proof |
341342
// |---------|---------|----------------|-----------|
342343
// | bytes32 | bytes32 | bytes48 | bytes48 |
343344
taskDetail.KzgProof = &message.Byte48{Big: hexutil.Big(*new(big.Int).SetBytes(dbBatch.BlobDataProof[112:160]))}
344345
taskDetail.KzgCommitment = &message.Byte48{Big: hexutil.Big(*new(big.Int).SetBytes(dbBatch.BlobDataProof[64:112]))}
346+
} else {
347+
log.Debug("Apply validium mode for batch proving task")
348+
codec := cutils.FromVersion(version)
349+
batchHeader, decodeErr := codec.DABatchForTaskFromBytes(dbBatch.BatchHeader)
350+
if decodeErr != nil {
351+
return nil, fmt.Errorf("failed to decode batch header version %d: %w", dbBatch.CodecVersion, decodeErr)
352+
}
353+
batchHeader.SetHash(common.HexToHash(dbBatch.Hash))
354+
taskDetail.BatchHeader = batchHeader
345355
}
346356

347357
return taskDetail, nil

coordinator/internal/logic/provertask/prover_task.go

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"scroll-tech/coordinator/internal/logic/libzkp"
2121
"scroll-tech/coordinator/internal/orm"
2222
coordinatorType "scroll-tech/coordinator/internal/types"
23+
"scroll-tech/coordinator/internal/utils"
2324
)
2425

2526
var (
@@ -66,29 +67,13 @@ type proverTaskContext struct {
6667
hasAssignedTask *orm.ProverTask
6768
}
6869

69-
// version get the version for the chain instance
70-
//
71-
// TODO: This is not foolproof and does not cover all scenarios.
7270
func (b *BaseProverTask) version(hardForkName string) (uint8, error) {
73-
var domain, stfVersion uint8
74-
75-
if b.cfg.L2.ValidiumMode {
76-
domain = 1
77-
stfVersion = 1
78-
} else {
79-
domain = 0
80-
stfVersion = 8
81-
if hardForkName != "feynman" {
82-
return 0, errors.New("expected hardfork=feynman")
83-
}
84-
}
85-
86-
return (domain << 6) + stfVersion, nil
71+
return utils.Version(hardForkName, b.validiumMode())
8772
}
8873

8974
// validiumMode induce different behavior in task generation:
9075
// + skip the point_evaluation part in batch task
91-
// +
76+
// + encode batch header with codec in utils instead of da-codec
9277
func (b *BaseProverTask) validiumMode() bool {
9378
return b.cfg.L2.ValidiumMode
9479
}

coordinator/internal/logic/submitproof/proof_receiver.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor
207207
return errors.New("no vk specified match current hard fork, check your config")
208208
}
209209

210+
log.Info("metadata", "string", string(proverTask.Metadata))
210211
proofParameter.Proof = libzkp.GenerateWrappedProof(proofParameter.Proof, string(proverTask.Metadata), expected_vk)
211212
if proofParameter.Proof == "" {
212213
return errors.New("can not re-wrapping proof, see coordinator log for reason")
@@ -219,6 +220,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor
219220
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &chunkProof); unmarshalErr != nil {
220221
return unmarshalErr
221222
}
223+
log.Info("parse chunkproof", "key", chunkProof.MetaData.ChunkInfo.EncryptionKey)
222224
success, verifyErr = m.verifier.VerifyChunkProof(chunkProof, hardForkName)
223225
if stat := chunkProof.VmProof.Stat; stat != nil {
224226
if g, _ := m.proverSpeed.GetMetricWithLabelValues("chunk", "exec"); g != nil && stat.ExecutionTimeMills > 0 {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package utils
2+
3+
import (
4+
"encoding/binary"
5+
"fmt"
6+
7+
"github.com/scroll-tech/go-ethereum/common"
8+
)
9+
10+
type CodecVersion uint8
11+
12+
const (
13+
daBatchValidiumEncodedLength = 137
14+
)
15+
16+
type DABatch interface {
17+
SetHash(common.Hash)
18+
}
19+
20+
type daBatchValidiumV1 struct {
21+
Version CodecVersion `json:"version"`
22+
BatchIndex uint64 `json:"batch_index"`
23+
BlobVersionedHash common.Hash `json:"blob_versioned_hash"`
24+
ParentBatchHash common.Hash `json:"parent_batch_hash"`
25+
PostStateRoot common.Hash `json:"post_state_root"`
26+
WithDrawRoot common.Hash `json:"withdraw_root"`
27+
Commitment common.Hash `json:"commitment"`
28+
}
29+
30+
type daBatchValidium struct {
31+
V1 *daBatchValidiumV1 `json:"V1,omitempty"`
32+
BatchHash common.Hash `json:"batch_hash"`
33+
}
34+
35+
func (da *daBatchValidium) SetHash(h common.Hash) {
36+
da.BatchHash = h
37+
}
38+
39+
func FromVersion(v uint8) CodecVersion {
40+
return CodecVersion(v & STFVersionMask)
41+
}
42+
43+
func (c CodecVersion) DABatchForTaskFromBytes(b []byte) (DABatch, error) {
44+
switch c {
45+
case 1:
46+
if v1, err := decodeDABatchV1(b); err == nil {
47+
return &daBatchValidium{
48+
V1: v1,
49+
}, nil
50+
} else {
51+
return nil, err
52+
}
53+
default:
54+
return nil, fmt.Errorf("unknown codec type %d", c)
55+
}
56+
}
57+
58+
func decodeDABatchV1(data []byte) (*daBatchValidiumV1, error) {
59+
if len(data) != daBatchValidiumEncodedLength {
60+
return nil, fmt.Errorf("invalid data length for DABatchV7, expected %d bytes but got %d", daBatchValidiumEncodedLength, len(data))
61+
}
62+
63+
const (
64+
versionSize = 1
65+
indexSize = 8
66+
hashSize = 32
67+
)
68+
69+
// Offsets (same as encodeBatchHeaderValidium)
70+
versionOffset := 0
71+
indexOffset := versionOffset + versionSize
72+
parentHashOffset := indexOffset + indexSize
73+
stateRootOffset := parentHashOffset + hashSize
74+
withdrawRootOffset := stateRootOffset + hashSize
75+
commitmentOffset := withdrawRootOffset + hashSize
76+
77+
version := CodecVersion(data[versionOffset])
78+
batchIndex := binary.BigEndian.Uint64(data[indexOffset : indexOffset+indexSize])
79+
parentBatchHash := common.BytesToHash(data[parentHashOffset : parentHashOffset+hashSize])
80+
postStateRoot := common.BytesToHash(data[stateRootOffset : stateRootOffset+hashSize])
81+
withdrawRoot := common.BytesToHash(data[withdrawRootOffset : withdrawRootOffset+hashSize])
82+
commitment := common.BytesToHash(data[commitmentOffset : commitmentOffset+hashSize])
83+
84+
return &daBatchValidiumV1{
85+
Version: version,
86+
BatchIndex: batchIndex,
87+
ParentBatchHash: parentBatchHash,
88+
PostStateRoot: postStateRoot,
89+
WithDrawRoot: withdrawRoot,
90+
Commitment: commitment,
91+
}, nil
92+
}

coordinator/internal/utils/version.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import (
55
"strings"
66
)
77

8+
const (
9+
DomainOffset = 6
10+
STFVersionMask = (1 << DomainOffset) - 1
11+
)
12+
813
// version get the version for the chain instance
914
//
1015
// TODO: This is not foolproof and does not cover all scenarios.
@@ -29,5 +34,5 @@ func Version(hardForkName string, ValidiumMode bool) (uint8, error) {
2934
}
3035
}
3136

32-
return (domain << 6) + stfVersion, nil
37+
return (domain << DomainOffset) + stfVersion, nil
3338
}

crates/libzkp/src/tasks/batch.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,31 @@ use crate::proofs::ChunkProof;
1818
mod utils;
1919
use utils::{base64, point_eval};
2020

21+
#[derive(Clone, serde::Deserialize, serde::Serialize)]
22+
pub struct BatchHeaderValidiumWithHash {
23+
#[serde(flatten)]
24+
header: BatchHeaderValidium,
25+
batch_hash: B256,
26+
}
27+
2128
/// Define variable batch header type, since BatchHeaderV6 can not
2229
/// be decoded as V7 we can always has correct deserialization
2330
/// Notice: V6 header MUST be put above V7 since untagged enum
2431
/// try to decode each defination in order
2532
#[derive(Clone, serde::Deserialize, serde::Serialize)]
2633
#[serde(untagged)]
2734
pub enum BatchHeaderV {
35+
Validium(BatchHeaderValidiumWithHash),
2836
V6(BatchHeaderV6),
2937
V7_8(BatchHeaderV7),
30-
Validium(BatchHeaderValidium),
3138
}
3239

3340
impl BatchHeaderV {
3441
pub fn batch_hash(&self) -> B256 {
3542
match self {
3643
BatchHeaderV::V6(h) => h.batch_hash(),
3744
BatchHeaderV::V7_8(h) => h.batch_hash(),
38-
BatchHeaderV::Validium(h) => h.batch_hash(),
45+
BatchHeaderV::Validium(h) => h.header.batch_hash(),
3946
}
4047
}
4148

@@ -62,7 +69,7 @@ impl BatchHeaderV {
6269

6370
pub fn must_validium_header(&self) -> &BatchHeaderValidium {
6471
match self {
65-
BatchHeaderV::Validium(h) => h,
72+
BatchHeaderV::Validium(h) => &h.header,
6673
_ => panic!("try to pick other header type"),
6774
}
6875
}
@@ -197,6 +204,15 @@ impl BatchProvingTask {
197204
self.challenge_digest.is_none(),
198205
"domain=validium has no blob-da"
199206
);
207+
208+
match &self.batch_header {
209+
BatchHeaderV::Validium(h) => assert_eq!(
210+
h.header.batch_hash(),
211+
h.batch_hash,
212+
"calculated batch hash match which from coordinator"
213+
),
214+
_ => panic!("unexpected header type"),
215+
}
200216
None
201217
};
202218

@@ -244,3 +260,58 @@ impl BatchProvingTask {
244260
Ok(metadata)
245261
}
246262
}
263+
264+
265+
266+
#[test]
267+
fn test_deserde_batch_header_v_validium() {
268+
use std::str::FromStr;
269+
270+
// Top-level JSON: flattened enum tag "V1" + batch_hash
271+
let json = r#"{
272+
"V1": {
273+
"version": 1,
274+
"batch_index": 42,
275+
"parent_batch_hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
276+
"post_state_root": "0x2222222222222222222222222222222222222222222222222222222222222222",
277+
"withdraw_root": "0x3333333333333333333333333333333333333333333333333333333333333333",
278+
"commitment": "0x4444444444444444444444444444444444444444444444444444444444444444"
279+
},
280+
"batch_hash": "0x5555555555555555555555555555555555555555555555555555555555555555"
281+
}"#;
282+
283+
let parsed: BatchHeaderV = serde_json::from_str(json).expect("deserialize BatchHeaderV");
284+
285+
match parsed {
286+
BatchHeaderV::Validium(v) => {
287+
// Check the batch_hash field
288+
let expected_batch_hash = B256::from_str(
289+
"0x5555555555555555555555555555555555555555555555555555555555555555",
290+
)
291+
.unwrap();
292+
assert_eq!(v.batch_hash, expected_batch_hash);
293+
294+
// Check the inner header variant and fields
295+
match v.header {
296+
BatchHeaderValidium::V1(h) => {
297+
assert_eq!(h.version, 1);
298+
assert_eq!(h.batch_index, 42);
299+
300+
let p = B256::from_str("0x1111111111111111111111111111111111111111111111111111111111111111").unwrap();
301+
let s = B256::from_str("0x2222222222222222222222222222222222222222222222222222222222222222").unwrap();
302+
let w = B256::from_str("0x3333333333333333333333333333333333333333333333333333333333333333").unwrap();
303+
let c = B256::from_str("0x4444444444444444444444444444444444444444444444444444444444444444").unwrap();
304+
305+
assert_eq!(h.parent_batch_hash, p);
306+
assert_eq!(h.post_state_root, s);
307+
assert_eq!(h.withdraw_root, w);
308+
assert_eq!(h.commitment, c);
309+
310+
// Sanity: computed batch hash equals the provided one (if method available)
311+
// assert_eq!(v.header.batch_hash(), expected_batch_hash);
312+
}
313+
}
314+
}
315+
_ => panic!("expected validium header variant"),
316+
}
317+
}

0 commit comments

Comments
 (0)