1use super::{sh_err, sh_warn};
2use clap::ValueEnum;
3use rustc_hash::FxHashMap;
4use serde::{Deserialize, Serialize};
5use std::fs;
6use std::fs::File;
7use std::io::{BufReader, BufWriter};
8use std::path::Path;
9use std::result::Result;
10use std::str::FromStr;
11use zksync_types::H256;
12use zksync_types::Transaction as RawTransaction;
13use zksync_types::api::{Block, BridgeAddresses, Transaction, TransactionVariant};
14
15pub const DEFAULT_DISK_CACHE_DIR: &str = ".cache";
16const CACHE_TYPE_BLOCKS_FULL: &str = "blocks_full";
18const CACHE_TYPE_BLOCKS_MIN: &str = "blocks_min";
20const CACHE_TYPE_BLOCK_RAW_TRANSACTIONS: &str = "block_raw_transactions";
22const CACHE_TYPE_TRANSACTIONS: &str = "transactions";
24const CACHE_TYPE_RESOLVER_SELECTORS: &str = "resolver_selectors";
26const CACHE_TYPE_KEY_VALUE: &str = "key_value";
28
29const CACHE_KEY_BRIDGE_ADDRESSES: &str = "bridge_addresses";
31
32#[derive(ValueEnum, Deserialize, Default, Debug, Copy, Clone)]
34pub enum CacheType {
35 None,
36 Memory,
37 #[default]
38 Disk,
39}
40
41#[derive(Deserialize, Debug, Clone)]
43pub enum CacheConfig {
44 #[serde(rename = "none")]
45 None,
46 #[serde(rename = "memory")]
47 Memory,
48 #[serde(rename = "disk")]
49 Disk { dir: String, reset: bool },
50}
51
52impl Default for CacheConfig {
53 fn default() -> Self {
54 Self::Disk {
55 dir: String::from(DEFAULT_DISK_CACHE_DIR),
56 reset: false,
57 }
58 }
59}
60
61#[derive(Default, Debug, Clone)]
63pub struct Cache {
64 config: CacheConfig,
65 block_hashes: FxHashMap<u64, H256>,
66 blocks_full: FxHashMap<H256, Block<TransactionVariant>>,
67 blocks_min: FxHashMap<H256, Block<TransactionVariant>>,
68 block_raw_transactions: FxHashMap<u64, Vec<RawTransaction>>,
69 transactions: FxHashMap<H256, Transaction>,
70 resolver_selectors: FxHashMap<String, String>,
71 bridge_addresses: Option<BridgeAddresses>,
72 confirmed_tokens: FxHashMap<(u32, u8), Vec<zksync_web3_decl::types::Token>>,
73}
74
75impl Cache {
76 pub fn new(config: CacheConfig) -> Self {
78 let mut cache = Cache {
79 config: config.clone(),
80 ..Default::default()
81 };
82
83 if let CacheConfig::Disk { dir, reset } = &config {
84 if *reset {
85 for cache_type in [
86 CACHE_TYPE_BLOCKS_FULL,
87 CACHE_TYPE_BLOCKS_MIN,
88 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
89 CACHE_TYPE_TRANSACTIONS,
90 CACHE_TYPE_RESOLVER_SELECTORS,
91 CACHE_TYPE_KEY_VALUE,
92 ] {
93 fs::remove_dir_all(Path::new(dir).join(cache_type)).unwrap_or_else(|err| {
94 sh_warn!(
95 "failed removing directory {:?}: {:?}",
96 Path::new(dir).join(cache_type),
97 err
98 )
99 });
100 }
101
102 fs::remove_dir(Path::new(dir))
103 .unwrap_or_else(|err| sh_warn!("failed removing cache directory: {:?}", err));
104 }
105
106 for cache_type in [
107 CACHE_TYPE_BLOCKS_FULL,
108 CACHE_TYPE_BLOCKS_MIN,
109 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
110 CACHE_TYPE_TRANSACTIONS,
111 CACHE_TYPE_RESOLVER_SELECTORS,
112 CACHE_TYPE_KEY_VALUE,
113 ] {
114 fs::create_dir_all(Path::new(dir).join(cache_type)).unwrap_or_else(|err| {
115 panic!("failed creating directory {cache_type}: {err:?}");
116 });
117 }
118 cache
119 .read_all_from_disk(dir)
120 .unwrap_or_else(|err| sh_err!("failed reading cache from disk: {:?}", err));
121 }
122
123 cache
124 }
125
126 pub fn get_block(
128 &self,
129 hash: &H256,
130 full_transactions: bool,
131 ) -> Option<&Block<TransactionVariant>> {
132 if matches!(self.config, CacheConfig::None) {
133 return None;
134 }
135
136 if full_transactions {
137 self.blocks_full.get(hash)
138 } else {
139 self.blocks_min.get(hash)
140 }
141 }
142
143 pub fn insert_block(
145 &mut self,
146 hash: H256,
147 full_transactions: bool,
148 block: Block<TransactionVariant>,
149 ) {
150 if matches!(self.config, CacheConfig::None) {
151 return;
152 }
153
154 self.block_hashes.insert(block.number.as_u64(), block.hash);
155 if full_transactions {
156 self.write_to_disk(CACHE_TYPE_BLOCKS_FULL, format!("{hash:#x}"), &block);
157 self.blocks_full.insert(hash, block);
158 } else {
159 self.write_to_disk(CACHE_TYPE_BLOCKS_MIN, format!("{hash:#x}"), &block);
160 self.blocks_min.insert(hash, block);
161 }
162 }
163
164 pub fn get_block_hash(&self, number: &u64) -> Option<&H256> {
166 if matches!(self.config, CacheConfig::None) {
167 return None;
168 }
169
170 self.block_hashes.get(number)
171 }
172
173 pub fn get_block_raw_transactions(&self, number: &u64) -> Option<&Vec<RawTransaction>> {
175 if matches!(self.config, CacheConfig::None) {
176 return None;
177 }
178
179 self.block_raw_transactions.get(number)
180 }
181
182 pub fn set_confirmed_tokens(
184 &mut self,
185 from: u32,
186 limit: u8,
187 confirmed_tokens: Vec<zksync_web3_decl::types::Token>,
188 ) {
189 if matches!(self.config, CacheConfig::None) {
190 return;
191 }
192 self.confirmed_tokens
193 .insert((from, limit), confirmed_tokens);
194 }
195
196 pub fn insert_block_raw_transactions(
198 &mut self,
199 number: u64,
200 transactions: Vec<RawTransaction>,
201 ) {
202 if matches!(self.config, CacheConfig::None) {
203 return;
204 }
205
206 self.write_to_disk(
207 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
208 format!("{number}"),
209 &transactions,
210 );
211 self.block_raw_transactions.insert(number, transactions);
212 }
213
214 pub fn get_transaction(&self, hash: &H256) -> Option<&Transaction> {
216 if matches!(self.config, CacheConfig::None) {
217 return None;
218 }
219
220 self.transactions.get(hash)
221 }
222
223 pub fn get_resolver_selector(&self, selector: &String) -> Option<&String> {
225 if matches!(self.config, CacheConfig::None) {
226 return None;
227 }
228
229 self.resolver_selectors.get(selector)
230 }
231
232 pub fn insert_transaction(&mut self, hash: H256, transaction: Transaction) {
234 if matches!(self.config, CacheConfig::None) {
235 return;
236 }
237
238 self.write_to_disk(CACHE_TYPE_TRANSACTIONS, format!("{hash:#x}"), &transaction);
239 self.transactions.insert(hash, transaction);
240 }
241
242 pub fn insert_resolver_selector(&mut self, selector: String, selector_value: String) {
244 if matches!(self.config, CacheConfig::None) {
245 return;
246 }
247
248 self.write_to_disk(
249 CACHE_TYPE_RESOLVER_SELECTORS,
250 selector.clone(),
251 &selector_value,
252 );
253 self.resolver_selectors.insert(selector, selector_value);
254 }
255
256 pub fn get_bridge_addresses(&self) -> Option<&BridgeAddresses> {
258 if matches!(self.config, CacheConfig::None) {
259 return None;
260 }
261
262 self.bridge_addresses.as_ref()
263 }
264
265 pub fn set_bridge_addresses(&mut self, bridge_addresses: BridgeAddresses) {
267 if matches!(self.config, CacheConfig::None) {
268 return;
269 }
270
271 self.write_to_disk(
272 CACHE_TYPE_KEY_VALUE,
273 String::from(CACHE_KEY_BRIDGE_ADDRESSES),
274 &bridge_addresses,
275 );
276 self.bridge_addresses = Some(bridge_addresses);
277 }
278
279 fn read_all_from_disk(&mut self, dir: &str) -> Result<(), String> {
281 for cache_type in [
282 CACHE_TYPE_BLOCKS_FULL,
283 CACHE_TYPE_BLOCKS_MIN,
284 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
285 CACHE_TYPE_TRANSACTIONS,
286 CACHE_TYPE_RESOLVER_SELECTORS,
287 CACHE_TYPE_KEY_VALUE,
288 ] {
289 let cache_dir = Path::new(dir).join(cache_type);
290 let dir_listing = fs::read_dir(cache_dir.clone())
291 .map_err(|err| format!("failed reading dir '{cache_dir:?}': {err:?}"))?
292 .flatten();
293 for file in dir_listing {
294 let key = file
295 .file_name()
296 .to_str()
297 .ok_or_else(|| String::from("failed converting filename to string"))?
298 .to_string();
299
300 let cache_file = File::open(file.path()).map_err(|err| {
301 format!("failed reading file: '{:?}': {:?}", file.path(), err)
302 })?;
303 let reader = BufReader::new(cache_file);
304 match cache_type {
305 CACHE_TYPE_BLOCKS_FULL => {
306 let key = H256::from_str(&key).map_err(|err| {
307 format!("invalid key for cache file '{key:?}': {err:?}")
308 })?;
309 let block: Block<TransactionVariant> = serde_json::from_reader(reader)
310 .map_err(|err| {
311 format!("failed parsing json for cache file '{key:?}': {err:?}")
312 })?;
313 self.block_hashes.insert(block.number.as_u64(), block.hash);
314 self.blocks_full.insert(key, block);
315 }
316 CACHE_TYPE_BLOCKS_MIN => {
317 let key = H256::from_str(&key).map_err(|err| {
318 format!("invalid key for cache file '{key:?}': {err:?}")
319 })?;
320 let block: Block<TransactionVariant> = serde_json::from_reader(reader)
321 .map_err(|err| {
322 format!("failed parsing json for cache file '{key:?}': {err:?}")
323 })?;
324 self.block_hashes.insert(block.number.as_u64(), block.hash);
325 self.blocks_min.insert(key, block);
326 }
327 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS => {
328 let key = key.parse::<u64>().map_err(|err| {
329 format!("invalid key for cache file '{key:?}': {err:?}")
330 })?;
331 let transactions: Vec<RawTransaction> = serde_json::from_reader(reader)
332 .map_err(|err| {
333 format!("failed parsing json for cache file '{key:?}': {err:?}")
334 })?;
335 self.block_raw_transactions.insert(key, transactions);
336 }
337 CACHE_TYPE_TRANSACTIONS => {
338 let key = H256::from_str(&key).map_err(|err| {
339 format!("invalid key for cache file '{key:?}': {err:?}")
340 })?;
341 let transaction: Transaction =
342 serde_json::from_reader(reader).map_err(|err| {
343 format!("failed parsing json for cache file '{key:?}': {err:?}")
344 })?;
345 self.transactions.insert(key, transaction);
346 }
347 CACHE_TYPE_RESOLVER_SELECTORS => {
348 let selector: String = serde_json::from_reader(reader).map_err(|err| {
349 format!("failed parsing json for cache file '{key:?}': {err:?}")
350 })?;
351 self.resolver_selectors.insert(key, selector);
352 }
353 CACHE_TYPE_KEY_VALUE => match key.as_str() {
354 CACHE_KEY_BRIDGE_ADDRESSES => {
355 self.bridge_addresses =
356 Some(serde_json::from_reader(reader).map_err(|err| {
357 format!("failed parsing json for cache file '{key:?}': {err:?}")
358 })?);
359 }
360 _ => return Err(format!("invalid cache_type_value key {cache_type}")),
361 },
362 _ => return Err(format!("invalid cache_type {cache_type}")),
363 }
364 }
365 }
366
367 Ok(())
368 }
369
370 fn write_to_disk<T: Serialize>(&self, cache_type: &'static str, key: String, data: &T) {
372 if let CacheConfig::Disk { dir, .. } = &self.config {
373 let file = Path::new(&dir).join(cache_type).join(key);
374
375 tracing::debug!("writing cache {:?}", file);
376 match File::create(file.clone()) {
377 Ok(cache_file) => {
378 let writer = BufWriter::new(cache_file);
379 if let Err(err) = serde_json::to_writer(writer, data) {
380 sh_err!("failed writing to cache '{:?}': {:?}", file, err);
381 }
382 }
383 Err(err) => sh_err!("failed creating file: '{:?}': {:?}", file, err),
384 }
385 }
386 }
387}
388
389#[cfg(test)]
390mod tests {
391 use zksync_types::{Execute, ExecuteTransactionCommon};
392 use zksync_types::{H160, U64};
393
394 use super::*;
397
398 #[test]
399 fn test_cache_config_none_disables_cache() {
400 let mut cache = Cache::new(CacheConfig::None);
401
402 cache.insert_block(H256::zero(), true, Default::default());
403 assert_eq!(None, cache.get_block(&H256::zero(), true));
404 assert_eq!(None, cache.get_block_hash(&0));
405
406 cache.insert_block(H256::zero(), false, Default::default());
407 assert_eq!(None, cache.get_block(&H256::zero(), false));
408 assert_eq!(None, cache.get_block_hash(&0));
409
410 cache.insert_block_raw_transactions(0, Default::default());
411 assert_eq!(None, cache.get_block_raw_transactions(&0));
412
413 cache.insert_transaction(H256::zero(), Default::default());
414 assert_eq!(None, cache.get_transaction(&H256::zero()));
415 }
416
417 #[test]
418 fn test_cache_config_memory_enables_cache() {
419 let block_full = Block::<TransactionVariant> {
420 hash: H256::repeat_byte(0x1),
421 number: U64::from(1),
422 ..Default::default()
423 };
424 let block_min = Block::<TransactionVariant> {
425 hash: H256::repeat_byte(0x2),
426 number: U64::from(2),
427 ..Default::default()
428 };
429 let transaction = Transaction::default();
430 let raw_transactions = vec![RawTransaction {
431 common_data: ExecuteTransactionCommon::L1(Default::default()),
432 execute: Execute {
433 calldata: Default::default(),
434 contract_address: Default::default(),
435 factory_deps: vec![],
436 value: Default::default(),
437 },
438 received_timestamp_ms: 0,
439 raw_bytes: None,
440 }];
441 let bridge_addresses = BridgeAddresses {
442 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
443 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
444 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
445 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
446 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
447 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
448 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
449 };
450
451 let mut cache = Cache::new(CacheConfig::Memory);
452
453 cache.insert_block(block_full.hash, true, block_full.clone());
454 assert_eq!(
455 Some(&block_full),
456 cache.get_block(&H256::repeat_byte(0x1), true)
457 );
458 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
459
460 cache.insert_block(block_min.hash, false, block_min.clone());
461 assert_eq!(
462 Some(&block_min),
463 cache.get_block(&H256::repeat_byte(0x2), false)
464 );
465 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
466
467 cache.insert_block_raw_transactions(0, raw_transactions.clone());
468 assert_eq!(
469 Some(&raw_transactions),
470 cache.get_block_raw_transactions(&0)
471 );
472
473 cache.insert_transaction(H256::zero(), transaction.clone());
474 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
475
476 cache.set_bridge_addresses(bridge_addresses.clone());
477 assert_bridge_addresses_eq(
478 &bridge_addresses,
479 cache.get_bridge_addresses().expect("expected addresses"),
480 );
481 }
482
483 #[test]
484 fn test_cache_config_disk_enables_cache_and_preserves_it_to_disk() {
485 let block_full = Block::<TransactionVariant> {
486 hash: H256::repeat_byte(0x1),
487 number: U64::from(1),
488 ..Default::default()
489 };
490 let block_min = Block::<TransactionVariant> {
491 hash: H256::repeat_byte(0x2),
492 number: U64::from(2),
493 ..Default::default()
494 };
495 let transaction = Transaction::default();
496 let raw_transactions = vec![RawTransaction {
497 common_data: ExecuteTransactionCommon::L1(Default::default()),
498 execute: Execute {
499 calldata: Default::default(),
500 contract_address: Default::default(),
501 factory_deps: vec![],
502 value: Default::default(),
503 },
504 received_timestamp_ms: 0,
505 raw_bytes: None,
506 }];
507 let bridge_addresses = BridgeAddresses {
508 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
509 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
510 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
511 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
512 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
513 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
514 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
515 };
516
517 let cache_dir = tempfile::Builder::new()
518 .prefix("cache-test")
519 .tempdir()
520 .expect("failed creating temporary dir");
521 let cache_dir_path = cache_dir
522 .path()
523 .to_str()
524 .expect("invalid dir name")
525 .to_string();
526 let mut cache = Cache::new(CacheConfig::Disk {
527 dir: cache_dir_path.clone(),
528 reset: true,
529 });
530
531 cache.insert_block(block_full.hash, true, block_full.clone());
532 assert_eq!(
533 Some(&block_full),
534 cache.get_block(&H256::repeat_byte(0x1), true)
535 );
536 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
537
538 cache.insert_block(block_min.hash, false, block_min.clone());
539 assert_eq!(
540 Some(&block_min),
541 cache.get_block(&H256::repeat_byte(0x2), false)
542 );
543 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
544
545 cache.insert_block_raw_transactions(0, raw_transactions.clone());
546 assert_eq!(
547 Some(&raw_transactions),
548 cache.get_block_raw_transactions(&0)
549 );
550
551 cache.insert_transaction(H256::zero(), transaction.clone());
552 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
553
554 cache.set_bridge_addresses(bridge_addresses.clone());
555 assert_bridge_addresses_eq(
556 &bridge_addresses,
557 cache.get_bridge_addresses().expect("expected addresses"),
558 );
559
560 let new_cache = Cache::new(CacheConfig::Disk {
561 dir: cache_dir_path,
562 reset: false,
563 });
564 assert_eq!(
565 Some(&block_full),
566 new_cache.get_block(&H256::repeat_byte(0x1), true)
567 );
568 assert_eq!(Some(&H256::repeat_byte(0x1)), new_cache.get_block_hash(&1));
569 assert_eq!(
570 Some(&block_min),
571 new_cache.get_block(&H256::repeat_byte(0x2), false)
572 );
573 assert_eq!(Some(&H256::repeat_byte(0x2)), new_cache.get_block_hash(&2));
574 assert_eq!(
575 Some(&raw_transactions),
576 new_cache.get_block_raw_transactions(&0)
577 );
578 assert_eq!(Some(&transaction), new_cache.get_transaction(&H256::zero()));
579 assert_bridge_addresses_eq(
580 &bridge_addresses,
581 new_cache
582 .get_bridge_addresses()
583 .expect("expected addresses"),
584 );
585 }
586
587 #[test]
588 fn test_cache_config_disk_enables_cache_and_can_reset_data_on_disk() {
589 let block_full = Block::<TransactionVariant> {
590 hash: H256::repeat_byte(0x1),
591 number: U64::from(1),
592 ..Default::default()
593 };
594 let block_min = Block::<TransactionVariant> {
595 hash: H256::repeat_byte(0x2),
596 number: U64::from(2),
597 ..Default::default()
598 };
599 let transaction = Transaction::default();
600 let raw_transactions = vec![RawTransaction {
601 common_data: ExecuteTransactionCommon::L1(Default::default()),
602 execute: Execute {
603 calldata: Default::default(),
604 contract_address: Default::default(),
605 factory_deps: vec![],
606 value: Default::default(),
607 },
608 received_timestamp_ms: 0,
609 raw_bytes: None,
610 }];
611 let bridge_addresses = BridgeAddresses {
612 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
613 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
614 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
615 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
616 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
617 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
618 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
619 };
620
621 let cache_dir = tempfile::Builder::new()
622 .prefix("cache-test")
623 .tempdir()
624 .expect("failed creating temporary dir");
625 let cache_dir_path = cache_dir
626 .path()
627 .to_str()
628 .expect("invalid dir name")
629 .to_string();
630 let mut cache = Cache::new(CacheConfig::Disk {
631 dir: cache_dir_path.clone(),
632 reset: true,
633 });
634
635 cache.insert_block(block_full.hash, true, block_full.clone());
636 assert_eq!(
637 Some(&block_full),
638 cache.get_block(&H256::repeat_byte(0x1), true)
639 );
640 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
641
642 cache.insert_block(block_min.hash, false, block_min.clone());
643 assert_eq!(
644 Some(&block_min),
645 cache.get_block(&H256::repeat_byte(0x2), false)
646 );
647 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
648
649 cache.insert_block_raw_transactions(0, raw_transactions.clone());
650 assert_eq!(
651 Some(&raw_transactions),
652 cache.get_block_raw_transactions(&0)
653 );
654
655 cache.insert_transaction(H256::zero(), transaction.clone());
656 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
657
658 cache.set_bridge_addresses(bridge_addresses.clone());
659 assert_bridge_addresses_eq(
660 &bridge_addresses,
661 cache.get_bridge_addresses().expect("expected addresses"),
662 );
663
664 let new_cache = Cache::new(CacheConfig::Disk {
665 dir: cache_dir_path,
666 reset: true,
667 });
668 assert_eq!(None, new_cache.get_block(&H256::zero(), true));
669 assert_eq!(None, new_cache.get_block_hash(&1));
670 assert_eq!(None, new_cache.get_block(&H256::zero(), false));
671 assert_eq!(None, new_cache.get_block_hash(&2));
672 assert_eq!(None, new_cache.get_block_raw_transactions(&0));
673 assert_eq!(None, new_cache.get_transaction(&H256::zero()));
674 assert!(new_cache.get_bridge_addresses().is_none());
675 }
676
677 #[test]
678 fn test_cache_config_disk_only_resets_created_data_on_disk() {
679 let cache_dir = tempfile::Builder::new()
680 .prefix("cache-test")
681 .tempdir()
682 .expect("failed creating temporary dir");
683 let cache_dir_path = cache_dir
684 .path()
685 .to_str()
686 .expect("invalid dir name")
687 .to_string();
688 let mut cache = Cache::new(CacheConfig::Disk {
689 dir: cache_dir_path.clone(),
690 reset: true,
691 });
692
693 cache.insert_transaction(H256::zero(), Default::default());
694 let cached_tx_file = cache_dir
695 .path()
696 .join(CACHE_TYPE_TRANSACTIONS)
697 .join(format!("{:#x}", H256::zero()));
698 assert!(
699 cached_tx_file.exists(),
700 "cached transaction did not exist on disk"
701 );
702
703 let random_file_path = cache_dir.path().join("foobar.txt");
704 _ = File::create(&random_file_path).expect("failed creating random file");
705
706 Cache::new(CacheConfig::Disk {
707 dir: cache_dir_path,
708 reset: true,
709 });
710
711 assert!(
712 !cached_tx_file.exists(),
713 "cached transaction was not reset on disk"
714 );
715 assert!(random_file_path.exists(), "random file was reset from disk");
716 }
717
718 pub fn assert_bridge_addresses_eq(
720 expected_bridge_addresses: &BridgeAddresses,
721 actual_bridge_addresses: &BridgeAddresses,
722 ) {
723 assert_eq!(
724 expected_bridge_addresses.l1_erc20_default_bridge,
725 actual_bridge_addresses.l1_erc20_default_bridge
726 );
727 assert_eq!(
728 expected_bridge_addresses.l2_erc20_default_bridge,
729 actual_bridge_addresses.l2_erc20_default_bridge
730 );
731 assert_eq!(
732 expected_bridge_addresses.l1_weth_bridge,
733 actual_bridge_addresses.l1_weth_bridge
734 );
735 assert_eq!(
736 expected_bridge_addresses.l2_weth_bridge,
737 actual_bridge_addresses.l2_weth_bridge
738 );
739 }
740}