Implement support for optional fuel metering #643
Labels
enhancement
New feature or request
wasmtime-mirror
Issue for a use case of a missing API that exists in Wasmtime.
This issue is about implementing out-of-the-box gas (or fuel) metering support in
wasmi
.The main goal is to have optional support that serves users who are in need of fuel metering and those who aren't by only introducing runtime overhead in cases where fuel metering is actually enabled. (zero-cost abstraction)
Motivation
Let us take a look at one of
wasmi
's biggest users right now: the so-called Substratecontracts-pallet
useswasmi
in order to compile, instantiate and execute Wasm smart contracts.Smart contracts generally require so-called gas metering during their execution so that Wasm executions are guaranteed to halt and can be charged in dependence of their computational intensity.
Currently the
contracts-pallet
runs its own Wasm instrumentation in order to manipulate all uploaded Wasm blobs so that they include gas metering by themselves. This is done by introducing special host function calls at basic block entry points. This instrumentation is rather complex and computationally intense. The advantage is that it allows to have Wasm engine agnostic gas metering and stems from the time where it was not foreseeable what Wasm engine is going to be used in the future. The drawback is that it is (probably) less efficient and also more complex by nature of having to abstract away from a concrete Wasm runtime implementation. Thecontracts-pallet
has to implement assumptions into its gas metering process about the underlying runtime which is a blackbox towards thecontracts-pallet
.Wasm runtime implementations themselves can be very complex and abstracting over them doesn't make the process of gas metering simpler. The idea of having gas metering support out-of-the-box is that there no longer is the need to abstract over the implementation details of a Wasm runtime. Instead the Wasm runtime itself knows best how to charge for executed Wasm instructions.
On a side note this simplification for the
contracts-pallet
would allow to enable Wasm proposals whereas right now it is restricted to a very small subset of the Wasm MVP. This could be very beneficial for users when it comes to Wasm code efficiency and code optimizations by Wasm producers. For example, thebulk-memory
Wasm proposal can be used instead of raw loops which should also charge a lot less fuel for the same underlying computation while also requiring less binary space in the Wasm blob.Abstract Design
Naively gas metering can be thought of by introducing a
u64
counter to the Wasm engine that is set to some value before execution and decremented for each executed instruction. When this counter reaches zero the execution is promtly halted. When the execution ends before the counter reaches 0 then the counter can be queried so that a caller knows how much of the initial gas or fuel was used for the execution.API
As always we want to mirror the Wasmtime API.
The Wasmtime API has different entry point with respect to its fuel metering which are:
Store
,StoreContextMut
andCaller
type each provide 3 methodsfuel_consumed
,add_fuel
,consume_fuel
.Store
: https://docs.rs/wasmtime/5.0.0/wasmtime/struct.Store.html#method.fuel_consumedCaller
: https://docs.rs/wasmtime/5.0.0/wasmtime/struct.Caller.html#method.fuel_consumedCaller
type provides called host functions with the ability to report their fuel costs back to theEngine
.StoreContext
type provides thefuel_consumed
getter method.Config
type can be configured to use the fuel metering functionality of theEngine
.This way it is possible to create
Engine
instances that have fuel metering enabled (or disabled).This configuration cannot be changed during the lifetime of an
Engine
and allows theEngine
tocompile the incoming Wasm bytecode into different code that either checks or ignores fuel consumption.
In order for
wasmi
to have similar zero-cost abstraction with respect to its fuel metering we should adopta similar technique so that users not requiring fuel metering do not have to pay the costs for additional checks.
Trap
type receives a newOutOfFuel
trap code to signal that an execution has haltedsince no fuel was left for the execution to finish.
Previous Work
The
wasm_instrument
crate already implements a routine to inject fuel metering into Wasm bytecode. Thewasmi
engine can use a similar strategy to addConsumeFuel
instructions while translating Wasm bytecode to the internalwasmi
bytecode.Link to implementation: https://github.com/paritytech/wasm-instrument/blob/master/src/gas_metering/mod.rs
The text was updated successfully, but these errors were encountered: