Gas rescaling

The goal is to rescale gas in Tezos by 2^10 (or any another multiple of 2^7, for reasons explained below).

History

In Babylon, after extensive benches, we observed that the execution time corresponding to one unit of gas (the conversion ratio corresponding to the maximum per-block validation time) was too coarse to properly account for the resource consumption of most simple instructions. We were faced with the choice of either rescaling gas, or introducing a hidden accounting unit, internal_gas, corresponding to 1/128 of a gas unit. We chose the latter option as it seemed simpler and had the advantage of being seamless for the users.

However, internal_gas presents some problems:

  • it introduces some state in the protocol which can't be observed in execution traces of contracts, making some regressions invisible
  • it complicates greatly the gas accounting code

Overview of this MR

In 007, we want to finally proceed to the gas rescaling and get rid of internal_gas.

Rescaling means intuitively that we multiply per-block, per-operation gas limits by some constants K as well as all gas costs.

Some properties that we expect:

  • This rescaling should not change which contract can be typechecked or executed, i.e. it should be a no-op from the point of view of the users

However, it is a breaking change for any application that hard-coded gas constants. Mitigations should be discussed independently from this MR, which concentrates on ensuring correctness of the rescaling.

Detailed contents of this MR

We perform the rescaling in two steps, in order to facilitate review:

  1. First, we deactivate internal_gas by rescaling by 2^7. At this stage, internal_gas is always equal to 0
  2. Then, remove internal_gas
  3. Then, we proceed to the rest of the rescaling by eg 2^3 (or any other positive integer constant, really)

In between each of those steps, we regenerate regression traces. This requires fixing a lot of tests where gas constants are hardcoded.

Here's a description of each group of commits:

  • The two first commits add some unit tests related to gas, checking that gas consumption commutes and admits the obvious neutral element (1fef1f75, 48340af9)

  • The next commit switches from Z to Q for fee computation. This is required as nanotez are not small enough to account for fees after rescaling. Using rational numbers makes it easy to have sub-nanotez per-gas-unit fees, without having to worry about rounding errors. (0d4ec653)

Up to this point, there should be no change in functionality nor in observable behaviour: all tests should pass.

  • The next commits are a bugfix in gas consumption and some updates to some affected Python tests reflecting the effect of the bugfix. Unrelated to the rescaling but discovered in the process. These two commits invalidate some regression traces. (eba817db, 95e0310f)

The following commits implement the rescaling by 2^7

  • the first commit makes internal_gas visible in the interpreter traces (6d452567)
  • the second one regenerates traces (previously invalidated), with internal_gas included per the previous commit. The increase in gas consumption is induced by the bugfix. (3bf7414e)
  • the third one performs the rescaling by 2^7, making internal_gas always equal to 0. Also, scale fees and hardcoded gas limits in client. (d6e5af6a)
  • the next commit fix the tests (3afaaf96)
  • this commit regenerates traces, allowing to observe that internal_gas is effectively always 0 (21753c0a)
  • this commit fixes gas limits used in unit tests (5c870b66)

Now, internal_gas is always equal to 0.

  • We can remove the corresponding code to the protocol (trace included) and regenerate traces (4b64c489, 925f0f6d)

Side-effects of this MR (besides the rescaling)

  • fees must be allowed to handle fractional values of minimal_fees_per_nanotez (switch from Z to Q for the handling of fees)
  • slight gas increase due to the fix
  • slight fee increase due to the increased size of transactions
Edited by Adrian Brink

Merge request reports

Loading