mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 22:11:06 +00:00
contracts: Expose rent parameter to contracts (#8231)
* contracts: Expose rent parameter to contracts * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Fix typos * Improve comments * Add rent parameter weights * Allow deploying a new schedule with the same version * Add storage migration for new schedule * Only decode the schedule version in storage migration * Remove confusing docs * Replace original_code_len() by aggregate_code_len() Co-authored-by: Parity Benchmarking Bot <admin@parity.io>
This commit is contained in:
committed by
GitHub
parent
3743cec9bd
commit
a4e8875897
@@ -224,13 +224,21 @@ where
|
||||
fn occupied_storage(&self) -> u32 {
|
||||
// We disregard the size of the struct itself as the size is completely
|
||||
// dominated by the code size.
|
||||
let len = self.original_code_len.saturating_add(self.code.len() as u32);
|
||||
let len = self.aggregate_code_len();
|
||||
len.checked_div(self.refcount as u32).unwrap_or(len)
|
||||
}
|
||||
|
||||
fn code_len(&self) -> u32 {
|
||||
self.code.len() as u32
|
||||
}
|
||||
|
||||
fn aggregate_code_len(&self) -> u32 {
|
||||
self.original_code_len.saturating_add(self.code_len())
|
||||
}
|
||||
|
||||
fn refcount(&self) -> u32 {
|
||||
self.refcount as u32
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -238,7 +246,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
CodeHash, BalanceOf, Error, Module as Contracts,
|
||||
exec::{Ext, StorageKey, AccountIdOf, Executable},
|
||||
exec::{Ext, StorageKey, AccountIdOf, Executable, RentParams},
|
||||
gas::GasMeter,
|
||||
tests::{Test, Call, ALICE, BOB},
|
||||
};
|
||||
@@ -249,6 +257,7 @@ mod tests {
|
||||
use frame_support::{dispatch::DispatchResult, weights::Weight};
|
||||
use assert_matches::assert_matches;
|
||||
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin};
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
const GAS_LIMIT: Weight = 10_000_000_000;
|
||||
|
||||
@@ -295,6 +304,7 @@ mod tests {
|
||||
// (topics, data)
|
||||
events: Vec<(Vec<H256>, Vec<u8>)>,
|
||||
schedule: Schedule<Test>,
|
||||
rent_params: RentParams<Test>,
|
||||
}
|
||||
|
||||
impl Ext for MockExt {
|
||||
@@ -395,46 +405,38 @@ mod tests {
|
||||
fn value_transferred(&self) -> u64 {
|
||||
1337
|
||||
}
|
||||
|
||||
fn now(&self) -> &u64 {
|
||||
&1111
|
||||
}
|
||||
|
||||
fn minimum_balance(&self) -> u64 {
|
||||
666
|
||||
}
|
||||
|
||||
fn tombstone_deposit(&self) -> u64 {
|
||||
16
|
||||
}
|
||||
|
||||
fn random(&self, subject: &[u8]) -> H256 {
|
||||
H256::from_slice(subject)
|
||||
}
|
||||
|
||||
fn deposit_event(&mut self, topics: Vec<H256>, data: Vec<u8>) {
|
||||
self.events.push((topics, data))
|
||||
}
|
||||
|
||||
fn set_rent_allowance(&mut self, rent_allowance: u64) {
|
||||
self.rent_allowance = rent_allowance;
|
||||
}
|
||||
|
||||
fn rent_allowance(&self) -> u64 {
|
||||
self.rent_allowance
|
||||
}
|
||||
|
||||
fn block_number(&self) -> u64 { 121 }
|
||||
|
||||
fn max_value_size(&self) -> u32 { 16_384 }
|
||||
|
||||
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
|
||||
BalanceOf::<Self::T>::from(1312_u32).saturating_mul(weight.into())
|
||||
}
|
||||
|
||||
fn schedule(&self) -> &Schedule<Self::T> {
|
||||
&self.schedule
|
||||
}
|
||||
fn rent_params(&self) -> &RentParams<Self::T> {
|
||||
&self.rent_params
|
||||
}
|
||||
}
|
||||
|
||||
impl Ext for &mut MockExt {
|
||||
@@ -537,6 +539,9 @@ mod tests {
|
||||
fn schedule(&self) -> &Schedule<Self::T> {
|
||||
(**self).schedule()
|
||||
}
|
||||
fn rent_params(&self) -> &RentParams<Self::T> {
|
||||
(**self).rent_params()
|
||||
}
|
||||
}
|
||||
|
||||
fn execute<E: Ext>(
|
||||
@@ -1840,4 +1845,45 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
const CODE_RENT_PARAMS: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_rent_params" (func $seal_rent_params (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 4) buffer size = 128 bytes
|
||||
(data (i32.const 0) "\80")
|
||||
|
||||
;; [4; inf) buffer where the result is copied
|
||||
|
||||
(func (export "call")
|
||||
;; Load the rent params into memory
|
||||
(call $seal_rent_params
|
||||
(i32.const 4) ;; Pointer to the output buffer
|
||||
(i32.const 0) ;; Pointer to the size of the buffer
|
||||
)
|
||||
|
||||
;; Return the contents of the buffer
|
||||
(call $seal_return
|
||||
(i32.const 0) ;; return flags
|
||||
(i32.const 4) ;; buffer pointer
|
||||
(i32.load (i32.const 0)) ;; buffer size
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn rent_params_work() {
|
||||
let output = execute(
|
||||
CODE_RENT_PARAMS,
|
||||
vec![],
|
||||
MockExt::default(),
|
||||
&mut GasMeter::new(GAS_LIMIT),
|
||||
).unwrap();
|
||||
let rent_params = <RentParams<Test>>::default().encode();
|
||||
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_params });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +215,8 @@ pub enum RuntimeToken {
|
||||
ChainExtension(u64),
|
||||
/// Weight charged for copying data from the sandbox.
|
||||
CopyIn(u32),
|
||||
/// Weight of calling `seal_rent_params`.
|
||||
RentParams,
|
||||
}
|
||||
|
||||
impl<T: Config> Token<T> for RuntimeToken
|
||||
@@ -283,6 +285,7 @@ where
|
||||
.saturating_add(s.hash_blake2_128_per_byte.saturating_mul(len.into())),
|
||||
ChainExtension(amount) => amount,
|
||||
CopyIn(len) => s.return_per_byte.saturating_mul(len.into()),
|
||||
RentParams => s.rent_params,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1513,4 +1516,25 @@ define_env!(Env, <E: Ext>,
|
||||
})),
|
||||
}
|
||||
},
|
||||
|
||||
// Stores the rent params 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 [`crate::exec::RentParams`].
|
||||
//
|
||||
// # Note
|
||||
//
|
||||
// The returned information was collected and cached when the current contract call
|
||||
// started execution. Any change to those values that happens due to actions of the
|
||||
// current call or contracts that are called by this contract are not considered.
|
||||
seal_rent_params(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
ctx.charge_gas(RuntimeToken::RentParams)?;
|
||||
Ok(ctx.write_sandbox_output(
|
||||
out_ptr, out_len_ptr, &ctx.ext.rent_params().encode(), false, already_charged
|
||||
)?)
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user