Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/codegen/encoding/soroban_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub fn soroban_decode_arg(
},
Type::Uint(64) => decode_u64(wrapper_cfg, vartab, arg),

Type::Address(_) | Type::String => arg.clone(),
Type::Address(_) | Type::String | Type::DynamicBytes => arg.clone(),

Type::Enum(enum_no) => {
let decoded = soroban_decode_arg(arg, wrapper_cfg, vartab, ns, Some(Type::Uint(32)));
Expand Down Expand Up @@ -721,6 +721,11 @@ pub fn soroban_encode_arg(
res: obj,
expr: encode_vector(item.clone(), cfg, vartab),
},
Type::DynamicBytes => Instr::Set {
loc: Loc::Codegen,
res: obj,
expr: item.clone(),
},

_ => todo!("Type not yet supported in soroban encoder: {:?}", item.ty()),
};
Expand Down
7 changes: 2 additions & 5 deletions src/emit/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,11 +888,8 @@ impl<'a> Binary<'a> {

fn var_ty_uses_pointer_storage(&self, ty: &Type) -> bool {
match ty.deref_memory() {
Type::Struct(_)
| Type::Array(..)
| Type::DynamicBytes
| Type::ExternalFunction { .. } => true,
Type::String => self.ns.target != Target::Soroban,
Type::Struct(_) | Type::Array(..) | Type::ExternalFunction { .. } => true,
Type::String | Type::DynamicBytes => self.ns.target != Target::Soroban,
_ => false,
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/emit/soroban/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ impl SorobanTarget {
ast::Type::Uint(256) => ScSpecTypeDef::U256,
ast::Type::Bool => ScSpecTypeDef::Bool,
ast::Type::Address(_) => ScSpecTypeDef::Address,
ast::Type::Bytes(_) => ScSpecTypeDef::Bytes,
ast::Type::Bytes(_) | ast::Type::DynamicBytes => {
ScSpecTypeDef::Bytes
}
ast::Type::String => ScSpecTypeDef::String,
ast::Type::Array(ty, _) => {
let element = Self::vec_spec_type(ty.as_ref());
Expand Down Expand Up @@ -377,7 +379,7 @@ impl SorobanTarget {
ast::Type::Int(_) => ScSpecTypeDef::I32,
ast::Type::Bool => ScSpecTypeDef::Bool,
ast::Type::Address(_) => ScSpecTypeDef::Address,
ast::Type::Bytes(_) => ScSpecTypeDef::Bytes,
ast::Type::Bytes(_) | ast::Type::DynamicBytes => ScSpecTypeDef::Bytes,
ast::Type::String => ScSpecTypeDef::String,
ast::Type::Void => ScSpecTypeDef::Void,
ast::Type::Struct(_) => ScSpecTypeDef::Void, // TODO: Map struct types.
Expand Down
32 changes: 32 additions & 0 deletions tests/soroban_testcases/dynamic_bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: Apache-2.0

use crate::build_solidity;
use soroban_sdk::{Bytes, FromVal, IntoVal};

#[test]
fn set_and_get_bytes() {
let src = build_solidity(
r#"contract BytesWriteStub {
bytes public data;

function set_data(bytes memory d) public {
data = d;
}
}"#,
|_| {},
);

let addr = src.contracts.last().unwrap();

// empty bytes round-trip
let empty = Bytes::from_slice(&src.env, b"");
src.invoke_contract(addr, "set_data", vec![empty.clone().into_val(&src.env)]);
let res = src.invoke_contract(addr, "data", vec![]);
assert_eq!(Bytes::from_val(&src.env, &res), empty);

// non-empty bytes round-trip
let payload = Bytes::from_slice(&src.env, b"hello");
src.invoke_contract(addr, "set_data", vec![payload.clone().into_val(&src.env)]);
let res = src.invoke_contract(addr, "data", vec![]);
assert_eq!(Bytes::from_val(&src.env, &res), payload);
}
1 change: 1 addition & 0 deletions tests/soroban_testcases/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
mod alloc;
mod array_args;
mod dynamic_bytes;
mod atomic_swap;
mod auth;
mod constructor;
Expand Down
Loading