Skip to content

Commit

Permalink
Merge pull request #168 from eosnetworkfoundation/elmato/merge-change…
Browse files Browse the repository at this point in the history
…-gas-refund-in-v2-to-master

[1.0 -> main] Change gas refund for eos_evm_version >= 2
  • Loading branch information
elmato authored Jun 26, 2024
2 parents dbc1477 + 44306d4 commit 23bd8ed
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
3 changes: 2 additions & 1 deletion eosevm/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <eosevm/assert.hpp>
namespace eosevm {

static constexpr uint64_t max_eos_evm_version = 1;
static constexpr uint64_t max_eos_evm_version = 2;

using NonceType=silkworm::BlockHeader::NonceType;

Expand All @@ -24,6 +24,7 @@ inline evmc_revision version_to_evmc_revision(uint64_t version) {
switch (version) {
case 0: return EVMC_ISTANBUL;
case 1: return EVMC_SHANGHAI;
case 2: return EVMC_SHANGHAI;
}
auto msg = "Unknown EOSEVM version: " + std::to_string(version);
EOSEVM_ABORT(msg.c_str());
Expand Down
18 changes: 13 additions & 5 deletions silkworm/core/execution/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,19 @@ uint64_t ExecutionProcessor::available_gas() const noexcept {
uint64_t ExecutionProcessor::refund_gas(const Transaction& txn, uint64_t gas_left, uint64_t gas_refund) noexcept {
const evmc_revision rev{evm_.revision()};

const uint64_t max_refund_quotient{rev >= EVMC_LONDON ? protocol::kMaxRefundQuotientLondon
: protocol::kMaxRefundQuotientFrontier};
const uint64_t max_refund{(txn.gas_limit - gas_left) / max_refund_quotient};
uint64_t refund = std::min(gas_refund, max_refund);
gas_left += refund;
if( evm_.get_eos_evm_version() < 2 ) {
const uint64_t max_refund_quotient{rev >= EVMC_LONDON ? protocol::kMaxRefundQuotientLondon
: protocol::kMaxRefundQuotientFrontier};
const uint64_t max_refund{(txn.gas_limit - gas_left) / max_refund_quotient};
uint64_t refund = std::min(gas_refund, max_refund);
gas_left += refund;
} else {
gas_left += gas_refund;
if( gas_left > txn.gas_limit - silkworm::protocol::fee::kGTransaction ) {
gas_left = txn.gas_limit - silkworm::protocol::fee::kGTransaction;
}
}


const intx::uint256 base_fee_per_gas{evm_.block().header.base_fee_per_gas.value_or(0)};
const intx::uint256 effective_gas_price{txn.effective_gas_price(base_fee_per_gas)};
Expand Down
72 changes: 72 additions & 0 deletions silkworm/core/execution/processor_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,78 @@ TEST_CASE("No refund on error") {
CHECK(receipt2.cumulative_gas_used - receipt1.cumulative_gas_used == txn.gas_limit);
}

TEST_CASE("refund eosevm v2") {

auto deploy_and_execute = [&](uint64_t v) {
Block block{};
block.header.number = 10'050'107;
block.header.gas_limit = 10'000'000;
block.header.nonce = eosevm::version_to_nonce(v);
block.header.beneficiary = 0x5146556427ff689250ed1801a783d12138c3dd5e_address;
evmc::address caller{0x834e9b529ac9fa63b39a06f8d8c9b0d6791fa5df_address};
uint64_t nonce{3};

/*
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract Refund {
uint256 number;
function run(uint256 times) public {
for (uint i = 0; i < times; i++) {
number = 1;
number = 0;
}
}
}
*/
Bytes code{*from_hex("608060405234801561001057600080fd5b50610192806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a444f5e914610030575b600080fd5b61004a600480360381019061004591906100b8565b61004c565b005b60005b8181101561007957600160008190555060008081905550808061007190610114565b91505061004f565b5050565b600080fd5b6000819050919050565b61009581610082565b81146100a057600080fd5b50565b6000813590506100b28161008c565b92915050565b6000602082840312156100ce576100cd61007d565b5b60006100dc848285016100a3565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061011f82610082565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610151576101506100e5565b5b60018201905091905056fea26469706673582212203d88f52fc817048f72a222d4f3e50f4c76512b2119e3b493958f9b2bc033363a64736f6c63430008110033")};

InMemoryState state;
auto rule_set{protocol::rule_set_factory(kEOSEVMMainnetConfig)};
ExecutionProcessor processor{block, *rule_set, state, kEOSEVMMainnetConfig, {}};

Transaction txn{
{.nonce = nonce,
.max_priority_fee_per_gas = 150 * kGiga,
.max_fee_per_gas = 150 * kGiga,
.gas_limit = 150'000,
.data = code},
false, // odd_y_parity
1, // r
1, // s
};

processor.evm().state().add_to_balance(caller, 100*kEther);
processor.evm().state().set_nonce(caller, nonce);
txn.from = caller;

Receipt receipt1;
processor.execute_transaction(txn, receipt1);
CHECK(receipt1.success);

// Call run(10) on the newly created contract //a444f5e9 = run, 00..0a = 10
txn.nonce = nonce + 1;
txn.to = create_address(caller, nonce);
txn.data = *from_hex("a444f5e9000000000000000000000000000000000000000000000000000000000000000a");
txn.gas_limit = 800'000;

Receipt receipt2;
processor.execute_transaction(txn, receipt2);
CHECK(receipt2.success);
return receipt2.cumulative_gas_used - receipt1.cumulative_gas_used;
};

auto gas_used_v0 = deploy_and_execute(0);
CHECK(gas_used_v0 == 115830);

auto gas_used_v1 = deploy_and_execute(1);
CHECK(gas_used_v1 == 181408);

auto gas_used_v2 = deploy_and_execute(2);
CHECK(gas_used_v2 == 27760);
}


TEST_CASE("Self-destruct") {
Block block{};
block.header.number = 1'487'375;
Expand Down

0 comments on commit 23bd8ed

Please sign in to comment.