Skip to content

Commit

Permalink
Support ExitError::InvalidCode in gas estimation (polkadot-evm#840)
Browse files Browse the repository at this point in the history
* Pin evm

* Support `InvalidCode` in gas estimation

* Add ts test

* EOF new line

(cherry picked from commit 233173e)

# Conflicts:
#	Cargo.lock
#	client/rpc/Cargo.toml
#	frame/ethereum/Cargo.toml
#	frame/evm/Cargo.toml
#	frame/evm/test-vector-support/Cargo.toml
#	primitives/evm/Cargo.toml
  • Loading branch information
tgmichel committed Sep 5, 2022
1 parent 80053f0 commit 7ce626d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
4 changes: 3 additions & 1 deletion client/rpc/src/eth/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,9 @@ where
}
previous_highest = highest;
}
ExitReason::Revert(_) | ExitReason::Error(ExitError::OutOfGas) => {
ExitReason::Revert(_)
| ExitReason::Error(ExitError::OutOfGas)
| ExitReason::Error(ExitError::InvalidCode(_)) => {
lowest = mid;
}
other => error_on_execution_failure(&other, &data)?,
Expand Down
15 changes: 15 additions & 0 deletions ts-tests/contracts/InvalidOpcode.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity >=0.8.0;

contract InvalidOpcode {
uint public number;

function call() public {
number = 1;
if (gasleft() < 40000 ){
assembly {
// Calls the INVALID opcode (0xFE)
invalid()
}
}
}
}
33 changes: 33 additions & 0 deletions ts-tests/tests/test-gas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect } from "chai";
import { AbiItem } from "web3-utils";

import InvalidOpcode from "../build/contracts/InvalidOpcode.json";
import Test from "../build/contracts/Test.json";
import { GENESIS_ACCOUNT, GENESIS_ACCOUNT_PRIVATE_KEY, FIRST_CONTRACT_ADDRESS } from "./config";
import { describeWithFrontier, createAndFinalizeBlock, customRequest } from "./util";
Expand Down Expand Up @@ -189,3 +190,35 @@ describeWithFrontier("Frontier RPC (Gas)", (context) => {
);
});
});

describeWithFrontier("Frontier RPC (Invalid opcode estimate gas)", (context) => {
const INVALID_OPCODE_BYTECODE = InvalidOpcode.bytecode;

let contractAddess;
before(async () => {
const tx = await context.web3.eth.accounts.signTransaction(
{
from: GENESIS_ACCOUNT,
data: INVALID_OPCODE_BYTECODE,
value: "0x00",
gasPrice: "0x3B9ACA00",
gas: "0x100000",
},
GENESIS_ACCOUNT_PRIVATE_KEY
);
const txHash = (await customRequest(context.web3, "eth_sendRawTransaction", [tx.rawTransaction])).result;
await createAndFinalizeBlock(context.web3);
contractAddess = (await context.web3.eth.getTransactionReceipt(txHash)).contractAddress;
});

it("should estimate gas with invalid opcode", async function () {
let estimate = await context.web3.eth.estimateGas({
from: GENESIS_ACCOUNT,
to: contractAddess,
data: "0x28b5e32b", // selector for the contract's `call` method
});
// The actual estimated value is irrelevant for this test purposes, we just want to verify that
// the binary search is not interrupted when an InvalidCode is returned by the evm.
expect(estimate).to.equal(85703);
});
});

0 comments on commit 7ce626d

Please sign in to comment.