Description
Similarly to #638, we want to serialize all the arguments into a single Vec<u8>
. Further, we need to make sure that the bytes aren't dropped before they're read by the host.
I'm going to propose that all host functions (on the Rust side) have a safe wrapper and that their actual definition is written with a macro instead of being called directly.
Right now, the code looks something like this:
#[link(wasm_import_module = "state")]
extern "C" {
#[link_name = "put"]
fn _put(caller: i64, key: i64, value: i64) -> i64;
}
pub unsafe fn put_bytes<V>(caller: &Program, key: &Key, value: &V) -> Result<(), Error>
where
V: BorshSerialize,
{
let value_bytes = borsh::to_vec(value).map_err(|_| Error::Serialization)?;
let caller = to_host_ptr(caller.id())?;
let value = to_host_ptr(&value_bytes)?;
let key = to_host_ptr(key)?;
match unsafe { _put(caller, key, value) } {
0 => Ok(()),
_ => Err(Error::Write),
}
}
But this functionality should look something like this:
pub fn put_bytes<V>(caller: &Program, key: &Key, value: &V) -> Result<(), Error>
where
V: BorshSerialize,
{
call_host_fn! {
wasm_import_module = "state";
link_name = "put";
args = (caller, key, value);
}
}
Here the macro would actually define the external function. Alternatively, if there is no module, there should be another pattern to patch the following:
pub fn put_bytes<V>(caller: &Program, key: &Key, value: &V) -> Result<(), Error>
where
V: BorshSerialize,
{
call_host_fn!("put", (caller, key, value))
}
Inside the macro, the actual name of the function inside the extern
block doesn't matter; it's only the link name that does something.
Could also fix #849 while fixing this.
Metadata
Metadata
Assignees
Type
Projects
Status
Done ✅
Activity