@@ -69,20 +69,21 @@ fn home_path() -> PathBuf {
69
69
Workspace :: locate ( ) . core ( )
70
70
}
71
71
72
- fn read_file_to_json_value ( path : impl AsRef < Path > + std:: fmt:: Debug ) -> serde_json:: Value {
72
+ fn read_file_to_json_value ( path : impl AsRef < Path > + std:: fmt:: Debug ) -> Option < serde_json:: Value > {
73
73
let zksync_home = home_path ( ) ;
74
74
let path = Path :: new ( & zksync_home) . join ( path) ;
75
- let file =
76
- File :: open ( & path) . unwrap_or_else ( |e| panic ! ( "Failed to open file {:?}: {}" , path, e) ) ;
77
- serde_json:: from_reader ( BufReader :: new ( file) )
78
- . unwrap_or_else ( |e| panic ! ( "Failed to parse file {:?}: {}" , path, e) )
75
+ let file = File :: open ( & path) . ok ( ) ?;
76
+ Some (
77
+ serde_json:: from_reader ( BufReader :: new ( file) )
78
+ . unwrap_or_else ( |e| panic ! ( "Failed to parse file {:?}: {}" , path, e) ) ,
79
+ )
79
80
}
80
81
81
82
fn load_contract_if_present < P : AsRef < Path > + std:: fmt:: Debug > ( path : P ) -> Option < Contract > {
82
83
let zksync_home = home_path ( ) ;
83
84
let path = Path :: new ( & zksync_home) . join ( path) ;
84
85
path. exists ( ) . then ( || {
85
- serde_json:: from_value ( read_file_to_json_value ( & path) [ "abi" ] . take ( ) )
86
+ serde_json:: from_value ( read_file_to_json_value ( & path) . unwrap ( ) [ "abi" ] . take ( ) )
86
87
. unwrap_or_else ( |e| panic ! ( "Failed to parse contract abi from file {:?}: {}" , path, e) )
87
88
} )
88
89
}
@@ -114,17 +115,26 @@ pub fn load_contract<P: AsRef<Path> + std::fmt::Debug>(path: P) -> Contract {
114
115
}
115
116
116
117
pub fn load_sys_contract ( contract_name : & str ) -> Contract {
117
- load_contract ( format ! (
118
+ if let Some ( contract ) = load_contract_if_present ( format ! (
118
119
"contracts/system-contracts/artifacts-zk/contracts-preprocessed/{0}.sol/{0}.json" ,
119
120
contract_name
120
- ) )
121
+ ) ) {
122
+ contract
123
+ } else {
124
+ load_contract ( format ! (
125
+ "contracts/system-contracts/zkout/{0}.sol/{0}.json" ,
126
+ contract_name
127
+ ) )
128
+ }
121
129
}
122
130
123
- pub fn read_contract_abi ( path : impl AsRef < Path > + std:: fmt:: Debug ) -> String {
124
- read_file_to_json_value ( path) [ "abi" ]
125
- . as_str ( )
126
- . expect ( "Failed to parse abi" )
127
- . to_string ( )
131
+ pub fn read_contract_abi ( path : impl AsRef < Path > + std:: fmt:: Debug ) -> Option < String > {
132
+ Some (
133
+ read_file_to_json_value ( path) ?[ "abi" ]
134
+ . as_str ( )
135
+ . expect ( "Failed to parse abi" )
136
+ . to_string ( ) ,
137
+ )
128
138
}
129
139
130
140
pub fn bridgehub_contract ( ) -> Contract {
@@ -200,7 +210,7 @@ pub fn l1_messenger_contract() -> Contract {
200
210
201
211
/// Reads bytecode from the path RELATIVE to the Cargo workspace location.
202
212
pub fn read_bytecode ( relative_path : impl AsRef < Path > + std:: fmt:: Debug ) -> Vec < u8 > {
203
- read_bytecode_from_path ( relative_path)
213
+ read_bytecode_from_path ( relative_path) . expect ( "Exists" )
204
214
}
205
215
206
216
pub fn eth_contract ( ) -> Contract {
@@ -212,25 +222,33 @@ pub fn known_codes_contract() -> Contract {
212
222
}
213
223
214
224
/// Reads bytecode from a given path.
215
- pub fn read_bytecode_from_path ( artifact_path : impl AsRef < Path > + std:: fmt:: Debug ) -> Vec < u8 > {
216
- let artifact = read_file_to_json_value ( & artifact_path) ;
217
-
218
- let bytecode = artifact[ "bytecode" ]
219
- . as_str ( )
220
- . unwrap_or_else ( || panic ! ( "Bytecode not found in {:?}" , artifact_path) )
221
- . strip_prefix ( "0x" )
222
- . unwrap_or_else ( || panic ! ( "Bytecode in {:?} is not hex" , artifact_path) ) ;
225
+ pub fn read_bytecode_from_path (
226
+ artifact_path : impl AsRef < Path > + std:: fmt:: Debug ,
227
+ ) -> Option < Vec < u8 > > {
228
+ let artifact = read_file_to_json_value ( & artifact_path) ?;
229
+
230
+ let bytecode = if let Some ( bytecode) = artifact[ "bytecode" ] . as_str ( ) {
231
+ bytecode
232
+ . strip_prefix ( "0x" )
233
+ . unwrap_or_else ( || panic ! ( "Bytecode in {:?} is not hex" , artifact_path) )
234
+ } else {
235
+ artifact[ "bytecode" ] [ "object" ]
236
+ . as_str ( )
237
+ . unwrap_or_else ( || panic ! ( "Bytecode not found in {:?}" , artifact_path) )
238
+ } ;
223
239
224
- hex:: decode ( bytecode)
225
- . unwrap_or_else ( |err| panic ! ( "Can't decode bytecode in {:?}: {}" , artifact_path, err) )
240
+ Some (
241
+ hex:: decode ( bytecode)
242
+ . unwrap_or_else ( |err| panic ! ( "Can't decode bytecode in {:?}: {}" , artifact_path, err) ) ,
243
+ )
226
244
}
227
245
228
246
pub fn read_sys_contract_bytecode ( directory : & str , name : & str , lang : ContractLanguage ) -> Vec < u8 > {
229
247
DEFAULT_SYSTEM_CONTRACTS_REPO . read_sys_contract_bytecode ( directory, name, lang)
230
248
}
231
249
232
250
static DEFAULT_SYSTEM_CONTRACTS_REPO : Lazy < SystemContractsRepo > =
233
- Lazy :: new ( SystemContractsRepo :: from_env ) ;
251
+ Lazy :: new ( SystemContractsRepo :: default ) ;
234
252
235
253
/// Structure representing a system contract repository - that allows
236
254
/// fetching contracts that are located there.
@@ -240,38 +258,65 @@ pub struct SystemContractsRepo {
240
258
pub root : PathBuf ,
241
259
}
242
260
243
- impl SystemContractsRepo {
261
+ impl Default for SystemContractsRepo {
244
262
/// Returns the default system contracts repository with directory based on the Cargo workspace location.
245
- pub fn from_env ( ) -> Self {
263
+ fn default ( ) -> Self {
246
264
SystemContractsRepo {
247
265
root : home_path ( ) . join ( "contracts/system-contracts" ) ,
248
266
}
249
267
}
268
+ }
250
269
270
+ impl SystemContractsRepo {
251
271
pub fn read_sys_contract_bytecode (
252
272
& self ,
253
273
directory : & str ,
254
274
name : & str ,
255
275
lang : ContractLanguage ,
256
276
) -> Vec < u8 > {
257
277
match lang {
258
- ContractLanguage :: Sol => read_bytecode_from_path ( self . root . join ( format ! (
259
- "artifacts-zk/contracts-preprocessed/{0}{1}.sol/{1}.json" ,
260
- directory, name
261
- ) ) ) ,
278
+ ContractLanguage :: Sol => {
279
+ if let Some ( contracts) = read_bytecode_from_path (
280
+ self . root
281
+ . join ( format ! ( "zkout/{0}{1}.sol/{1}.json" , directory, name) ) ,
282
+ ) {
283
+ contracts
284
+ } else {
285
+ read_bytecode_from_path ( self . root . join ( format ! (
286
+ "artifacts-zk/contracts-preprocessed/{0}{1}.sol/{1}.json" ,
287
+ directory, name
288
+ ) ) )
289
+ . expect ( "One of the outputs should exists" )
290
+ }
291
+ }
262
292
ContractLanguage :: Yul => {
263
- let artifacts_path = self
264
- . root
265
- . join ( format ! ( "contracts-preprocessed/{}artifacts/" , directory) ) ;
266
- read_yul_bytecode_by_path ( artifacts_path, name)
293
+ if let Some ( contract) = read_bytecode_from_path ( self . root . join ( format ! (
294
+ "zkout/{name}.yul/contracts-preprocessed/{directory}/{name}.yul.json" ,
295
+ ) ) ) {
296
+ contract
297
+ } else {
298
+ read_zbin_bytecode_from_path ( self . root . join ( format ! (
299
+ "contracts-preprocessed/{0}artifacts/{1}.yul.zbin" ,
300
+ directory, name
301
+ ) ) )
302
+ }
267
303
}
268
304
}
269
305
}
270
306
}
271
307
272
308
pub fn read_bootloader_code ( bootloader_type : & str ) -> Vec < u8 > {
273
- let artifacts_path = "contracts/system-contracts/bootloader/build/artifacts/" ;
274
- read_yul_bytecode ( artifacts_path, bootloader_type)
309
+ if let Some ( contract) =
310
+ read_bytecode_from_path ( home_path ( ) . join ( "contracts/system-contracts" ) . join ( format ! (
311
+ "zkout/{bootloader_type}.yul/contracts-preprocessed/bootloader/{bootloader_type}.yul.json" ,
312
+ ) ) )
313
+ {
314
+ return contract;
315
+ } ;
316
+ read_zbin_bytecode ( format ! (
317
+ "contracts/system-contracts/bootloader/build/artifacts/{}.yul.zbin" ,
318
+ bootloader_type
319
+ ) )
275
320
}
276
321
277
322
fn read_proved_batch_bootloader_bytecode ( ) -> Vec < u8 > {
@@ -463,6 +508,13 @@ impl BaseSystemContracts {
463
508
BaseSystemContracts :: load_with_bootloader ( bootloader_bytecode)
464
509
}
465
510
511
+ pub fn playground_post_protocol_defense ( ) -> Self {
512
+ let bootloader_bytecode = read_zbin_bytecode (
513
+ "etc/multivm_bootloaders/vm_protocol_defense/playground_batch.yul/playground_batch.yul.zbin" ,
514
+ ) ;
515
+ BaseSystemContracts :: load_with_bootloader ( bootloader_bytecode)
516
+ }
517
+
466
518
pub fn estimate_gas_pre_virtual_blocks ( ) -> Self {
467
519
let bootloader_bytecode = read_zbin_bytecode (
468
520
"etc/multivm_bootloaders/vm_1_3_2/fee_estimate.yul/fee_estimate.yul.zbin" ,
@@ -526,6 +578,13 @@ impl BaseSystemContracts {
526
578
BaseSystemContracts :: load_with_bootloader ( bootloader_bytecode)
527
579
}
528
580
581
+ pub fn estimate_gas_post_protocol_defense ( ) -> Self {
582
+ let bootloader_bytecode = read_zbin_bytecode (
583
+ "etc/multivm_bootloaders/vm_protocol_defense/fee_estimate.yul/fee_estimate.yul.zbin" ,
584
+ ) ;
585
+ BaseSystemContracts :: load_with_bootloader ( bootloader_bytecode)
586
+ }
587
+
529
588
pub fn hashes ( & self ) -> BaseSystemContractsHashes {
530
589
BaseSystemContractsHashes {
531
590
bootloader : self . bootloader . hash ,
0 commit comments