Skip to content

Commit b24e652

Browse files
authored
Merge pull request #2473 from CosmWasm/co/enable-reference-types
Enable reference-types during validation
2 parents c8763bc + 5a79791 commit b24e652

File tree

6 files changed

+101
-5
lines changed

6 files changed

+101
-5
lines changed

.circleci/config.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,8 @@ jobs:
731731

732732
contract_hackatom:
733733
docker:
734-
- image: rust:1.81
734+
# We compile this contract with the upper bound to detect issues with new Rust versions early
735+
- image: rust:1.84.1
735736
environment:
736737
RUST_BACKTRACE: 1
737738
working_directory: ~/cosmwasm/contracts/hackatom
@@ -743,9 +744,9 @@ jobs:
743744
command: rustc --version; cargo --version; rustup --version
744745
- restore_cache:
745746
keys:
746-
- cargocache-v2-contract_hackatom-rust:1.81-{{ checksum "Cargo.lock" }}
747+
- cargocache-v2-contract_hackatom-rust:1.84.1-{{ checksum "Cargo.lock" }}
747748
- check_contract:
748-
min_version: "2.2"
749+
min_version: "3.0"
749750
- save_cache:
750751
paths:
751752
- /usr/local/cargo/registry
@@ -755,7 +756,7 @@ jobs:
755756
- target/wasm32-unknown-unknown/release/.fingerprint
756757
- target/wasm32-unknown-unknown/release/build
757758
- target/wasm32-unknown-unknown/release/deps
758-
key: cargocache-v2-contract_hackatom-rust:1.81-{{ checksum "Cargo.lock" }}
759+
key: cargocache-v2-contract_hackatom-rust:1.84.1-{{ checksum "Cargo.lock" }}
759760

760761
contract_ibc_callbacks:
761762
docker:

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ and this project adheres to
8181
- cosmwasm-vm: Update wasmer to 5.0.6. ([#2472])
8282
- cosmwasm-std: Add a new `exports` feature which needs to be enabled for the
8383
primary cosmwasm_std dependency of a contract.
84+
- cosmwasm-vm: Enable partial reference-type support, enabling contracts
85+
compiled with Rust 1.82 or newer to be stored. ([#2473])
8486

8587
## Fixed
8688

@@ -122,6 +124,7 @@ and this project adheres to
122124
[#2458]: https://github.com/CosmWasm/cosmwasm/pull/2458
123125
[#2467]: https://github.com/CosmWasm/cosmwasm/pull/2467
124126
[#2472]: https://github.com/CosmWasm/cosmwasm/pull/2472
127+
[#2473]: https://github.com/CosmWasm/cosmwasm/pull/2473
125128

126129
## [2.2.0] - 2024-12-17
127130

packages/vm/src/cache.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,32 @@ mod tests {
17301730
assert_eq!(restored, HACKATOM);
17311731
}
17321732

1733+
#[test]
1734+
fn func_ref_test() {
1735+
let wasm = wat::parse_str(
1736+
r#"(module
1737+
(type (func))
1738+
(type (func (param funcref)))
1739+
(import "env" "abort" (func $f (type 1)))
1740+
(func (type 0) nop)
1741+
(export "add_one" (func 0))
1742+
(export "allocate" (func 0))
1743+
(export "interface_version_8" (func 0))
1744+
(export "deallocate" (func 0))
1745+
(export "memory" (memory 0))
1746+
(memory 3)
1747+
)"#,
1748+
)
1749+
.unwrap();
1750+
1751+
let cache: Cache<MockApi, MockStorage, MockQuerier> =
1752+
unsafe { Cache::new(make_testing_options()).unwrap() };
1753+
1754+
// making sure this doesn't panic
1755+
let err = cache.store_code(&wasm, true, true).unwrap_err();
1756+
assert!(err.to_string().contains("FuncRef"));
1757+
}
1758+
17331759
#[test]
17341760
fn test_wasm_limits_checked() {
17351761
let tmp_dir = TempDir::new().unwrap();

packages/vm/src/parsed_wasm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ impl<'a> ParsedWasm<'a> {
7777
| WasmFeatures::SATURATING_FLOAT_TO_INT
7878
| WasmFeatures::SIGN_EXTENSION
7979
| WasmFeatures::MULTI_VALUE
80-
| WasmFeatures::FLOATS;
80+
| WasmFeatures::FLOATS
81+
| WasmFeatures::REFERENCE_TYPES;
8182

8283
let mut validator = Validator::new_with_features(features);
8384

packages/vm/src/wasm_backend/compile.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,17 @@ mod tests {
2020
let engine = make_compiling_engine(None);
2121
assert!(compile(&engine, FLOATY).is_ok());
2222
}
23+
24+
#[test]
25+
fn reference_types_dont_panic() {
26+
const WASM: &str = r#"(module
27+
(type $t0 (func (param funcref externref)))
28+
(import "" "" (func $hello (type $t0)))
29+
)"#;
30+
31+
let wasm = wat::parse_str(WASM).unwrap();
32+
let engine = make_compiling_engine(None);
33+
let error = compile(&engine, &wasm).unwrap_err();
34+
assert!(error.to_string().contains("FuncRef"));
35+
}
2336
}

packages/vm/src/wasm_backend/gatekeeper.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ impl Default for Gatekeeper {
6363
Self::new(GatekeeperConfig {
6464
allow_floats: true,
6565
allow_feature_bulk_memory_operations: false,
66+
// we allow the reference types proposal during compatibility checking because a subset
67+
// of it is required since Rust 1.82, but we don't allow any of the instructions specific
68+
// to the proposal here. Especially `table.grow` and `table.fill` can be abused to cause
69+
// very long runtime and high memory usage.
6670
allow_feature_reference_types: false,
6771
allow_feature_simd: false,
6872
allow_feature_exception_handling: false,
@@ -444,4 +448,52 @@ mod tests {
444448
.to_string()
445449
.contains("Bulk memory operation"));
446450
}
451+
452+
#[test]
453+
fn bulk_table_operations_not_supported() {
454+
// these operations can take a long time with big tables
455+
let deterministic = Arc::new(Gatekeeper::default());
456+
let mut compiler = make_compiler_config();
457+
compiler.push_middleware(deterministic);
458+
let store = Store::new(compiler);
459+
460+
let wasm = wat::parse_str(
461+
r#"
462+
(module
463+
(table 2 funcref)
464+
(func (export "test") (param $i i32) (result i32)
465+
;; grow table to size of $i
466+
ref.null func
467+
local.get $i
468+
table.grow 0))
469+
"#,
470+
)
471+
.unwrap();
472+
473+
let result = Module::new(&store, wasm);
474+
assert!(result
475+
.unwrap_err()
476+
.to_string()
477+
.contains("Reference type operation"));
478+
479+
let wasm = wat::parse_str(
480+
r#"
481+
(module
482+
(table 1000000 funcref)
483+
(func (export "test") (param $i i32)
484+
;; fill with nulls
485+
i32.const 0
486+
ref.null func
487+
i32.const 1000000
488+
table.fill 0))
489+
"#,
490+
)
491+
.unwrap();
492+
493+
let result = Module::new(&store, wasm);
494+
assert!(result
495+
.unwrap_err()
496+
.to_string()
497+
.contains("Reference type operation"));
498+
}
447499
}

0 commit comments

Comments
 (0)