Skip to content

Commit 201829c

Browse files
committed
Test recovers_from_out_of_gas
1 parent 236cc05 commit 201829c

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/vm/src/backends/singlepass.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,10 @@ pub fn set_gas(instance: &mut Instance, limit: u64) {
4040

4141
pub fn get_gas(instance: &Instance) -> u64 {
4242
let used = metering::get_points_used(instance);
43-
GAS_LIMIT - used
43+
// when running out of gas, get_points_used can exceed GAS_LIMIT
44+
if used < GAS_LIMIT {
45+
GAS_LIMIT - used
46+
} else {
47+
0
48+
}
4449
}

lib/vm/src/cache.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,44 @@ mod test {
335335
assert_eq!(cache.stats.misses, 0);
336336
assert_eq!(instance2.get_gas(), TESTING_GAS_LIMIT);
337337
}
338+
339+
#[test]
340+
#[cfg(feature = "default-singlepass")]
341+
fn recovers_from_out_of_gas() {
342+
let tmp_dir = TempDir::new().unwrap();
343+
let mut cache = unsafe { CosmCache::new(tmp_dir.path(), 10).unwrap() };
344+
let id = cache.save_wasm(CONTRACT_0_7).unwrap();
345+
346+
let deps1 = dependencies(20);
347+
let deps2 = dependencies(20);
348+
349+
// Init from module cache
350+
let mut instance1 = cache.get_instance(&id, deps1, 10).unwrap();
351+
assert_eq!(cache.stats.hits_module, 1);
352+
assert_eq!(cache.stats.hits_instance, 0);
353+
assert_eq!(cache.stats.misses, 0);
354+
355+
// Consume some gas. This fails
356+
let env1 = mock_env(&instance1.api, "owner1", &coin("1000", "earth"), &[]);
357+
let msg1 = r#"{"verifier": "sue", "beneficiary": "mary"}"#.as_bytes();
358+
match call_init(&mut instance1, &env1, msg1) {
359+
Err(Error::RuntimeErr { .. }) => (), // all good, continue
360+
Err(e) => panic!("unexpected error, {:?}", e),
361+
Ok(_) => panic!("call_init must run out of gas"),
362+
}
363+
assert_eq!(instance1.get_gas(), 0);
364+
cache.store_instance(&id, instance1).unwrap();
365+
366+
// Init from instance cache
367+
let mut instance2 = cache.get_instance(&id, deps2, TESTING_GAS_LIMIT).unwrap();
368+
assert_eq!(cache.stats.hits_module, 1);
369+
assert_eq!(cache.stats.hits_instance, 1);
370+
assert_eq!(cache.stats.misses, 0);
371+
assert_eq!(instance2.get_gas(), TESTING_GAS_LIMIT);
372+
373+
// Now it works
374+
let env2 = mock_env(&instance2.api, "owner2", &coin("500", "earth"), &[]);
375+
let msg2 = r#"{"verifier": "bob", "beneficiary": "john"}"#.as_bytes();
376+
call_init(&mut instance2, &env2, msg2).unwrap();
377+
}
338378
}

0 commit comments

Comments
 (0)