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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions