|
| 1 | +use std::sync::Arc; |
| 2 | +use std::thread; |
| 3 | +use tempfile::TempDir; |
| 4 | + |
| 5 | +use cosmwasm_std::{coins, Empty}; |
| 6 | +use cosmwasm_vm::testing::{mock_backend, mock_env, mock_info, MockApi, MockQuerier, MockStorage}; |
| 7 | +use cosmwasm_vm::{ |
| 8 | + call_execute, call_instantiate, features_from_csv, Cache, CacheOptions, InstanceOptions, Size, |
| 9 | +}; |
| 10 | + |
| 11 | +// Instance |
| 12 | +const DEFAULT_MEMORY_LIMIT: Size = Size::mebi(64); |
| 13 | +const DEFAULT_GAS_LIMIT: u64 = 400_000; |
| 14 | +const DEFAULT_INSTANCE_OPTIONS: InstanceOptions = InstanceOptions { |
| 15 | + gas_limit: DEFAULT_GAS_LIMIT, |
| 16 | + print_debug: false, |
| 17 | +}; |
| 18 | +// Cache |
| 19 | +const MEMORY_CACHE_SIZE: Size = Size::mebi(200); |
| 20 | + |
| 21 | +static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); |
| 22 | + |
| 23 | +const SAVE_WASM_THREADS: usize = 32; |
| 24 | +const INSTANTIATION_THREADS: usize = 2048; |
| 25 | +const THREADS: usize = SAVE_WASM_THREADS + INSTANTIATION_THREADS; |
| 26 | + |
| 27 | +pub fn main() { |
| 28 | + let options = CacheOptions { |
| 29 | + base_dir: TempDir::new().unwrap().into_path(), |
| 30 | + supported_features: features_from_csv("staking"), |
| 31 | + memory_cache_size: MEMORY_CACHE_SIZE, |
| 32 | + instance_memory_limit: DEFAULT_MEMORY_LIMIT, |
| 33 | + }; |
| 34 | + |
| 35 | + let cache: Cache<MockApi, MockStorage, MockQuerier> = |
| 36 | + unsafe { Cache::new(options.clone()).unwrap() }; |
| 37 | + let cache = Arc::new(cache); |
| 38 | + |
| 39 | + let checksum = cache.save_wasm(CONTRACT).unwrap(); |
| 40 | + |
| 41 | + let mut threads = Vec::with_capacity(THREADS); |
| 42 | + for _ in 0..SAVE_WASM_THREADS { |
| 43 | + let cache = Arc::clone(&cache); |
| 44 | + |
| 45 | + threads.push(thread::spawn(move || { |
| 46 | + let checksum = cache.save_wasm(CONTRACT).unwrap(); |
| 47 | + println!("Done saving Wasm {}", checksum); |
| 48 | + })); |
| 49 | + } |
| 50 | + for _ in 0..INSTANTIATION_THREADS { |
| 51 | + let cache = Arc::clone(&cache); |
| 52 | + |
| 53 | + threads.push(thread::spawn(move || { |
| 54 | + let checksum = checksum.clone(); |
| 55 | + let mut instance = cache |
| 56 | + .get_instance(&checksum, mock_backend(&[]), DEFAULT_INSTANCE_OPTIONS) |
| 57 | + .unwrap(); |
| 58 | + println!("Done instantiating contract"); |
| 59 | + |
| 60 | + let info = mock_info("creator", &coins(1000, "earth")); |
| 61 | + let msg = br#"{"verifier": "verifies", "beneficiary": "benefits"}"#; |
| 62 | + let contract_result = |
| 63 | + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap(); |
| 64 | + assert!(contract_result.into_result().is_ok()); |
| 65 | + |
| 66 | + let info = mock_info("verifies", &coins(15, "earth")); |
| 67 | + let msg = br#"{"release":{}}"#; |
| 68 | + let contract_result = |
| 69 | + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap(); |
| 70 | + assert!(contract_result.into_result().is_ok()); |
| 71 | + })); |
| 72 | + } |
| 73 | + |
| 74 | + threads.into_iter().for_each(|thread| { |
| 75 | + thread |
| 76 | + .join() |
| 77 | + .expect("The thread creating or execution failed !") |
| 78 | + }); |
| 79 | + |
| 80 | + assert_eq!(cache.stats().misses, 0); |
| 81 | + assert_eq!(cache.stats().hits_pinned_memory_cache, 0); |
| 82 | + assert_eq!( |
| 83 | + cache.stats().hits_memory_cache, |
| 84 | + INSTANTIATION_THREADS as u32 - 1 |
| 85 | + ); |
| 86 | + assert_eq!(cache.stats().hits_fs_cache, 1); |
| 87 | +} |
0 commit comments