Skip to content

Commit

Permalink
Merge pull request #722 from eosnetworkfoundation/elmato/merge-dynami…
Browse files Browse the repository at this point in the history
…c-gas-limit-in-handle-evm-transfer-to-main

[1.0 -> main] Make gas_limit dynamic in handle_evm_transfer
  • Loading branch information
elmato authored May 30, 2024
2 parents c12bf82 + 4e2db4c commit a14f853
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 17 deletions.
16 changes: 15 additions & 1 deletion src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,13 +659,27 @@ void evm_contract::handle_evm_transfer(eosio::asset quantity, const std::string&
intx::uint256 value((uint64_t)quantity.amount);
value *= intx::uint256(_config->get_minimum_natively_representable());

auto calculate_gas_limit = [&](const evmc::address& destination) -> int64_t {
int64_t gas_limit = 21000;

account_table accounts(get_self(), get_self().value);
auto inx = accounts.get_index<"by.address"_n>();
auto itr = inx.find(make_key(destination));

if(itr == inx.end()) {
gas_limit += std::visit([&](const auto &v) { return v.gas_parameter.gas_txnewaccount; }, _config->get_consensus_param());
}

return gas_limit;
};

Transaction txn;
txn.type = TransactionType::kLegacy;
txn.nonce = get_and_increment_nonce(get_self());
txn.max_priority_fee_per_gas = _config->get_gas_price();
txn.max_fee_per_gas = _config->get_gas_price();
txn.gas_limit = 21000;
txn.to = to_evmc_address(*address_bytes);
txn.gas_limit = calculate_gas_limit(*txn.to);
txn.value = value;
txn.r = 0u; // r == 0 is pseudo signature that resolves to reserved address range
txn.s = get_self().value;
Expand Down
17 changes: 17 additions & 0 deletions tests/basic_evm_tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,4 +809,21 @@ void basic_evm_tester::check_balances() {
}
}

silkworm::Transaction basic_evm_tester::get_tx_from_trace(const bytes& v) {
auto evmtx_v = fc::raw::unpack<evm_test::evmtx_type>(v.data(), v.size());

BOOST_REQUIRE(std::holds_alternative<evm_test::evmtx_v0>(evmtx_v));

const auto& evmtx = std::get<evm_test::evmtx_v0>(evmtx_v);
BOOST_REQUIRE(evmtx.eos_evm_version == 1);

silkworm::Transaction tx;
silkworm::ByteView bv{(const uint8_t*)evmtx.rlptx.data(), evmtx.rlptx.size()};
silkworm::rlp::decode(bv, tx);
BOOST_REQUIRE(bv.empty());

return tx;
};


} // namespace evm_test
1 change: 1 addition & 0 deletions tests/basic_evm_tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ class basic_evm_tester : public evm_validating_tester
bool scan_price_queue(std::function<bool(evm_test::price_queue)> visitor) const;

intx::uint128 tx_data_cost(const silkworm::Transaction& txn) const;
silkworm::Transaction get_tx_from_trace(const bytes& v);
};

inline constexpr intx::uint256 operator"" _wei(const char* s) { return intx::from_string<intx::uint256>(s); }
Expand Down
35 changes: 35 additions & 0 deletions tests/gas_param_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,4 +469,39 @@ BOOST_FIXTURE_TEST_CASE(gas_param_G_sset, gas_param_evm_tester) try {

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(gas_limit_internal_transaction, gas_param_evm_tester) try {

uint64_t suggested_gas_price = 150'000'000'000ull;
init(15555, suggested_gas_price);

produce_block();
fund_evm_faucet();
produce_block();

setversion(1, evm_account_name);
produce_block();
produce_block();

// Send 0.0001 EOS to a never used address (21000 GAS)
evm_eoa evm1;
auto trace = transfer_token("alice"_n, "evm"_n, make_asset(1), evm1.address_0x());
auto tx = get_tx_from_trace(trace->action_traces[3].act.data);
BOOST_REQUIRE(tx.gas_limit == 21000);
BOOST_REQUIRE(evm_balance(evm1) == 100000000000000);

// Set gas_txnewaccount = 1
setgasparam(1, gas_newaccount, gas_txcreate, gas_codedeposit, gas_sset, evm_account_name);
produce_block();
produce_block();
produce_block();

// Send 0.0001 EOS to a never used address (21001 GAS)
evm_eoa evm2;
trace = transfer_token("alice"_n, "evm"_n, make_asset(1), evm2.address_0x());
tx = get_tx_from_trace(trace->action_traces[4].act.data);
BOOST_REQUIRE(tx.gas_limit == 21001);
BOOST_REQUIRE(evm_balance(evm2) == 100000000000000);

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()
16 changes: 0 additions & 16 deletions tests/version_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,22 +221,6 @@ BOOST_FIXTURE_TEST_CASE(traces_in_different_eosevm_version, version_tester) try
setversion(1, evm_account_name);
produce_blocks(2);

auto get_tx_from_trace = [&](const bytes& v) {
auto evmtx_v = fc::raw::unpack<evm_test::evmtx_type>(v.data(), v.size());

BOOST_REQUIRE(std::holds_alternative<evm_test::evmtx_v0>(evmtx_v));

const auto& evmtx = std::get<evm_test::evmtx_v0>(evmtx_v);
BOOST_REQUIRE(evmtx.eos_evm_version == 1);

silkworm::Transaction tx;
silkworm::ByteView bv{(const uint8_t*)evmtx.rlptx.data(), evmtx.rlptx.size()};
silkworm::rlp::decode(bv, tx);
BOOST_REQUIRE(bv.empty());

return tx;
};

// Test traces of `handle_evm_transfer` (EVM VERSION=1)
trace = transfer_token("alice"_n, evm_account_name, make_asset(to_bridge), evm1.address_0x());
BOOST_REQUIRE(trace->action_traces.size() == 4);
Expand Down

0 comments on commit a14f853

Please sign in to comment.