1
1
use crate :: Block ;
2
2
use alloy:: primitives:: { Address , Bytes , B256 , U256 } ;
3
- use serde:: { Deserialize , Serialize } ;
3
+ use rkyv:: Archive ;
4
+ use serde:: { Deserialize , Deserializer , Serialize } ;
4
5
use serde_with:: { serde_as, Map } ;
6
+ use std:: collections:: { BTreeSet , HashMap } ;
7
+ use std:: fmt:: Debug ;
8
+ use std:: hash:: Hash ;
5
9
6
10
mod tx;
7
11
pub use tx:: { ArchivedTransactionTrace , TransactionTrace , TxL1Msg , TypedTransaction } ;
@@ -58,16 +62,15 @@ pub struct BytecodeTrace {
58
62
}
59
63
60
64
/// storage trace
61
- #[ serde_as]
62
65
#[ derive(
63
66
rkyv:: Archive ,
64
67
rkyv:: Serialize ,
65
68
rkyv:: Deserialize ,
66
69
Serialize ,
67
- Deserialize ,
68
70
Default ,
69
71
Debug ,
70
72
Clone ,
73
+ Hash ,
71
74
Eq ,
72
75
PartialEq ,
73
76
) ]
@@ -82,8 +85,44 @@ pub struct StorageTrace {
82
85
pub root_after : B256 ,
83
86
/// proofs
84
87
#[ serde( rename = "flattenProofs" ) ]
88
+ pub flatten_proofs : Vec < Bytes > ,
89
+ }
90
+
91
+ /// legacy storage trace
92
+ #[ serde_as]
93
+ #[ derive(
94
+ rkyv:: Archive ,
95
+ rkyv:: Serialize ,
96
+ rkyv:: Deserialize ,
97
+ Serialize ,
98
+ Deserialize ,
99
+ Default ,
100
+ Debug ,
101
+ Clone ,
102
+ Hash ,
103
+ Eq ,
104
+ PartialEq ,
105
+ ) ]
106
+ #[ archive( check_bytes) ]
107
+ #[ archive_attr( derive( Debug , Hash , PartialEq , Eq ) ) ]
108
+ pub struct LegacyStorageTrace {
109
+ /// root before
110
+ #[ serde( rename = "rootBefore" ) ]
111
+ pub root_before : B256 ,
112
+ /// root after
113
+ #[ serde( rename = "rootAfter" ) ]
114
+ pub root_after : B256 ,
115
+ /// account proofs
116
+ #[ serde( default ) ]
85
117
#[ serde_as( as = "Map<_, _>" ) ]
86
- pub flatten_proofs : Vec < ( B256 , Bytes ) > ,
118
+ pub proofs : Vec < ( Address , Vec < Bytes > ) > ,
119
+ #[ serde( rename = "storageProofs" , default ) ]
120
+ #[ serde_as( as = "Map<_, Map<_, _>>" ) ]
121
+ /// storage proofs for each account
122
+ pub storage_proofs : Vec < ( Address , Vec < ( B256 , Vec < Bytes > ) > ) > ,
123
+ #[ serde( rename = "deletionProofs" , default ) ]
124
+ /// additional deletion proofs
125
+ pub deletion_proofs : Vec < Bytes > ,
87
126
}
88
127
89
128
/// Block trace format
@@ -94,7 +133,11 @@ pub struct StorageTrace {
94
133
) ]
95
134
#[ archive( check_bytes) ]
96
135
#[ archive_attr( derive( Debug , Hash , PartialEq , Eq ) ) ]
97
- pub struct BlockTrace {
136
+ pub struct BlockTrace < S = StorageTrace >
137
+ where
138
+ S : Archive ,
139
+ <S as Archive >:: Archived : Debug + Hash + PartialEq + Eq ,
140
+ {
98
141
/// chain id
99
142
#[ serde( rename = "chainID" , default ) ]
100
143
pub chain_id : u64 ,
@@ -108,14 +151,86 @@ pub struct BlockTrace {
108
151
pub codes : Vec < BytecodeTrace > ,
109
152
/// storage trace BEFORE execution
110
153
#[ serde( rename = "storageTrace" ) ]
111
- pub storage_trace : StorageTrace ,
154
+ pub storage_trace : S ,
112
155
/// l1 tx queue
113
156
#[ serde( rename = "startL1QueueIndex" , default ) ]
114
157
pub start_l1_queue_index : u64 ,
115
158
/// Withdraw root
116
159
pub withdraw_trie_root : B256 ,
117
160
}
118
161
162
+ impl < ' de > Deserialize < ' de > for StorageTrace {
163
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
164
+ where
165
+ D : Deserializer < ' de > ,
166
+ {
167
+ #[ derive( Deserialize ) ]
168
+ #[ serde( untagged) ]
169
+ enum FlattenProofs {
170
+ Map ( HashMap < B256 , Bytes > ) ,
171
+ Vec ( Vec < Bytes > ) ,
172
+ }
173
+ #[ derive( Deserialize ) ]
174
+ struct StorageTraceDe {
175
+ #[ serde( rename = "rootBefore" ) ]
176
+ pub root_before : B256 ,
177
+ #[ serde( rename = "rootAfter" ) ]
178
+ pub root_after : B256 ,
179
+ #[ serde( rename = "flattenProofs" ) ]
180
+ pub flatten_proofs : FlattenProofs ,
181
+ }
182
+
183
+ let de = StorageTraceDe :: deserialize ( deserializer) ?;
184
+ let mut flatten_proofs = match de. flatten_proofs {
185
+ FlattenProofs :: Map ( map) => map. into_iter ( ) . map ( |( _, v) | v) . collect ( ) ,
186
+ FlattenProofs :: Vec ( vec) => vec,
187
+ } ;
188
+ flatten_proofs. sort ( ) ;
189
+
190
+ Ok ( StorageTrace {
191
+ root_before : de. root_before ,
192
+ root_after : de. root_after ,
193
+ flatten_proofs,
194
+ } )
195
+ }
196
+ }
197
+
198
+ impl From < LegacyStorageTrace > for StorageTrace {
199
+ fn from ( trace : LegacyStorageTrace ) -> Self {
200
+ let mut flatten_proofs = BTreeSet :: new ( ) ;
201
+ for ( _, proofs) in trace. proofs {
202
+ flatten_proofs. extend ( proofs) ;
203
+ }
204
+ for ( _, proofs) in trace. storage_proofs {
205
+ for ( _, proofs) in proofs {
206
+ flatten_proofs. extend ( proofs) ;
207
+ }
208
+ }
209
+ flatten_proofs. extend ( trace. deletion_proofs ) ;
210
+
211
+ StorageTrace {
212
+ root_before : trace. root_before ,
213
+ root_after : trace. root_after ,
214
+ flatten_proofs : flatten_proofs. into_iter ( ) . collect ( ) ,
215
+ }
216
+ }
217
+ }
218
+
219
+ impl From < BlockTrace < LegacyStorageTrace > > for BlockTrace {
220
+ fn from ( trace : BlockTrace < LegacyStorageTrace > ) -> Self {
221
+ BlockTrace {
222
+ chain_id : trace. chain_id ,
223
+ coinbase : trace. coinbase ,
224
+ header : trace. header ,
225
+ transactions : trace. transactions ,
226
+ codes : trace. codes ,
227
+ storage_trace : trace. storage_trace . into ( ) ,
228
+ start_l1_queue_index : trace. start_l1_queue_index ,
229
+ withdraw_trie_root : trace. withdraw_trie_root ,
230
+ }
231
+ }
232
+ }
233
+
119
234
impl Block for BlockTrace {
120
235
type Tx = TransactionTrace ;
121
236
@@ -179,11 +294,8 @@ impl Block for BlockTrace {
179
294
self . start_l1_queue_index
180
295
}
181
296
182
- fn flatten_proofs ( & self ) -> impl Iterator < Item = ( & B256 , & [ u8 ] ) > {
183
- self . storage_trace
184
- . flatten_proofs
185
- . iter ( )
186
- . map ( |( k, v) | ( k, v. as_ref ( ) ) )
297
+ fn flatten_proofs ( & self ) -> impl Iterator < Item = & [ u8 ] > {
298
+ self . storage_trace . flatten_proofs . iter ( ) . map ( |v| v. as_ref ( ) )
187
299
}
188
300
}
189
301
@@ -254,11 +366,8 @@ impl Block for ArchivedBlockTrace {
254
366
self . start_l1_queue_index
255
367
}
256
368
257
- fn flatten_proofs ( & self ) -> impl Iterator < Item = ( & B256 , & [ u8 ] ) > {
258
- self . storage_trace
259
- . flatten_proofs
260
- . iter ( )
261
- . map ( |( k, v) | ( k, v. as_ref ( ) ) )
369
+ fn flatten_proofs ( & self ) -> impl Iterator < Item = & [ u8 ] > {
370
+ self . storage_trace . flatten_proofs . iter ( ) . map ( |v| v. as_ref ( ) )
262
371
}
263
372
}
264
373
@@ -404,8 +513,7 @@ mod tests {
404
513
. iter ( )
405
514
. zip ( archived_block. storage_trace . flatten_proofs . iter ( ) )
406
515
{
407
- assert_eq ! ( proof. 0 , archived_proof. 0 ) ;
408
- assert_eq ! ( proof. 1 . as_ref( ) , archived_proof. 1 . as_ref( ) ) ;
516
+ assert_eq ! ( proof. as_ref( ) , archived_proof. as_ref( ) ) ;
409
517
}
410
518
411
519
assert_eq ! (
0 commit comments