1- use crate :: { proofs:: ChunkProof , VALIDIUM_VERSION } ;
21use c_kzg:: Bytes48 ;
32use eyre:: Result ;
43use sbv_primitives:: { B256 , U256 } ;
54use 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+
1618mod utils;
1719use utils:: { base64, point_eval} ;
1820
@@ -25,13 +27,15 @@ use utils::{base64, point_eval};
2527pub enum BatchHeaderV {
2628 V6 ( BatchHeaderV6 ) ,
2729 V7_8 ( BatchHeaderV7 ) ,
30+ Validium ( BatchHeaderValidium ) ,
2831}
2932
3033impl 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 ) ]
6374pub 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
108121impl 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 }
0 commit comments