Skip to content

Commit 342c015

Browse files
committed
feat: handle versioning and validium tasks
1 parent f6e6176 commit 342c015

6 files changed

Lines changed: 151 additions & 99 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ repository = "https://github.com/scroll-tech/scroll"
1717
version = "4.5.47"
1818

1919
[workspace.dependencies]
20-
scroll-zkvm-prover = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "5c361ad" }
21-
scroll-zkvm-verifier = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "5c361ad" }
22-
scroll-zkvm-types = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "5c361ad" }
20+
scroll-zkvm-prover = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "aa935df" }
21+
scroll-zkvm-verifier = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "aa935df" }
22+
scroll-zkvm-types = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "aa935df" }
2323

2424
sbv-primitives = { git = "https://github.com/scroll-tech/stateless-block-verifier", branch = "master", features = ["scroll", "rkyv"] }
2525
sbv-utils = { git = "https://github.com/scroll-tech/stateless-block-verifier", branch = "master" }

crates/libzkp/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tasks::chunk_interpreter::{ChunkInterpreter, TryFromWithInterpreter};
1313

1414
/// global features: use legacy encoding for witness
1515
static mut LEGACY_WITNESS_ENCODING: bool = false;
16+
1617
pub(crate) fn witness_use_legacy_mode() -> bool {
1718
unsafe { LEGACY_WITNESS_ENCODING }
1819
}

crates/libzkp/src/tasks/batch.rs

Lines changed: 105 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
use crate::{proofs::ChunkProof, VALIDIUM_VERSION};
21
use c_kzg::Bytes48;
32
use eyre::Result;
43
use sbv_primitives::{B256, U256};
54
use scroll_zkvm_types::{
65
batch::{
76
build_point_eval_witness, BatchHeader, BatchHeaderV6, BatchHeaderV7, BatchHeaderV8,
8-
BatchInfo, BatchWitness, Envelope, EnvelopeV6, EnvelopeV7, EnvelopeV8, LegacyBatchWitness,
9-
ReferenceHeader, N_BLOB_BYTES,
7+
BatchHeaderValidium, BatchInfo, BatchWitness, Envelope, EnvelopeV6, EnvelopeV7, EnvelopeV8,
8+
LegacyBatchWitness, ReferenceHeader, N_BLOB_BYTES,
109
},
1110
public_inputs::{ForkName, Version},
1211
task::ProvingTask,
1312
utils::{to_rkyv_bytes, RancorError},
13+
version::{Domain, STFVersion},
1414
};
1515

16+
use crate::proofs::ChunkProof;
17+
1618
mod utils;
1719
use utils::{base64, point_eval};
1820

@@ -25,13 +27,15 @@ use utils::{base64, point_eval};
2527
pub enum BatchHeaderV {
2628
V6(BatchHeaderV6),
2729
V7_8(BatchHeaderV7),
30+
Validium(BatchHeaderValidium),
2831
}
2932

3033
impl BatchHeaderV {
3134
pub fn batch_hash(&self) -> B256 {
3235
match self {
3336
BatchHeaderV::V6(h) => h.batch_hash(),
3437
BatchHeaderV::V7_8(h) => h.batch_hash(),
38+
BatchHeaderV::Validium(h) => h.batch_hash(),
3539
}
3640
}
3741

@@ -55,12 +59,21 @@ impl BatchHeaderV {
5559
_ => panic!("try to pick other header type"),
5660
}
5761
}
62+
63+
pub fn must_validium_header(&self) -> &BatchHeaderValidium {
64+
match self {
65+
BatchHeaderV::Validium(h) => h,
66+
_ => panic!("try to pick other header type"),
67+
}
68+
}
5869
}
5970

6071
/// Defines a proving task for batch proof generation, the format
6172
/// is compatible with both pre-euclidv2 and euclidv2
6273
#[derive(Clone, serde::Deserialize, serde::Serialize)]
6374
pub struct BatchProvingTask {
75+
/// The version of the chunks in the batch, as per [`Version`].
76+
pub version: Version,
6477
/// Chunk proofs for the contiguous list of chunks within the batch.
6578
pub chunk_proofs: Vec<ChunkProof>,
6679
/// The [`BatchHeaderV6/V7`], as computed on-chain for this batch.
@@ -93,7 +106,7 @@ impl TryFrom<BatchProvingTask> for ProvingTask {
93106

94107
Ok(ProvingTask {
95108
identifier: value.batch_header.batch_hash().to_string(),
96-
fork_name: value.fork_name,
109+
fork_name: value.version.fork.to_string(),
97110
aggregated_proofs: value
98111
.chunk_proofs
99112
.into_iter()
@@ -107,80 +120,105 @@ impl TryFrom<BatchProvingTask> for ProvingTask {
107120

108121
impl BatchProvingTask {
109122
fn build_guest_input(&self) -> BatchWitness {
110-
let fork_name = self.fork_name.to_lowercase().as_str().into();
111-
112-
// sanity check: calculate point eval needed and compare with task input
113-
let (kzg_commitment, kzg_proof, challenge_digest) = {
114-
let blob = point_eval::to_blob(&self.blob_bytes);
115-
let commitment = point_eval::blob_to_kzg_commitment(&blob);
116-
let versioned_hash = point_eval::get_versioned_hash(&commitment);
117-
let challenge_digest = match &self.batch_header {
118-
BatchHeaderV::V6(_) => {
119-
assert_eq!(
120-
fork_name,
121-
ForkName::EuclidV1,
122-
"hardfork mismatch for da-codec@v6 header: found={fork_name:?}, expected={:?}",
123-
ForkName::EuclidV1,
124-
);
125-
EnvelopeV6::from_slice(self.blob_bytes.as_slice())
126-
.challenge_digest(versioned_hash)
127-
}
128-
BatchHeaderV::V7_8(_) => {
129-
let padded_blob_bytes = {
130-
let mut padded_blob_bytes = self.blob_bytes.to_vec();
131-
padded_blob_bytes.resize(N_BLOB_BYTES, 0);
132-
padded_blob_bytes
133-
};
134-
135-
match fork_name {
136-
ForkName::EuclidV2 => {
137-
<EnvelopeV7 as Envelope>::from_slice(padded_blob_bytes.as_slice())
138-
.challenge_digest(versioned_hash)
139-
}
140-
ForkName::Feynman => {
141-
<EnvelopeV8 as Envelope>::from_slice(padded_blob_bytes.as_slice())
142-
.challenge_digest(versioned_hash)
123+
let point_eval_witness = if !self.version.is_validium() {
124+
// sanity check: calculate point eval needed and compare with task input
125+
let (kzg_commitment, kzg_proof, challenge_digest) = {
126+
let blob = point_eval::to_blob(&self.blob_bytes);
127+
let commitment = point_eval::blob_to_kzg_commitment(&blob);
128+
let versioned_hash = point_eval::get_versioned_hash(&commitment);
129+
let challenge_digest = match &self.batch_header {
130+
BatchHeaderV::V6(_) => {
131+
assert_eq!(
132+
self.version.fork,
133+
ForkName::EuclidV1,
134+
"hardfork mismatch for da-codec@v6 header: found={:?}, expected={:?}",
135+
self.version.fork,
136+
ForkName::EuclidV1,
137+
);
138+
EnvelopeV6::from_slice(self.blob_bytes.as_slice())
139+
.challenge_digest(versioned_hash)
140+
}
141+
BatchHeaderV::V7_8(_) => {
142+
let padded_blob_bytes = {
143+
let mut padded_blob_bytes = self.blob_bytes.to_vec();
144+
padded_blob_bytes.resize(N_BLOB_BYTES, 0);
145+
padded_blob_bytes
146+
};
147+
148+
match self.version.fork {
149+
ForkName::EuclidV2 => {
150+
<EnvelopeV7 as Envelope>::from_slice(padded_blob_bytes.as_slice())
151+
.challenge_digest(versioned_hash)
152+
}
153+
ForkName::Feynman => {
154+
<EnvelopeV8 as Envelope>::from_slice(padded_blob_bytes.as_slice())
155+
.challenge_digest(versioned_hash)
156+
}
157+
fork_name => unreachable!(
158+
"hardfork mismatch for da-codec@v7 header: found={}, expected={:?}",
159+
fork_name,
160+
[ForkName::EuclidV2, ForkName::Feynman],
161+
),
143162
}
144-
f => unreachable!(
145-
"hardfork mismatch for da-codec@v7 header: found={}, expected={:?}",
146-
f,
147-
[ForkName::EuclidV2, ForkName::Feynman],
148-
),
149163
}
150-
}
151-
};
164+
BatchHeaderV::Validium(_) => unreachable!("version!=validium"),
165+
};
152166

153-
let (proof, _) = point_eval::get_kzg_proof(&blob, challenge_digest);
167+
let (proof, _) = point_eval::get_kzg_proof(&blob, challenge_digest);
154168

155-
(commitment.to_bytes(), proof.to_bytes(), challenge_digest)
156-
};
169+
(commitment.to_bytes(), proof.to_bytes(), challenge_digest)
170+
};
157171

158-
if let Some(k) = self.kzg_commitment {
159-
assert_eq!(k, kzg_commitment);
160-
}
172+
if let Some(k) = self.kzg_commitment {
173+
assert_eq!(k, kzg_commitment);
174+
}
161175

162-
if let Some(c) = self.challenge_digest {
163-
assert_eq!(c, U256::from_be_bytes(challenge_digest.0));
164-
}
176+
if let Some(c) = self.challenge_digest {
177+
assert_eq!(c, U256::from_be_bytes(challenge_digest.0));
178+
}
165179

166-
if let Some(p) = self.kzg_proof {
167-
assert_eq!(p, kzg_proof);
168-
}
180+
if let Some(p) = self.kzg_proof {
181+
assert_eq!(p, kzg_proof);
182+
}
169183

170-
let point_eval_witness = Some(build_point_eval_witness(
171-
kzg_commitment.into_inner(),
172-
kzg_proof.into_inner(),
173-
));
184+
Some(build_point_eval_witness(
185+
kzg_commitment.into_inner(),
186+
kzg_proof.into_inner(),
187+
))
188+
} else {
189+
assert!(self.kzg_proof.is_none(), "domain=validium has no blob-da");
190+
assert!(
191+
self.kzg_commitment.is_none(),
192+
"domain=validium has no blob-da"
193+
);
194+
assert!(
195+
self.challenge_digest.is_none(),
196+
"domain=validium has no blob-da"
197+
);
198+
None
199+
};
174200

175-
let reference_header = match fork_name {
176-
ForkName::EuclidV1 => ReferenceHeader::V6(*self.batch_header.must_v6_header()),
177-
ForkName::EuclidV2 => ReferenceHeader::V7(*self.batch_header.must_v7_header()),
178-
ForkName::Feynman => ReferenceHeader::V8(*self.batch_header.must_v8_header()),
201+
let reference_header = match (self.version.domain, self.version.stf_version) {
202+
(Domain::Scroll, STFVersion::V6) => {
203+
ReferenceHeader::V6(*self.batch_header.must_v6_header())
204+
}
205+
(Domain::Scroll, STFVersion::V7) => {
206+
ReferenceHeader::V7(*self.batch_header.must_v7_header())
207+
}
208+
(Domain::Scroll, STFVersion::V8) => {
209+
ReferenceHeader::V8(*self.batch_header.must_v8_header())
210+
}
211+
(Domain::Validium, STFVersion::V1) => {
212+
ReferenceHeader::Validium(*self.batch_header.must_validium_header())
213+
}
214+
(domain, stf_version) => {
215+
unreachable!("unsupported domain={domain:?},stf-version={stf_version:?}")
216+
}
179217
};
180218

181219
BatchWitness {
182-
version: VALIDIUM_VERSION,
183-
fork_name,
220+
version: self.version.as_version_byte(),
221+
fork_name: self.version.fork,
184222
chunk_proofs: self.chunk_proofs.iter().map(|proof| proof.into()).collect(),
185223
chunk_infos: self
186224
.chunk_proofs
@@ -194,15 +232,12 @@ impl BatchProvingTask {
194232
}
195233

196234
pub fn precheck_and_build_metadata(&self) -> Result<BatchInfo> {
197-
let fork_name = ForkName::from(self.fork_name.as_str());
198235
// for every aggregation task, there are two steps needed to build the metadata:
199236
// 1. generate data for metadata from the witness
200237
// 2. validate every adjacent proof pair
201238
let witness = self.build_guest_input();
202239
let metadata = BatchInfo::from(&witness);
203-
204-
// FIXME
205-
super::check_aggregation_proofs(self.chunk_proofs.as_slice(), Version::validium_v1())?;
240+
super::check_aggregation_proofs(self.chunk_proofs.as_slice(), self.version)?;
206241

207242
Ok(metadata)
208243
}

crates/libzkp/src/tasks/bundle.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
use crate::{proofs::BatchProof, VALIDIUM_VERSION};
21
use eyre::Result;
32
use scroll_zkvm_types::{
43
bundle::{BundleInfo, BundleWitness, LegacyBundleWitness},
5-
public_inputs::{ForkName, Version},
4+
public_inputs::Version,
65
task::ProvingTask,
76
utils::{to_rkyv_bytes, RancorError},
87
};
98

9+
use crate::proofs::BatchProof;
10+
1011
/// Message indicating a sanity check failure.
1112
const BUNDLE_SANITY_MSG: &str = "bundle must have at least one batch";
1213

1314
#[derive(Clone, serde::Deserialize, serde::Serialize)]
1415
pub struct BundleProvingTask {
16+
/// The version of batches in the bundle.
17+
pub version: Version,
18+
/// The STARK proofs of each batch in the bundle.
1519
pub batch_proofs: Vec<BatchProof>,
1620
/// for sanity check
1721
pub bundle_info: Option<BundleInfo>,
@@ -41,26 +45,24 @@ impl BundleProvingTask {
4145

4246
fn build_guest_input(&self) -> BundleWitness {
4347
BundleWitness {
44-
version: VALIDIUM_VERSION,
48+
version: self.version.as_version_byte(),
4549
batch_proofs: self.batch_proofs.iter().map(|proof| proof.into()).collect(),
4650
batch_infos: self
4751
.batch_proofs
4852
.iter()
4953
.map(|wrapped_proof| wrapped_proof.metadata.batch_info.clone())
5054
.collect(),
51-
fork_name: self.fork_name.to_lowercase().as_str().into(),
55+
fork_name: self.version.fork,
5256
}
5357
}
5458

5559
pub fn precheck_and_build_metadata(&self) -> Result<BundleInfo> {
56-
let fork_name = ForkName::from(self.fork_name.as_str());
5760
// for every aggregation task, there are two steps needed to build the metadata:
5861
// 1. generate data for metadata from the witness
5962
// 2. validate every adjacent proof pair
6063
let witness = self.build_guest_input();
6164
let metadata = BundleInfo::from(&witness);
62-
63-
super::check_aggregation_proofs(self.batch_proofs.as_slice(), Version::validium_v1())?;
65+
super::check_aggregation_proofs(self.batch_proofs.as_slice(), self.version)?;
6466

6567
Ok(metadata)
6668
}

0 commit comments

Comments
 (0)