Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precompile tests where we run up agains the (63/64)-ths stuff #1153

Open
OlivierBBB opened this issue Sep 10, 2024 · 1 comment · May be fixed by #1842
Open

Precompile tests where we run up agains the (63/64)-ths stuff #1153

OlivierBBB opened this issue Sep 10, 2024 · 1 comment · May be fixed by #1842
Assignees
Labels
documentation Improvements or additions to documentation IRL edge case Real life onflations producing edge cases of our arithmetization testing

Comments

@OlivierBBB
Copy link
Collaborator

OlivierBBB commented Sep 10, 2024

We need to write tests with very simple bytecode. The specifics of these tests are as follows:

  • message call transaction to a very simple contract
  • bytecode: some pushes followed by e.g. GAS followed by CALL / STATICCALL to a precompile
  • provide the transaction with a very low amount of gas

The goal is to trigger the (63/64)-ths business. We want to do this so that the callee will not meet its gas requirements.

In other words we must extract several unit tests (for all precompiles) from the issue #1136. See the documentation.

This is more advanced version of the test described in #1730. In the present test, we cannot give enough gas to run the precompile, while in the simpler version we deliberately do not give enough gas.

@OlivierBBB OlivierBBB added testing IRL edge case Real life onflations producing edge cases of our arithmetization labels Sep 10, 2024
@OlivierBBB OlivierBBB added the documentation Improvements or additions to documentation label Sep 11, 2024
@OlivierBBB
Copy link
Collaborator Author

OlivierBBB commented Feb 21, 2025

Gas calculation

int gasPreCall = frame.getRemainingGas() // prior to the CALL-type instruction processing
int gasUpfront =
    (value == 0)
        ? 100 // precompiles are warm
        : (precompileExistsInState)
            ? 9_000 + 100
            : 25_000 + 9_000 + 100;

checkState(gasPreCall >= gasUpfront);

int x = gasPreCall - gasUpfront;
int k = x / 64;
int l = x - 64 * k;
// x = 64 * k + l with 0 ≤ l < 64 is the euclidean division
// this k and l is what we are after

int stipend = (value == 0) ? 0 : 2_300;

int calleeGas = 63 * k + l + stipend;

You also compute the precompile cost and the desired targetCalleeGas

int prcCost = precompileExecutionCost() // cost of precompile execution
int targetCalleeGas = switch (costParam) {
    case COST_MO -> prcCost - 1;
    case COST -> prcCost;
}

At this point the goal is to work backwards from the desired conclusion:

63 * k + l + stipend = targetCalleeGas
0 ≤ k
0 ≤ l < 64

You work backwards. The above gets you uniquely the right k and l. Then you deduce the x, and from x you deduce gasPreCall. At that point you add up all the previous costs (the pushes, the initial memory expansion so as to incur no memory expansion during the CALL-type instruction, the 21_000 for the transaction) and you get the transaction gas limit.


Actually the above does not determine k and l uniquely. So we may have more freedom than initially expected. See graph below of the $L$ function from the yellow paper ($L(n) = n - (n/64)$ with $x/64$ representing integer division.)

20250221_145119.jpg


We can actually search for

63 * k + l + stipend = targetCalleeGas
0 ≤ k
0 ≤ l < 63 // not 64

instead, and still uniquely achieve every target value possible. The main point being that $g: n \mapsto 63 \cdot k + l$ has $g(64k - 1) = g(64k)$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation IRL edge case Real life onflations producing edge cases of our arithmetization testing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants