mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 22:47:56 +00:00
seal: Change prefix and module name from "ext_" to "seal_" for contract callable functions (#6798)
* seal: Change prefix "ext_" to "seal_" for contract callable functions The word Ext is a overloaded term in the context of substrate. It usually is a trait which abstracts away access to external resources usually in order to mock them away for the purpose of tests. The contract module has its own `Ext` trait in addition the the substrate `Ext` which makes things even more confusing. In order to differentiate the contract callable functions more clearly from this `Ext` concept we rename them to use the "seal_" prefix instead. This should change no behaviour at all. This is a pure renaming commit. * seal: Rename import module from "env" to "seal0" * seal: Fixup integration test * seal: Add more tests for new import module names
This commit is contained in:
committed by
GitHub
parent
f9f8262303
commit
04b185e3d4
@@ -130,9 +130,9 @@ benchmarks! {
|
||||
|
||||
// Instantiate uses a dummy contract constructor to measure the overhead of the instantiate.
|
||||
// The size of the data has no influence on the costs of this extrinsic as long as the contract
|
||||
// won't call `ext_input` in its constructor to copy the data to contract memory.
|
||||
// won't call `seal_input` in its constructor to copy the data to contract memory.
|
||||
// The dummy contract used here does not do this. The costs for the data copy is billed as
|
||||
// part of `ext_input`.
|
||||
// part of `seal_input`.
|
||||
instantiate {
|
||||
let data = vec![0u8; 128];
|
||||
let endowment = Config::<T>::subsistence_threshold_uncached();
|
||||
|
||||
@@ -58,9 +58,9 @@ pub enum TransactorKind {
|
||||
/// Output of a contract call or instantiation which ran to completion.
|
||||
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
|
||||
pub struct ExecReturnValue {
|
||||
/// Flags passed along by `ext_return`. Empty when `ext_return` was never called.
|
||||
/// Flags passed along by `seal_return`. Empty when `seal_return` was never called.
|
||||
pub flags: ReturnFlags,
|
||||
/// Buffer passed along by `ext_return`. Empty when `ext_return` was never called.
|
||||
/// Buffer passed along by `seal_return`. Empty when `seal_return` was never called.
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ where
|
||||
// `collect_rent` will be done on first call and destination contract and balance
|
||||
// cannot be changed before the first call
|
||||
// We do not allow 'calling' plain accounts. For transfering value
|
||||
// `ext_transfer` must be used.
|
||||
// `seal_transfer` must be used.
|
||||
let contract = if let Some(ContractInfo::Alive(info)) = rent::collect_rent::<T>(&dest) {
|
||||
info
|
||||
} else {
|
||||
@@ -455,7 +455,7 @@ where
|
||||
|
||||
// We need each contract that exists to be above the subsistence threshold
|
||||
// in order to keep up the guarantuee that we always leave a tombstone behind
|
||||
// with the exception of a contract that called `ext_terminate`.
|
||||
// with the exception of a contract that called `seal_terminate`.
|
||||
if T::Currency::total_balance(&dest) < nested.config.subsistence_threshold() {
|
||||
Err(Error::<T>::NewContractNotFunded)?
|
||||
}
|
||||
@@ -599,7 +599,7 @@ fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
|
||||
Err(Error::<T>::OutOfGas)?
|
||||
}
|
||||
|
||||
// Only ext_terminate is allowed to bring the sender below the subsistence
|
||||
// Only seal_terminate is allowed to bring the sender below the subsistence
|
||||
// threshold or even existential deposit.
|
||||
let existence_requirement = match (cause, origin) {
|
||||
(Terminate, _) => ExistenceRequirement::AllowDeath,
|
||||
|
||||
@@ -419,7 +419,7 @@ decl_error! {
|
||||
OutputBufferTooSmall,
|
||||
/// Performing the requested transfer would have brought the contract below
|
||||
/// the subsistence threshold. No transfer is allowed to do this in order to allow
|
||||
/// for a tombstone to be created. Use `ext_terminate` to remove a contract without
|
||||
/// for a tombstone to be created. Use `seal_terminate` to remove a contract without
|
||||
/// leaving a tombstone behind.
|
||||
BelowSubsistenceThreshold,
|
||||
/// The newly created contract is below the subsistence threshold after executing
|
||||
@@ -768,7 +768,7 @@ impl<T: Trait> Config<T> {
|
||||
/// Rent or any contract initiated balance transfer mechanism cannot make the balance lower
|
||||
/// than the subsistence threshold in order to guarantee that a tombstone is created.
|
||||
///
|
||||
/// The only way to completely kill a contract without a tombstone is calling `ext_terminate`.
|
||||
/// The only way to completely kill a contract without a tombstone is calling `seal_terminate`.
|
||||
pub fn subsistence_threshold(&self) -> BalanceOf<T> {
|
||||
self.existential_deposit.saturating_add(self.tombstone_deposit)
|
||||
}
|
||||
@@ -846,7 +846,7 @@ pub struct Schedule {
|
||||
/// Maximum allowed size of a declared table.
|
||||
pub max_table_size: u32,
|
||||
|
||||
/// Whether the `ext_println` function is allowed to be used contracts.
|
||||
/// Whether the `seal_println` function is allowed to be used contracts.
|
||||
/// MUST only be enabled for `dev` chains, NOT for production chains
|
||||
pub enable_println: bool,
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ fn account_removal_does_not_remove_storage() {
|
||||
//
|
||||
// This does not remove the contract storage as we are not notified about a
|
||||
// account removal. This cannot happen in reality because a contract can only
|
||||
// remove itself by `ext_terminate`. There is no external event that can remove
|
||||
// remove itself by `seal_terminate`. There is no external event that can remove
|
||||
// the account appart from that.
|
||||
assert_ok!(Balances::transfer(Origin::signed(ALICE), BOB, 20));
|
||||
|
||||
@@ -1546,7 +1546,7 @@ fn cannot_self_destruct_in_constructor() {
|
||||
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
|
||||
assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm));
|
||||
|
||||
// Fail to instantiate the BOB because the contructor calls ext_terminate.
|
||||
// Fail to instantiate the BOB because the contructor calls seal_terminate.
|
||||
assert_err_ignore_postinfo!(
|
||||
Contracts::instantiate(
|
||||
Origin::signed(ALICE),
|
||||
|
||||
@@ -123,8 +123,8 @@ macro_rules! unmarshall_then_body_then_marshall {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_func {
|
||||
( < E: $ext_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => {
|
||||
fn $name< E: $ext_ty >(
|
||||
( < E: $seal_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => {
|
||||
fn $name< E: $seal_ty >(
|
||||
$ctx: &mut $crate::wasm::Runtime<E>,
|
||||
args: &[sp_sandbox::Value],
|
||||
) -> Result<sp_sandbox::ReturnValue, sp_sandbox::HostError> {
|
||||
@@ -142,9 +142,9 @@ macro_rules! define_func {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! register_func {
|
||||
( $reg_cb:ident, < E: $ext_ty:tt > ; ) => {};
|
||||
( $reg_cb:ident, < E: $seal_ty:tt > ; ) => {};
|
||||
|
||||
( $reg_cb:ident, < E: $ext_ty:tt > ;
|
||||
( $reg_cb:ident, < E: $seal_ty:tt > ;
|
||||
$name:ident ( $ctx:ident $( , $names:ident : $params:ty )* )
|
||||
$( -> $returns:ty )* => $body:tt $($rest:tt)*
|
||||
) => {
|
||||
@@ -152,12 +152,12 @@ macro_rules! register_func {
|
||||
stringify!($name).as_bytes(),
|
||||
{
|
||||
define_func!(
|
||||
< E: $ext_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body
|
||||
< E: $seal_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body
|
||||
);
|
||||
$name::<E>
|
||||
}
|
||||
);
|
||||
register_func!( $reg_cb, < E: $ext_ty > ; $($rest)* );
|
||||
register_func!( $reg_cb, < E: $seal_ty > ; $($rest)* );
|
||||
};
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ macro_rules! register_func {
|
||||
/// It's up to the user of this macro to check signatures of wasm code to be executed
|
||||
/// and reject the code if any imported function has a mismatched signature.
|
||||
macro_rules! define_env {
|
||||
( $init_name:ident , < E: $ext_ty:tt > ,
|
||||
( $init_name:ident , < E: $seal_ty:tt > ,
|
||||
$( $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* )
|
||||
$( -> $returns:ty )* => $body:tt , )*
|
||||
) => {
|
||||
@@ -185,7 +185,7 @@ macro_rules! define_env {
|
||||
|
||||
impl<E: Ext> $crate::wasm::env_def::FunctionImplProvider<E> for $init_name {
|
||||
fn impls<F: FnMut(&[u8], $crate::wasm::env_def::HostFunc<E>)>(f: &mut F) {
|
||||
register_func!(f, < E: $ext_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* );
|
||||
register_func!(f, < E: $seal_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* );
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -255,7 +255,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn macro_define_func() {
|
||||
define_func!( <E: Ext> ext_gas (_ctx, amount: u32) => {
|
||||
define_func!( <E: Ext> seal_gas (_ctx, amount: u32) => {
|
||||
let amount = Gas::from(amount);
|
||||
if !amount.is_zero() {
|
||||
Ok(())
|
||||
@@ -264,7 +264,7 @@ mod tests {
|
||||
}
|
||||
});
|
||||
let _f: fn(&mut Runtime<MockExt>, &[sp_sandbox::Value])
|
||||
-> Result<sp_sandbox::ReturnValue, sp_sandbox::HostError> = ext_gas::<MockExt>;
|
||||
-> Result<sp_sandbox::ReturnValue, sp_sandbox::HostError> = seal_gas::<MockExt>;
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -307,7 +307,7 @@ mod tests {
|
||||
use crate::wasm::env_def::ImportSatisfyCheck;
|
||||
|
||||
define_env!(Env, <E: Ext>,
|
||||
ext_gas( _ctx, amount: u32 ) => {
|
||||
seal_gas( _ctx, amount: u32 ) => {
|
||||
let amount = Gas::from(amount);
|
||||
if !amount.is_zero() {
|
||||
Ok(())
|
||||
@@ -317,7 +317,7 @@ mod tests {
|
||||
},
|
||||
);
|
||||
|
||||
assert!(Env::can_satisfy(b"ext_gas", &FunctionType::new(vec![ValueType::I32], None)));
|
||||
assert!(Env::can_satisfy(b"seal_gas", &FunctionType::new(vec![ValueType::I32], None)));
|
||||
assert!(!Env::can_satisfy(b"not_exists", &FunctionType::new(vec![], None)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,9 +127,9 @@ impl<'a, T: Trait> crate::exec::Vm<T> for WasmVm<'a> {
|
||||
});
|
||||
|
||||
let mut imports = sp_sandbox::EnvironmentDefinitionBuilder::new();
|
||||
imports.add_memory("env", "memory", memory.clone());
|
||||
imports.add_memory(self::prepare::IMPORT_MODULE_MEMORY, "memory", memory.clone());
|
||||
runtime::Env::impls(&mut |name, func_ptr| {
|
||||
imports.add_host_func("env", name, func_ptr);
|
||||
imports.add_host_func(self::prepare::IMPORT_MODULE_FN, name, func_ptr);
|
||||
});
|
||||
|
||||
let mut runtime = Runtime::new(
|
||||
@@ -477,17 +477,17 @@ mod tests {
|
||||
|
||||
const CODE_TRANSFER: &str = r#"
|
||||
(module
|
||||
;; ext_transfer(
|
||||
;; seal_transfer(
|
||||
;; account_ptr: u32,
|
||||
;; account_len: u32,
|
||||
;; value_ptr: u32,
|
||||
;; value_len: u32,
|
||||
;;) -> u32
|
||||
(import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(drop
|
||||
(call $ext_transfer
|
||||
(call $seal_transfer
|
||||
(i32.const 4) ;; Pointer to "account" address.
|
||||
(i32.const 8) ;; Length of "account" address.
|
||||
(i32.const 12) ;; Pointer to the buffer with value to transfer
|
||||
@@ -530,7 +530,7 @@ mod tests {
|
||||
|
||||
const CODE_CALL: &str = r#"
|
||||
(module
|
||||
;; ext_call(
|
||||
;; seal_call(
|
||||
;; callee_ptr: u32,
|
||||
;; callee_len: u32,
|
||||
;; gas: u64,
|
||||
@@ -541,11 +541,11 @@ mod tests {
|
||||
;; output_ptr: u32,
|
||||
;; output_len_ptr: u32
|
||||
;;) -> u32
|
||||
(import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(drop
|
||||
(call $ext_call
|
||||
(call $seal_call
|
||||
(i32.const 4) ;; Pointer to "callee" address.
|
||||
(i32.const 8) ;; Length of "callee" address.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
@@ -594,7 +594,7 @@ mod tests {
|
||||
|
||||
const CODE_INSTANTIATE: &str = r#"
|
||||
(module
|
||||
;; ext_instantiate(
|
||||
;; seal_instantiate(
|
||||
;; code_ptr: u32,
|
||||
;; code_len: u32,
|
||||
;; gas: u64,
|
||||
@@ -608,11 +608,11 @@ mod tests {
|
||||
;; output_ptr: u32,
|
||||
;; output_len_ptr: u32
|
||||
;; ) -> u32
|
||||
(import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(drop
|
||||
(call $ext_instantiate
|
||||
(call $seal_instantiate
|
||||
(i32.const 16) ;; Pointer to `code_hash`
|
||||
(i32.const 32) ;; Length of `code_hash`
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
@@ -665,14 +665,14 @@ mod tests {
|
||||
|
||||
const CODE_TERMINATE: &str = r#"
|
||||
(module
|
||||
;; ext_terminate(
|
||||
;; seal_terminate(
|
||||
;; beneficiary_ptr: u32,
|
||||
;; beneficiary_len: u32,
|
||||
;; )
|
||||
(import "env" "ext_terminate" (func $ext_terminate (param i32 i32)))
|
||||
(import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(call $ext_terminate
|
||||
(call $seal_terminate
|
||||
(i32.const 4) ;; Pointer to "beneficiary" address.
|
||||
(i32.const 8) ;; Length of "beneficiary" address.
|
||||
)
|
||||
@@ -706,7 +706,7 @@ mod tests {
|
||||
|
||||
const CODE_TRANSFER_LIMITED_GAS: &str = r#"
|
||||
(module
|
||||
;; ext_call(
|
||||
;; seal_call(
|
||||
;; callee_ptr: u32,
|
||||
;; callee_len: u32,
|
||||
;; gas: u64,
|
||||
@@ -717,11 +717,11 @@ mod tests {
|
||||
;; output_ptr: u32,
|
||||
;; output_len_ptr: u32
|
||||
;;) -> u32
|
||||
(import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(drop
|
||||
(call $ext_call
|
||||
(call $seal_call
|
||||
(i32.const 4) ;; Pointer to "callee" address.
|
||||
(i32.const 8) ;; Length of "callee" address.
|
||||
(i64.const 228) ;; How much gas to devote for the execution.
|
||||
@@ -770,8 +770,8 @@ mod tests {
|
||||
|
||||
const CODE_GET_STORAGE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_get_storage" (func $ext_get_storage (param i32 i32 i32) (result i32)))
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) key for get storage
|
||||
@@ -800,7 +800,7 @@ mod tests {
|
||||
;; Load a storage value into contract memory.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $ext_get_storage
|
||||
(call $seal_get_storage
|
||||
(i32.const 0) ;; The pointer to the storage key to fetch
|
||||
(i32.const 36) ;; Pointer to the output buffer
|
||||
(i32.const 32) ;; Pointer to the size of the buffer
|
||||
@@ -818,13 +818,13 @@ mod tests {
|
||||
)
|
||||
|
||||
;; Return the contents of the buffer
|
||||
(call $ext_return
|
||||
(call $seal_return
|
||||
(i32.const 0)
|
||||
(i32.const 36)
|
||||
(get_local $buf_size)
|
||||
)
|
||||
|
||||
;; env:ext_return doesn't return, so this is effectively unreachable.
|
||||
;; env:seal_return doesn't return, so this is effectively unreachable.
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
@@ -849,10 +849,10 @@ mod tests {
|
||||
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: [0x22; 32].to_vec() });
|
||||
}
|
||||
|
||||
/// calls `ext_caller` and compares the result with the constant 42.
|
||||
/// calls `seal_caller` and compares the result with the constant 42.
|
||||
const CODE_CALLER: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_caller" (func $ext_caller (param i32 i32)))
|
||||
(import "seal0" "seal_caller" (func $seal_caller (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -869,7 +869,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; fill the buffer with the caller.
|
||||
(call $ext_caller (i32.const 0) (i32.const 32))
|
||||
(call $seal_caller (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -902,10 +902,10 @@ mod tests {
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
/// calls `ext_address` and compares the result with the constant 69.
|
||||
/// calls `seal_address` and compares the result with the constant 69.
|
||||
const CODE_ADDRESS: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_address" (func $ext_address (param i32 i32)))
|
||||
(import "seal0" "seal_address" (func $seal_address (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -922,7 +922,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; fill the buffer with the self address.
|
||||
(call $ext_address (i32.const 0) (i32.const 32))
|
||||
(call $seal_address (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert size == 8
|
||||
(call $assert
|
||||
@@ -957,7 +957,7 @@ mod tests {
|
||||
|
||||
const CODE_BALANCE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_balance" (func $ext_balance (param i32 i32)))
|
||||
(import "seal0" "seal_balance" (func $seal_balance (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -974,7 +974,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the balance in the buffer
|
||||
(call $ext_balance (i32.const 0) (i32.const 32))
|
||||
(call $seal_balance (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1009,7 +1009,7 @@ mod tests {
|
||||
|
||||
const CODE_GAS_PRICE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_weight_to_fee" (func $ext_weight_to_fee (param i64 i32 i32)))
|
||||
(import "seal0" "seal_weight_to_fee" (func $seal_weight_to_fee (param i64 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1026,7 +1026,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas price in the buffer
|
||||
(call $ext_weight_to_fee (i64.const 2) (i32.const 0) (i32.const 32))
|
||||
(call $seal_weight_to_fee (i64.const 2) (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1061,8 +1061,8 @@ mod tests {
|
||||
|
||||
const CODE_GAS_LEFT: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_gas_left" (func $ext_gas_left (param i32 i32)))
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_gas_left" (func $seal_gas_left (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1079,7 +1079,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas left in the buffer
|
||||
(call $ext_gas_left (i32.const 0) (i32.const 32))
|
||||
(call $seal_gas_left (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1090,7 +1090,7 @@ mod tests {
|
||||
)
|
||||
|
||||
;; return gas left
|
||||
(call $ext_return (i32.const 0) (i32.const 0) (i32.const 8))
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 8))
|
||||
|
||||
(unreachable)
|
||||
)
|
||||
@@ -1116,7 +1116,7 @@ mod tests {
|
||||
|
||||
const CODE_VALUE_TRANSFERRED: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_value_transferred" (func $ext_value_transferred (param i32 i32)))
|
||||
(import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1133,7 +1133,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the value transferred in the buffer
|
||||
(call $ext_value_transferred (i32.const 0) (i32.const 32))
|
||||
(call $seal_value_transferred (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1168,12 +1168,12 @@ mod tests {
|
||||
|
||||
const CODE_RETURN_FROM_START_FN: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(start $start)
|
||||
(func $start
|
||||
(call $ext_return
|
||||
(call $seal_return
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 4)
|
||||
@@ -1204,7 +1204,7 @@ mod tests {
|
||||
|
||||
const CODE_TIMESTAMP_NOW: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_now" (func $ext_now (param i32 i32)))
|
||||
(import "seal0" "seal_now" (func $seal_now (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1221,7 +1221,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the block timestamp in the buffer
|
||||
(call $ext_now (i32.const 0) (i32.const 32))
|
||||
(call $seal_now (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1256,7 +1256,7 @@ mod tests {
|
||||
|
||||
const CODE_MINIMUM_BALANCE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_minimum_balance" (func $ext_minimum_balance (param i32 i32)))
|
||||
(import "seal0" "seal_minimum_balance" (func $seal_minimum_balance (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1272,7 +1272,7 @@ mod tests {
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_minimum_balance (i32.const 0) (i32.const 32))
|
||||
(call $seal_minimum_balance (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1307,7 +1307,7 @@ mod tests {
|
||||
|
||||
const CODE_TOMBSTONE_DEPOSIT: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_tombstone_deposit" (func $ext_tombstone_deposit (param i32 i32)))
|
||||
(import "seal0" "seal_tombstone_deposit" (func $seal_tombstone_deposit (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1323,7 +1323,7 @@ mod tests {
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_tombstone_deposit (i32.const 0) (i32.const 32))
|
||||
(call $seal_tombstone_deposit (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1358,8 +1358,8 @@ mod tests {
|
||||
|
||||
const CODE_RANDOM: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_random" (func $ext_random (param i32 i32 i32 i32)))
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_random" (func $seal_random (param i32 i32 i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0,128) is reserved for the result of PRNG.
|
||||
@@ -1384,7 +1384,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the block random seed in the buffer
|
||||
(call $ext_random
|
||||
(call $seal_random
|
||||
(i32.const 128) ;; Pointer in memory to the start of the subject buffer
|
||||
(i32.const 32) ;; The subject buffer's length
|
||||
(i32.const 0) ;; Pointer to the output buffer
|
||||
@@ -1400,7 +1400,7 @@ mod tests {
|
||||
)
|
||||
|
||||
;; return the random data
|
||||
(call $ext_return
|
||||
(call $seal_return
|
||||
(i32.const 0)
|
||||
(i32.const 0)
|
||||
(i32.const 32)
|
||||
@@ -1433,11 +1433,11 @@ mod tests {
|
||||
|
||||
const CODE_DEPOSIT_EVENT: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_deposit_event
|
||||
(call $seal_deposit_event
|
||||
(i32.const 32) ;; Pointer to the start of topics buffer
|
||||
(i32.const 33) ;; The length of the topics buffer.
|
||||
(i32.const 8) ;; Pointer to the start of the data buffer
|
||||
@@ -1475,11 +1475,11 @@ mod tests {
|
||||
|
||||
const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_deposit_event
|
||||
(call $seal_deposit_event
|
||||
(i32.const 32) ;; Pointer to the start of topics buffer
|
||||
(i32.const 161) ;; The length of the topics buffer.
|
||||
(i32.const 8) ;; Pointer to the start of the data buffer
|
||||
@@ -1521,11 +1521,11 @@ mod tests {
|
||||
|
||||
const CODE_DEPOSIT_EVENT_DUPLICATES: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_deposit_event
|
||||
(call $seal_deposit_event
|
||||
(i32.const 32) ;; Pointer to the start of topics buffer
|
||||
(i32.const 129) ;; The length of the topics buffer.
|
||||
(i32.const 8) ;; Pointer to the start of the data buffer
|
||||
@@ -1564,10 +1564,10 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// calls `ext_block_number` compares the result with the constant 121.
|
||||
/// calls `seal_block_number` compares the result with the constant 121.
|
||||
const CODE_BLOCK_NUMBER: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_block_number" (func $ext_block_number (param i32 i32)))
|
||||
(import "seal0" "seal_block_number" (func $seal_block_number (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1584,7 +1584,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the block height in the buffer
|
||||
(call $ext_block_number (i32.const 0) (i32.const 32))
|
||||
(call $seal_block_number (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1619,8 +1619,8 @@ mod tests {
|
||||
|
||||
const CODE_RETURN_WITH_DATA: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_input" (func $ext_input (param i32 i32)))
|
||||
(import "env" "ext_return" (func $ext_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(data (i32.const 32) "\20")
|
||||
@@ -1633,13 +1633,13 @@ mod tests {
|
||||
;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data.
|
||||
(func $call (export "call")
|
||||
;; Copy input data this contract memory.
|
||||
(call $ext_input
|
||||
(call $seal_input
|
||||
(i32.const 0) ;; Pointer where to store input
|
||||
(i32.const 32) ;; Pointer to the length of the buffer
|
||||
)
|
||||
|
||||
;; Copy all but the first 4 bytes of the input data as the output data.
|
||||
(call $ext_return
|
||||
(call $seal_return
|
||||
(i32.load (i32.const 0))
|
||||
(i32.const 4)
|
||||
(i32.sub (i32.load (i32.const 32)) (i32.const 4))
|
||||
@@ -1650,7 +1650,7 @@ mod tests {
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn ext_return_with_success_status() {
|
||||
fn seal_return_with_success_status() {
|
||||
let output = execute(
|
||||
CODE_RETURN_WITH_DATA,
|
||||
hex!("00000000445566778899").to_vec(),
|
||||
@@ -1677,13 +1677,13 @@ mod tests {
|
||||
|
||||
const CODE_OUT_OF_BOUNDS_ACCESS: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_terminate" (func $ext_terminate (param i32 i32)))
|
||||
(import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_terminate
|
||||
(call $seal_terminate
|
||||
(i32.const 65536) ;; Pointer to "account" address (out of bound).
|
||||
(i32.const 8) ;; Length of "account" address.
|
||||
)
|
||||
@@ -1712,13 +1712,13 @@ mod tests {
|
||||
|
||||
const CODE_DECODE_FAILURE: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_terminate" (func $ext_terminate (param i32 i32)))
|
||||
(import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_terminate
|
||||
(call $seal_terminate
|
||||
(i32.const 0) ;; Pointer to "account" address.
|
||||
(i32.const 4) ;; Length of "account" address (too small -> decode fail).
|
||||
)
|
||||
|
||||
@@ -28,6 +28,14 @@ use pwasm_utils::rules;
|
||||
use sp_std::prelude::*;
|
||||
use sp_runtime::traits::{SaturatedConversion};
|
||||
|
||||
/// Currently, all imported functions must be located inside this module. We might support
|
||||
/// additional modules for versioning later.
|
||||
pub const IMPORT_MODULE_FN: &str = "seal0";
|
||||
|
||||
/// Imported memory must be located inside this module. The reason for that is that current
|
||||
/// compiler toolchains might not support specifying other modules than "env" for memory imports.
|
||||
pub const IMPORT_MODULE_MEMORY: &str = "env";
|
||||
|
||||
struct ContractModule<'a> {
|
||||
/// A deserialized module. The module is valid (this is Guaranteed by `new` method).
|
||||
module: elements::Module,
|
||||
@@ -146,8 +154,11 @@ impl<'a> ContractModule<'a> {
|
||||
.with_grow_cost(self.schedule.grow_mem_cost.clone().saturated_into())
|
||||
.with_forbidden_floats();
|
||||
|
||||
let contract_module = pwasm_utils::inject_gas_counter(self.module, &gas_rules)
|
||||
.map_err(|_| "gas instrumentation failed")?;
|
||||
let contract_module = pwasm_utils::inject_gas_counter(
|
||||
self.module,
|
||||
&gas_rules,
|
||||
IMPORT_MODULE_FN
|
||||
).map_err(|_| "gas instrumentation failed")?;
|
||||
Ok(ContractModule {
|
||||
module: contract_module,
|
||||
schedule: self.schedule,
|
||||
@@ -270,17 +281,19 @@ impl<'a> ContractModule<'a> {
|
||||
let mut imported_mem_type = None;
|
||||
|
||||
for import in import_entries {
|
||||
if import.module() != "env" {
|
||||
// This import tries to import something from non-"env" module,
|
||||
// but all imports are located in "env" at the moment.
|
||||
return Err("module has imports from a non-'env' namespace");
|
||||
}
|
||||
|
||||
let type_idx = match import.external() {
|
||||
&External::Table(_) => return Err("Cannot import tables"),
|
||||
&External::Global(_) => return Err("Cannot import globals"),
|
||||
&External::Function(ref type_idx) => type_idx,
|
||||
&External::Function(ref type_idx) => {
|
||||
if import.module() != IMPORT_MODULE_FN {
|
||||
return Err("Invalid module for imported function");
|
||||
}
|
||||
type_idx
|
||||
},
|
||||
&External::Memory(ref memory_type) => {
|
||||
if import.module() != IMPORT_MODULE_MEMORY {
|
||||
return Err("Invalid module for imported memory");
|
||||
}
|
||||
if import.field() != "memory" {
|
||||
return Err("Memory import must have the field name 'memory'")
|
||||
}
|
||||
@@ -296,10 +309,10 @@ impl<'a> ContractModule<'a> {
|
||||
.get(*type_idx as usize)
|
||||
.ok_or_else(|| "validation: import entry points to a non-existent type")?;
|
||||
|
||||
// We disallow importing `ext_println` unless debug features are enabled,
|
||||
// We disallow importing `seal_println` unless debug features are enabled,
|
||||
// which should only be allowed on a dev chain
|
||||
if !self.schedule.enable_println && import.field().as_bytes() == b"ext_println" {
|
||||
return Err("module imports `ext_println` but debug features disabled");
|
||||
if !self.schedule.enable_println && import.field().as_bytes() == b"seal_println" {
|
||||
return Err("module imports `seal_println` but debug features disabled");
|
||||
}
|
||||
|
||||
// We disallow importing `gas` function here since it is treated as implementation detail.
|
||||
@@ -409,7 +422,7 @@ mod tests {
|
||||
|
||||
nop(_ctx, _unused: u64) => { unreachable!(); },
|
||||
|
||||
ext_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); },
|
||||
seal_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); },
|
||||
);
|
||||
|
||||
macro_rules! prepare_test {
|
||||
@@ -548,7 +561,7 @@ mod tests {
|
||||
prepare_test!(table_import,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "table" (table 1 anyfunc))
|
||||
(import "seal0" "table" (table 1 anyfunc))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -560,7 +573,7 @@ mod tests {
|
||||
prepare_test!(global_import,
|
||||
r#"
|
||||
(module
|
||||
(global $g (import "env" "global") i32)
|
||||
(global $g (import "seal0" "global") i32)
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -618,7 +631,7 @@ mod tests {
|
||||
prepare_test!(can_import_legit_function,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "nop" (func (param i64)))
|
||||
(import "seal0" "nop" (func (param i64)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -632,7 +645,7 @@ mod tests {
|
||||
prepare_test!(can_not_import_gas_function,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "gas" (func (param i32)))
|
||||
(import "seal0" "gas" (func (param i32)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -641,24 +654,63 @@ mod tests {
|
||||
Err("module imports a non-existent function")
|
||||
);
|
||||
|
||||
// nothing can be imported from non-"env" module for now.
|
||||
prepare_test!(non_env_import,
|
||||
// memory is in "env" and not in "seal0"
|
||||
prepare_test!(memory_not_in_seal0,
|
||||
r#"
|
||||
(module
|
||||
(import "another_module" "memory" (memory 1 1))
|
||||
(import "seal0" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#,
|
||||
Err("module has imports from a non-'env' namespace")
|
||||
Err("Invalid module for imported memory")
|
||||
);
|
||||
|
||||
// memory is in "env" and not in some arbitrary module
|
||||
prepare_test!(memory_not_in_arbitrary_module,
|
||||
r#"
|
||||
(module
|
||||
(import "any_module" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#,
|
||||
Err("Invalid module for imported memory")
|
||||
);
|
||||
|
||||
// functions are in "env" and not in "seal0"
|
||||
prepare_test!(function_not_in_env,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "nop" (func (param i64)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#,
|
||||
Err("Invalid module for imported function")
|
||||
);
|
||||
|
||||
// functions are in "seal0" and not in in some arbitrary module
|
||||
prepare_test!(function_not_arbitrary_module,
|
||||
r#"
|
||||
(module
|
||||
(import "any_module" "nop" (func (param i64)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#,
|
||||
Err("Invalid module for imported function")
|
||||
);
|
||||
|
||||
// wrong signature
|
||||
prepare_test!(wrong_signature,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "gas" (func (param i64)))
|
||||
(import "seal0" "gas" (func (param i64)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -670,7 +722,7 @@ mod tests {
|
||||
prepare_test!(unknown_func_name,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "unknown_func" (func))
|
||||
(import "seal0" "unknown_func" (func))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -679,24 +731,24 @@ mod tests {
|
||||
Err("module imports a non-existent function")
|
||||
);
|
||||
|
||||
prepare_test!(ext_println_debug_disabled,
|
||||
prepare_test!(seal_println_debug_disabled,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "ext_println" (func $ext_println (param i32 i32)))
|
||||
(import "seal0" "seal_println" (func $seal_println (param i32 i32)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#,
|
||||
Err("module imports `ext_println` but debug features disabled")
|
||||
Err("module imports `seal_println` but debug features disabled")
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn ext_println_debug_enabled() {
|
||||
fn seal_println_debug_enabled() {
|
||||
let wasm = wat::parse_str(
|
||||
r#"
|
||||
(module
|
||||
(import "env" "ext_println" (func $ext_println (param i32 i32)))
|
||||
(import "seal0" "seal_println" (func $seal_println (param i32 i32)))
|
||||
|
||||
(func (export "call"))
|
||||
(func (export "deploy"))
|
||||
@@ -745,7 +797,7 @@ mod tests {
|
||||
prepare_test!(try_sneak_export_as_entrypoint,
|
||||
r#"
|
||||
(module
|
||||
(import "env" "panic" (func))
|
||||
(import "seal0" "panic" (func))
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ impl From<ExecReturnValue> for ReturnCode {
|
||||
}
|
||||
}
|
||||
|
||||
/// The data passed through when a contract uses `ext_return`.
|
||||
/// The data passed through when a contract uses `seal_return`.
|
||||
struct ReturnData {
|
||||
/// The flags as passed through by the contract. They are still unchecked and
|
||||
/// will later be parsed into a `ReturnFlags` bitflags struct.
|
||||
@@ -106,10 +106,10 @@ enum TrapReason {
|
||||
/// The supervisor trapped the contract because of an error condition occurred during
|
||||
/// execution in privileged code.
|
||||
SupervisorError(DispatchError),
|
||||
/// Signals that trap was generated in response to call `ext_return` host function.
|
||||
/// Signals that trap was generated in response to call `seal_return` host function.
|
||||
Return(ReturnData),
|
||||
/// Signals that a trap was generated in response to a successful call to the
|
||||
/// `ext_terminate` host function.
|
||||
/// `seal_terminate` host function.
|
||||
Termination,
|
||||
/// Signals that a trap was generated because of a successful restoration.
|
||||
Restoration,
|
||||
@@ -378,7 +378,7 @@ fn write_sandbox_memory<E: Ext>(
|
||||
///
|
||||
/// If `out_ptr` is set to the sentinel value of `u32::max_value()` and `allow_skip` is true the
|
||||
/// operation is skipped and `Ok` is returned. This is supposed to help callers to make copying
|
||||
/// output optional. For example to skip copying back the output buffer of an `ext_call`
|
||||
/// output optional. For example to skip copying back the output buffer of an `seal_call`
|
||||
/// when the caller is not interested in the result.
|
||||
///
|
||||
/// In addition to the error conditions of `write_sandbox_memory` this functions returns
|
||||
@@ -538,7 +538,7 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// - If value length exceeds the configured maximum value length of a storage entry.
|
||||
// - Upon trying to set an empty storage entry (value length is 0).
|
||||
ext_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => {
|
||||
seal_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => {
|
||||
if value_len > ctx.ext.max_value_size() {
|
||||
// Bail out if value length exceeds the set maximum value size.
|
||||
return Err(sp_sandbox::HostError);
|
||||
@@ -555,7 +555,7 @@ define_env!(Env, <E: Ext>,
|
||||
// # Parameters
|
||||
//
|
||||
// - `key_ptr`: pointer into the linear memory where the location to clear the value is placed.
|
||||
ext_clear_storage(ctx, key_ptr: u32) => {
|
||||
seal_clear_storage(ctx, key_ptr: u32) => {
|
||||
let mut key: StorageKey = [0; 32];
|
||||
read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?;
|
||||
ctx.ext.set_storage(key, None);
|
||||
@@ -574,7 +574,7 @@ define_env!(Env, <E: Ext>,
|
||||
// # Errors
|
||||
//
|
||||
// `ReturnCode::KeyNotFound`
|
||||
ext_get_storage(ctx, key_ptr: u32, out_ptr: u32, out_len_ptr: u32) -> ReturnCode => {
|
||||
seal_get_storage(ctx, key_ptr: u32, out_ptr: u32, out_len_ptr: u32) -> ReturnCode => {
|
||||
let mut key: StorageKey = [0; 32];
|
||||
read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?;
|
||||
if let Some(value) = ctx.ext.get_storage(&key) {
|
||||
@@ -600,7 +600,7 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// `ReturnCode::BelowSubsistenceThreshold`
|
||||
// `ReturnCode::TransferFailed`
|
||||
ext_transfer(
|
||||
seal_transfer(
|
||||
ctx,
|
||||
account_ptr: u32,
|
||||
account_len: u32,
|
||||
@@ -647,7 +647,7 @@ define_env!(Env, <E: Ext>,
|
||||
// `ReturnCode::BelowSubsistenceThreshold`
|
||||
// `ReturnCode::TransferFailed`
|
||||
// `ReturnCode::NotCallable`
|
||||
ext_call(
|
||||
seal_call(
|
||||
ctx,
|
||||
callee_ptr: u32,
|
||||
callee_len: u32,
|
||||
@@ -734,7 +734,7 @@ define_env!(Env, <E: Ext>,
|
||||
// `ReturnCode::TransferFailed`
|
||||
// `ReturnCode::NewContractNotFunded`
|
||||
// `ReturnCode::CodeNotFound`
|
||||
ext_instantiate(
|
||||
seal_instantiate(
|
||||
ctx,
|
||||
code_hash_ptr: u32,
|
||||
code_hash_len: u32,
|
||||
@@ -798,7 +798,7 @@ define_env!(Env, <E: Ext>,
|
||||
// # Traps
|
||||
//
|
||||
// - The contract is live i.e is already on the call stack.
|
||||
ext_terminate(
|
||||
seal_terminate(
|
||||
ctx,
|
||||
beneficiary_ptr: u32,
|
||||
beneficiary_len: u32
|
||||
@@ -812,7 +812,7 @@ define_env!(Env, <E: Ext>,
|
||||
Err(sp_sandbox::HostError)
|
||||
},
|
||||
|
||||
ext_input(ctx, buf_ptr: u32, buf_len_ptr: u32) => {
|
||||
seal_input(ctx, buf_ptr: u32, buf_len_ptr: u32) => {
|
||||
if let Some(input) = ctx.input_data.take() {
|
||||
write_sandbox_output(ctx, buf_ptr, buf_len_ptr, &input, false)
|
||||
} else {
|
||||
@@ -826,7 +826,7 @@ define_env!(Env, <E: Ext>,
|
||||
// This is the only way to return a data buffer to the caller. Returning from
|
||||
// execution without calling this function is equivalent to calling:
|
||||
// ```
|
||||
// ext_return(0, 0, 0);
|
||||
// seal_return(0, 0, 0);
|
||||
// ```
|
||||
//
|
||||
// The flags argument is a bitfield that can be used to signal special return
|
||||
@@ -837,7 +837,7 @@ define_env!(Env, <E: Ext>,
|
||||
// --- msb ---
|
||||
//
|
||||
// Using a reserved bit triggers a trap.
|
||||
ext_return(ctx, flags: u32, data_ptr: u32, data_len: u32) => {
|
||||
seal_return(ctx, flags: u32, data_ptr: u32, data_len: u32) => {
|
||||
charge_gas(
|
||||
ctx.gas_meter,
|
||||
ctx.schedule,
|
||||
@@ -866,7 +866,7 @@ define_env!(Env, <E: Ext>,
|
||||
// If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the
|
||||
// extrinsic will be returned. Otherwise, if this call is initiated by another contract then the
|
||||
// address of the contract will be returned. The value is encoded as T::AccountId.
|
||||
ext_caller(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_caller(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.caller().encode(), false)
|
||||
},
|
||||
|
||||
@@ -876,7 +876,7 @@ define_env!(Env, <E: Ext>,
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
// `out_ptr`. This call overwrites it with the size of the value. If the available
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
ext_address(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_address(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.address().encode(), false)
|
||||
},
|
||||
|
||||
@@ -893,7 +893,7 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// It is recommended to avoid specifying very small values for `gas` as the prices for a single
|
||||
// gas can be smaller than one.
|
||||
ext_weight_to_fee(ctx, gas: u64, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_weight_to_fee(ctx, gas: u64, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(
|
||||
ctx, out_ptr, out_len_ptr, &ctx.ext.get_weight_price(gas).encode(), false
|
||||
)
|
||||
@@ -907,7 +907,7 @@ define_env!(Env, <E: Ext>,
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as Gas.
|
||||
ext_gas_left(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_gas_left(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.gas_meter.gas_left().encode(), false)
|
||||
},
|
||||
|
||||
@@ -919,7 +919,7 @@ define_env!(Env, <E: Ext>,
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as T::Balance.
|
||||
ext_balance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_balance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.balance().encode(), false)
|
||||
},
|
||||
|
||||
@@ -931,7 +931,7 @@ define_env!(Env, <E: Ext>,
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as T::Balance.
|
||||
ext_value_transferred(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_value_transferred(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(
|
||||
ctx, out_ptr, out_len_ptr, &ctx.ext.value_transferred().encode(), false
|
||||
)
|
||||
@@ -945,7 +945,7 @@ define_env!(Env, <E: Ext>,
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as T::Hash.
|
||||
ext_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => {
|
||||
// The length of a subject can't exceed `max_subject_len`.
|
||||
if subject_len > ctx.schedule.max_subject_len {
|
||||
return Err(sp_sandbox::HostError);
|
||||
@@ -962,14 +962,14 @@ define_env!(Env, <E: Ext>,
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
// `out_ptr`. This call overwrites it with the size of the value. If the available
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
ext_now(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_now(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.now().encode(), false)
|
||||
},
|
||||
|
||||
// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer.
|
||||
//
|
||||
// The data is encoded as T::Balance.
|
||||
ext_minimum_balance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_minimum_balance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.minimum_balance().encode(), false)
|
||||
},
|
||||
|
||||
@@ -988,7 +988,7 @@ define_env!(Env, <E: Ext>,
|
||||
// a contract to leave a tombstone the balance of the contract must not go
|
||||
// below the sum of existential deposit and the tombstone deposit. The sum
|
||||
// is commonly referred as subsistence threshold in code.
|
||||
ext_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(
|
||||
ctx, out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false
|
||||
)
|
||||
@@ -1020,7 +1020,7 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// - Tombstone hashes do not match
|
||||
// - Calling cantract is live i.e is already on the call stack.
|
||||
ext_restore_to(
|
||||
seal_restore_to(
|
||||
ctx,
|
||||
dest_ptr: u32,
|
||||
dest_len: u32,
|
||||
@@ -1077,7 +1077,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - topics_len - the length of the topics buffer. Pass 0 if you want to pass an empty vector.
|
||||
// - data_ptr - a pointer to a raw data buffer which will saved along the event.
|
||||
// - data_len - the length of the data buffer.
|
||||
ext_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => {
|
||||
seal_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => {
|
||||
let mut topics: Vec::<TopicOf<<E as Ext>::T>> = match topics_len {
|
||||
0 => Vec::new(),
|
||||
_ => read_sandbox_memory_as(ctx, topics_ptr, topics_len)?,
|
||||
@@ -1111,7 +1111,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - value_ptr: a pointer to the buffer with value, how much to allow for rent
|
||||
// Should be decodable as a `T::Balance`. Traps otherwise.
|
||||
// - value_len: length of the value buffer.
|
||||
ext_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => {
|
||||
seal_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => {
|
||||
let value: BalanceOf<<E as Ext>::T> =
|
||||
read_sandbox_memory_as(ctx, value_ptr, value_len)?;
|
||||
ctx.ext.set_rent_allowance(value);
|
||||
@@ -1127,14 +1127,14 @@ define_env!(Env, <E: Ext>,
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as T::Balance.
|
||||
ext_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.rent_allowance().encode(), false)
|
||||
},
|
||||
|
||||
// Prints utf8 encoded string from the data buffer.
|
||||
// Only available on `--dev` chains.
|
||||
// This function may be removed at any time, superseded by a more general contract debugging feature.
|
||||
ext_println(ctx, str_ptr: u32, str_len: u32) => {
|
||||
seal_println(ctx, str_ptr: u32, str_len: u32) => {
|
||||
let data = read_sandbox_memory(ctx, str_ptr, str_len)?;
|
||||
if let Ok(utf8) = core::str::from_utf8(&data) {
|
||||
sp_runtime::print(utf8);
|
||||
@@ -1148,7 +1148,7 @@ define_env!(Env, <E: Ext>,
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
// `out_ptr`. This call overwrites it with the size of the value. If the available
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
ext_block_number(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
seal_block_number(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.block_number().encode(), false)
|
||||
},
|
||||
|
||||
@@ -1172,7 +1172,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - `output_ptr`: the pointer into the linear memory where the output
|
||||
// data is placed. The function will write the result
|
||||
// directly into this buffer.
|
||||
ext_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
seal_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
compute_hash_on_intermediate_buffer(ctx, sha2_256, input_ptr, input_len, output_ptr)
|
||||
},
|
||||
|
||||
@@ -1196,7 +1196,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - `output_ptr`: the pointer into the linear memory where the output
|
||||
// data is placed. The function will write the result
|
||||
// directly into this buffer.
|
||||
ext_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
seal_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
compute_hash_on_intermediate_buffer(ctx, keccak_256, input_ptr, input_len, output_ptr)
|
||||
},
|
||||
|
||||
@@ -1220,7 +1220,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - `output_ptr`: the pointer into the linear memory where the output
|
||||
// data is placed. The function will write the result
|
||||
// directly into this buffer.
|
||||
ext_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
seal_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
compute_hash_on_intermediate_buffer(ctx, blake2_256, input_ptr, input_len, output_ptr)
|
||||
},
|
||||
|
||||
@@ -1244,7 +1244,7 @@ define_env!(Env, <E: Ext>,
|
||||
// - `output_ptr`: the pointer into the linear memory where the output
|
||||
// data is placed. The function will write the result
|
||||
// directly into this buffer.
|
||||
ext_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
seal_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => {
|
||||
compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr)
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user