@@ -14,7 +14,7 @@ use crate::{
14
14
/// Batch header provides additional fields from the context (within recursion)
15
15
/// for constructing the preimage of the batch hash.
16
16
#[ derive( Default , Debug , Clone , Copy , Serialize , Deserialize ) ]
17
- pub struct BatchHeader {
17
+ pub struct BatchHeader < const N_SNARKS : usize > {
18
18
/// the batch version
19
19
pub version : u8 ,
20
20
/// the index of the batch
@@ -35,7 +35,65 @@ pub struct BatchHeader {
35
35
pub blob_data_proof : [ H256 ; 2 ] ,
36
36
}
37
37
38
- impl BatchHeader {
38
+ impl < const N_SNARKS : usize > BatchHeader < N_SNARKS > {
39
+ /// Constructs the correct batch header from chunks data and context variables
40
+ pub fn construct_from_chunks (
41
+ version : u8 ,
42
+ batch_index : u64 ,
43
+ l1_message_popped : u64 ,
44
+ total_l1_message_popped : u64 ,
45
+ parent_batch_hash : H256 ,
46
+ last_block_timestamp : u64 ,
47
+ chunks : & [ ChunkInfo ] ,
48
+ ) -> Self {
49
+ assert_ne ! ( chunks. len( ) , 0 ) ;
50
+ assert ! ( chunks. len( ) <= N_SNARKS ) ;
51
+
52
+ let mut chunks_with_padding = chunks. to_vec ( ) ;
53
+ if chunks. len ( ) < N_SNARKS {
54
+ let last_chunk = chunks. last ( ) . unwrap ( ) ;
55
+ let mut padding_chunk = last_chunk. clone ( ) ;
56
+ padding_chunk. is_padding = true ;
57
+ chunks_with_padding
58
+ . extend ( std:: iter:: repeat ( padding_chunk) . take ( N_SNARKS - chunks. len ( ) ) ) ;
59
+ }
60
+
61
+ let number_of_valid_chunks = match chunks_with_padding
62
+ . iter ( )
63
+ . enumerate ( )
64
+ . find ( |( _index, chunk) | chunk. is_padding )
65
+ {
66
+ Some ( ( index, _) ) => index,
67
+ None => N_SNARKS ,
68
+ } ;
69
+
70
+ let batch_data_hash_preimage = chunks_with_padding
71
+ . iter ( )
72
+ . take ( number_of_valid_chunks)
73
+ . flat_map ( |chunk_info| chunk_info. data_hash . 0 . iter ( ) )
74
+ . cloned ( )
75
+ . collect :: < Vec < _ > > ( ) ;
76
+ let batch_data_hash = keccak256 ( batch_data_hash_preimage) ;
77
+
78
+ let batch_data = BatchData :: < N_SNARKS > :: new ( number_of_valid_chunks, & chunks_with_padding) ;
79
+ let point_evaluation_assignments = PointEvaluationAssignments :: from ( & batch_data) ;
80
+
81
+ Self {
82
+ version,
83
+ batch_index,
84
+ l1_message_popped,
85
+ total_l1_message_popped,
86
+ parent_batch_hash,
87
+ last_block_timestamp,
88
+ data_hash : batch_data_hash. into ( ) ,
89
+ blob_versioned_hash : batch_data. get_versioned_hash ( ) ,
90
+ blob_data_proof : [
91
+ H256 :: from_slice ( & point_evaluation_assignments. challenge . to_be_bytes ( ) ) ,
92
+ H256 :: from_slice ( & point_evaluation_assignments. evaluation . to_be_bytes ( ) ) ,
93
+ ] ,
94
+ }
95
+ }
96
+
39
97
/// Returns the batch hash as per BatchHeaderV3.
40
98
pub fn batch_hash ( & self ) -> H256 {
41
99
// the current batch hash is build as
@@ -107,12 +165,15 @@ pub struct BatchHash<const N_SNARKS: usize> {
107
165
/// The 4844 versioned hash for the blob.
108
166
pub ( crate ) versioned_hash : H256 ,
109
167
/// The context batch header
110
- pub ( crate ) batch_header : BatchHeader ,
168
+ pub ( crate ) batch_header : BatchHeader < N_SNARKS > ,
111
169
}
112
170
113
171
impl < const N_SNARKS : usize > BatchHash < N_SNARKS > {
114
172
/// Build Batch hash from an ordered list of chunks. Will pad if needed
115
- pub fn construct_with_unpadded ( chunks : & [ ChunkInfo ] , batch_header : BatchHeader ) -> Self {
173
+ pub fn construct_with_unpadded (
174
+ chunks : & [ ChunkInfo ] ,
175
+ batch_header : BatchHeader < N_SNARKS > ,
176
+ ) -> Self {
116
177
assert_ne ! ( chunks. len( ) , 0 ) ;
117
178
assert ! ( chunks. len( ) <= N_SNARKS ) ;
118
179
let mut chunks_with_padding = chunks. to_vec ( ) ;
@@ -132,15 +193,16 @@ impl<const N_SNARKS: usize> BatchHash<N_SNARKS> {
132
193
}
133
194
134
195
/// Build Batch hash from an ordered list of #N_SNARKS of chunks.
135
- pub fn construct ( chunks_with_padding : & [ ChunkInfo ] , batch_header : BatchHeader ) -> Self {
196
+ pub fn construct (
197
+ chunks_with_padding : & [ ChunkInfo ] ,
198
+ batch_header : BatchHeader < N_SNARKS > ,
199
+ ) -> Self {
136
200
assert_eq ! (
137
201
chunks_with_padding. len( ) ,
138
202
N_SNARKS ,
139
203
"input chunk slice does not match N_SNARKS"
140
204
) ;
141
205
142
- let mut export_batch_header = batch_header;
143
-
144
206
let number_of_valid_chunks = match chunks_with_padding
145
207
. iter ( )
146
208
. enumerate ( )
@@ -209,24 +271,34 @@ impl<const N_SNARKS: usize> BatchHash<N_SNARKS> {
209
271
. collect :: < Vec < _ > > ( ) ;
210
272
let batch_data_hash = keccak256 ( preimage) ;
211
273
212
- // Update export value
213
- export_batch_header. data_hash = batch_data_hash. into ( ) ;
274
+ assert_eq ! (
275
+ batch_header. data_hash,
276
+ H256 :: from_slice( & batch_data_hash) ,
277
+ "Expect provided BatchHeader's data_hash field to be correct"
278
+ ) ;
214
279
215
280
let batch_data = BatchData :: < N_SNARKS > :: new ( number_of_valid_chunks, chunks_with_padding) ;
216
281
let point_evaluation_assignments = PointEvaluationAssignments :: from ( & batch_data) ;
217
282
218
- // Update export value
219
- export_batch_header. blob_data_proof [ 0 ] =
220
- H256 :: from_slice ( & point_evaluation_assignments. challenge . to_be_bytes ( ) ) ;
221
- export_batch_header. blob_data_proof [ 1 ] =
222
- H256 :: from_slice ( & point_evaluation_assignments. evaluation . to_be_bytes ( ) ) ;
283
+ assert_eq ! (
284
+ batch_header. blob_data_proof[ 0 ] ,
285
+ H256 :: from_slice( & point_evaluation_assignments. challenge. to_be_bytes( ) ) ,
286
+ "Expect provided BatchHeader's blob_data_proof field 0 to be correct"
287
+ ) ;
288
+ assert_eq ! (
289
+ batch_header. blob_data_proof[ 1 ] ,
290
+ H256 :: from_slice( & point_evaluation_assignments. evaluation. to_be_bytes( ) ) ,
291
+ "Expect provided BatchHeader's blob_data_proof field 1 to be correct"
292
+ ) ;
223
293
224
294
let versioned_hash = batch_data. get_versioned_hash ( ) ;
225
295
226
- // Update export value
227
- export_batch_header. blob_versioned_hash = versioned_hash;
296
+ assert_eq ! (
297
+ batch_header. blob_versioned_hash, versioned_hash,
298
+ "Expect provided BatchHeader's blob_versioned_hash field to be correct"
299
+ ) ;
228
300
229
- let current_batch_hash = export_batch_header . batch_hash ( ) ;
301
+ let current_batch_hash = batch_header . batch_hash ( ) ;
230
302
231
303
log:: info!(
232
304
"batch hash {:?}, datahash {}, z {}, y {}, versioned hash {:x}" ,
@@ -248,7 +320,7 @@ impl<const N_SNARKS: usize> BatchHash<N_SNARKS> {
248
320
number_of_valid_chunks,
249
321
point_evaluation_assignments,
250
322
versioned_hash,
251
- batch_header : export_batch_header ,
323
+ batch_header,
252
324
}
253
325
}
254
326
@@ -378,7 +450,7 @@ impl<const N_SNARKS: usize> BatchHash<N_SNARKS> {
378
450
}
379
451
380
452
/// ...
381
- pub fn batch_header ( & self ) -> BatchHeader {
453
+ pub fn batch_header ( & self ) -> BatchHeader < N_SNARKS > {
382
454
self . batch_header
383
455
}
384
456
}
0 commit comments