mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 01:01:04 +00:00
contracts: switch to wasmi gas metering (#14084)
* upgrade to wasmi 0.29 * prepare cleanup * sync ref_time w engine from the stack frame * proc_macro: sync gas in host funcs save: compiles, only gas pushing left to macro WIP proc macro proc macro: done * clean benchmarks & schedule: w_base = w_i64const * scale gas values btw engine and gas meter * (re)instrumentation & code_cache removed * remove gas() host fn, continue clean-up save * address review comments * move from CodeStorage&PrefabWasmModule to PristineCode&WasmBlob * refactor: no reftime_limit&schedule passes, no CodeStorage * bugs fixing * fix tests: expected deposit amount * fix prepare::tests * update tests and fix bugs tests::run_out_of_gas_engine, need 2 more save: 2 bugs with gas syncs: 1 of 2 tests done gas_syncs_no_overcharge bug fixed, test passes! cleaned out debug prints second bug is not a bug disabled_chain_extension test fix (err msg) tests run_out_of_fuel_host, chain_extension pass all tests pass * update docs * bump wasmi 0.30.0 * benchmarks updated, tests pass * refactoring * s/OwnerInfo/CodeInfo/g; * migration: draft, compiles * migration: draft, runs * migration: draft, runs (fixing) * deposits repaid non pro rata * deposits repaid pro rata * better try-runtime output * even better try-runtime output * benchmark migration * fix merge leftover * add forgotten fixtures, fix docs * address review comments * ci fixes * cleanup * benchmarks::prepare to return DispatchError * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * store memory limits to CodeInfo * ci: roll back weights * ".git/.scripts/commands/bench-vm/bench-vm.sh" pallet dev pallet_contracts * drive-by: update Readme and pallet rustdoc * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * use wasmi 0.29 * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * use wasmi 0.30 again * query memory limits from wasmi * better migration types * ci: pull weights from master * refactoring * ".git/.scripts/commands/bench-vm/bench-vm.sh" pallet dev pallet_contracts * addressing review comments * refactor * address review comments * optimize migration * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * another review round comments addressed * ci fix one * clippy fix * ci fix two --------- Co-authored-by: command-bot <>
This commit is contained in:
@@ -624,19 +624,15 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
|
||||
let trace_fmt_str = format!("{}::{}({}) = {{:?}}\n", module, name, params_fmt_str);
|
||||
|
||||
quote! {
|
||||
let result = #body;
|
||||
if ::log::log_enabled!(target: "runtime::contracts::strace", ::log::Level::Trace) {
|
||||
let result = #body;
|
||||
{
|
||||
use sp_std::fmt::Write;
|
||||
let mut w = sp_std::Writer::default();
|
||||
let _ = core::write!(&mut w, #trace_fmt_str, #( #trace_fmt_args, )* result);
|
||||
let msg = core::str::from_utf8(&w.inner()).unwrap_or_default();
|
||||
ctx.ext().append_debug_buffer(msg);
|
||||
}
|
||||
result
|
||||
} else {
|
||||
#body
|
||||
}
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
@@ -661,7 +657,7 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
|
||||
::core::unreachable!()
|
||||
} }
|
||||
};
|
||||
let map_err = if expand_blocks {
|
||||
let into_host = if expand_blocks {
|
||||
quote! {
|
||||
|reason| {
|
||||
::wasmi::core::Trap::from(reason)
|
||||
@@ -677,6 +673,43 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
|
||||
} else {
|
||||
quote! { #[allow(unused_variables)] }
|
||||
};
|
||||
let sync_gas_before = if expand_blocks {
|
||||
quote! {
|
||||
// Gas left in the gas meter right before switching to engine execution.
|
||||
let __gas_before__ = {
|
||||
let engine_consumed_total =
|
||||
__caller__.fuel_consumed().expect("Fuel metering is enabled; qed");
|
||||
let gas_meter = __caller__.data_mut().ext().gas_meter_mut();
|
||||
gas_meter
|
||||
.charge_fuel(engine_consumed_total)
|
||||
.map_err(TrapReason::from)
|
||||
.map_err(#into_host)?
|
||||
.ref_time()
|
||||
};
|
||||
}
|
||||
} else {
|
||||
quote! { }
|
||||
};
|
||||
// Gas left in the gas meter right after returning from engine execution.
|
||||
let sync_gas_after = if expand_blocks {
|
||||
quote! {
|
||||
let mut gas_after = __caller__.data_mut().ext().gas_meter().gas_left().ref_time();
|
||||
let mut host_consumed = __gas_before__.saturating_sub(gas_after);
|
||||
// Possible undercharge of at max 1 fuel here, if host consumed less than `instruction_weights.base`
|
||||
// Not a problem though, as soon as host accounts its spent gas properly.
|
||||
let fuel_consumed = host_consumed
|
||||
.checked_div(__caller__.data_mut().ext().schedule().instruction_weights.base as u64)
|
||||
.ok_or(Error::<E::T>::InvalidSchedule)
|
||||
.map_err(TrapReason::from)
|
||||
.map_err(#into_host)?;
|
||||
__caller__
|
||||
.consume_fuel(fuel_consumed)
|
||||
.map_err(|_| TrapReason::from(Error::<E::T>::OutOfGas))
|
||||
.map_err(#into_host)?;
|
||||
}
|
||||
} else {
|
||||
quote! { }
|
||||
};
|
||||
|
||||
quote! {
|
||||
// We need to allow all interfaces when runtime benchmarks are performed because
|
||||
@@ -688,10 +721,11 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
|
||||
{
|
||||
#allow_unused
|
||||
linker.define(#module, #name, ::wasmi::Func::wrap(&mut*store, |mut __caller__: ::wasmi::Caller<#host_state>, #( #params, )*| -> #wasm_output {
|
||||
#sync_gas_before
|
||||
let mut func = #inner;
|
||||
func()
|
||||
.map_err(#map_err)
|
||||
.map(::core::convert::Into::into)
|
||||
let result = func().map_err(#into_host).map(::core::convert::Into::into);
|
||||
#sync_gas_after
|
||||
result
|
||||
}))?;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user