mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-26 00:41:09 +00:00
Contracts: Only exec parsed code in benchmarks (#3915)
[Weights compare](https://weights.tasty.limo/compare?unit=weight&ignore_errors=true&threshold=10&method=asymptotic&repo=polkadot-sdk&old=master&new=pg%2Fbench_tweaks&path_pattern=substrate%2Fframe%2F**%2Fsrc%2Fweights.rs%2Cpolkadot%2Fruntime%2F*%2Fsrc%2Fweights%2F**%2F*.rs%2Cpolkadot%2Fbridges%2Fmodules%2F*%2Fsrc%2Fweights.rs%2Ccumulus%2F**%2Fweights%2F*.rs%2Ccumulus%2F**%2Fweights%2Fxcm%2F*.rs%2Ccumulus%2F**%2Fsrc%2Fweights.rs) Note: Raw weights change does not mean much here, as this PR reduce the scope of what is benchmarked, they are therefore decreased by a good margin. One should instead print the Schedule using cargo test --features runtime-benchmarks bench_print_schedule -- --nocapture or following the instructions from the [README](https://github.com/paritytech/polkadot-sdk/tree/pg/bench_tweaks/substrate/frame/contracts#schedule) for looking at the Schedule of a specific runtime --------- Co-authored-by: command-bot <>
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::{
|
||||
benchmarking::{Contract, WasmModule},
|
||||
exec::Stack,
|
||||
storage::meter::Meter,
|
||||
wasm::Runtime,
|
||||
BalanceOf, Config, DebugBufferVec, Determinism, ExecReturnValue, GasMeter, Origin, Schedule,
|
||||
TypeInfo, WasmBlob, Weight,
|
||||
};
|
||||
use codec::{Encode, HasCompact};
|
||||
use core::fmt::Debug;
|
||||
use sp_core::Get;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
type StackExt<'a, T> = Stack<'a, T, WasmBlob<T>>;
|
||||
|
||||
/// A prepared contract call ready to be executed.
|
||||
pub struct PreparedCall<'a, T: Config> {
|
||||
func: wasmi::Func,
|
||||
store: wasmi::Store<Runtime<'a, StackExt<'a, T>>>,
|
||||
}
|
||||
|
||||
impl<'a, T: Config> PreparedCall<'a, T> {
|
||||
pub fn call(mut self) -> ExecReturnValue {
|
||||
let result = self.func.call(&mut self.store, &[], &mut []);
|
||||
WasmBlob::<T>::process_result(self.store, result).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder used to prepare a contract call.
|
||||
pub struct CallSetup<T: Config> {
|
||||
contract: Contract<T>,
|
||||
dest: T::AccountId,
|
||||
origin: Origin<T>,
|
||||
gas_meter: GasMeter<T>,
|
||||
storage_meter: Meter<T>,
|
||||
schedule: Schedule<T>,
|
||||
value: BalanceOf<T>,
|
||||
debug_message: Option<DebugBufferVec<T>>,
|
||||
determinism: Determinism,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<T> CallSetup<T>
|
||||
where
|
||||
T: Config + pallet_balances::Config,
|
||||
<BalanceOf<T> as HasCompact>::Type: Clone + Eq + PartialEq + Debug + TypeInfo + Encode,
|
||||
{
|
||||
/// Setup a new call for the given module.
|
||||
pub fn new(module: WasmModule<T>) -> Self {
|
||||
let contract = Contract::<T>::new(module.clone(), vec![]).unwrap();
|
||||
let dest = contract.account_id.clone();
|
||||
let origin = Origin::from_account_id(contract.caller.clone());
|
||||
|
||||
let storage_meter = Meter::new(&origin, None, 0u32.into()).unwrap();
|
||||
|
||||
Self {
|
||||
contract,
|
||||
dest,
|
||||
origin,
|
||||
gas_meter: GasMeter::new(Weight::MAX),
|
||||
storage_meter,
|
||||
schedule: T::Schedule::get(),
|
||||
value: 0u32.into(),
|
||||
debug_message: None,
|
||||
determinism: Determinism::Enforced,
|
||||
data: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the meter's storage deposit limit.
|
||||
pub fn set_storage_deposit_limit(&mut self, balance: BalanceOf<T>) {
|
||||
self.storage_meter = Meter::new(&self.origin, Some(balance), 0u32.into()).unwrap();
|
||||
}
|
||||
|
||||
/// Set the call's origin.
|
||||
pub fn set_origin(&mut self, origin: Origin<T>) {
|
||||
self.origin = origin;
|
||||
}
|
||||
|
||||
/// Set the contract's balance.
|
||||
pub fn set_balance(&mut self, value: BalanceOf<T>) {
|
||||
self.contract.set_balance(value);
|
||||
}
|
||||
|
||||
/// Set the call's input data.
|
||||
pub fn set_data(&mut self, value: Vec<u8>) {
|
||||
self.data = value;
|
||||
}
|
||||
|
||||
/// Set the debug message.
|
||||
pub fn enable_debug_message(&mut self) {
|
||||
self.debug_message = Some(Default::default());
|
||||
}
|
||||
|
||||
/// Get the debug message.
|
||||
pub fn debug_message(&self) -> Option<DebugBufferVec<T>> {
|
||||
self.debug_message.clone()
|
||||
}
|
||||
|
||||
/// Get the call's input data.
|
||||
pub fn data(&self) -> Vec<u8> {
|
||||
self.data.clone()
|
||||
}
|
||||
|
||||
/// Get the call's contract.
|
||||
pub fn contract(&self) -> Contract<T> {
|
||||
self.contract.clone()
|
||||
}
|
||||
|
||||
/// Build the call stack.
|
||||
pub fn ext(&mut self) -> (StackExt<'_, T>, WasmBlob<T>) {
|
||||
StackExt::bench_new_call(
|
||||
self.dest.clone(),
|
||||
self.origin.clone(),
|
||||
&mut self.gas_meter,
|
||||
&mut self.storage_meter,
|
||||
&self.schedule,
|
||||
self.value,
|
||||
self.debug_message.as_mut(),
|
||||
self.determinism,
|
||||
)
|
||||
}
|
||||
|
||||
/// Prepare a call to the module.
|
||||
pub fn prepare_call<'a>(
|
||||
ext: &'a mut StackExt<'a, T>,
|
||||
module: WasmBlob<T>,
|
||||
input: Vec<u8>,
|
||||
) -> PreparedCall<'a, T> {
|
||||
let (func, store) = module.bench_prepare_call(ext, input);
|
||||
PreparedCall { func, store }
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! call_builder(
|
||||
($func: ident, $module:expr) => {
|
||||
$crate::call_builder!($func, _contract, $module);
|
||||
};
|
||||
($func: ident, $contract: ident, $module:expr) => {
|
||||
let mut setup = CallSetup::<T>::new($module);
|
||||
$crate::call_builder!($func, $contract, setup: setup);
|
||||
};
|
||||
($func:ident, setup: $setup: ident) => {
|
||||
$crate::call_builder!($func, _contract, setup: $setup);
|
||||
};
|
||||
($func:ident, $contract: ident, setup: $setup: ident) => {
|
||||
let data = $setup.data();
|
||||
let $contract = $setup.contract();
|
||||
let (mut ext, module) = $setup.ext();
|
||||
let $func = CallSetup::<T>::prepare_call(&mut ext, module, data);
|
||||
};
|
||||
);
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user