From 017599fe20d9a67120f5c1171f961faf09f19d68 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Mon, 27 Mar 2023 12:21:39 -0400 Subject: [PATCH 1/2] fix: parse XDR Result to JSON The test here copies the logic of [the errors example](https://github.com/stellar/soroban-examples/blob/main/errors/src/lib.rs), showing that valid `Ok` results were not being correctly parsed to JSON. Co-authored-by: Willem Wyndham --- .../test-wasms/custom_type/src/lib.rs | 19 ++++++++++++++++-- .../soroban-test/tests/it/custom_types.rs | 20 +++++++++++++++++++ cmd/soroban-cli/src/strval.rs | 5 +++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs index 0b3ce9c27..c2af3f469 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] use soroban_sdk::{ - contractimpl, contracttype, vec, Address, Bytes, BytesN, Env, Map, Set, String, Symbol, Vec, - I256, U256, + contracterror, contractimpl, contracttype, vec, Address, Bytes, BytesN, Env, Map, Set, String, + Symbol, Vec, I256, U256, }; pub struct Contract; @@ -43,12 +43,27 @@ pub enum ComplexEnum { Void, } +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum Error { + OhNo = 1, +} + #[contractimpl] impl Contract { pub fn hello(_env: Env, hello: Symbol) -> Symbol { hello } + pub fn u32_fail_on_even(_env: Env, u32_: u32) -> Result { + if u32_ % 2 == 1 { + Ok(u32_) + } else { + Err(Error::OhNo) + } + } + pub fn u32_(_env: Env, u32_: u32) -> u32 { u32_ } diff --git a/cmd/crates/soroban-test/tests/it/custom_types.rs b/cmd/crates/soroban-test/tests/it/custom_types.rs index 80013d932..9c19833a7 100644 --- a/cmd/crates/soroban-test/tests/it/custom_types.rs +++ b/cmd/crates/soroban-test/tests/it/custom_types.rs @@ -174,6 +174,26 @@ fn number_arg() { invoke_with_roundtrip("u32_", 42); } +#[test] +fn number_arg_return_ok() { + invoke(&TestEnv::default(), "u32_fail_on_even") + .arg("--u32_") + .arg("1") + .assert() + .success() + .stdout("1\n"); +} + +#[test] +fn number_arg_return_err() { + invoke(&TestEnv::default(), "u32_fail_on_even") + .arg("--u32_") + .arg("2") + .assert() + .success() + .stderr(predicates::str::contains("Status(ContractError(1))")); +} + #[test] fn i32() { invoke_with_roundtrip("i32_", 42); diff --git a/cmd/soroban-cli/src/strval.rs b/cmd/soroban-cli/src/strval.rs index 573333c35..50b56062b 100644 --- a/cmd/soroban-cli/src/strval.rs +++ b/cmd/soroban-cli/src/strval.rs @@ -650,6 +650,11 @@ impl Spec { (ScVal::Address(v), ScType::Address) => sc_address_to_json(v), + (ok_val, ScType::Result(result_type)) => { + let ScSpecTypeResult { ok_type, .. } = result_type.as_ref(); + self.xdr_to_json(ok_val, ok_type)? + } + (x, y) => return Err(Error::InvalidPair(x.clone(), y.clone())), }) } From 3f345cbb1000329e8e7114b66f5de7e07dd63acf Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Tue, 28 Mar 2023 16:15:16 -0400 Subject: [PATCH 2/2] fix(strval): encode RawVal return types --- .../fixtures/test-wasms/custom_type/src/lib.rs | 12 ++++++++++-- .../soroban-test/tests/it/custom_types.rs | 18 ++++++++++++++++++ cmd/soroban-cli/src/strval.rs | 3 ++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs index c2af3f469..938d95796 100644 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs +++ b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] use soroban_sdk::{ - contracterror, contractimpl, contracttype, vec, Address, Bytes, BytesN, Env, Map, Set, String, - Symbol, Vec, I256, U256, + contracterror, contractimpl, contracttype, vec, Address, Bytes, BytesN, Env, Map, RawVal, Set, + String, Symbol, Vec, I256, U256, }; pub struct Contract; @@ -56,6 +56,14 @@ impl Contract { hello } + pub fn void(_env: Env) { + // do nothing + } + + pub fn raw_val(_env: Env) -> RawVal { + RawVal::default() + } + pub fn u32_fail_on_even(_env: Env, u32_: u32) -> Result { if u32_ % 2 == 1 { Ok(u32_) diff --git a/cmd/crates/soroban-test/tests/it/custom_types.rs b/cmd/crates/soroban-test/tests/it/custom_types.rs index 9c19833a7..60185cb27 100644 --- a/cmd/crates/soroban-test/tests/it/custom_types.rs +++ b/cmd/crates/soroban-test/tests/it/custom_types.rs @@ -194,6 +194,24 @@ fn number_arg_return_err() { .stderr(predicates::str::contains("Status(ContractError(1))")); } +#[test] +fn void() { + invoke(&TestEnv::default(), "void") + .assert() + .success() + .stdout("\n") + .stderr(""); +} + +#[test] +fn raw_val() { + invoke(&TestEnv::default(), "raw_val") + .assert() + .success() + .stdout("null\n") + .stderr(""); +} + #[test] fn i32() { invoke_with_roundtrip("i32_", 42); diff --git a/cmd/soroban-cli/src/strval.rs b/cmd/soroban-cli/src/strval.rs index 50b56062b..2162481a8 100644 --- a/cmd/soroban-cli/src/strval.rs +++ b/cmd/soroban-cli/src/strval.rs @@ -438,7 +438,8 @@ impl Spec { /// May panic pub fn xdr_to_json(&self, val: &ScVal, output: &ScType) -> Result { Ok(match (val, output) { - (ScVal::Map(None) | ScVal::Vec(None), ScType::Option(_)) => Value::Null, + (ScVal::Void, ScType::Val) + | (ScVal::Map(None) | ScVal::Vec(None), ScType::Option(_)) => Value::Null, (ScVal::Bool(_), ScType::Bool) | (ScVal::Void, ScType::Void) | (ScVal::String(_), ScType::String)