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

[contracts] Remove stack height limiter wasm instrumentation #12957

Merged
merged 5 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions frame/contracts/src/benchmarking/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ pub struct ModuleDefinition {
pub aux_body: Option<FuncBody>,
/// The amount of I64 arguments the aux function should have.
pub aux_arg_num: u32,
/// If set to true the stack height limiter is injected into the the module. This is
/// needed for instruction debugging because the cost of executing the stack height
/// instrumentation should be included in the costs for the individual instructions
/// that cause more metering code (only call).
pub inject_stack_metering: bool,
/// Create a table containing function pointers.
pub table: Option<TableSegment>,
/// Create a section named "dummy" of the specified size. This is useful in order to
Expand Down Expand Up @@ -238,29 +233,20 @@ impl<T: Config> From<ModuleDefinition> for WasmModule<T> {
)));
}

let mut code = contract.build();

if def.inject_stack_metering {
code = inject_stack_metering::<T>(code);
}

let code = code.into_bytes().unwrap();
let code = contract.build().into_bytes().unwrap();
let hash = T::Hashing::hash(&code);
Self { code: code.into(), hash, memory: def.memory }
}
}

impl<T: Config> WasmModule<T> {
/// Uses the supplied wasm module and instruments it when requested.
pub fn instrumented(code: &[u8], inject_gas: bool, inject_stack: bool) -> Self {
pub fn instrumented(code: &[u8], inject_gas: bool) -> Self {
let module = {
let mut module = Module::from_bytes(code).unwrap();
if inject_gas {
module = inject_gas_metering::<T>(module);
}
if inject_stack {
module = inject_stack_metering::<T>(module);
}
module
};
let limits = *module
Expand Down Expand Up @@ -530,11 +516,3 @@ fn inject_gas_metering<T: Config>(module: Module) -> Module {
let backend = gas_metering::host_function::Injector::new("seal0", "gas");
gas_metering::inject(module, backend, &gas_rules).unwrap()
}

fn inject_stack_metering<T: Config>(module: Module) -> Module {
if let Some(height) = T::Schedule::get().limits.stack_height {
wasm_instrument::inject_stack_limiter(module, height).unwrap()
} else {
module
}
}
7 changes: 2 additions & 5 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2384,7 +2384,6 @@ benchmarks! {
call_body: Some(body::repeated(r * INSTR_BENCHMARK_BATCH_SIZE, &[
Instruction::Call(2), // call aux
])),
inject_stack_metering: true,
.. Default::default()
}));
}: {
Expand All @@ -2408,7 +2407,6 @@ benchmarks! {
RandomI32(0, num_elements as i32),
Regular(Instruction::CallIndirect(0, 0)), // we only have one sig: 0
])),
inject_stack_metering: true,
table: Some(TableSegment {
num_elements,
function_index: 2, // aux
Expand Down Expand Up @@ -2441,7 +2439,6 @@ benchmarks! {
RandomI32(0, num_elements as i32),
Regular(Instruction::CallIndirect(p.min(1), 0)), // aux signature: 1 or 0
])),
inject_stack_metering: true,
table: Some(TableSegment {
num_elements,
function_index: 2, // aux
Expand Down Expand Up @@ -2968,7 +2965,7 @@ benchmarks! {
new.encode()
};
let instance = Contract::<T>::new(
WasmModule::instrumented(code, gas_metering, true), data,
WasmModule::instrumented(code, gas_metering), data,
)?;
let data = {
let transfer: ([u8; 4], AccountIdOf<T>, BalanceOf<T>) = (
Expand Down Expand Up @@ -3015,7 +3012,7 @@ benchmarks! {
new.encode()
};
let instance = Contract::<T>::with_caller(
caller, WasmModule::instrumented(code, gas_metering, true), data,
caller, WasmModule::instrumented(code, gas_metering), data,
)?;
balance[0] = 1;
let data = {
Expand Down
18 changes: 1 addition & 17 deletions frame/contracts/src/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,9 @@ pub struct Limits {
/// The maximum number of topics supported by an event.
pub event_topics: u32,

/// Maximum allowed stack height in number of elements.
///
/// 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.
///
/// # 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.
///
/// Globals are not limited through the `stack_height` as locals are. Neither does
/// the linear memory limit `memory_pages` applies to them.
/// Globals are not limited through the linear memory limit `memory_pages`.
pub globals: u32,

/// Maximum number of locals a function can have.
Expand Down Expand Up @@ -532,8 +518,6 @@ impl Default for Limits {
fn default() -> Self {
Self {
event_topics: 4,
// No stack limit required because we use a runtime resident execution engine.
stack_height: None,
globals: 256,
locals: 1024,
parameters: 128,
Expand Down
15 changes: 6 additions & 9 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,6 @@ impl pallet_utility::Config for Test {
parameter_types! {
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.instruction_weights.fallback = 1;
schedule
};
Expand Down Expand Up @@ -2964,7 +2961,7 @@ fn upload_code_works() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Reserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand Down Expand Up @@ -3054,7 +3051,7 @@ fn remove_code_works() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Reserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand All @@ -3067,7 +3064,7 @@ fn remove_code_works() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Unreserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand Down Expand Up @@ -3110,7 +3107,7 @@ fn remove_code_wrong_origin() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Reserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand Down Expand Up @@ -3246,7 +3243,7 @@ fn instantiate_with_zero_balance_works() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Reserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand Down Expand Up @@ -3351,7 +3348,7 @@ fn instantiate_with_below_existential_deposit_works() {
phase: Phase::Initialization,
event: RuntimeEvent::Balances(pallet_balances::Event::Reserved {
who: ALICE,
amount: 241,
amount: 173,
}),
topics: vec![],
},
Expand Down
15 changes: 1 addition & 14 deletions frame/contracts/src/wasm/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,16 +216,6 @@ impl<'a, T: Config> ContractModule<'a, T> {
Ok(ContractModule { module: contract_module, schedule: self.schedule })
}

fn inject_stack_height_metering(self) -> Result<Self, &'static str> {
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 })
} else {
Ok(ContractModule { module: self.module, schedule: self.schedule })
}
}

/// Check that the module has required exported functions. For now
/// these are just entrypoints:
///
Expand Down Expand Up @@ -447,10 +437,7 @@ where
let memory_limits =
get_memory_limits(contract_module.scan_imports(&disallowed_imports)?, schedule)?;

let code = contract_module
.inject_gas_metering(determinism)?
.inject_stack_height_metering()?
.into_wasm_code()?;
let code = contract_module.inject_gas_metering(determinism)?.into_wasm_code()?;

Ok((code, memory_limits))
})()
Expand Down