Skip to content

Commit 8c63257

Browse files
committed
Add Cache::save_wasm_unchecked
1 parent dc4853c commit 8c63257

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ and this project adheres to
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- cosmwasm-vm: Add `Cache::save_wasm_unchecked` to save Wasm blobs that have
12+
been checked before. This is useful for state-sync where we know the Wasm code
13+
was checked when it was first uploaded. ([#1635])
14+
15+
[#1635]: https://github.com/CosmWasm/cosmwasm/pull/1635
16+
917
### Changed
1018

1119
- cosmwasm-vm: Add checks for table section of Wasm blob ([#1631]).

packages/vm/src/cache.rs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,27 @@ where
159159
}
160160
}
161161

162+
/// Takes a Wasm bytecode and stores it to the cache.
163+
///
164+
/// This performs static checks, compiles the bytescode to a module and
165+
/// stores the Wasm file on disk.
166+
///
167+
/// This does the same as [`save_wasm_unchecked`] plus the static checks.
168+
/// When a Wasm blob is stored the first time, use this function.
162169
pub fn save_wasm(&self, wasm: &[u8]) -> VmResult<Checksum> {
163170
check_wasm(wasm, &self.available_capabilities)?;
171+
self.save_wasm_unchecked(wasm)
172+
}
173+
174+
/// Takes a Wasm bytecode and stores it to the cache.
175+
///
176+
/// This compiles the bytescode to a module and
177+
/// stores the Wasm file on disk.
178+
///
179+
/// This does the same as [`save_wasm`] but without the static checks.
180+
/// When a Wasm blob is stored which was previously checked (e.g. as part of state sync),
181+
/// use this function.
182+
pub fn save_wasm_unchecked(&self, wasm: &[u8]) -> VmResult<Checksum> {
164183
let module = compile(wasm, None, &[])?;
165184

166185
let mut cache = self.inner.lock().unwrap();
@@ -431,6 +450,14 @@ mod tests {
431450

432451
static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm");
433452
static IBC_CONTRACT: &[u8] = include_bytes!("../testdata/ibc_reflect.wasm");
453+
// Invalid because it doesn't contain required memory and exports
454+
static INVALID_CONTRACT_WAT: &str = r#"(module
455+
(type $t0 (func (param i32) (result i32)))
456+
(func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
457+
get_local $p0
458+
i32.const 1
459+
i32.add))
460+
"#;
434461

435462
fn default_capabilities() -> HashSet<String> {
436463
capabilities_from_csv("iterator,staking")
@@ -489,17 +516,7 @@ mod tests {
489516

490517
#[test]
491518
fn save_wasm_rejects_invalid_contract() {
492-
// Invalid because it doesn't contain required memory and exports
493-
let wasm = wat::parse_str(
494-
r#"(module
495-
(type $t0 (func (param i32) (result i32)))
496-
(func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
497-
get_local $p0
498-
i32.const 1
499-
i32.add))
500-
"#,
501-
)
502-
.unwrap();
519+
let wasm = wat::parse_str(INVALID_CONTRACT_WAT).unwrap();
503520

504521
let cache: Cache<MockApi, MockStorage, MockQuerier> =
505522
unsafe { Cache::new(make_testing_options()).unwrap() };
@@ -530,6 +547,22 @@ mod tests {
530547
assert_eq!(cache.stats().misses, 0);
531548
}
532549

550+
#[test]
551+
fn save_wasm_unchecked_works() {
552+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
553+
unsafe { Cache::new(make_testing_options()).unwrap() };
554+
cache.save_wasm_unchecked(CONTRACT).unwrap();
555+
}
556+
557+
#[test]
558+
fn save_wasm_unchecked_accepts_invalid_contract() {
559+
let wasm = wat::parse_str(INVALID_CONTRACT_WAT).unwrap();
560+
561+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
562+
unsafe { Cache::new(make_testing_options()).unwrap() };
563+
cache.save_wasm_unchecked(&wasm).unwrap();
564+
}
565+
533566
#[test]
534567
fn load_wasm_works() {
535568
let cache: Cache<MockApi, MockStorage, MockQuerier> =

0 commit comments

Comments
 (0)