Update high level inject_gas_counter function documentation.

This commit is contained in:
Jim Posen 2019-07-02 15:04:06 +02:00
parent 24924f59ec
commit 0cf7daa9e5

View File

@ -385,17 +385,18 @@ fn insert_metering_calls(
/// function is meant to keep track of the total amount of gas used and trap or otherwise halt /// function is meant to keep track of the total amount of gas used and trap or otherwise halt
/// execution of the runtime if the gas usage exceeds some allowed limit. /// execution of the runtime if the gas usage exceeds some allowed limit.
/// ///
/// The calls to charge gas are inserted at the beginning of every block of code. A block is /// The body of each function is divided into metered blocks, and the calls to charge gas are
/// defined by `block`, `if`, `else`, `loop`, and `end` boundaries. Blocks form a nested hierarchy /// inserted at the beginning of every such block of code. A metered block is defined so that,
/// where `block`, `if`, `else`, and `loop` begin a new nested block, and `end` and `else` mark the /// unless there is a trap, either all of the instructions are executed or none are. These are
/// end of a block. The gas cost of a block is determined statically as 1 plus the gas cost of all /// similar to basic blocks in a control flow graph, except that in some cases multiple basic
/// instructions directly in that block. Each instruction is only counted in the most deeply /// blocks can be merged into a single metered block. This is the case if any path through the
/// nested block containing it (ie. a block's cost does not include the cost of instructions in any /// control flow graph containing one basic block also contains another.
/// blocks nested within it). The cost of the `begin`, `if`, and `loop` instructions is counted ///
/// towards the block containing them, not the nested block that they open. There is no gas cost /// Charging gas is at the beginning of each metered block ensures that 1) all instructions
/// added for `end`/`else`, as they are pseudo-instructions. The gas cost of each instruction is /// executed are already paid for, 2) instructions that will not be executed are not charged for
/// determined by a `rules::Set` parameter. At the beginning of each block, this procedure injects /// unless execution traps, and 3) the number of calls to "gas" is minimized. The corollary is that
/// new instructions to call the "gas" function with the gas cost of the block as an argument. /// modules instrumented with this metering code may charge gas for instructions not executed in
/// the event of a trap.
/// ///
/// Additionally, each `memory.grow` instruction found in the module is instrumented to first make /// Additionally, each `memory.grow` instruction found in the module is instrumented to first make
/// a call to charge gas for the additional pages requested. This cannot be done as part of the /// a call to charge gas for the additional pages requested. This cannot be done as part of the
@ -406,6 +407,8 @@ fn insert_metering_calls(
/// function also rewrites all function indices references by code, table elements, etc., since /// function also rewrites all function indices references by code, table elements, etc., since
/// the addition of an imported functions changes the indices of module-defined functions. /// the addition of an imported functions changes the indices of module-defined functions.
/// ///
/// This routine runs in time linear in the size of the input module.
///
/// The function fails if the module contains any operation forbidden by gas rule set, returning /// The function fails if the module contains any operation forbidden by gas rule set, returning
/// the original module as an Err. /// the original module as an Err.
pub fn inject_gas_counter(module: elements::Module, rules: &rules::Set) pub fn inject_gas_counter(module: elements::Module, rules: &rules::Set)