mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 20:21:06 +00:00
contracts: Change define_env! to expect a Result<T, DispatchError> for every function (#7762)
* Make host functions return TrapReason This avoids the need to manually store any trap reasons to the `Runtime` from the host function. This adds the following benefits: * It properly composes with the upcoming chain extensions * Missing to set a trap value is now a compile error * review: Remove superflous .into()
This commit is contained in:
committed by
GitHub
parent
dd8e7587cb
commit
ab876be9e9
@@ -96,7 +96,7 @@ macro_rules! unmarshall_then_body {
|
||||
#[inline(always)]
|
||||
pub fn constrain_closure<R, F>(f: F) -> F
|
||||
where
|
||||
F: FnOnce() -> Result<R, sp_sandbox::HostError>,
|
||||
F: FnOnce() -> Result<R, crate::wasm::runtime::TrapReason>,
|
||||
{
|
||||
f
|
||||
}
|
||||
@@ -109,14 +109,20 @@ macro_rules! unmarshall_then_body_then_marshall {
|
||||
>(|| {
|
||||
unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*)
|
||||
});
|
||||
let r = body()?;
|
||||
let r = body().map_err(|reason| {
|
||||
$ctx.set_trap_reason(reason);
|
||||
sp_sandbox::HostError
|
||||
})?;
|
||||
return Ok(sp_sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() }))
|
||||
});
|
||||
( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({
|
||||
let body = $crate::wasm::env_def::macros::constrain_closure::<(), _>(|| {
|
||||
unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*)
|
||||
});
|
||||
body()?;
|
||||
body().map_err(|reason| {
|
||||
$ctx.set_trap_reason(reason);
|
||||
sp_sandbox::HostError
|
||||
})?;
|
||||
return Ok(sp_sandbox::ReturnValue::Unit)
|
||||
})
|
||||
}
|
||||
@@ -207,15 +213,24 @@ mod tests {
|
||||
use parity_wasm::elements::ValueType;
|
||||
use sp_runtime::traits::Zero;
|
||||
use sp_sandbox::{ReturnValue, Value};
|
||||
use crate::wasm::tests::MockExt;
|
||||
use crate::wasm::Runtime;
|
||||
use crate::exec::Ext;
|
||||
use crate::gas::Gas;
|
||||
use crate::{
|
||||
wasm::{Runtime, runtime::TrapReason, tests::MockExt},
|
||||
exec::Ext,
|
||||
gas::Gas,
|
||||
};
|
||||
|
||||
struct TestRuntime {
|
||||
value: u32,
|
||||
}
|
||||
|
||||
impl TestRuntime {
|
||||
fn set_trap_reason(&mut self, _reason: TrapReason) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_unmarshall_then_body_then_marshall_value_or_trap() {
|
||||
fn test_value(
|
||||
_ctx: &mut u32,
|
||||
_ctx: &mut TestRuntime,
|
||||
args: &[sp_sandbox::Value],
|
||||
) -> Result<ReturnValue, sp_sandbox::HostError> {
|
||||
let mut args = args.iter();
|
||||
@@ -224,7 +239,7 @@ mod tests {
|
||||
_ctx,
|
||||
(a: u32, b: u32) -> u32 => {
|
||||
if b == 0 {
|
||||
Err(sp_sandbox::HostError)
|
||||
Err(crate::wasm::runtime::TrapReason::Termination)
|
||||
} else {
|
||||
Ok(a / b)
|
||||
}
|
||||
@@ -232,7 +247,7 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
let ctx = &mut 0;
|
||||
let ctx = &mut TestRuntime { value: 0 };
|
||||
assert_eq!(
|
||||
test_value(ctx, &[Value::I32(15), Value::I32(3)]).unwrap(),
|
||||
ReturnValue::Value(Value::I32(5)),
|
||||
@@ -243,7 +258,7 @@ mod tests {
|
||||
#[test]
|
||||
fn macro_unmarshall_then_body_then_marshall_unit() {
|
||||
fn test_unit(
|
||||
ctx: &mut u32,
|
||||
ctx: &mut TestRuntime,
|
||||
args: &[sp_sandbox::Value],
|
||||
) -> Result<ReturnValue, sp_sandbox::HostError> {
|
||||
let mut args = args.iter();
|
||||
@@ -251,16 +266,16 @@ mod tests {
|
||||
args,
|
||||
ctx,
|
||||
(a: u32, b: u32) => {
|
||||
*ctx = a + b;
|
||||
ctx.value = a + b;
|
||||
Ok(())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
let ctx = &mut 0;
|
||||
let ctx = &mut TestRuntime { value: 0 };
|
||||
let result = test_unit(ctx, &[Value::I32(2), Value::I32(3)]).unwrap();
|
||||
assert_eq!(result, ReturnValue::Unit);
|
||||
assert_eq!(*ctx, 5);
|
||||
assert_eq!(ctx.value, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -270,7 +285,7 @@ mod tests {
|
||||
if !amount.is_zero() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(sp_sandbox::HostError)
|
||||
Err(TrapReason::Termination)
|
||||
}
|
||||
});
|
||||
let _f: fn(&mut Runtime<MockExt>, &[sp_sandbox::Value])
|
||||
@@ -322,7 +337,7 @@ mod tests {
|
||||
if !amount.is_zero() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(sp_sandbox::HostError)
|
||||
Err(crate::wasm::runtime::TrapReason::Termination)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user