Skip to content

Commit be8176b

Browse files
authored
Merge pull request #847 from CosmWasm/interior_mutability
Implement interior mutability consistently and run concurrency tests
2 parents 6332ec3 + eb07177 commit be8176b

File tree

4 files changed

+219
-67
lines changed

4 files changed

+219
-67
lines changed

packages/vm/benches/main.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn bench_cache(c: &mut Criterion) {
9191
};
9292

9393
group.bench_function("save wasm", |b| {
94-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
94+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
9595
unsafe { Cache::new(options.clone()).unwrap() };
9696

9797
b.iter(|| {
@@ -101,7 +101,7 @@ fn bench_cache(c: &mut Criterion) {
101101
});
102102

103103
group.bench_function("load wasm", |b| {
104-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
104+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
105105
unsafe { Cache::new(options.clone()).unwrap() };
106106
let checksum = cache.save_wasm(CONTRACT).unwrap();
107107

@@ -112,7 +112,7 @@ fn bench_cache(c: &mut Criterion) {
112112
});
113113

114114
group.bench_function("analyze", |b| {
115-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
115+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
116116
unsafe { Cache::new(options.clone()).unwrap() };
117117
let checksum = cache.save_wasm(CONTRACT).unwrap();
118118

@@ -129,7 +129,7 @@ fn bench_cache(c: &mut Criterion) {
129129
memory_cache_size: Size(0),
130130
instance_memory_limit: DEFAULT_MEMORY_LIMIT,
131131
};
132-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
132+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
133133
unsafe { Cache::new(non_memcache).unwrap() };
134134
let checksum = cache.save_wasm(CONTRACT).unwrap();
135135

@@ -146,7 +146,7 @@ fn bench_cache(c: &mut Criterion) {
146146

147147
group.bench_function("instantiate from memory", |b| {
148148
let checksum = Checksum::generate(CONTRACT);
149-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
149+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
150150
unsafe { Cache::new(options.clone()).unwrap() };
151151
// Load into memory
152152
cache
@@ -167,7 +167,7 @@ fn bench_cache(c: &mut Criterion) {
167167

168168
group.bench_function("instantiate from pinned memory", |b| {
169169
let checksum = Checksum::generate(CONTRACT);
170-
let mut cache: Cache<MockApi, MockStorage, MockQuerier> =
170+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
171171
unsafe { Cache::new(options.clone()).unwrap() };
172172
// Load into pinned memory
173173
cache.pin(&checksum).unwrap();
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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

Comments
 (0)