Merge pull request #12282 from ethereum/fix-gas-test-enforcement

Fix gas cost enforcement for constructors and make `--enforce-gas-cost-min-value` actually work
This commit is contained in:
chriseth 2021-11-22 12:39:07 +01:00 committed by GitHub
commit defc74c8a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 107 additions and 28 deletions

View File

@ -182,7 +182,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
message.kind = EVMC_CALL;
message.destination = EVMHost::convertToEVMC(m_contractAddress);
}
message.gas = m_gas.convert_to<int64_t>();
message.gas = InitialGas.convert_to<int64_t>();
evmc::result result = m_evmcHost->call(message);
@ -190,7 +190,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
if (_isCreation)
m_contractAddress = EVMHost::convertFromEVMC(result.create_address);
m_gasUsed = m_gas - result.gas_left;
m_gasUsed = InitialGas - result.gas_left;
m_transactionSuccessful = (result.status_code == EVMC_SUCCESS);
if (m_showMessages)
@ -216,7 +216,7 @@ void ExecutionFramework::sendEther(h160 const& _addr, u256 const& _amount)
message.value = EVMHost::convertToEVMC(_amount);
message.kind = EVMC_CALL;
message.destination = EVMHost::convertToEVMC(_addr);
message.gas = m_gas.convert_to<int64_t>();
message.gas = InitialGas.convert_to<int64_t>();
m_evmcHost->call(message);
}

View File

@ -273,6 +273,9 @@ private:
}
protected:
u256 const GasPrice = 10 * gwei;
u256 const InitialGas = 100000000;
void selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1);
void reset();
@ -302,8 +305,6 @@ protected:
bool m_transactionSuccessful = true;
util::h160 m_sender = account(0);
util::h160 m_contractAddress;
u256 const m_gasPrice = 10 * gwei;
u256 const m_gas = 100000000;
bytes m_output;
u256 m_gasUsed;
};

View File

@ -407,7 +407,10 @@ TestCase::TestResult SemanticTest::runTest(
if (m_transactionSuccessful == test.call().expectations.failure)
success = false;
if (success && !checkGasCostExpectation(test, _isYulRun))
{
success = false;
m_gasCostFailure = true;
}
test.setFailure(!m_transactionSuccessful);
test.setRawBytes(bytes());
@ -562,14 +565,14 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp
// We don't check gas if enforce gas cost is not active
// or test is run with abi encoder v1 only
// or gas used less than threshold for enforcing feature
// or the test has used up all available gas (test will fail anyway)
// or setting is "ir" and it's not included in expectations
// or if the called function is an isoltest builtin e.g. `smokeTest` or `storageEmpty`
if (
!m_enforceGasCost ||
(
(setting == "ir" || m_gasUsed < m_enforceGasCostMinValue || m_gasUsed >= m_gas) &&
io_test.call().expectations.gasUsed.count(setting) == 0
) ||
m_gasUsed < m_enforceGasCostMinValue ||
m_gasUsed >= InitialGas ||
(setting == "ir" && io_test.call().expectations.gasUsed.count(setting) == 0) ||
io_test.call().kind == FunctionCall::Kind::Builtin
)
return true;

View File

@ -11,6 +11,9 @@ contract C {
// compileViaYul: also
// ----
// constructor(): 1, 2, 3 ->
// gas irOptimized: 143598
// gas legacy: 183490
// gas legacyOptimized: 151938
// a(uint256): 0 -> 1
// a(uint256): 1 -> 2
// a(uint256): 2 -> 3

View File

@ -11,5 +11,8 @@ contract Creator {
// compileViaYul: also
// ----
// constructor(): 1, 2, 3, 4 ->
// gas irOptimized: 132278
// gas legacy: 176789
// gas legacyOptimized: 129585
// r() -> 4
// ch() -> 3

View File

@ -10,5 +10,8 @@ contract Test {
// compileViaYul: also
// ----
// constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" ->
// gas irOptimized: 291443
// gas legacy: 309842
// gas legacyOptimized: 260801
// m_x() -> 7
// m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz"

View File

@ -19,5 +19,8 @@ contract Main {
// compileViaYul: also
// ----
// constructor(): "abc", true
// gas irOptimized: 112563
// gas legacy: 145838
// gas legacyOptimized: 104017
// getFlag() -> true
// getName() -> "abc"

View File

@ -12,6 +12,9 @@ contract C {
// compileViaYul: also
// ----
// constructor(): 1, 2, 3, 4 ->
// gas irOptimized: 180731
// gas legacy: 221377
// gas legacyOptimized: 177671
// a() -> 1
// b(uint256): 0 -> 2
// b(uint256): 1 -> 3

View File

@ -15,4 +15,5 @@ contract B is A {
// compileViaYul: true
// ----
// constructor() ->
// gas irOptimized: 122233
// y() -> 42

View File

@ -12,4 +12,7 @@ contract B is A {
// compileViaYul: also
// ----
// constructor() ->
// gas irOptimized: 122233
// gas legacy: 135046
// gas legacyOptimized: 116176
// y() -> 42

View File

@ -11,5 +11,7 @@ contract C {
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// gas irOptimized: 104227
// gas legacy: 117158
// i() -> 2
// k() -> 0

View File

@ -23,6 +23,9 @@ contract D is B, C {
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// gas irOptimized: 159542
// gas legacy: 170665
// gas legacyOptimized: 145396
// i() -> 2
// j() -> 2
// k() -> 1

View File

@ -14,5 +14,8 @@ contract D is C {
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// gas irOptimized: 124844
// gas legacy: 139250
// gas legacyOptimized: 119367
// i() -> 2
// k() -> 1

View File

@ -17,6 +17,8 @@ contract C {
// compileViaYul: also
// ----
// constructor() ->
// gas legacy: 249112
// gas irOptimized: 177344
// gas legacy: 250376
// gas legacyOptimized: 174522
// deposit(bytes32), 18 wei: 0x1234 ->
// ~ emit Deposit(address,bytes32,uint256) from 0xf01f7809444bd9a93a854361c6fae3f23d9e23db: #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b, #0x1234, 0x00

View File

@ -20,4 +20,4 @@ contract C {
// ----
// constructor()
// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00
// gas legacy: 150662
// gas legacy: 150602

View File

@ -76,7 +76,7 @@ contract FixedFeeRegistrar is Registrar {
// compileViaYul: also
// ----
// constructor()
// gas irOptimized: 425623
// gas irOptimized: 426283
// gas legacy: 936897
// gas legacyOptimized: 490983
// reserve(string), 69 ether: 0x20, 3, "abc" ->

View File

@ -178,9 +178,9 @@ contract DepositContract is IDepositContract, ERC165 {
// compileViaYul: also
// ----
// constructor()
// gas irOptimized: 1558013
// gas legacy: 2580394
// gas legacyOptimized: 1775403
// gas irOptimized: 1558001
// gas legacy: 2436584
// gas legacyOptimized: 1776483
// supportsInterface(bytes4): 0x0 -> 0
// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #
// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #

View File

@ -50,8 +50,8 @@ contract test {
// compileViaYul: also
// ----
// constructor()
// gas irOptimized: 1924584
// gas legacy: 2602700
// gas irOptimized: 1924392
// gas legacy: 2480887
// gas legacyOptimized: 1874490
// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328
// gas irOptimized: 22137

View File

@ -51,7 +51,7 @@ contract test {
// ----
// constructor()
// gas irOptimized: 1778342
// gas legacy: 2356230
// gas legacy: 2250130
// gas legacyOptimized: 1746528
// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328
// gas irOptimized: 22004

View File

@ -36,7 +36,7 @@ contract test {
// ----
// constructor()
// gas irOptimized: 465357
// gas legacy: 733634
// gas legacy: 672749
// gas legacyOptimized: 479606
// prb_pi() -> 3141592656369545286
// gas irOptimized: 57478

View File

@ -52,7 +52,7 @@ contract test {
// ----
// constructor()
// gas irOptimized: 702619
// gas legacy: 1188228
// gas legacy: 1130761
// gas legacyOptimized: 750416
// toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0
// gas irOptimized: 22660

View File

@ -17,4 +17,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(): 2 ->
// gas irOptimized: 200295
// gas legacy: 245842
// gas legacyOptimized: 195676
// f() -> 2

View File

@ -18,4 +18,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(): 2 ->
// gas irOptimized: 200458
// gas legacy: 246202
// gas legacyOptimized: 195914
// f() -> 2

View File

@ -25,8 +25,9 @@ contract C {
// compileViaYul: also
// ----
// constructor(), 1 ether ->
// gas irOptimized: 308423
// gas legacy: 465314
// gas legacyOptimized: 510004
// gas legacyOptimized: 304481
// f(uint256): 0 -> FAILURE
// f(uint256): 1 -> FAILURE
// f(uint256): 2 -> FAILURE

View File

@ -27,6 +27,8 @@ contract C {
// revertStrings: debug
// ----
// constructor(), 1 ether ->
// gas irOptimized: 448383
// gas legacy: 834272
// gas legacyOptimized: 510004
// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code"
// f(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code"

View File

@ -41,6 +41,9 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// gas irOptimized: 285350
// gas legacy: 402654
// gas legacyOptimized: 274470
// sendAmount(uint256): 5 -> 5
// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #
// checkState() -> false, 15

View File

@ -40,6 +40,9 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// gas irOptimized: 285350
// gas legacy: 402654
// gas legacyOptimized: 274470
// sendAmount(uint256): 5 -> 5
// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #
// checkState() -> false, 15

View File

@ -19,4 +19,7 @@ contract Main {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// gas irOptimized: 102862
// gas legacy: 116691
// gas legacyOptimized: 100361
// s() -> true

View File

@ -17,5 +17,8 @@ contract C {
// compileViaYul: also
// ----
// constructor(): 3 ->
// gas irOptimized: 137184
// gas legacy: 209361
// gas legacyOptimized: 139324
// f() -> 84, 23
// m(uint256): 3 -> 7

View File

@ -42,6 +42,9 @@ contract Main {
// compileViaYul: also
// ----
// constructor(), 22 wei ->
// gas irOptimized: 288778
// gas legacy: 402045
// gas legacyOptimized: 266772
// getFlag() -> true
// getName() -> "abc"
// getBalances() -> 12, 10

View File

@ -18,9 +18,9 @@ contract ClientReceipt {
// compileViaYul: also
// ----
// constructor(), 2000 wei ->
// gas irOptimized: 191881
// gas legacy: 235167
// gas legacyOptimized: 180756
// gas irOptimized: 184076
// gas legacy: 235195
// gas legacyOptimized: 176766
// balance -> 1500
// gas irOptimized: 191881
// gas legacy: 235167

View File

@ -14,7 +14,9 @@ contract C {
// compileViaYul: also
// ----
// constructor(), 2 wei: 3 ->
// gas legacy: 148000
// gas irOptimized: 111723
// gas legacy: 151416
// gas legacyOptimized: 108388
// state() -> 3
// balance() -> 2
// balance -> 2

View File

@ -14,6 +14,9 @@ contract C {
// compileViaYul: also
// ----
// constructor()
// gas irOptimized: 119839
// gas legacy: 155081
// gas legacyOptimized: 107997
// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737
// currentHash() -> 0
// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737

View File

@ -116,7 +116,7 @@ contract ERC20 {
// constructor()
// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14
// gas irOptimized: 442239
// gas legacy: 861547
// gas legacy: 861559
// gas legacyOptimized: 420959
// totalSupply() -> 20
// gas irOptimized: 23415

View File

@ -13,10 +13,13 @@ contract C {
function h() public view returns (uint) { return address(1).code.length; }
}
// ====
// compileViaYul: also
// compileToEwasm: also
// compileViaYul: also
// ----
// constructor() ->
// gas irOptimized: 199687
// gas legacy: 241124
// gas legacyOptimized: 155549
// initCode() -> 0x20, 0
// f() -> true
// g() -> 0

View File

@ -58,8 +58,9 @@ contract C {
}
}
// ====
// compileViaYul: also
// compileToEwasm: also
// compileViaYul: also
// ----
// constructor()
// gas legacy: 126455
// f(): true, true -> true, true

View File

@ -23,6 +23,7 @@ contract C {
// compileViaYul: also
// ----
// constructor(), 23 wei ->
// gas legacy: 100517
// f() -> 0
// g() -> 1
// h() -> 23

View File

@ -21,3 +21,4 @@ contract C {
// compileViaYul: also
// ----
// constructor() ->
// gas irOptimized: 104337

View File

@ -65,3 +65,5 @@ contract C {
// compileViaYul: false
// ----
// constructor() ->
// gas legacy: 588138
// gas legacyOptimized: 349636

View File

@ -19,4 +19,7 @@ contract D {
// compileViaYul: also
// ----
// constructor(), 27 wei ->
// gas irOptimized: 175261
// gas legacy: 222977
// gas legacyOptimized: 169779
// f() -> 27

View File

@ -22,4 +22,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// gas irOptimized: 185891
// gas legacy: 265006
// gas legacyOptimized: 182842
// sendAmount(uint256): 5 -> 8

View File

@ -21,4 +21,7 @@ contract test {
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// gas irOptimized: 187835
// gas legacy: 266728
// gas legacyOptimized: 184762
// sendAmount(uint256): 5 -> 8