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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,4 +20,4 @@ contract C {
// ---- // ----
// constructor() // constructor()
// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00 // ~ 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 // compileViaYul: also
// ---- // ----
// constructor() // constructor()
// gas irOptimized: 425623 // gas irOptimized: 426283
// gas legacy: 936897 // gas legacy: 936897
// gas legacyOptimized: 490983 // gas legacyOptimized: 490983
// reserve(string), 69 ether: 0x20, 3, "abc" -> // reserve(string), 69 ether: 0x20, 3, "abc" ->

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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