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 get_confirmed_tokens(
184 &self,
185 from: u32,
186 limit: u8,
187 ) -> Option<&Vec<zksync_web3_decl::types::Token>> {
188 if matches!(self.config, CacheConfig::None) {
189 return None;
190 }
191 self.confirmed_tokens.get(&(from, limit))
192 }
193
194 pub fn set_confirmed_tokens(
196 &mut self,
197 from: u32,
198 limit: u8,
199 confirmed_tokens: Vec<zksync_web3_decl::types::Token>,
200 ) {
201 if matches!(self.config, CacheConfig::None) {
202 return;
203 }
204 self.confirmed_tokens
205 .insert((from, limit), confirmed_tokens);
206 }
207
208 pub fn insert_block_raw_transactions(
210 &mut self,
211 number: u64,
212 transactions: Vec<RawTransaction>,
213 ) {
214 if matches!(self.config, CacheConfig::None) {
215 return;
216 }
217
218 self.write_to_disk(
219 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
220 format!("{number}"),
221 &transactions,
222 );
223 self.block_raw_transactions.insert(number, transactions);
224 }
225
226 pub fn get_transaction(&self, hash: &H256) -> Option<&Transaction> {
228 if matches!(self.config, CacheConfig::None) {
229 return None;
230 }
231
232 self.transactions.get(hash)
233 }
234
235 pub fn get_resolver_selector(&self, selector: &String) -> Option<&String> {
237 if matches!(self.config, CacheConfig::None) {
238 return None;
239 }
240
241 self.resolver_selectors.get(selector)
242 }
243
244 pub fn insert_transaction(&mut self, hash: H256, transaction: Transaction) {
246 if matches!(self.config, CacheConfig::None) {
247 return;
248 }
249
250 self.write_to_disk(CACHE_TYPE_TRANSACTIONS, format!("{hash:#x}"), &transaction);
251 self.transactions.insert(hash, transaction);
252 }
253
254 pub fn insert_resolver_selector(&mut self, selector: String, selector_value: String) {
256 if matches!(self.config, CacheConfig::None) {
257 return;
258 }
259
260 self.write_to_disk(
261 CACHE_TYPE_RESOLVER_SELECTORS,
262 selector.clone(),
263 &selector_value,
264 );
265 self.resolver_selectors.insert(selector, selector_value);
266 }
267
268 pub fn get_bridge_addresses(&self) -> Option<&BridgeAddresses> {
270 if matches!(self.config, CacheConfig::None) {
271 return None;
272 }
273
274 self.bridge_addresses.as_ref()
275 }
276
277 pub fn set_bridge_addresses(&mut self, bridge_addresses: BridgeAddresses) {
279 if matches!(self.config, CacheConfig::None) {
280 return;
281 }
282
283 self.write_to_disk(
284 CACHE_TYPE_KEY_VALUE,
285 String::from(CACHE_KEY_BRIDGE_ADDRESSES),
286 &bridge_addresses,
287 );
288 self.bridge_addresses = Some(bridge_addresses);
289 }
290
291 fn read_all_from_disk(&mut self, dir: &str) -> Result<(), String> {
293 for cache_type in [
294 CACHE_TYPE_BLOCKS_FULL,
295 CACHE_TYPE_BLOCKS_MIN,
296 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS,
297 CACHE_TYPE_TRANSACTIONS,
298 CACHE_TYPE_RESOLVER_SELECTORS,
299 CACHE_TYPE_KEY_VALUE,
300 ] {
301 let cache_dir = Path::new(dir).join(cache_type);
302 let dir_listing = fs::read_dir(cache_dir.clone())
303 .map_err(|err| format!("failed reading dir '{cache_dir:?}': {err:?}"))?
304 .flatten();
305 for file in dir_listing {
306 let key = file
307 .file_name()
308 .to_str()
309 .ok_or_else(|| String::from("failed converting filename to string"))?
310 .to_string();
311
312 let cache_file = File::open(file.path()).map_err(|err| {
313 format!("failed reading file: '{:?}': {:?}", file.path(), err)
314 })?;
315 let reader = BufReader::new(cache_file);
316 match cache_type {
317 CACHE_TYPE_BLOCKS_FULL => {
318 let key = H256::from_str(&key).map_err(|err| {
319 format!("invalid key for cache file '{key:?}': {err:?}")
320 })?;
321 let block: Block<TransactionVariant> = serde_json::from_reader(reader)
322 .map_err(|err| {
323 format!("failed parsing json for cache file '{key:?}': {err:?}")
324 })?;
325 self.block_hashes.insert(block.number.as_u64(), block.hash);
326 self.blocks_full.insert(key, block);
327 }
328 CACHE_TYPE_BLOCKS_MIN => {
329 let key = H256::from_str(&key).map_err(|err| {
330 format!("invalid key for cache file '{key:?}': {err:?}")
331 })?;
332 let block: Block<TransactionVariant> = serde_json::from_reader(reader)
333 .map_err(|err| {
334 format!("failed parsing json for cache file '{key:?}': {err:?}")
335 })?;
336 self.block_hashes.insert(block.number.as_u64(), block.hash);
337 self.blocks_min.insert(key, block);
338 }
339 CACHE_TYPE_BLOCK_RAW_TRANSACTIONS => {
340 let key = key.parse::<u64>().map_err(|err| {
341 format!("invalid key for cache file '{key:?}': {err:?}")
342 })?;
343 let transactions: Vec<RawTransaction> = serde_json::from_reader(reader)
344 .map_err(|err| {
345 format!("failed parsing json for cache file '{key:?}': {err:?}")
346 })?;
347 self.block_raw_transactions.insert(key, transactions);
348 }
349 CACHE_TYPE_TRANSACTIONS => {
350 let key = H256::from_str(&key).map_err(|err| {
351 format!("invalid key for cache file '{key:?}': {err:?}")
352 })?;
353 let transaction: Transaction =
354 serde_json::from_reader(reader).map_err(|err| {
355 format!("failed parsing json for cache file '{key:?}': {err:?}")
356 })?;
357 self.transactions.insert(key, transaction);
358 }
359 CACHE_TYPE_RESOLVER_SELECTORS => {
360 let selector: String = serde_json::from_reader(reader).map_err(|err| {
361 format!("failed parsing json for cache file '{key:?}': {err:?}")
362 })?;
363 self.resolver_selectors.insert(key, selector);
364 }
365 CACHE_TYPE_KEY_VALUE => match key.as_str() {
366 CACHE_KEY_BRIDGE_ADDRESSES => {
367 self.bridge_addresses =
368 Some(serde_json::from_reader(reader).map_err(|err| {
369 format!("failed parsing json for cache file '{key:?}': {err:?}")
370 })?);
371 }
372 _ => return Err(format!("invalid cache_type_value key {cache_type}")),
373 },
374 _ => return Err(format!("invalid cache_type {cache_type}")),
375 }
376 }
377 }
378
379 Ok(())
380 }
381
382 fn write_to_disk<T: Serialize>(&self, cache_type: &'static str, key: String, data: &T) {
384 if let CacheConfig::Disk { dir, .. } = &self.config {
385 let file = Path::new(&dir).join(cache_type).join(key);
386
387 tracing::debug!("writing cache {:?}", file);
388 match File::create(file.clone()) {
389 Ok(cache_file) => {
390 let writer = BufWriter::new(cache_file);
391 if let Err(err) = serde_json::to_writer(writer, data) {
392 sh_err!("failed writing to cache '{:?}': {:?}", file, err);
393 }
394 }
395 Err(err) => sh_err!("failed creating file: '{:?}': {:?}", file, err),
396 }
397 }
398 }
399}
400
401#[cfg(test)]
402mod tests {
403 use zksync_types::{Execute, ExecuteTransactionCommon};
404 use zksync_types::{H160, U64};
405
406 use super::*;
409
410 #[test]
411 fn test_cache_config_none_disables_cache() {
412 let mut cache = Cache::new(CacheConfig::None);
413
414 cache.insert_block(H256::zero(), true, Default::default());
415 assert_eq!(None, cache.get_block(&H256::zero(), true));
416 assert_eq!(None, cache.get_block_hash(&0));
417
418 cache.insert_block(H256::zero(), false, Default::default());
419 assert_eq!(None, cache.get_block(&H256::zero(), false));
420 assert_eq!(None, cache.get_block_hash(&0));
421
422 cache.insert_block_raw_transactions(0, Default::default());
423 assert_eq!(None, cache.get_block_raw_transactions(&0));
424
425 cache.insert_transaction(H256::zero(), Default::default());
426 assert_eq!(None, cache.get_transaction(&H256::zero()));
427 }
428
429 #[test]
430 fn test_cache_config_memory_enables_cache() {
431 let block_full = Block::<TransactionVariant> {
432 hash: H256::repeat_byte(0x1),
433 number: U64::from(1),
434 ..Default::default()
435 };
436 let block_min = Block::<TransactionVariant> {
437 hash: H256::repeat_byte(0x2),
438 number: U64::from(2),
439 ..Default::default()
440 };
441 let transaction = Transaction::default();
442 let raw_transactions = vec![RawTransaction {
443 common_data: ExecuteTransactionCommon::L1(Default::default()),
444 execute: Execute {
445 calldata: Default::default(),
446 contract_address: Default::default(),
447 factory_deps: vec![],
448 value: Default::default(),
449 },
450 received_timestamp_ms: 0,
451 raw_bytes: None,
452 }];
453 let bridge_addresses = BridgeAddresses {
454 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
455 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
456 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
457 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
458 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
459 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
460 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
461 };
462
463 let mut cache = Cache::new(CacheConfig::Memory);
464
465 cache.insert_block(block_full.hash, true, block_full.clone());
466 assert_eq!(
467 Some(&block_full),
468 cache.get_block(&H256::repeat_byte(0x1), true)
469 );
470 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
471
472 cache.insert_block(block_min.hash, false, block_min.clone());
473 assert_eq!(
474 Some(&block_min),
475 cache.get_block(&H256::repeat_byte(0x2), false)
476 );
477 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
478
479 cache.insert_block_raw_transactions(0, raw_transactions.clone());
480 assert_eq!(
481 Some(&raw_transactions),
482 cache.get_block_raw_transactions(&0)
483 );
484
485 cache.insert_transaction(H256::zero(), transaction.clone());
486 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
487
488 cache.set_bridge_addresses(bridge_addresses.clone());
489 assert_bridge_addresses_eq(
490 &bridge_addresses,
491 cache.get_bridge_addresses().expect("expected addresses"),
492 );
493 }
494
495 #[test]
496 fn test_cache_config_disk_enables_cache_and_preserves_it_to_disk() {
497 let block_full = Block::<TransactionVariant> {
498 hash: H256::repeat_byte(0x1),
499 number: U64::from(1),
500 ..Default::default()
501 };
502 let block_min = Block::<TransactionVariant> {
503 hash: H256::repeat_byte(0x2),
504 number: U64::from(2),
505 ..Default::default()
506 };
507 let transaction = Transaction::default();
508 let raw_transactions = vec![RawTransaction {
509 common_data: ExecuteTransactionCommon::L1(Default::default()),
510 execute: Execute {
511 calldata: Default::default(),
512 contract_address: Default::default(),
513 factory_deps: vec![],
514 value: Default::default(),
515 },
516 received_timestamp_ms: 0,
517 raw_bytes: None,
518 }];
519 let bridge_addresses = BridgeAddresses {
520 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
521 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
522 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
523 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
524 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
525 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
526 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
527 };
528
529 let cache_dir = tempfile::Builder::new()
530 .prefix("cache-test")
531 .tempdir()
532 .expect("failed creating temporary dir");
533 let cache_dir_path = cache_dir
534 .path()
535 .to_str()
536 .expect("invalid dir name")
537 .to_string();
538 let mut cache = Cache::new(CacheConfig::Disk {
539 dir: cache_dir_path.clone(),
540 reset: true,
541 });
542
543 cache.insert_block(block_full.hash, true, block_full.clone());
544 assert_eq!(
545 Some(&block_full),
546 cache.get_block(&H256::repeat_byte(0x1), true)
547 );
548 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
549
550 cache.insert_block(block_min.hash, false, block_min.clone());
551 assert_eq!(
552 Some(&block_min),
553 cache.get_block(&H256::repeat_byte(0x2), false)
554 );
555 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
556
557 cache.insert_block_raw_transactions(0, raw_transactions.clone());
558 assert_eq!(
559 Some(&raw_transactions),
560 cache.get_block_raw_transactions(&0)
561 );
562
563 cache.insert_transaction(H256::zero(), transaction.clone());
564 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
565
566 cache.set_bridge_addresses(bridge_addresses.clone());
567 assert_bridge_addresses_eq(
568 &bridge_addresses,
569 cache.get_bridge_addresses().expect("expected addresses"),
570 );
571
572 let new_cache = Cache::new(CacheConfig::Disk {
573 dir: cache_dir_path,
574 reset: false,
575 });
576 assert_eq!(
577 Some(&block_full),
578 new_cache.get_block(&H256::repeat_byte(0x1), true)
579 );
580 assert_eq!(Some(&H256::repeat_byte(0x1)), new_cache.get_block_hash(&1));
581 assert_eq!(
582 Some(&block_min),
583 new_cache.get_block(&H256::repeat_byte(0x2), false)
584 );
585 assert_eq!(Some(&H256::repeat_byte(0x2)), new_cache.get_block_hash(&2));
586 assert_eq!(
587 Some(&raw_transactions),
588 new_cache.get_block_raw_transactions(&0)
589 );
590 assert_eq!(Some(&transaction), new_cache.get_transaction(&H256::zero()));
591 assert_bridge_addresses_eq(
592 &bridge_addresses,
593 new_cache
594 .get_bridge_addresses()
595 .expect("expected addresses"),
596 );
597 }
598
599 #[test]
600 fn test_cache_config_disk_enables_cache_and_can_reset_data_on_disk() {
601 let block_full = Block::<TransactionVariant> {
602 hash: H256::repeat_byte(0x1),
603 number: U64::from(1),
604 ..Default::default()
605 };
606 let block_min = Block::<TransactionVariant> {
607 hash: H256::repeat_byte(0x2),
608 number: U64::from(2),
609 ..Default::default()
610 };
611 let transaction = Transaction::default();
612 let raw_transactions = vec![RawTransaction {
613 common_data: ExecuteTransactionCommon::L1(Default::default()),
614 execute: Execute {
615 calldata: Default::default(),
616 contract_address: Default::default(),
617 factory_deps: vec![],
618 value: Default::default(),
619 },
620 received_timestamp_ms: 0,
621 raw_bytes: None,
622 }];
623 let bridge_addresses = BridgeAddresses {
624 l1_shared_default_bridge: Some(H160::repeat_byte(0x5)),
625 l2_shared_default_bridge: Some(H160::repeat_byte(0x6)),
626 l2_erc20_default_bridge: Some(H160::repeat_byte(0x2)),
627 l1_erc20_default_bridge: Some(H160::repeat_byte(0x1)),
628 l1_weth_bridge: Some(H160::repeat_byte(0x3)),
629 l2_weth_bridge: Some(H160::repeat_byte(0x4)),
630 l2_legacy_shared_bridge: Some(H160::repeat_byte(0x6)),
631 };
632
633 let cache_dir = tempfile::Builder::new()
634 .prefix("cache-test")
635 .tempdir()
636 .expect("failed creating temporary dir");
637 let cache_dir_path = cache_dir
638 .path()
639 .to_str()
640 .expect("invalid dir name")
641 .to_string();
642 let mut cache = Cache::new(CacheConfig::Disk {
643 dir: cache_dir_path.clone(),
644 reset: true,
645 });
646
647 cache.insert_block(block_full.hash, true, block_full.clone());
648 assert_eq!(
649 Some(&block_full),
650 cache.get_block(&H256::repeat_byte(0x1), true)
651 );
652 assert_eq!(Some(&H256::repeat_byte(0x1)), cache.get_block_hash(&1));
653
654 cache.insert_block(block_min.hash, false, block_min.clone());
655 assert_eq!(
656 Some(&block_min),
657 cache.get_block(&H256::repeat_byte(0x2), false)
658 );
659 assert_eq!(Some(&H256::repeat_byte(0x2)), cache.get_block_hash(&2));
660
661 cache.insert_block_raw_transactions(0, raw_transactions.clone());
662 assert_eq!(
663 Some(&raw_transactions),
664 cache.get_block_raw_transactions(&0)
665 );
666
667 cache.insert_transaction(H256::zero(), transaction.clone());
668 assert_eq!(Some(&transaction), cache.get_transaction(&H256::zero()));
669
670 cache.set_bridge_addresses(bridge_addresses.clone());
671 assert_bridge_addresses_eq(
672 &bridge_addresses,
673 cache.get_bridge_addresses().expect("expected addresses"),
674 );
675
676 let new_cache = Cache::new(CacheConfig::Disk {
677 dir: cache_dir_path,
678 reset: true,
679 });
680 assert_eq!(None, new_cache.get_block(&H256::zero(), true));
681 assert_eq!(None, new_cache.get_block_hash(&1));
682 assert_eq!(None, new_cache.get_block(&H256::zero(), false));
683 assert_eq!(None, new_cache.get_block_hash(&2));
684 assert_eq!(None, new_cache.get_block_raw_transactions(&0));
685 assert_eq!(None, new_cache.get_transaction(&H256::zero()));
686 assert!(new_cache.get_bridge_addresses().is_none());
687 }
688
689 #[test]
690 fn test_cache_config_disk_only_resets_created_data_on_disk() {
691 let cache_dir = tempfile::Builder::new()
692 .prefix("cache-test")
693 .tempdir()
694 .expect("failed creating temporary dir");
695 let cache_dir_path = cache_dir
696 .path()
697 .to_str()
698 .expect("invalid dir name")
699 .to_string();
700 let mut cache = Cache::new(CacheConfig::Disk {
701 dir: cache_dir_path.clone(),
702 reset: true,
703 });
704
705 cache.insert_transaction(H256::zero(), Default::default());
706 let cached_tx_file = cache_dir
707 .path()
708 .join(CACHE_TYPE_TRANSACTIONS)
709 .join(format!("{:#x}", H256::zero()));
710 assert!(
711 cached_tx_file.exists(),
712 "cached transaction did not exist on disk"
713 );
714
715 let random_file_path = cache_dir.path().join("foobar.txt");
716 _ = File::create(&random_file_path).expect("failed creating random file");
717
718 Cache::new(CacheConfig::Disk {
719 dir: cache_dir_path,
720 reset: true,
721 });
722
723 assert!(
724 !cached_tx_file.exists(),
725 "cached transaction was not reset on disk"
726 );
727 assert!(random_file_path.exists(), "random file was reset from disk");
728 }
729
730 pub fn assert_bridge_addresses_eq(
732 expected_bridge_addresses: &BridgeAddresses,
733 actual_bridge_addresses: &BridgeAddresses,
734 ) {
735 assert_eq!(
736 expected_bridge_addresses.l1_erc20_default_bridge,
737 actual_bridge_addresses.l1_erc20_default_bridge
738 );
739 assert_eq!(
740 expected_bridge_addresses.l2_erc20_default_bridge,
741 actual_bridge_addresses.l2_erc20_default_bridge
742 );
743 assert_eq!(
744 expected_bridge_addresses.l1_weth_bridge,
745 actual_bridge_addresses.l1_weth_bridge
746 );
747 assert_eq!(
748 expected_bridge_addresses.l2_weth_bridge,
749 actual_bridge_addresses.l2_weth_bridge
750 );
751 }
752}