mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 09:21:05 +00:00
[contracts] Port host functions to Weight V2 and storage deposit limit (#13565)
* added [unstable][seal2] call() * updated test to cover new seal_call proof_limit * docs updated * add [seal2][unstable] instantiate() and test * add [seal2][unstable] weight_to_fee() + docs and test * add [seal2][unstable] gas_left() + docs and test * update benchmarks * add DefaultDepositLimit to pallet Config * specify deposit limit for nested call add test for nested call deposit limit save: separate deposit limit for nested calls * specify deposit limit for nested instantiate save: works with test cleaned up debugging outputs * update benchmarks * added missing fixtures * fix benches * pass explicit deposit limit to storage bench * explicit deposit limit for another set_storage bench * add more deposit limit for storage benches * moving to simplified benchmarks * moved to simplified benchmarks * fix seal_weight_to_fee bench * fix seal_instantiate benchmark * doc typo fix * default dl for benchmarking more dl for tests dl for tests to max deposit_limit fix in instantiate bench fix instantiate bench fix instantiate benchmark fix instantiate bench again remove dbg fix seal bench again fixing it still seal_instantiate zero deposit less runs to check if deposit enough try try 2 try 3 try 4 * max_runtime_mem to Schedule limits * add default deposit limit fallback check to test * weight params renaming * fmt * Update frame/contracts/src/benchmarking/mod.rs Co-authored-by: PG Herveou <pgherveou@gmail.com> * prettify inputs in tests * typestate param refactored --------- Co-authored-by: PG Herveou <pgherveou@gmail.com>
This commit is contained in:
@@ -370,7 +370,7 @@ mod tests {
|
||||
gas::GasMeter,
|
||||
storage::WriteOutcome,
|
||||
tests::{RuntimeCall, Test, ALICE, BOB},
|
||||
BalanceOf, CodeHash, Error, OldWeight, Pallet as Contracts,
|
||||
BalanceOf, CodeHash, Error, Pallet as Contracts,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use frame_support::{
|
||||
@@ -470,6 +470,7 @@ mod tests {
|
||||
fn call(
|
||||
&mut self,
|
||||
_gas_limit: Weight,
|
||||
_deposit_limit: BalanceOf<Self::T>,
|
||||
to: AccountIdOf<Self::T>,
|
||||
value: u64,
|
||||
data: Vec<u8>,
|
||||
@@ -489,6 +490,7 @@ mod tests {
|
||||
fn instantiate(
|
||||
&mut self,
|
||||
gas_limit: Weight,
|
||||
_deposit_limit: BalanceOf<Self::T>,
|
||||
code_hash: CodeHash<Test>,
|
||||
value: u64,
|
||||
data: Vec<u8>,
|
||||
@@ -587,7 +589,11 @@ mod tests {
|
||||
16_384
|
||||
}
|
||||
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
|
||||
BalanceOf::<Self::T>::from(1312_u32).saturating_mul(weight.ref_time().into())
|
||||
BalanceOf::<Self::T>::from(1312_u32)
|
||||
.saturating_mul(weight.ref_time().into())
|
||||
.saturating_add(
|
||||
BalanceOf::<Self::T>::from(103_u32).saturating_mul(weight.proof_size()),
|
||||
)
|
||||
}
|
||||
fn schedule(&self) -> &Schedule<Self::T> {
|
||||
&self.schedule
|
||||
@@ -1589,7 +1595,7 @@ mod tests {
|
||||
|
||||
const CODE_GAS_PRICE: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_weight_to_fee" (func $seal_weight_to_fee (param i64 i32 i32)))
|
||||
(import "seal1" "weight_to_fee" (func $seal_weight_to_fee (param i64 i64 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; size of our buffer is 32 bytes
|
||||
@@ -1606,7 +1612,7 @@ mod tests {
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas price in the buffer
|
||||
(call $seal_weight_to_fee (i64.const 2) (i32.const 0) (i32.const 32))
|
||||
(call $seal_weight_to_fee (i64.const 2) (i64.const 1) (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
@@ -1616,11 +1622,11 @@ mod tests {
|
||||
)
|
||||
)
|
||||
|
||||
;; assert that contents of the buffer is equal to the i64 value of 2 * 1312.
|
||||
;; assert that contents of the buffer is equal to the i64 value of 2 * 1312 + 103 = 2727.
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load (i32.const 0))
|
||||
(i64.const 2624)
|
||||
(i64.const 2727)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1635,12 +1641,12 @@ mod tests {
|
||||
|
||||
const CODE_GAS_LEFT: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_gas_left" (func $seal_gas_left (param i32 i32)))
|
||||
(import "seal1" "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
|
||||
(data (i32.const 32) "\20")
|
||||
;; Make output buffer size 20 bytes
|
||||
(data (i32.const 20) "\14")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
@@ -1652,19 +1658,19 @@ mod tests {
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; This stores the gas left in the buffer
|
||||
(call $seal_gas_left (i32.const 0) (i32.const 32))
|
||||
;; This stores the weight left to the buffer
|
||||
(call $seal_gas_left (i32.const 0) (i32.const 20))
|
||||
|
||||
;; assert len == 8
|
||||
;; Assert len <= 16 (max encoded Weight len)
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 32))
|
||||
(i32.const 8)
|
||||
(i32.le_u
|
||||
(i32.load (i32.const 20))
|
||||
(i32.const 16)
|
||||
)
|
||||
)
|
||||
|
||||
;; return gas left
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 8))
|
||||
;; Return weight left and its encoded value len
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.load (i32.const 20)))
|
||||
|
||||
(unreachable)
|
||||
)
|
||||
@@ -1679,11 +1685,11 @@ mod tests {
|
||||
|
||||
let output = execute(CODE_GAS_LEFT, vec![], &mut ext).unwrap();
|
||||
|
||||
let gas_left = OldWeight::decode(&mut &*output.data).unwrap();
|
||||
let weight_left = Weight::decode(&mut &*output.data).unwrap();
|
||||
let actual_left = ext.gas_meter.gas_left();
|
||||
// TODO: account for proof size weight
|
||||
assert!(gas_left < gas_limit.ref_time(), "gas_left must be less than initial");
|
||||
assert!(gas_left > actual_left.ref_time(), "gas_left must be greater than final");
|
||||
|
||||
assert!(weight_left.all_lt(gas_limit), "gas_left must be less than initial");
|
||||
assert!(weight_left.all_gt(actual_left), "gas_left must be greater than final");
|
||||
}
|
||||
|
||||
/// Test that [`frame_support::weights::OldWeight`] en/decodes the same as our
|
||||
|
||||
@@ -433,7 +433,7 @@ bitflags! {
|
||||
/// The kind of call that should be performed.
|
||||
enum CallType {
|
||||
/// Execute another instantiated contract
|
||||
Call { callee_ptr: u32, value_ptr: u32, gas: u64 },
|
||||
Call { callee_ptr: u32, value_ptr: u32, deposit_ptr: u32, weight: Weight },
|
||||
/// Execute deployed code in the context (storage, account ID, value) of the caller contract
|
||||
DelegateCall { code_hash_ptr: u32 },
|
||||
}
|
||||
@@ -873,16 +873,22 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
|
||||
};
|
||||
|
||||
let call_outcome = match call_type {
|
||||
CallType::Call { callee_ptr, value_ptr, gas } => {
|
||||
CallType::Call { callee_ptr, value_ptr, deposit_ptr, weight } => {
|
||||
let callee: <<E as Ext>::T as frame_system::Config>::AccountId =
|
||||
self.read_sandbox_memory_as(memory, callee_ptr)?;
|
||||
let deposit_limit: BalanceOf<<E as Ext>::T> = if deposit_ptr == SENTINEL {
|
||||
BalanceOf::<<E as Ext>::T>::zero()
|
||||
} else {
|
||||
self.read_sandbox_memory_as(memory, deposit_ptr)?
|
||||
};
|
||||
let value: BalanceOf<<E as Ext>::T> =
|
||||
self.read_sandbox_memory_as(memory, value_ptr)?;
|
||||
if value > 0u32.into() {
|
||||
self.charge_gas(RuntimeCosts::CallSurchargeTransfer)?;
|
||||
}
|
||||
self.ext.call(
|
||||
Weight::from_parts(gas, 0),
|
||||
weight,
|
||||
deposit_limit,
|
||||
callee,
|
||||
value,
|
||||
input_data,
|
||||
@@ -926,7 +932,8 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
|
||||
&mut self,
|
||||
memory: &mut [u8],
|
||||
code_hash_ptr: u32,
|
||||
gas: u64,
|
||||
weight: Weight,
|
||||
deposit_ptr: u32,
|
||||
value_ptr: u32,
|
||||
input_data_ptr: u32,
|
||||
input_data_len: u32,
|
||||
@@ -937,8 +944,12 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
|
||||
salt_ptr: u32,
|
||||
salt_len: u32,
|
||||
) -> Result<ReturnCode, TrapReason> {
|
||||
let gas = Weight::from_parts(gas, 0);
|
||||
self.charge_gas(RuntimeCosts::InstantiateBase { input_data_len, salt_len })?;
|
||||
let deposit_limit: BalanceOf<<E as Ext>::T> = if deposit_ptr == SENTINEL {
|
||||
BalanceOf::<<E as Ext>::T>::zero()
|
||||
} else {
|
||||
self.read_sandbox_memory_as(memory, deposit_ptr)?
|
||||
};
|
||||
let value: BalanceOf<<E as Ext>::T> = self.read_sandbox_memory_as(memory, value_ptr)?;
|
||||
if value > 0u32.into() {
|
||||
self.charge_gas(RuntimeCosts::InstantiateSurchargeTransfer)?;
|
||||
@@ -947,7 +958,8 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
|
||||
self.read_sandbox_memory_as(memory, code_hash_ptr)?;
|
||||
let input_data = self.read_sandbox_memory(memory, input_data_ptr, input_data_len)?;
|
||||
let salt = self.read_sandbox_memory(memory, salt_ptr, salt_len)?;
|
||||
let instantiate_outcome = self.ext.instantiate(gas, code_hash, value, input_data, &salt);
|
||||
let instantiate_outcome =
|
||||
self.ext.instantiate(weight, deposit_limit, code_hash, value, input_data, &salt);
|
||||
if let Ok((address, output)) = &instantiate_outcome {
|
||||
if !output.flags.contains(ReturnFlags::REVERT) {
|
||||
self.write_sandbox_output(
|
||||
@@ -993,6 +1005,7 @@ pub mod env {
|
||||
///
|
||||
/// NOTE: This is a implementation defined call and is NOT a part of the public API.
|
||||
/// This call is supposed to be called only by instrumentation injected code.
|
||||
/// It deals only with the *ref_time* Weight.
|
||||
///
|
||||
/// - `amount`: How much gas is used.
|
||||
fn gas(ctx: _, _memory: _, amount: u64) -> Result<(), TrapReason> {
|
||||
@@ -1002,8 +1015,9 @@ pub mod env {
|
||||
|
||||
/// Set the value at the given key in the contract storage.
|
||||
///
|
||||
/// Equivalent to the newer version [`super::seal1::Api::set_storage`] with the exception of the
|
||||
/// return type. Still a valid thing to call when not interested in the return value.
|
||||
/// Equivalent to the newer [`seal1`][`super::api_doc::Version1::set_storage`] version with the
|
||||
/// exception of the return type. Still a valid thing to call when not interested in the return
|
||||
/// value.
|
||||
#[prefixed_alias]
|
||||
fn set_storage(
|
||||
ctx: _,
|
||||
@@ -1076,8 +1090,9 @@ pub mod env {
|
||||
|
||||
/// Clear the value at the given key in the contract storage.
|
||||
///
|
||||
/// Equivalent to the newer version [`super::seal1::Api::clear_storage`] with the exception of
|
||||
/// the return type. Still a valid thing to call when not interested in the return value.
|
||||
/// Equivalent to the newer [`seal1`][`super::api_doc::Version1::clear_storage`] version with
|
||||
/// the exception of the return type. Still a valid thing to call when not interested in the
|
||||
/// return value.
|
||||
#[prefixed_alias]
|
||||
fn clear_storage(ctx: _, memory: _, key_ptr: u32) -> Result<(), TrapReason> {
|
||||
ctx.clear_storage(memory, KeyType::Fix, key_ptr).map(|_| ())
|
||||
@@ -1299,7 +1314,47 @@ pub mod env {
|
||||
ctx.call(
|
||||
memory,
|
||||
CallFlags::ALLOW_REENTRY,
|
||||
CallType::Call { callee_ptr, value_ptr, gas },
|
||||
CallType::Call {
|
||||
callee_ptr,
|
||||
value_ptr,
|
||||
deposit_ptr: SENTINEL,
|
||||
weight: Weight::from_parts(gas, 0),
|
||||
},
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
output_ptr,
|
||||
output_len_ptr,
|
||||
)
|
||||
}
|
||||
|
||||
/// Make a call to another contract.
|
||||
///
|
||||
/// Equivalent to the newer [`seal2`][`super::api_doc::Version2::call`] version but works with
|
||||
/// *ref_time* Weight only. It is recommended to switch to the latest version, once it's
|
||||
/// stabilized.
|
||||
#[version(1)]
|
||||
#[prefixed_alias]
|
||||
fn call(
|
||||
ctx: _,
|
||||
memory: _,
|
||||
flags: u32,
|
||||
callee_ptr: u32,
|
||||
gas: u64,
|
||||
value_ptr: u32,
|
||||
input_data_ptr: u32,
|
||||
input_data_len: u32,
|
||||
output_ptr: u32,
|
||||
output_len_ptr: u32,
|
||||
) -> Result<ReturnCode, TrapReason> {
|
||||
ctx.call(
|
||||
memory,
|
||||
CallFlags::from_bits(flags).ok_or(Error::<E::T>::InvalidCallFlags)?,
|
||||
CallType::Call {
|
||||
callee_ptr,
|
||||
value_ptr,
|
||||
deposit_ptr: SENTINEL,
|
||||
weight: Weight::from_parts(gas, 0),
|
||||
},
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
output_ptr,
|
||||
@@ -1318,7 +1373,12 @@ pub mod env {
|
||||
/// - `flags`: See `crate::wasm::runtime::CallFlags` for a documentation of the supported flags.
|
||||
/// - `callee_ptr`: a pointer to the address of the callee contract. Should be decodable as an
|
||||
/// `T::AccountId`. Traps otherwise.
|
||||
/// - `gas`: how much gas to devote to the execution.
|
||||
/// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
|
||||
/// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
|
||||
/// - `deposit_ptr`: a pointer to the buffer with value of the storage deposit limit for the
|
||||
/// call. Should be decodable as a `T::Balance`. Traps otherwise. Passing `SENTINEL` means
|
||||
/// setting no specific limit for the call, which implies storage usage up to the limit of the
|
||||
/// parent call.
|
||||
/// - `value_ptr`: a pointer to the buffer with value, how much value to send. Should be
|
||||
/// decodable as a `T::Balance`. Traps otherwise.
|
||||
/// - `input_data_ptr`: a pointer to a buffer to be used as input data to the callee.
|
||||
@@ -1336,14 +1396,16 @@ pub mod env {
|
||||
/// - `ReturnCode::CalleeTrapped`
|
||||
/// - `ReturnCode::TransferFailed`
|
||||
/// - `ReturnCode::NotCallable`
|
||||
#[version(1)]
|
||||
#[prefixed_alias]
|
||||
#[version(2)]
|
||||
#[unstable]
|
||||
fn call(
|
||||
ctx: _,
|
||||
memory: _,
|
||||
flags: u32,
|
||||
callee_ptr: u32,
|
||||
gas: u64,
|
||||
ref_time_limit: u64,
|
||||
proof_size_limit: u64,
|
||||
deposit_ptr: u32,
|
||||
value_ptr: u32,
|
||||
input_data_ptr: u32,
|
||||
input_data_len: u32,
|
||||
@@ -1353,7 +1415,12 @@ pub mod env {
|
||||
ctx.call(
|
||||
memory,
|
||||
CallFlags::from_bits(flags).ok_or(Error::<E::T>::InvalidCallFlags)?,
|
||||
CallType::Call { callee_ptr, value_ptr, gas },
|
||||
CallType::Call {
|
||||
callee_ptr,
|
||||
value_ptr,
|
||||
deposit_ptr,
|
||||
weight: Weight::from_parts(ref_time_limit, proof_size_limit),
|
||||
},
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
output_ptr,
|
||||
@@ -1417,8 +1484,7 @@ pub mod env {
|
||||
/// # Note
|
||||
///
|
||||
/// The values `_code_hash_len` and `_value_len` are ignored because the encoded sizes
|
||||
/// of those types are fixed through
|
||||
/// [`codec::MaxEncodedLen`]. The fields exist
|
||||
/// of those types are fixed through [`codec::MaxEncodedLen`]. The fields exist
|
||||
/// for backwards compatibility. Consider switching to the newest version of this function.
|
||||
#[prefixed_alias]
|
||||
fn instantiate(
|
||||
@@ -1441,7 +1507,47 @@ pub mod env {
|
||||
ctx.instantiate(
|
||||
memory,
|
||||
code_hash_ptr,
|
||||
gas,
|
||||
Weight::from_parts(gas, 0),
|
||||
SENTINEL,
|
||||
value_ptr,
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
address_ptr,
|
||||
address_len_ptr,
|
||||
output_ptr,
|
||||
output_len_ptr,
|
||||
salt_ptr,
|
||||
salt_len,
|
||||
)
|
||||
}
|
||||
|
||||
/// Instantiate a contract with the specified code hash.
|
||||
///
|
||||
/// Equivalent to the newer [`seal2`][`super::api_doc::Version2::instantiate`] version but works
|
||||
/// with *ref_time* Weight only. It is recommended to switch to the latest version, once it's
|
||||
/// stabilized.
|
||||
#[version(1)]
|
||||
#[prefixed_alias]
|
||||
fn instantiate(
|
||||
ctx: _,
|
||||
memory: _,
|
||||
code_hash_ptr: u32,
|
||||
gas: u64,
|
||||
value_ptr: u32,
|
||||
input_data_ptr: u32,
|
||||
input_data_len: u32,
|
||||
address_ptr: u32,
|
||||
address_len_ptr: u32,
|
||||
output_ptr: u32,
|
||||
output_len_ptr: u32,
|
||||
salt_ptr: u32,
|
||||
salt_len: u32,
|
||||
) -> Result<ReturnCode, TrapReason> {
|
||||
ctx.instantiate(
|
||||
memory,
|
||||
code_hash_ptr,
|
||||
Weight::from_parts(gas, 0),
|
||||
SENTINEL,
|
||||
value_ptr,
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
@@ -1468,15 +1574,21 @@ pub mod env {
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `code_hash_ptr`: a pointer to the buffer that contains the initializer code.
|
||||
/// - `gas`: how much gas to devote to the execution of the initializer code.
|
||||
/// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
|
||||
/// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
|
||||
/// - `deposit_ptr`: a pointer to the buffer with value of the storage deposit limit for
|
||||
/// instantiation. Should be decodable as a `T::Balance`. Traps otherwise. Passing `SENTINEL`
|
||||
/// means setting no specific limit for the call, which implies storage usage up to the limit
|
||||
/// of the parent call.
|
||||
/// - `value_ptr`: a pointer to the buffer with value, how much value to send. Should be
|
||||
/// decodable as a `T::Balance`. Traps otherwise.
|
||||
/// - `input_data_ptr`: a pointer to a buffer to be used as input data to the initializer code.
|
||||
/// - `input_data_len`: length of the input data buffer.
|
||||
/// - `address_ptr`: a pointer where the new account's address is copied to.
|
||||
/// - `address_len_ptr`: in-out pointer to where the length of the buffer is read from and the
|
||||
/// actual length is written to.
|
||||
/// - `output_ptr`: a pointer where the output buffer is copied to.
|
||||
/// - `address_ptr`: a pointer where the new account's address is copied to. `SENTINEL` means
|
||||
/// not to copy.
|
||||
/// - `address_len_ptr`: pointer to where put the length of the address.
|
||||
/// - `output_ptr`: a pointer where the output buffer is copied to. `SENTINEL` means not to
|
||||
/// copy.
|
||||
/// - `output_len_ptr`: in-out pointer to where the length of the buffer is read from and the
|
||||
/// actual length is written to.
|
||||
/// - `salt_ptr`: Pointer to raw bytes used for address derivation. See `fn contract_address`.
|
||||
@@ -1494,13 +1606,15 @@ pub mod env {
|
||||
/// - `ReturnCode::CalleeTrapped`
|
||||
/// - `ReturnCode::TransferFailed`
|
||||
/// - `ReturnCode::CodeNotFound`
|
||||
#[version(1)]
|
||||
#[prefixed_alias]
|
||||
#[version(2)]
|
||||
#[unstable]
|
||||
fn instantiate(
|
||||
ctx: _,
|
||||
memory: _,
|
||||
code_hash_ptr: u32,
|
||||
gas: u64,
|
||||
ref_time_limit: u64,
|
||||
proof_size_limit: u64,
|
||||
deposit_ptr: u32,
|
||||
value_ptr: u32,
|
||||
input_data_ptr: u32,
|
||||
input_data_len: u32,
|
||||
@@ -1514,7 +1628,8 @@ pub mod env {
|
||||
ctx.instantiate(
|
||||
memory,
|
||||
code_hash_ptr,
|
||||
gas,
|
||||
Weight::from_parts(ref_time_limit, proof_size_limit),
|
||||
deposit_ptr,
|
||||
value_ptr,
|
||||
input_data_ptr,
|
||||
input_data_len,
|
||||
@@ -1762,17 +1877,9 @@ pub mod env {
|
||||
|
||||
/// Stores the price for the specified amount of gas into the supplied buffer.
|
||||
///
|
||||
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
|
||||
/// `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.
|
||||
///
|
||||
/// The data is encoded as `T::Balance`.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// It is recommended to avoid specifying very small values for `gas` as the prices for a single
|
||||
/// gas can be smaller than one.
|
||||
/// Equivalent to the newer [`seal1`][`super::api_doc::Version2::weight_to_fee`] version but
|
||||
/// works with *ref_time* Weight only. It is recommended to switch to the latest version, once
|
||||
/// it's stabilized.
|
||||
#[prefixed_alias]
|
||||
fn weight_to_fee(
|
||||
ctx: _,
|
||||
@@ -1793,18 +1900,76 @@ pub mod env {
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Stores the amount of gas left into the supplied buffer.
|
||||
/// Stores the price for the specified amount of weight into the supplied buffer.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `out_ptr`: pointer to the linear memory where the returning value is written to. If the
|
||||
/// available space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
/// - `out_len_ptr`: in-out pointer into linear memory where the buffer length is read from and
|
||||
/// the value length is written to.
|
||||
///
|
||||
/// The data is encoded as `T::Balance`.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// It is recommended to avoid specifying very small values for `ref_time_limit` and
|
||||
/// `proof_size_limit` as the prices for a single gas can be smaller than the basic balance
|
||||
/// unit.
|
||||
#[version(1)]
|
||||
#[unstable]
|
||||
fn weight_to_fee(
|
||||
ctx: _,
|
||||
memory: _,
|
||||
ref_time_limit: u64,
|
||||
proof_size_limit: u64,
|
||||
out_ptr: u32,
|
||||
out_len_ptr: u32,
|
||||
) -> Result<(), TrapReason> {
|
||||
let weight = Weight::from_parts(ref_time_limit, proof_size_limit);
|
||||
ctx.charge_gas(RuntimeCosts::WeightToFee)?;
|
||||
Ok(ctx.write_sandbox_output(
|
||||
memory,
|
||||
out_ptr,
|
||||
out_len_ptr,
|
||||
&ctx.ext.get_weight_price(weight).encode(),
|
||||
false,
|
||||
already_charged,
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Stores the weight left into the supplied buffer.
|
||||
///
|
||||
/// Equivalent to the newer [`seal1`][`super::api_doc::Version2::gas_left`] version but
|
||||
/// works with *ref_time* Weight only. It is recommended to switch to the latest version, once
|
||||
/// it's stabilized.
|
||||
#[prefixed_alias]
|
||||
fn gas_left(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
|
||||
ctx.charge_gas(RuntimeCosts::GasLeft)?;
|
||||
let gas_left = &ctx.ext.gas_meter().gas_left().ref_time().encode();
|
||||
Ok(ctx.write_sandbox_output(
|
||||
memory,
|
||||
out_ptr,
|
||||
out_len_ptr,
|
||||
gas_left,
|
||||
false,
|
||||
already_charged,
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Stores the amount of weight left into the supplied buffer.
|
||||
///
|
||||
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
|
||||
/// `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.
|
||||
///
|
||||
/// The data is encoded as Gas.
|
||||
#[prefixed_alias]
|
||||
/// The data is encoded as Weight.
|
||||
#[version(1)]
|
||||
#[unstable]
|
||||
fn gas_left(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
|
||||
ctx.charge_gas(RuntimeCosts::GasLeft)?;
|
||||
let gas_left = &ctx.ext.gas_meter().gas_left().ref_time().encode();
|
||||
let gas_left = &ctx.ext.gas_meter().gas_left().encode();
|
||||
Ok(ctx.write_sandbox_output(
|
||||
memory,
|
||||
out_ptr,
|
||||
|
||||
Reference in New Issue
Block a user