Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
contracts: Allow stack height metering to be disabled (#10877)
Browse files Browse the repository at this point in the history
* Allow stack height metering to be disabled

* cargo run --quiet --profile=production  --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

* cargo run --quiet --profile=production  --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

Co-authored-by: Parity Bot <admin@parity.io>
  • Loading branch information
athei and Parity Bot committed Feb 22, 2022
1 parent b16a721 commit b46702e
Show file tree
Hide file tree
Showing 6 changed files with 609 additions and 591 deletions.
7 changes: 5 additions & 2 deletions frame/contracts/src/benchmarking/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ fn inject_gas_metering<T: Config>(module: Module) -> Module {
}

fn inject_stack_metering<T: Config>(module: Module) -> Module {
let height = T::Schedule::get().limits.stack_height;
wasm_instrument::inject_stack_limiter(module, height).unwrap()
if let Some(height) = T::Schedule::get().limits.stack_height {
wasm_instrument::inject_stack_limiter(module, height).unwrap()
} else {
module
}
}
6 changes: 3 additions & 3 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,7 @@ benchmarks! {
// w_local_get = w_bench - 1 * w_param
instr_local_get {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let max_locals = T::Schedule::get().limits.stack_height;
let max_locals = T::Schedule::get().limits.stack_height.unwrap_or(512);
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
RandomGetLocal(0, max_locals),
Regular(Instruction::Drop),
Expand All @@ -2267,7 +2267,7 @@ benchmarks! {
// w_local_set = w_bench - 1 * w_param
instr_local_set {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let max_locals = T::Schedule::get().limits.stack_height;
let max_locals = T::Schedule::get().limits.stack_height.unwrap_or(512);
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
RandomI64Repeated(1),
RandomSetLocal(0, max_locals),
Expand All @@ -2284,7 +2284,7 @@ benchmarks! {
// w_local_tee = w_bench - 2 * w_param
instr_local_tee {
let r in 0 .. INSTR_BENCHMARK_BATCHES;
let max_locals = T::Schedule::get().limits.stack_height;
let max_locals = T::Schedule::get().limits.stack_height.unwrap_or(512);
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
RandomI64Repeated(1),
RandomTeeLocal(0, max_locals),
Expand Down
12 changes: 9 additions & 3 deletions frame/contracts/src/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ pub struct Limits {
/// See <https://wiki.parity.io/WebAssembly-StackHeight> to find out
/// how the stack frame cost is calculated. Each element can be of one of the
/// wasm value types. This means the maximum size per element is 64bit.
pub stack_height: u32,
///
/// # Note
///
/// It is safe to disable (pass `None`) the `stack_height` when the execution engine
/// is part of the runtime and hence there can be no indeterminism between different
/// client resident execution engines.
pub stack_height: Option<u32>,

/// Maximum number of globals a module is allowed to declare.
///
Expand Down Expand Up @@ -496,8 +502,8 @@ impl Default for Limits {
fn default() -> Self {
Self {
event_topics: 4,
// 512 * sizeof(i64) will give us a 4k stack.
stack_height: 512,
// No stack limit required because we use a runtime resident execution engine.
stack_height: None,
globals: 256,
parameters: 128,
memory_pages: 16,
Expand Down
8 changes: 7 additions & 1 deletion frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,13 @@ parameter_types! {
pub const MaxValueSize: u32 = 16_384;
pub const DeletionWeightLimit: Weight = 500_000_000_000;
pub const MaxCodeSize: u32 = 2 * 1024;
pub MySchedule: Schedule<Test> = <Schedule<Test>>::default();
pub MySchedule: Schedule<Test> = {
let mut schedule = <Schedule<Test>>::default();
// We want stack height to be always enabled for tests so that this
// instrumentation path is always tested implicitly.
schedule.limits.stack_height = Some(512);
schedule
};
pub const TransactionByteFee: u64 = 0;
pub static DepositPerByte: BalanceOf<Test> = 1;
pub const DepositPerItem: BalanceOf<Test> = 2;
Expand Down
9 changes: 6 additions & 3 deletions frame/contracts/src/wasm/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,13 @@ impl<'a, T: Config> ContractModule<'a, T> {
}

fn inject_stack_height_metering(self) -> Result<Self, &'static str> {
let contract_module =
wasm_instrument::inject_stack_limiter(self.module, self.schedule.limits.stack_height)
if let Some(limit) = self.schedule.limits.stack_height {
let contract_module = wasm_instrument::inject_stack_limiter(self.module, limit)
.map_err(|_| "stack height instrumentation failed")?;
Ok(ContractModule { module: contract_module, schedule: self.schedule })
Ok(ContractModule { module: contract_module, schedule: self.schedule })
} else {
Ok(ContractModule { module: self.module, schedule: self.schedule })
}
}

/// Check that the module has required exported functions. For now
Expand Down
Loading

0 comments on commit b46702e

Please sign in to comment.