Open
Description
This idea has been independently suggested by @chfast, @poemm, @jwasinger and me.
Currently the metering injection inserts a call to an imported method (ethereum::useGas
) at every check, which comes with a large overhead. One potential solution to this is to inline the statements and reduce the amount of external calls being make.
If we assume that code is validated (via the "sentinel contract") prior to metering injection, then we can make use of globals. The proposal is the following:
- Insert a new global and call it
gasLeft
- Set the value of this global prior to execution to the gas limit of the execution
- Insert code which decrements this counter and aborts if it is less than 0
Some questions:
- What is the overhead of inserting the branch at every single metering statement? A potential optimisation is inject a helper function which does the check and call this helper instead of calling the external import.
- Is it safe to use
unreachable
for the failure case? Can it be optimised out by engines? Would it be better to insert a call to an imported abort function? (ethereum::abortOutOfGas
for example)