From 4b366a38798a84ca0ca4dde2aaef5ffdcc1cc4a4 Mon Sep 17 00:00:00 2001 From: Dmytro Kozhevin Date: Thu, 29 Aug 2024 19:15:25 -0400 Subject: [PATCH 1/3] Improved error message for Symbol validation error. (#1451) ### What Resolves https://github.com/stellar/rs-soroban-env/issues/812 Improved error message for Symbol validation error. ### Why Error improvement ### Known limitations N/A --- soroban-env-common/src/symbol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soroban-env-common/src/symbol.rs b/soroban-env-common/src/symbol.rs index 72122d91e..256fdbbdb 100644 --- a/soroban-env-common/src/symbol.rs +++ b/soroban-env-common/src/symbol.rs @@ -77,7 +77,7 @@ impl core::fmt::Display for SymbolError { "symbol too long: length {len}, max {MAX_SMALL_CHARS}" )), SymbolError::BadChar(char) => f.write_fmt(format_args!( - "symbol bad char: encountered {char}, supported range [a-zA-Z0-9_]" + "symbol bad char: encountered `{char}`, supported range [a-zA-Z0-9_]" )), SymbolError::MalformedSmall => f.write_str("malformed small symbol"), } From df188038e07672e7a1f1a3a46bb84bc118cdd30f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 3 Sep 2024 10:02:50 +1000 Subject: [PATCH 2/3] Update with stellar-xdr with split interface version (#1453) ### What Update with stellar-xdr with split interface version. ### Why See: - https://github.com/stellar/stellar-xdr/pull/212 Dependent on: - https://github.com/stellar/stellar-xdr/pull/212 - https://github.com/stellar/stellar-xdr/pull/213 - https://github.com/stellar/rs-stellar-xdr/pull/389 --- Cargo.lock | 2 +- Cargo.toml | 2 +- soroban-env-common/src/lib.rs | 2 +- soroban-env-common/src/meta.rs | 30 ++++++------------- soroban-env-host/Cargo.toml | 2 +- soroban-env-host/src/host.rs | 2 +- soroban-env-host/src/test/hostile.rs | 14 +++++---- .../src/test/metering_benchmark.rs | 2 +- soroban-env-host/src/test/protocol_gate.rs | 4 +-- soroban-env-host/src/testutils.rs | 11 +++---- soroban-env-host/src/vm/parsed_module.rs | 26 +++++++++------- soroban-env-macros/src/lib.rs | 27 ++++++++++------- soroban-synth-wasm/src/mod_emitter.rs | 13 ++++---- 13 files changed, 69 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1404b618f..2715ced0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1575,7 +1575,7 @@ dependencies = [ [[package]] name = "stellar-xdr" version = "22.0.0" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=550743b50cd3ca5a63f03f9d7175b4cfdfd9c4ac#550743b50cd3ca5a63f03f9d7175b4cfdfd9c4ac" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=39d7dbb0c12bd422ee43a6e2e3277789da4eaac8#39d7dbb0c12bd422ee43a6e2e3277789da4eaac8" dependencies = [ "arbitrary", "base64 0.13.1", diff --git a/Cargo.toml b/Cargo.toml index 4d8449e34..82ab4d2b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ wasmparser = "=0.116.1" [workspace.dependencies.stellar-xdr] version = "=22.0.0" git = "https://github.com/stellar/rs-stellar-xdr" -rev = "550743b50cd3ca5a63f03f9d7175b4cfdfd9c4ac" +rev = "39d7dbb0c12bd422ee43a6e2e3277789da4eaac8" default-features = false [workspace.dependencies.wasmi] diff --git a/soroban-env-common/src/lib.rs b/soroban-env-common/src/lib.rs index 937ee9fee..9ff21e563 100644 --- a/soroban-env-common/src/lib.rs +++ b/soroban-env-common/src/lib.rs @@ -45,7 +45,7 @@ macro_rules! tracy_span { pub struct Version<'a> { pub pkg: &'a str, pub rev: &'a str, - pub interface: u64, + pub interface: xdr::ScEnvMetaEntryInterfaceVersion, pub xdr: stellar_xdr::Version<'a>, } diff --git a/soroban-env-common/src/meta.rs b/soroban-env-common/src/meta.rs index 9a0783ea1..f79d53854 100644 --- a/soroban-env-common/src/meta.rs +++ b/soroban-env-common/src/meta.rs @@ -5,13 +5,13 @@ //! [Env](crate::Env) interface provided by the host, rather than a cryptic failure //! due to a runtime host function signature mismatch. -// Currently the only constant is `INTERFACE_VERSION` which is a u64 with a low -// and high component. The low component is a pre-release version which should -// be zero any time you make a real release, and the high component is the -// ledger version / protocol version (the two terms are used interchangably in -// the stellar codebase), which should both match the major release version of -// soroban and the major release version of stellar-core that it's embedded -// within. +// Currently the only constant is `INTERFACE_VERSION` which is a struct +// containing a 32-bit protocol version and 32-bit pre-release version. The +// pre-release version should be zero any time you make a real release, and the +// protocol version is the ledger version / protocol version (the two terms are +// used interchangably in the stellar codebase), which should both match the +// major release version of soroban and the major release version of +// stellar-core that it's embedded within. // // Protocol numbers will be checked for ordered compatibility (a host will only // run contracts built for same-or-older protocol versions than its own) whereas @@ -38,6 +38,8 @@ // nonzero pre-release number can be used to force recompiles on interface // changes. +use crate::xdr::ScEnvMetaEntryInterfaceVersion; + pub const ENV_META_V0_SECTION_NAME: &str = "contractenvmetav0"; // If the "next" feature is enabled, we're building from the "next" xdr @@ -60,17 +62,3 @@ soroban_env_macros::generate_env_meta_consts!( ledger_protocol_version: 22, pre_release_version: 0, ); - -pub const fn make_interface_version(protocol_version: u32, pre_release_version: u32) -> u64 { - ((protocol_version as u64) << 32) | (pre_release_version as u64) -} - -pub const fn get_ledger_protocol_version(interface_version: u64) -> u32 { - // The ledger protocol version is the high 32 bits of INTERFACE_VERSION - (interface_version >> 32) as u32 -} - -pub const fn get_pre_release_version(interface_version: u64) -> u32 { - // The pre-release version is the low 32 bits of INTERFACE_VERSION - interface_version as u32 -} diff --git a/soroban-env-host/Cargo.toml b/soroban-env-host/Cargo.toml index dee66a826..da1db8f61 100644 --- a/soroban-env-host/Cargo.toml +++ b/soroban-env-host/Cargo.toml @@ -100,7 +100,7 @@ p256 = {version = "0.13.2", default-features = false, features = ["alloc"]} [dev-dependencies.stellar-xdr] version = "=22.0.0" git = "https://github.com/stellar/rs-stellar-xdr" -rev = "550743b50cd3ca5a63f03f9d7175b4cfdfd9c4ac" +rev = "39d7dbb0c12bd422ee43a6e2e3277789da4eaac8" default-features = false features = ["arbitrary"] diff --git a/soroban-env-host/src/host.rs b/soroban-env-host/src/host.rs index 0a015e0cc..549c0aeb3 100644 --- a/soroban-env-host/src/host.rs +++ b/soroban-env-host/src/host.rs @@ -548,7 +548,7 @@ impl Host { &[proto.into()], )); } - if proto > meta::get_ledger_protocol_version(meta::INTERFACE_VERSION) { + if proto > meta::INTERFACE_VERSION.protocol { return Err(self.err( ScErrorType::Context, ScErrorCode::InternalError, diff --git a/soroban-env-host/src/test/hostile.rs b/soroban-env-host/src/test/hostile.rs index 3552b2d5d..0981db11d 100644 --- a/soroban-env-host/src/test/hostile.rs +++ b/soroban-env-host/src/test/hostile.rs @@ -751,8 +751,7 @@ fn test_integer_overflow() -> Result<(), HostError> { #[test] fn test_corrupt_custom_section() -> Result<(), HostError> { - use crate::meta::make_interface_version; - use crate::xdr::{Limits, ScEnvMetaEntry, WriteXdr}; + use crate::xdr::{Limits, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, WriteXdr}; let host = observe_host!(Host::test_host_with_recording_footprint()); host.enable_debug()?; @@ -781,9 +780,12 @@ fn test_corrupt_custom_section() -> Result<(), HostError> { )); // invalid section name - let xdr = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(make_interface_version(20, 0)) - .to_xdr(Limits::none()) - .unwrap(); + let xdr = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(ScEnvMetaEntryInterfaceVersion { + protocol: 20, + pre_release: 0, + }) + .to_xdr(Limits::none()) + .unwrap(); let res = host.register_test_contract_wasm_from_source_account( wasm_util::wasm_module_with_custom_section("contractenvmetav1", &xdr).as_slice(), generate_account_id(&host), @@ -828,7 +830,7 @@ fn test_corrupt_custom_section() -> Result<(), HostError> { )); // invalid: protocol is current but pre-release version doesn't match env's - let env_pre = meta::get_pre_release_version(meta::INTERFACE_VERSION); + let env_pre = meta::INTERFACE_VERSION.pre_release; let res = host.register_test_contract_wasm_from_source_account( wasm_util::wasm_module_with_custom_section( "contractenvmetav0", diff --git a/soroban-env-host/src/test/metering_benchmark.rs b/soroban-env-host/src/test/metering_benchmark.rs index cf481df09..30d077371 100644 --- a/soroban-env-host/src/test/metering_benchmark.rs +++ b/soroban-env-host/src/test/metering_benchmark.rs @@ -21,7 +21,7 @@ use crate::testutils::{generate_account_id, generate_bytes_array}; // RUST_TEST_THREADS=1 cargo test --release --package soroban-env-host --lib --features testutils -- test::metering_benchmark --nocapture --ignored const LEDGER_INFO: LedgerInfo = LedgerInfo { - protocol_version: crate::meta::get_ledger_protocol_version(crate::meta::INTERFACE_VERSION), + protocol_version: crate::meta::INTERFACE_VERSION.protocol, sequence_number: 1234, timestamp: 1234, network_id: [7; 32], diff --git a/soroban-env-host/src/test/protocol_gate.rs b/soroban-env-host/src/test/protocol_gate.rs index 282a874b7..418398e1d 100644 --- a/soroban-env-host/src/test/protocol_gate.rs +++ b/soroban-env-host/src/test/protocol_gate.rs @@ -1,5 +1,5 @@ use crate::{ - meta::{get_ledger_protocol_version, INTERFACE_VERSION}, + meta::INTERFACE_VERSION, testutils::{generate_account_id, generate_bytes_array, wasm as wasm_util}, xdr::{ScErrorCode, ScErrorType}, AddressObject, Env, Host, HostError, LedgerInfo, Symbol, Val, WasmiMarshal, @@ -9,7 +9,7 @@ use crate::{ fn ledger_protocol_greater_than_env_protocol_should_fail() -> Result<(), HostError> { let host = Host::test_host_with_recording_footprint(); host.enable_debug()?; - let env_proto = get_ledger_protocol_version(INTERFACE_VERSION); + let env_proto = INTERFACE_VERSION.protocol; // This test only makes sense if TEST_PROTOCOL is equal to the env version if env_proto != host.get_ledger_protocol_version()? { diff --git a/soroban-env-host/src/testutils.rs b/soroban-env-host/src/testutils.rs index c3e4b2019..18f9792ab 100644 --- a/soroban-env-host/src/testutils.rs +++ b/soroban-env-host/src/testutils.rs @@ -146,9 +146,11 @@ impl SnapshotSource for MockSnapshotSource { #[cfg(test)] pub(crate) fn interface_meta_with_custom_versions(proto: u32, pre: u32) -> Vec { - use crate::xdr::{Limited, Limits, ScEnvMetaEntry, WriteXdr}; - let iv = crate::meta::make_interface_version(proto, pre); - let entry = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(iv); + use crate::xdr::{Limited, Limits, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, WriteXdr}; + let entry = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(ScEnvMetaEntryInterfaceVersion { + protocol: proto, + pre_release: pre, + }); let bytes = Vec::::new(); let mut w = Limited::new(bytes, Limits::none()); entry.write_xdr(&mut w).unwrap(); @@ -163,8 +165,7 @@ impl Host { } pub fn current_test_protocol() -> u32 { - use crate::meta::{get_ledger_protocol_version, INTERFACE_VERSION}; - let max_supported_protocol = get_ledger_protocol_version(INTERFACE_VERSION); + let max_supported_protocol = crate::meta::INTERFACE_VERSION.protocol; let min_supported_protocol = crate::host::MIN_LEDGER_PROTOCOL_VERSION; if let Ok(vers) = std::env::var("TEST_PROTOCOL") { let test_protocol = vers.parse().expect("parsing TEST_PROTOCOL"); diff --git a/soroban-env-host/src/vm/parsed_module.rs b/soroban-env-host/src/vm/parsed_module.rs index 08d6ac906..096653cf8 100644 --- a/soroban-env-host/src/vm/parsed_module.rs +++ b/soroban-env-host/src/vm/parsed_module.rs @@ -1,8 +1,11 @@ use crate::{ err, host::metered_clone::MeteredContainer, - meta::{self, get_ledger_protocol_version}, - xdr::{ContractCostType, Limited, ReadXdr, ScEnvMetaEntry, ScErrorCode, ScErrorType}, + meta, + xdr::{ + ContractCostType, Limited, ReadXdr, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, + ScErrorCode, ScErrorType, + }, Host, HostError, DEFAULT_XDR_RW_LIMITS, }; @@ -219,18 +222,18 @@ impl ParsedModule { Self::check_max_args(host, &module)?; let interface_version = Self::check_meta_section(host, &module)?; - let contract_proto = get_ledger_protocol_version(interface_version); + let contract_proto = interface_version.protocol; Ok((module, contract_proto)) } fn check_contract_interface_version( host: &Host, - interface_version: u64, + interface_version: &ScEnvMetaEntryInterfaceVersion, ) -> Result<(), HostError> { let want_proto = { let ledger_proto = host.get_ledger_protocol_version()?; - let env_proto = get_ledger_protocol_version(meta::INTERFACE_VERSION); + let env_proto = meta::INTERFACE_VERSION.protocol; if ledger_proto <= env_proto { // ledger proto should be before or equal to env proto ledger_proto @@ -247,9 +250,9 @@ impl ParsedModule { // Not used when "next" is enabled #[cfg(not(feature = "next"))] - let got_pre = meta::get_pre_release_version(interface_version); + let got_pre = interface_version.pre_release; - let got_proto = get_ledger_protocol_version(interface_version); + let got_proto = interface_version.protocol; if got_proto < want_proto { // Old protocols are finalized, we only support contracts @@ -277,7 +280,7 @@ impl ParsedModule { { // Current protocol might have a nonzero prerelease number; we will // allow it only if it matches the current prerelease exactly. - let want_pre = meta::get_pre_release_version(meta::INTERFACE_VERSION); + let want_pre = meta::INTERFACE_VERSION.pre_release; if want_pre != got_pre { return Err(err!( host, @@ -321,7 +324,10 @@ impl ParsedModule { Self::module_custom_section(&self.module, name) } - fn check_meta_section(host: &Host, m: &Module) -> Result { + fn check_meta_section( + host: &Host, + m: &Module, + ) -> Result { if let Some(env_meta) = Self::module_custom_section(m, meta::ENV_META_V0_SECTION_NAME) { let mut limits = DEFAULT_XDR_RW_LIMITS; limits.len = env_meta.len(); @@ -329,7 +335,7 @@ impl ParsedModule { if let Some(env_meta_entry) = ScEnvMetaEntry::read_xdr_iter(&mut cursor).next() { let ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) = host.map_err(env_meta_entry)?; - Self::check_contract_interface_version(host, v)?; + Self::check_contract_interface_version(host, &v)?; Ok(v) } else { Err(host.err( diff --git a/soroban-env-macros/src/lib.rs b/soroban-env-macros/src/lib.rs index 6d7c2751a..7d2aff15b 100644 --- a/soroban-env-macros/src/lib.rs +++ b/soroban-env-macros/src/lib.rs @@ -17,7 +17,7 @@ use stellar_xdr::curr as xdr; #[cfg(feature = "next")] use stellar_xdr::next as xdr; -use crate::xdr::{Limits, ScEnvMetaEntry, WriteXdr}; +use crate::xdr::{Limits, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, WriteXdr}; // We need the protocol version for some tests generated by this crate. // Unfortunately it is not available at this layer and can't read from @@ -29,7 +29,7 @@ pub(crate) const LEDGER_PROTOCOL_VERSION: u32 = 22; pub(crate) const LEDGER_PROTOCOL_VERSION: u32 = 23; struct MetaInput { - pub interface_version: u64, + pub interface_version: ScEnvMetaEntryInterfaceVersion, } impl Parse for MetaInput { @@ -38,16 +38,17 @@ impl Parse for MetaInput { interface_version: { assert_eq!(input.parse::()?, "ledger_protocol_version"); input.parse::()?; - let proto: u64 = input.parse::()?.base10_parse()?; + let proto: u32 = input.parse::()?.base10_parse()?; input.parse::()?; assert_eq!(input.parse::()?, "pre_release_version"); input.parse::()?; - let pre: u64 = input.parse::()?.base10_parse()?; + let pre: u32 = input.parse::()?.base10_parse()?; input.parse::()?; - assert!(pre <= 0xffff_ffff); - assert!(proto <= 0xffff_ffff); - assert_eq!(proto, LEDGER_PROTOCOL_VERSION as u64); - proto << 32 | pre + assert_eq!(proto, LEDGER_PROTOCOL_VERSION); + ScEnvMetaEntryInterfaceVersion { + protocol: proto, + pre_release: pre, + } }, }) } @@ -60,7 +61,7 @@ struct MetaConstsOutput { impl MetaConstsOutput { pub fn to_meta_entries(&self) -> Vec { vec![ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion( - self.input.interface_version, + self.input.interface_version.clone(), )] } } @@ -68,7 +69,8 @@ impl MetaConstsOutput { impl ToTokens for MetaConstsOutput { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { // Build params for expressing the interface version. - let interface_version = self.input.interface_version; + let proto = &self.input.interface_version.protocol; + let pre = &self.input.interface_version.pre_release; // Build params for expressing the meta xdr. let meta_xdr = self @@ -84,7 +86,10 @@ impl ToTokens for MetaConstsOutput { // Output. tokens.extend(quote! { - pub const INTERFACE_VERSION: u64 = #interface_version; + pub const INTERFACE_VERSION: ScEnvMetaEntryInterfaceVersion = ScEnvMetaEntryInterfaceVersion{ + protocol: #proto, + pre_release: #pre, + }; pub const XDR: [u8; #meta_xdr_len] = *#meta_xdr_lit; }); } diff --git a/soroban-synth-wasm/src/mod_emitter.rs b/soroban-synth-wasm/src/mod_emitter.rs index 42a6aae1b..c0518ab47 100644 --- a/soroban-synth-wasm/src/mod_emitter.rs +++ b/soroban-synth-wasm/src/mod_emitter.rs @@ -1,5 +1,5 @@ use crate::FuncEmitter; -use soroban_env_common::xdr::{Limits, ScEnvMetaEntry, WriteXdr}; +use soroban_env_common::xdr::{Limits, ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion, WriteXdr}; use std::str::FromStr; use std::{borrow::Cow, collections::BTreeMap, env}; #[cfg(feature = "adversarial")] @@ -117,9 +117,10 @@ impl ModEmitter { /// Add a metadata section marking the module as belonging to the specified /// protocol version. pub fn add_protocol_version_meta(&mut self, protocol_version: u32) -> &mut Self { - let meta = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion( - soroban_env_common::meta::make_interface_version(protocol_version, 0), - ); + let meta = ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(ScEnvMetaEntryInterfaceVersion { + protocol: protocol_version, + pre_release: 0, + }); self.custom_section( soroban_env_common::meta::ENV_META_V0_SECTION_NAME, &meta.to_xdr(Limits::none()).unwrap(), @@ -133,9 +134,7 @@ impl ModEmitter { pub fn add_test_protocol_version_meta(&mut self) -> &mut Self { let protocol_version = env::var("TEST_PROTOCOL") .map(|v| u32::from_str(&v).unwrap()) - .unwrap_or(soroban_env_common::meta::get_ledger_protocol_version( - soroban_env_common::meta::INTERFACE_VERSION, - )); + .unwrap_or(soroban_env_common::meta::INTERFACE_VERSION.protocol); self.add_protocol_version_meta(protocol_version) } From a79b3cfe3ff7229813eb49399c3f9f8a45c4fec8 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 5 Sep 2024 17:10:34 -0700 Subject: [PATCH 3/3] Add a small harness that just loads all wasms from a workspace directory (#1454) This is just a small test harness to help people who want to run simple testcases they've generated outside soroban. Put your wasm file in `soroban-env-host/src/test/hostile_inputs` and run `cargo test test_misc_hostile_wasms` and it should just pick your wasm up and attempt to instantiate and run it. Requirements: - The wasm has to have the normal contract metadata section on the front! Absent that it will be rejected immediately. - The wasm of course has to comply with the limited profile soroban uses (few-if-any post-MVP features, no floating point, etc.) - The wasm has to expose a 0-arg function called "test" which is the only thing the test tries to execute. --- .github/workflows/rust.yml | 4 +- soroban-env-host/src/test/hostile.rs | 101 ++++++++++++++++++ .../test/hostile_inputs/example_add_i32.wasm | Bin 0 -> 584 bytes .../src/test/hostile_inputs/smoke.wasm | Bin 0 -> 68 bytes 4 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 soroban-env-host/src/test/hostile_inputs/example_add_i32.wasm create mode 100644 soroban-env-host/src/test/hostile_inputs/smoke.wasm diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 397d6a132..e83decf87 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -63,10 +63,10 @@ jobs: steps: - uses: actions/checkout@v3 - run: rustup update - - uses: stellar/binaries@v24 + - uses: stellar/binaries@v29 with: name: cargo-semver-checks - version: 0.32.0 + version: 0.35.0 - run: cargo semver-checks --exclude soroban-simulation build-and-test: diff --git a/soroban-env-host/src/test/hostile.rs b/soroban-env-host/src/test/hostile.rs index 0981db11d..a7d7081eb 100644 --- a/soroban-env-host/src/test/hostile.rs +++ b/soroban-env-host/src/test/hostile.rs @@ -1322,3 +1322,104 @@ fn test_stack_depth_stability() { (ScErrorType::Budget, ScErrorCode::ExceededLimit) )); } + +#[test] +fn test_misc_hostile_wasms() { + // This test loads and runs a bunch of hostile WASM modules + // found in the hostile_inputs subdirectory. It attempts to + // instantiate the contract and then run a 0-ary function in + // the contract called "test". + let mut bad_inputs = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + bad_inputs.push("src/test/hostile_inputs"); + eprintln!("loading hostile inputs from {:?}", bad_inputs); + let mut n_wasms = 0; + let mut n_instantiated_ok = 0; + let mut n_instantiated_external_error = 0; + let mut n_instantiated_internal_error = 0; + let mut n_executed_ok = 0; + let mut n_executed_external_error = 0; + let mut n_executed_internal_error = 0; + + for entry in std::fs::read_dir(bad_inputs).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.extension().unwrap() == "wasm" { + let host = Host::test_host_with_recording_footprint(); + let filename = path.file_name().unwrap().to_str().unwrap().to_string(); + let wasm_code = std::fs::read(path).unwrap(); + eprintln!("loaded {}-byte wasm {}", wasm_code.len(), filename); + n_wasms += 1; + host.as_budget().reset_unlimited().unwrap(); + let addr_res = host.register_test_contract_wasm_from_source_account( + &wasm_code, + generate_account_id(&host), + generate_bytes_array(&host), + ); + match addr_res { + Err(e) => { + if e.error.is_code(ScErrorCode::InternalError) { + eprintln!( + "instantiation failed with internal error for {}: {:?}", + filename, e + ); + n_instantiated_internal_error += 1; + } else { + eprintln!( + "instantiation failed with external error for {}: {:?}", + filename, e + ); + n_instantiated_external_error += 1; + } + continue; + } + Ok(contract_id) => { + n_instantiated_ok += 1; + let call_res = host.call( + contract_id, + Symbol::try_from_small_str("test").unwrap(), + test_vec![&host].into(), + ); + if let Err(e) = call_res { + if e.error.is_code(ScErrorCode::InternalError) { + eprintln!( + "execution failed with internal error for {}: {:?}", + filename, e + ); + n_executed_internal_error += 1; + } else { + eprintln!( + "execution failed with external error for {}: {:?}", + filename, e + ); + n_executed_external_error += 1; + } + } else { + n_executed_ok += 1; + eprintln!("execution succeeded for {}", filename); + } + } + } + } + } + eprintln!("loaded {} hostile Wasm modules", n_wasms); + eprintln!("instantiated {} contracts successfully", n_instantiated_ok); + eprintln!( + "instantiation failed with external error for {} contracts", + n_instantiated_external_error + ); + eprintln!( + "instantiation failed with internal error for {} contracts", + n_instantiated_internal_error + ); + eprintln!("executed {} contracts successfully", n_executed_ok); + eprintln!( + "execution failed with external error for {} contracts", + n_executed_external_error + ); + eprintln!( + "execution failed with internal error for {} contracts", + n_executed_internal_error + ); + assert_eq!(n_instantiated_internal_error, 0); + assert_eq!(n_executed_internal_error, 0); +} diff --git a/soroban-env-host/src/test/hostile_inputs/example_add_i32.wasm b/soroban-env-host/src/test/hostile_inputs/example_add_i32.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ba6b3fc4e132b2fa351b6ef2863bb5159b7b71e3 GIT binary patch literal 584 zcmY*V&2G~`5S|~escH&~KoxL6>$X?YI7z$oR$D?;;>HWO8+!w4lr*xV2rfw^s;Vbm z199LTdf^3l1s(*Z`Dy8lv@`R4GvBNRTs=SlK+UH#o#OPAW;1yKXp8VOCPGc{BLD{s zNQx13_=0Dc&ga(<&ES4~u&=^_ADmZT2-uY+5atkU=6UJHF89NdG0O8#-i`9Et3A`^ zALL(1f$ZFc)bw|F59ruH_7}fq>Vv^mQoRjsP;>P?4g|c3%5e7W_m8KRH!_OD6l3CJ zL()en_G4O*arh9U$gl}5Ys0BN+Ywf?Aeha?MzZF@@^b;;e?W^0Y1Z)4s1#02V3drS z;N;yFijFzk14BPEb1CDGBM{#P0}CLyFt|!IMsl_Y-ajhNhvUi><9g(aNmDMqw#AvG zpcQ~_nW%N$y{l1D1+Sj0#r$wG@MCwY_iWKx-!8jHs;Zv&YAF^b4clqlePg4l>$1P3 u+pT6p{B>2dc5RUybh@3MKXh$d+QQky+IFW^`m%d?)N3crH_f91--Cb1f^ud6 literal 0 HcmV?d00001 diff --git a/soroban-env-host/src/test/hostile_inputs/smoke.wasm b/soroban-env-host/src/test/hostile_inputs/smoke.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e7abcab3e58e625c9bae5ae0122eebf0574fa839 GIT binary patch literal 68 zcmWm4F%Ezr5Cp*8;{<}0U-BhV5JHq|p!PYwQ*9@MJURhz;Q`)Gh!Cl>j0q%9#f}w8 TE%zespIf+^oz1F5Pdp#JJB|s~ literal 0 HcmV?d00001