diff --git a/soroban-env-host/src/test/map.rs b/soroban-env-host/src/test/map.rs index 147286f09..f9d9a95ba 100644 --- a/soroban-env-host/src/test/map.rs +++ b/soroban-env-host/src/test/map.rs @@ -7,6 +7,7 @@ use soroban_env_common::{ }, MapObject, U32Val, }; +use soroban_test_wasms::LINEAR_MEMORY; use crate::{ xdr::{ScMap, ScMapEntry, ScVal, ScVec, VecM}, @@ -338,3 +339,62 @@ fn map_build_bad_element_integrity() -> Result<(), HostError> { Ok(()) } + +#[test] +fn initialization_invalid() -> Result<(), HostError> { + use crate::EnvBase; + let host = observe_host!(Host::default()); + + // Out of order keys + assert!(host + .map_new_from_slices(&["b", "a"], &[1u32.into(), 2u32.into()]) + .is_err()); + + // Duplicate + assert!(host + .map_new_from_slices(&["a", "a"], &[1u32.into(), 2u32.into()]) + .is_err()); + + let buf = vec![0; 7000000]; + let scv_bytes = ScVal::Bytes(buf.try_into().unwrap()); + let bytes_val = host.to_host_val(&scv_bytes)?; + + // roughly consumes 7*5=42MiB (> 40 MiB is the budget limit) + let vals = vec![bytes_val; 5]; + let keys = ["a", "b", "c", "d", "e"]; + + let res = host.map_new_from_slices(&keys, &vals.as_slice())?; + assert!(host.from_host_val(res.to_val()).is_err()); + + Ok(()) +} + +#[test] +fn linear_memory_operations() -> Result<(), HostError> { + let host = observe_host!(Host::test_host_with_recording_footprint()); + host.enable_debug()?; + let id_obj = host.register_test_contract_wasm(LINEAR_MEMORY); + + { + let args = host.vec_new()?; + let res = host.call( + id_obj, + Symbol::try_from_val(&*host, &"map_mem_ok").unwrap(), + args, + ); + + assert!(res.is_ok()); + } + + { + let args = host.vec_new()?; + let res = host.call( + id_obj, + Symbol::try_from_val(&*host, &"map_mem_bad").unwrap(), + args, + ); + assert!(res.is_err()); + assert!(res.unwrap_err().error.is_code(ScErrorCode::InvalidInput)); + } + Ok(()) +} diff --git a/soroban-test-wasms/wasm-workspace/linear_memory/src/lib.rs b/soroban-test-wasms/wasm-workspace/linear_memory/src/lib.rs index 641ce3945..52e54b738 100644 --- a/soroban-test-wasms/wasm-workspace/linear_memory/src/lib.rs +++ b/soroban-test-wasms/wasm-workspace/linear_memory/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] use soroban_sdk::{contract, contractimpl, Bytes, Env}; -use soroban_env_common::{VecObject, Val, EnvBase, Error}; +use soroban_env_common::{VecObject, MapObject, Val, EnvBase, Error}; #[contract] pub struct Contract; @@ -51,4 +51,26 @@ impl Contract { assert!(e.vec_unpack_to_slice(vec, &mut long_buf).is_err()); Ok(()) } + + // Bounce a map of vals off the host, successfully + pub fn map_mem_ok(e: Env) -> Result<(), Error> { + let map: MapObject = e.map_new_from_slices(&["a", "b"], &[1u32.into(), 2u32.into()])?; + + let key_buf = ["a", "b"]; + let mut val_buf: [Val; 2] = [Val::from(0); 2]; + + e.map_unpack_to_slice(map, &key_buf, &mut val_buf)?; + Ok(()) + } + + // Same but with out of order keys + pub fn map_mem_bad(e: Env) -> Result<(), Error> { + // out of order + assert!(e.map_new_from_slices(&["b", "a"], &[1u32.into(), 2u32.into()]).is_err()); + + // duplicate + assert!(e.map_new_from_slices(&["a", "a"], &[1u32.into(), 2u32.into()]).is_err()); + + Ok(()) + } } diff --git a/soroban-test-wasms/wasm-workspace/opt/curr/example_linear_memory.wasm b/soroban-test-wasms/wasm-workspace/opt/curr/example_linear_memory.wasm index 8bfe36bbe..e51df9d65 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/curr/example_linear_memory.wasm and b/soroban-test-wasms/wasm-workspace/opt/curr/example_linear_memory.wasm differ