Skip to content
This repository was archived by the owner on Jan 17, 2022. It is now read-only.
This repository was archived by the owner on Jan 17, 2022. It is now read-only.

Gas metering does not handle branches and external calls #120

@jimpo

Description

@jimpo

The gas metering code currently inserts metering instructions at the beginning of block, if, loop statements but does not correctly handle code that uses br_* to jump to a label. For example, in the following program, gas is charged for instructions after the br_if that are skipped.

(module
	(func $fibonacci_with_break (result i32)
		(local $x i32) (local $y i32)

		(block $unrolled_loop
			(set_local $x (i32.const 0))
			(set_local $y (i32.const 1))

			get_local $x
			get_local $y
			tee_local $x
			i32.add
			set_local $y

			i32.const 1
			br_if $unrolled_loop

			get_local $x
			get_local $y
			tee_local $x
			i32.add
			set_local $y
		)

		get_local $y
	)
)

There may also be imported functions that affect control flow or have more strict requirements on the state of the gas meter. In the Substrate srml-contracts module for example, the imported functions such ext_return and ext_gas_left need more delicate handling. ext_return affects control flow and currently gas is over-deducted if there are any unreachable instructions after the call. In the case of ext_gas_left the caller may see a lower result than expected (though this arguably is not a bug).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions