From d8e9fff3e40af95bd0d07c258c2a2fa5d3ed06fd Mon Sep 17 00:00:00 2001 From: Sasha Gryaznov Date: Wed, 7 Sep 2022 11:54:17 +0300 Subject: [PATCH] [contracts] API host functions: remove `seal_` name prefix + enable aliasing (#12126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * works but ugly * refactored + renamed host fns * fixed tests * fix benchmarks * updated marco docs * Update frame/contracts/proc-macro/src/lib.rs Co-authored-by: Alexander Theißen * fix for the duplicated prefixed alias bug + test * refactored a bit * fix warnings + try to make macro rustdoc compile * fmt after clearing * examples update + nocompile * add seal_ prefixes to unstable host functions * updated after a review Co-authored-by: Alexander Theißen --- .../frame/contracts/fixtures/call_runtime.wat | 4 +- .../frame/contracts/proc-macro/src/lib.rs | 72 ++++- .../frame/contracts/src/benchmarking/mod.rs | 22 +- substrate/frame/contracts/src/wasm/mod.rs | 66 ++++- substrate/frame/contracts/src/wasm/runtime.rs | 260 +++++++++--------- 5 files changed, 262 insertions(+), 162 deletions(-) diff --git a/substrate/frame/contracts/fixtures/call_runtime.wat b/substrate/frame/contracts/fixtures/call_runtime.wat index d5467f6e95..62fa08680a 100644 --- a/substrate/frame/contracts/fixtures/call_runtime.wat +++ b/substrate/frame/contracts/fixtures/call_runtime.wat @@ -1,6 +1,6 @@ ;; This passes its input to `seal_call_runtime` and returns the return value to its caller. (module - (import "__unstable__" "seal_call_runtime" (func $seal_call_runtime (param i32 i32) (result i32))) + (import "__unstable__" "call_runtime" (func $call_runtime (param i32 i32) (result 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)) @@ -17,7 +17,7 @@ ) ;; Just use the call passed as input and store result to memory (i32.store (i32.const 0) - (call $seal_call_runtime + (call $call_runtime (i32.const 4) ;; Pointer where the call is stored (i32.load (i32.const 0)) ;; Size of the call ) diff --git a/substrate/frame/contracts/proc-macro/src/lib.rs b/substrate/frame/contracts/proc-macro/src/lib.rs index 65c13bb1fc..648bf0fd1f 100644 --- a/substrate/frame/contracts/proc-macro/src/lib.rs +++ b/substrate/frame/contracts/proc-macro/src/lib.rs @@ -174,22 +174,16 @@ impl ToTokens for HostFn { } impl HostFn { - pub fn try_from(item: syn::Item) -> syn::Result { + pub fn try_from(item: syn::ItemFn) -> syn::Result { let err = |span, msg| { let msg = format!("Invalid host function definition. {}", msg); syn::Error::new(span, msg) }; let msg = "only #[version()] or #[unstable] attribute is allowed."; let span = item.span(); - let item = match item { - syn::Item::Fn(i_fn) => Ok(i_fn), - _ => Err(err(span, msg)), - }?; - + let mut attrs = item.attrs.clone(); + attrs.retain(|a| !(a.path.is_ident("doc") || a.path.is_ident("prefixed_alias"))); let name = item.sig.ident.to_string(); - let attrs: Vec<&syn::Attribute> = - item.attrs.iter().filter(|m| !m.path.is_ident("doc")).collect(); - let module = match attrs.len() { 0 => Ok("seal0".to_string()), 1 => { @@ -306,6 +300,7 @@ impl HostFn { } } } + impl EnvDef { pub fn try_from(item: syn::ItemMod) -> syn::Result { let span = item.span(); @@ -316,9 +311,32 @@ impl EnvDef { .ok_or(err("Invalid environment definition, expected `mod` to be inlined."))? .1; + let extract_fn = |i: &syn::Item| match i { + syn::Item::Fn(i_fn) => Some(i_fn.clone()), + _ => None, + }; + + let selector = |a: &syn::Attribute| a.path.is_ident("prefixed_alias"); + + let aliases = items + .iter() + .filter_map(extract_fn) + .filter(|i| i.attrs.iter().any(selector)) + .map(|mut i| { + i.attrs.retain(|i| !selector(i)); + i.sig.ident = syn::Ident::new( + &format!("seal_{}", &i.sig.ident.to_string()), + i.sig.ident.span(), + ); + i + }) + .map(|i| HostFn::try_from(i)); + let host_funcs = items .iter() - .map(|i| HostFn::try_from(i.clone())) + .filter_map(extract_fn) + .map(|i| HostFn::try_from(i)) + .chain(aliases) .collect::, _>>()?; Ok(Self { host_funcs }) @@ -484,7 +502,7 @@ fn expand_impls(def: &mut EnvDef) -> proc_macro2::TokenStream { /// ```nocompile /// #[define_env] /// pub mod some_env { -/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<(), TrapReason> { +/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<(), TrapReason> { /// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ()) /// } /// } @@ -499,17 +517,45 @@ fn expand_impls(def: &mut EnvDef) -> proc_macro2::TokenStream { /// #[define_env] /// pub mod some_env { /// #[version(1)] -/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { +/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { /// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ()) /// } /// /// #[unstable] -/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { +/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { /// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ()) /// } /// } /// ``` /// +/// In legacy versions of pallet_contracts, it was a naming convention that all host functions had +/// to be named with the `seal_` prefix. For the sake of backwards compatibility, each host function +/// now can get a such prefix-named alias function generated by marking it by the +/// `#[prefixed_alias]` attribute: +/// +/// ## Example +/// +/// ```nocompile +/// #[define_env] +/// pub mod some_env { +/// #[version(1)] +/// #[prefixed_alias] +/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { +/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ()) +/// } +/// +/// #[unstable] +/// fn some_host_fn(ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result { +/// ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ()) +/// } +/// } +/// ``` +/// +/// In this example, the following host functions will be generated by the macro: +/// - `some_host_fn()` in module `seal1`, +/// - `seal_some_host_fn()` in module `seal1`, +/// - `some_host_fn()` in module `__unstable__`. +/// /// Only following return types are allowed for the host functions defined with the macro: /// - `Result<(), TrapReason>`, /// - `Result`, diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index e29cb51728..2f8d101504 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -920,7 +920,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_set_storage", + name: "set_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -968,7 +968,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_set_storage", + name: "set_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1016,7 +1016,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_set_storage", + name: "set_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1068,7 +1068,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_clear_storage", + name: "clear_storage", params: vec![ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1115,7 +1115,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_clear_storage", + name: "clear_storage", params: vec![ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1163,7 +1163,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_get_storage", + name: "get_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1217,7 +1217,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_get_storage", + name: "get_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1272,7 +1272,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_contains_storage", + name: "contains_storage", params: vec![ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1319,7 +1319,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_contains_storage", + name: "contains_storage", params: vec![ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1367,7 +1367,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_take_storage", + name: "take_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], @@ -1421,7 +1421,7 @@ benchmarks! { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { module: "__unstable__", - name: "seal_take_storage", + name: "take_storage", params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32], return_type: Some(ValueType::I32), }], diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index f989c21b00..6790830b97 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -929,7 +929,7 @@ mod tests { (module (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "__unstable__" "seal_contains_storage" (func $seal_contains_storage (param i32 i32) (result i32))) + (import "__unstable__" "contains_storage" (func $contains_storage (param i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) @@ -947,7 +947,7 @@ mod tests { ) ;; Call seal_clear_storage and save what it returns at 0 (i32.store (i32.const 0) - (call $seal_contains_storage + (call $contains_storage (i32.const 8) ;; key_ptr (i32.load (i32.const 4)) ;; key_len ) @@ -1678,11 +1678,53 @@ mod tests { ) (func (export "deploy")) ) +"#; + + const CODE_TIMESTAMP_NOW_UNPREFIXED: &str = r#" +(module + (import "seal0" "now" (func $now (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + ;; This stores the block timestamp in the buffer + (call $now (i32.const 0) (i32.const 32)) + + ;; assert len == 8 + (call $assert + (i32.eq + (i32.load (i32.const 32)) + (i32.const 8) + ) + ) + + ;; assert that contents of the buffer is equal to the i64 value of 1111. + (call $assert + (i64.eq + (i64.load (i32.const 0)) + (i64.const 1111) + ) + ) + ) + (func (export "deploy")) +) "#; #[test] fn now() { assert_ok!(execute(CODE_TIMESTAMP_NOW, vec![], MockExt::default())); + assert_ok!(execute(CODE_TIMESTAMP_NOW_UNPREFIXED, vec![], MockExt::default())); } const CODE_MINIMUM_BALANCE: &str = r#" @@ -2221,7 +2263,7 @@ mod tests { #[cfg(feature = "unstable-interface")] const CODE_CALL_RUNTIME: &str = r#" (module - (import "__unstable__" "seal_call_runtime" (func $seal_call_runtime (param i32 i32) (result i32))) + (import "__unstable__" "call_runtime" (func $call_runtime (param i32 i32) (result 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)) @@ -2238,7 +2280,7 @@ mod tests { ) ;; Just use the call passed as input and store result to memory (i32.store (i32.const 0) - (call $seal_call_runtime + (call $call_runtime (i32.const 4) ;; Pointer where the call is stored (i32.load (i32.const 0)) ;; Size of the call ) @@ -2350,7 +2392,7 @@ mod tests { (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "__unstable__" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32 i32) (result i32))) + (import "__unstable__" "set_storage" (func $set_storage (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) ;; [0, 4) size of input buffer @@ -2367,7 +2409,7 @@ mod tests { ) ;; Store the passed value to the passed key and store result to memory (i32.store (i32.const 168) - (call $seal_set_storage + (call $set_storage (i32.const 8) ;; key_ptr (i32.load (i32.const 4)) ;; key_len (i32.add ;; value_ptr = 8 + key_len @@ -2421,7 +2463,7 @@ mod tests { (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "__unstable__" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32 i32) (result i32))) + (import "__unstable__" "get_storage" (func $get_storage (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) ;; [0, 4) size of input buffer (160 bytes as we copy the key+len here) @@ -2442,7 +2484,7 @@ mod tests { ) ;; Load a storage value and result of this call into the output buffer (i32.store (i32.const 168) - (call $seal_get_storage + (call $get_storage (i32.const 12) ;; key_ptr (i32.load (i32.const 8)) ;; key_len (i32.const 172) ;; Pointer to the output buffer @@ -2515,7 +2557,7 @@ mod tests { (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "__unstable__" "seal_clear_storage" (func $seal_clear_storage (param i32 i32) (result i32))) + (import "__unstable__" "clear_storage" (func $clear_storage (param i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) ;; size of input buffer @@ -2532,7 +2574,7 @@ mod tests { ) ;; Call seal_clear_storage and save what it returns at 0 (i32.store (i32.const 0) - (call $seal_clear_storage + (call $clear_storage (i32.const 8) ;; key_ptr (i32.load (i32.const 4)) ;; key_len ) @@ -2601,7 +2643,7 @@ mod tests { (module (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "__unstable__" "seal_take_storage" (func $seal_take_storage (param i32 i32 i32 i32) (result i32))) + (import "__unstable__" "take_storage" (func $take_storage (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) ;; [0, 4) size of input buffer (160 bytes as we copy the key+len here) @@ -2623,7 +2665,7 @@ mod tests { ;; Load a storage value and result of this call into the output buffer (i32.store (i32.const 168) - (call $seal_take_storage + (call $take_storage (i32.const 12) ;; key_ptr (i32.load (i32.const 8)) ;; key_len (i32.const 172) ;; Pointer to the output buffer diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index 296f322f49..334223e3b8 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -957,7 +957,7 @@ pub mod env { /// This call is supposed to be called only by instrumentation injected code. /// /// - amount: How much gas is used. - fn gas(ctx: Runtime, amount: u32) -> Result<(), TrapReason> { + fn gas(ctx: Runtime, amount: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::MeteringBlock(amount))?; Ok(()) } @@ -966,8 +966,9 @@ pub mod env { /// /// Equivalent to the newer version of `seal_set_storage` with the exception of the return /// type. Still a valid thing to call when not interested in the return value. - fn seal_set_storage( - ctx: Runtime, + #[prefixed_alias] + fn set_storage( + ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32, @@ -994,8 +995,9 @@ pub mod env { /// Returns the size of the pre-existing value at the specified key if any. Otherwise /// `SENTINEL` is returned as a sentinel value. #[version(1)] - fn seal_set_storage( - ctx: Runtime, + #[prefixed_alias] + fn set_storage( + ctx: Runtime, key_ptr: u32, value_ptr: u32, value_len: u32, @@ -1020,8 +1022,9 @@ pub mod env { /// Returns the size of the pre-existing value at the specified key if any. Otherwise /// `SENTINEL` is returned as a sentinel value. #[unstable] - fn seal_set_storage( - ctx: Runtime, + #[prefixed_alias] + fn set_storage( + ctx: Runtime, key_ptr: u32, key_len: u32, value_ptr: u32, @@ -1034,7 +1037,8 @@ pub mod env { /// /// Equivalent to the newer version of `seal_clear_storage` with the exception of the return /// type. Still a valid thing to call when not interested in the return value. - fn seal_clear_storage(ctx: Runtime, key_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn clear_storage(ctx: Runtime, key_ptr: u32) -> Result<(), TrapReason> { ctx.clear_storage(KeyType::Fix, key_ptr).map(|_| ()) } @@ -1050,11 +1054,8 @@ pub mod env { /// Returns the size of the pre-existing value at the specified key if any. Otherwise /// `SENTINEL` is returned as a sentinel value. #[unstable] - fn seal_clear_storage( - ctx: Runtime, - key_ptr: u32, - key_len: u32, - ) -> Result { + #[prefixed_alias] + fn clear_storage(ctx: Runtime, key_ptr: u32, key_len: u32) -> Result { ctx.clear_storage(KeyType::Variable(key_len), key_ptr) } @@ -1073,8 +1074,9 @@ pub mod env { /// # Errors /// /// `ReturnCode::KeyNotFound` - fn seal_get_storage( - ctx: Runtime, + #[prefixed_alias] + fn get_storage( + ctx: Runtime, key_ptr: u32, out_ptr: u32, out_len_ptr: u32, @@ -1101,8 +1103,9 @@ pub mod env { /// /// `ReturnCode::KeyNotFound` #[unstable] - fn seal_get_storage( - ctx: Runtime, + #[prefixed_alias] + fn get_storage( + ctx: Runtime, key_ptr: u32, key_len: u32, out_ptr: u32, @@ -1124,7 +1127,8 @@ pub mod env { /// /// Returns the size of the pre-existing value at the specified key if any. Otherwise /// `SENTINEL` is returned as a sentinel value. - fn seal_contains_storage(ctx: Runtime, key_ptr: u32) -> Result { + #[prefixed_alias] + fn contains_storage(ctx: Runtime, key_ptr: u32) -> Result { ctx.contains_storage(KeyType::Fix, key_ptr) } @@ -1142,11 +1146,8 @@ pub mod env { /// Returns the size of the pre-existing value at the specified key if any. Otherwise /// `SENTINEL` is returned as a sentinel value. #[unstable] - fn seal_contains_storage( - ctx: Runtime, - key_ptr: u32, - key_len: u32, - ) -> Result { + #[prefixed_alias] + fn contains_storage(ctx: Runtime, key_ptr: u32, key_len: u32) -> Result { ctx.contains_storage(KeyType::Variable(key_len), key_ptr) } @@ -1164,8 +1165,9 @@ pub mod env { /// /// `ReturnCode::KeyNotFound` #[unstable] - fn seal_take_storage( - ctx: Runtime, + #[prefixed_alias] + fn take_storage( + ctx: Runtime, key_ptr: u32, key_len: u32, out_ptr: u32, @@ -1200,8 +1202,9 @@ pub mod env { /// # Errors /// /// `ReturnCode::TransferFailed` - fn seal_transfer( - ctx: Runtime, + #[prefixed_alias] + fn transfer( + ctx: Runtime, account_ptr: u32, _account_len: u32, value_ptr: u32, @@ -1233,8 +1236,9 @@ pub mod env { /// The values `_callee_len` and `_value_len` are ignored because the encoded sizes /// of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards /// compatibility. Consider switching to the newest version of this function. - fn seal_call( - ctx: Runtime, + #[prefixed_alias] + fn call( + ctx: Runtime, callee_ptr: u32, _callee_len: u32, gas: u64, @@ -1285,8 +1289,9 @@ pub mod env { /// `ReturnCode::TransferFailed` /// `ReturnCode::NotCallable` #[version(1)] - fn seal_call( - ctx: Runtime, + #[prefixed_alias] + fn call( + ctx: Runtime, flags: u32, callee_ptr: u32, gas: u64, @@ -1330,8 +1335,9 @@ pub mod env { /// `ReturnCode::CalleeReverted`: Output buffer is returned. /// `ReturnCode::CalleeTrapped` /// `ReturnCode::CodeNotFound` - fn seal_delegate_call( - ctx: Runtime, + #[prefixed_alias] + fn delegate_call( + ctx: Runtime, flags: u32, code_hash_ptr: u32, input_data_ptr: u32, @@ -1360,8 +1366,9 @@ pub mod env { /// The values `_code_hash_len` and `_value_len` are ignored because the encoded sizes /// of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards /// compatibility. Consider switching to the newest version of this function. - fn seal_instantiate( - ctx: Runtime, + #[prefixed_alias] + fn instantiate( + ctx: Runtime, code_hash_ptr: u32, _code_hash_len: u32, gas: u64, @@ -1432,8 +1439,9 @@ pub mod env { /// `ReturnCode::TransferFailed` /// `ReturnCode::CodeNotFound` #[version(1)] - fn seal_instantiate( - ctx: Runtime, + #[prefixed_alias] + fn instantiate( + ctx: Runtime, code_hash_ptr: u32, gas: u64, value_ptr: u32, @@ -1473,8 +1481,9 @@ pub mod env { /// The value `_beneficiary_len` is ignored because the encoded sizes /// this type is fixed through `[`MaxEncodedLen`]. The field exist for backwards /// compatibility. Consider switching to the newest version of this function. - fn seal_terminate( - ctx: Runtime, + #[prefixed_alias] + fn terminate( + ctx: Runtime, beneficiary_ptr: u32, _beneficiary_len: u32, ) -> Result<(), TrapReason> { @@ -1497,7 +1506,8 @@ pub mod env { /// - Failed to send the balance to the beneficiary. /// - The deletion queue is full. #[version(1)] - fn seal_terminate(ctx: Runtime, beneficiary_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn terminate(ctx: Runtime, beneficiary_ptr: u32) -> Result<(), TrapReason> { ctx.terminate(beneficiary_ptr) } @@ -1511,7 +1521,8 @@ pub mod env { /// # Note /// /// This function traps if the input was previously forwarded by a `seal_call`. - fn seal_input(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn input(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::InputBase)?; if let Some(input) = ctx.input_data.take() { ctx.write_sandbox_output(out_ptr, out_len_ptr, &input, false, |len| { @@ -1542,7 +1553,7 @@ pub mod env { /// /// Using a reserved bit triggers a trap. fn seal_return( - ctx: Runtime, + ctx: Runtime, flags: u32, data_ptr: u32, data_len: u32, @@ -1564,7 +1575,8 @@ pub mod env { /// 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. - fn seal_caller(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn caller(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::Caller)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -1583,7 +1595,8 @@ pub mod env { /// `T::AccountId`. Traps otherwise. /// /// Returned value is a u32-encoded boolean: (0 = false, 1 = true). - fn seal_is_contract(ctx: Runtime, account_ptr: u32) -> Result { + #[prefixed_alias] + fn is_contract(ctx: Runtime, account_ptr: u32) -> Result { ctx.charge_gas(RuntimeCosts::IsContract)?; let address: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(account_ptr)?; @@ -1604,8 +1617,9 @@ pub mod env { /// # Errors /// /// `ReturnCode::KeyNotFound` - fn seal_code_hash( - ctx: Runtime, + #[prefixed_alias] + fn code_hash( + ctx: Runtime, account_ptr: u32, out_ptr: u32, out_len_ptr: u32, @@ -1634,11 +1648,8 @@ pub mod env { /// - `out_ptr`: pointer to the linear memory where the returning value is written to. /// - `out_len_ptr`: in-out pointer into linear memory where the buffer length is read from and /// the value length is written to. - fn seal_own_code_hash( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn own_code_hash(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::OwnCodeHash)?; let code_hash_encoded = &ctx.ext.own_code_hash().encode(); Ok(ctx.write_sandbox_output( @@ -1660,7 +1671,8 @@ pub mod env { /// and `false` indicates that the caller is another contract. /// /// Returned value is a u32-encoded boolean: (0 = false, 1 = true). - fn seal_caller_is_origin(ctx: Runtime) -> Result { + #[prefixed_alias] + fn caller_is_origin(ctx: Runtime) -> Result { ctx.charge_gas(RuntimeCosts::CallerIsOrigin)?; Ok(ctx.ext.caller_is_origin() as u32) } @@ -1671,11 +1683,8 @@ pub mod env { /// `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. - fn seal_address( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn address(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::Address)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -1699,8 +1708,9 @@ pub mod env { /// /// It is recommended to avoid specifying very small values for `gas` as the prices for a single /// gas can be smaller than one. - fn seal_weight_to_fee( - ctx: Runtime, + #[prefixed_alias] + fn weight_to_fee( + ctx: Runtime, gas: u64, out_ptr: u32, out_len_ptr: u32, @@ -1724,11 +1734,8 @@ pub mod env { /// space at `out_ptr` is less than the size of the value a trap is triggered. /// /// The data is encoded as Gas. - fn seal_gas_left( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn gas_left(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::GasLeft)?; let gas_left = &ctx.ext.gas_meter().gas_left().encode(); Ok(ctx.write_sandbox_output(out_ptr, out_len_ptr, gas_left, false, already_charged)?) @@ -1742,11 +1749,8 @@ pub mod env { /// space at `out_ptr` is less than the size of the value a trap is triggered. /// /// The data is encoded as T::Balance. - fn seal_balance( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn balance(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::Balance)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -1765,8 +1769,9 @@ pub mod env { /// space at `out_ptr` is less than the size of the value a trap is triggered. /// /// The data is encoded as T::Balance. - fn seal_value_transferred( - ctx: Runtime, + #[prefixed_alias] + fn value_transferred( + ctx: Runtime, out_ptr: u32, out_len_ptr: u32, ) -> Result<(), TrapReason> { @@ -1792,8 +1797,9 @@ pub mod env { /// # Deprecation /// /// This function is deprecated. Users should migrate to the version in the "seal1" module. - fn seal_random( - ctx: Runtime, + #[prefixed_alias] + fn random( + ctx: Runtime, subject_ptr: u32, subject_len: u32, out_ptr: u32, @@ -1835,8 +1841,9 @@ pub mod env { /// call this on later blocks until the block number returned is later than the latest /// commitment. #[version(1)] - fn seal_random( - ctx: Runtime, + #[prefixed_alias] + fn random( + ctx: Runtime, subject_ptr: u32, subject_len: u32, out_ptr: u32, @@ -1862,7 +1869,8 @@ pub mod env { /// `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. - fn seal_now(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn now(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::Now)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -1876,11 +1884,8 @@ pub mod env { /// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer. /// /// The data is encoded as T::Balance. - fn seal_minimum_balance( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn minimum_balance(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::MinimumBalance)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -1901,8 +1906,9 @@ pub mod env { /// # Deprecation /// /// There is no longer a tombstone deposit. This function always returns 0. - fn seal_tombstone_deposit( - ctx: Runtime, + #[prefixed_alias] + fn tombstone_deposit( + ctx: Runtime, out_ptr: u32, out_len_ptr: u32, ) -> Result<(), TrapReason> { @@ -1917,8 +1923,9 @@ pub mod env { /// /// The state rent functionality was removed. This is stub only exists for /// backwards compatiblity - fn seal_restore_to( - ctx: Runtime, + #[prefixed_alias] + fn restore_to( + ctx: Runtime, _dest_ptr: u32, _dest_len: u32, _code_hash_ptr: u32, @@ -1939,8 +1946,9 @@ pub mod env { /// The state rent functionality was removed. This is stub only exists for /// backwards compatiblity #[version(1)] - fn seal_restore_to( - ctx: Runtime, + #[prefixed_alias] + fn restore_to( + ctx: Runtime, _dest_ptr: u32, _code_hash_ptr: u32, _rent_allowance_ptr: u32, @@ -1959,8 +1967,9 @@ pub mod env { /// - 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. - fn seal_deposit_event( - ctx: Runtime, + #[prefixed_alias] + fn deposit_event( + ctx: Runtime, topics_ptr: u32, topics_len: u32, data_ptr: u32, @@ -2017,8 +2026,9 @@ pub mod env { /// /// The state rent functionality was removed. This is stub only exists for /// backwards compatiblity. - fn seal_set_rent_allowance( - ctx: Runtime, + #[prefixed_alias] + fn set_rent_allowance( + ctx: Runtime, _value_ptr: u32, _value_len: u32, ) -> Result<(), TrapReason> { @@ -2033,7 +2043,8 @@ pub mod env { /// The state rent functionality was removed. This is stub only exists for /// backwards compatiblity. #[version(1)] - fn seal_set_rent_allowance(ctx: Runtime, _value_ptr: u32) -> Result<(), TrapReason> { + #[prefixed_alias] + fn set_rent_allowance(ctx: Runtime, _value_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::DebugMessage)?; Ok(()) } @@ -2044,11 +2055,8 @@ pub mod env { /// /// The state rent functionality was removed. This is stub only exists for /// backwards compatiblity. - fn seal_rent_allowance( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn rent_allowance(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::Balance)?; let rent_allowance = >::max_value().encode(); Ok(ctx.write_sandbox_output( @@ -2066,11 +2074,8 @@ pub mod env { /// `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. - fn seal_block_number( - ctx: Runtime, - out_ptr: u32, - out_len_ptr: u32, - ) -> Result<(), TrapReason> { + #[prefixed_alias] + fn block_number(ctx: Runtime, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::BlockNumber)?; Ok(ctx.write_sandbox_output( out_ptr, @@ -2098,8 +2103,9 @@ pub mod env { /// - `input_len`: the length of the input data in bytes. /// - `output_ptr`: the pointer into the linear memory where the output data is placed. The /// function will write the result directly into this buffer. - fn seal_hash_sha2_256( - ctx: Runtime, + #[prefixed_alias] + fn hash_sha2_256( + ctx: Runtime, input_ptr: u32, input_len: u32, output_ptr: u32, @@ -2125,8 +2131,9 @@ pub mod env { /// - `input_len`: the length of the input data in bytes. /// - `output_ptr`: the pointer into the linear memory where the output data is placed. The /// function will write the result directly into this buffer. - fn seal_hash_keccak_256( - ctx: Runtime, + #[prefixed_alias] + fn hash_keccak_256( + ctx: Runtime, input_ptr: u32, input_len: u32, output_ptr: u32, @@ -2152,8 +2159,9 @@ pub mod env { /// - `input_len`: the length of the input data in bytes. /// - `output_ptr`: the pointer into the linear memory where the output data is placed. The /// function will write the result directly into this buffer. - fn seal_hash_blake2_256( - ctx: Runtime, + #[prefixed_alias] + fn hash_blake2_256( + ctx: Runtime, input_ptr: u32, input_len: u32, output_ptr: u32, @@ -2179,8 +2187,9 @@ pub mod env { /// - `input_len`: the length of the input data in bytes. /// - `output_ptr`: the pointer into the linear memory where the output data is placed. The /// function will write the result directly into this buffer. - fn seal_hash_blake2_128( - ctx: Runtime, + #[prefixed_alias] + fn hash_blake2_128( + ctx: Runtime, input_ptr: u32, input_len: u32, output_ptr: u32, @@ -2200,8 +2209,9 @@ pub mod env { /// /// If no chain extension exists the contract will trap with the `NoChainExtension` /// module error. - fn seal_call_chain_extension( - ctx: Runtime, + #[prefixed_alias] + fn call_chain_extension( + ctx: Runtime, id: u32, input_ptr: u32, input_len: u32, @@ -2243,8 +2253,9 @@ pub mod env { /// not being executed as an RPC. For example, they could allow users to disable logging /// through compile time flags (cargo features) for on-chain deployment. Additionally, the /// return value of this function can be cached in order to prevent further calls at runtime. - fn seal_debug_message( - ctx: Runtime, + #[prefixed_alias] + fn debug_message( + ctx: Runtime, str_ptr: u32, str_len: u32, ) -> Result { @@ -2297,8 +2308,9 @@ pub mod env { /// This function is unstable and subject to change (or removal) in the future. Do not /// deploy a contract using it to a production chain. #[unstable] - fn seal_call_runtime( - ctx: Runtime, + #[prefixed_alias] + fn call_runtime( + ctx: Runtime, call_ptr: u32, call_len: u32, ) -> Result { @@ -2334,8 +2346,9 @@ pub mod env { /// # Errors /// /// `ReturnCode::EcdsaRecoverFailed` - fn seal_ecdsa_recover( - ctx: Runtime, + #[prefixed_alias] + fn ecdsa_recover( + ctx: Runtime, signature_ptr: u32, message_hash_ptr: u32, output_ptr: u32, @@ -2387,10 +2400,8 @@ pub mod env { /// # Errors /// /// `ReturnCode::CodeNotFound` - fn seal_set_code_hash( - ctx: Runtime, - code_hash_ptr: u32, - ) -> Result { + #[prefixed_alias] + fn set_code_hash(ctx: Runtime, code_hash_ptr: u32) -> Result { ctx.charge_gas(RuntimeCosts::SetCodeHash)?; let code_hash: CodeHash<::T> = ctx.read_sandbox_memory_as(code_hash_ptr)?; match ctx.ext.set_code_hash(code_hash) { @@ -2418,8 +2429,9 @@ pub mod env { /// # Errors /// /// `ReturnCode::EcdsaRecoverFailed` - fn seal_ecdsa_to_eth_address( - ctx: Runtime, + #[prefixed_alias] + fn ecdsa_to_eth_address( + ctx: Runtime, key_ptr: u32, out_ptr: u32, ) -> Result {