Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into elmato/fix-basefee-ch…
Browse files Browse the repository at this point in the history
…ange
  • Loading branch information
elmato committed Apr 24, 2024
2 parents f958bb6 + e2d91be commit b11d52c
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 16 deletions.
4 changes: 2 additions & 2 deletions include/evm_runtime/evm_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class [[eosio::contract]] evm_contract : public contract

[[eosio::action]] void exec(const exec_input& input, const std::optional<exec_callback>& callback);

[[eosio::action]] void pushtx(eosio::name miner, bytes rlptx);
[[eosio::action]] void pushtx(eosio::name miner, bytes rlptx, eosio::binary_extension<uint64_t> min_inclusion_price);

[[eosio::action]] void open(eosio::name owner);

Expand Down Expand Up @@ -148,7 +148,7 @@ class [[eosio::contract]] evm_contract : public contract

using pushtx_action = eosio::action_wrapper<"pushtx"_n, &evm_contract::pushtx>;

void process_tx(const runtime_config& rc, eosio::name miner, const transaction& tx);
void process_tx(const runtime_config& rc, eosio::name miner, const transaction& tx, std::optional<uint64_t> min_inclusion_price);
void dispatch_tx(const runtime_config& rc, const transaction& tx);
};

Expand Down
2 changes: 1 addition & 1 deletion silkworm
Submodule silkworm updated 1 files
+1 −1 eosevm/version.hpp
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ target_compile_options(evm_runtime PUBLIC --no-missing-ricardian-clause)
if (WITH_LARGE_STACK)
target_link_options(evm_runtime PUBLIC --stack-size=50000000)
else()
target_link_options(evm_runtime PUBLIC --stack-size=34896)
target_link_options(evm_runtime PUBLIC --stack-size=34816)
endif()
32 changes: 23 additions & 9 deletions src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ void evm_contract::process_filtered_messages(const std::vector<silkworm::Filtere

}

void evm_contract::process_tx(const runtime_config& rc, eosio::name miner, const transaction& txn) {
void evm_contract::process_tx(const runtime_config& rc, eosio::name miner, const transaction& txn, std::optional<uint64_t> min_inclusion_price) {
LOGTIME("EVM START1");

const auto& tx = txn.get_tx();
Expand Down Expand Up @@ -479,8 +479,13 @@ void evm_contract::process_tx(const runtime_config& rc, eosio::name miner, const

silkworm::ExecutionProcessor ep{block, engine, state, *found_chain_config->second, gas_params};

check(tx.max_priority_fee_per_gas == tx.max_fee_per_gas, "max_priority_fee_per_gas must be equal to max_fee_per_gas");
check(tx.max_fee_per_gas >= _config->get_gas_price(), "gas price is too low");
if (current_version >= 1) {
auto inclusion_price = std::min(tx.max_priority_fee_per_gas, tx.max_fee_per_gas - *base_fee_per_gas);
eosio::check(inclusion_price >= (min_inclusion_price.has_value() ? *min_inclusion_price : 0), "inclusion price must >= min_inclusion_price");
} else { // old behavior
check(tx.max_priority_fee_per_gas == tx.max_fee_per_gas, "max_priority_fee_per_gas must be equal to max_fee_per_gas");
check(tx.max_fee_per_gas >= _config->get_gas_price(), "gas price is too low");
}

// Filter EVM messages (with data) that are sent to the reserved address
// corresponding to the EOS account holding the contract (self)
Expand Down Expand Up @@ -509,10 +514,12 @@ void evm_contract::process_tx(const runtime_config& rc, eosio::name miner, const
LOGTIME("EVM END");
}

void evm_contract::pushtx(eosio::name miner, bytes rlptx) {
void evm_contract::pushtx(eosio::name miner, bytes rlptx, eosio::binary_extension<uint64_t> min_inclusion_price) {
LOGTIME("EVM START0");
assert_unfrozen();
if(_config->get_evm_version() >= 1) _config->process_price_queue();

auto evm_version = _config->get_evm_version();
if (evm_version >= 1) _config->process_price_queue();

// Use default runtime configuration parameters.
runtime_config rc;
Expand All @@ -537,7 +544,13 @@ void evm_contract::pushtx(eosio::name miner, bytes rlptx) {
rc.allow_non_self_miner = false;
}

process_tx(rc, miner, transaction{std::move(rlptx)});
std::optional<uint64_t> min_inclusion_price_;
if (min_inclusion_price.has_value()) {
min_inclusion_price_ = *min_inclusion_price;
check(evm_version >= 1, "min_inclusion_price requires evm_version >= 1");
}

process_tx(rc, miner, transaction{std::move(rlptx)}, min_inclusion_price_);
}

void evm_contract::open(eosio::name owner) {
Expand Down Expand Up @@ -715,11 +728,12 @@ void evm_contract::call_(const runtime_config& rc, intx::uint256 s, const bytes&

void evm_contract::dispatch_tx(const runtime_config& rc, const transaction& tx) {
if (_config->get_evm_version_and_maybe_promote() >= 1) {
process_tx(rc, get_self(), tx);
process_tx(rc, get_self(), tx, {} /* min_inclusion_price */);
} else {
eosio::check(rc.allow_special_signature && rc.abort_on_failure && !rc.enforce_chain_id && !rc.allow_non_self_miner, "invalid runtime config");
pushtx_action pushtx_act(get_self(), {{get_self(), "active"_n}});
pushtx_act.send(get_self(), tx.get_rlptx());
action(permission_level{get_self(),"active"_n}, get_self(), "pushtx"_n,
std::tuple<eosio::name, bytes>(get_self(), tx.get_rlptx())
).send();
}
}

Expand Down
8 changes: 6 additions & 2 deletions tests/basic_evm_tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ transaction_trace_ptr basic_evm_tester::assertnonce(name account, uint64_t next_
mvo()("account", account)("next_nonce", next_nonce));
}

transaction_trace_ptr basic_evm_tester::pushtx(const silkworm::Transaction& trx, name miner)
transaction_trace_ptr basic_evm_tester::pushtx(const silkworm::Transaction& trx, name miner, std::optional<uint64_t> min_inclusion_price)
{
silkworm::Bytes rlp;
silkworm::rlp::encode(rlp, trx);
Expand All @@ -430,7 +430,11 @@ transaction_trace_ptr basic_evm_tester::pushtx(const silkworm::Transaction& trx,
rlp_bytes.resize(rlp.size());
memcpy(rlp_bytes.data(), rlp.data(), rlp.size());

return push_action(evm_account_name, "pushtx"_n, miner, mvo()("miner", miner)("rlptx", rlp_bytes));
if (min_inclusion_price.has_value()) {
return push_action(evm_account_name, "pushtx"_n, miner, mvo()("miner", miner)("rlptx", rlp_bytes)("min_inclusion_price", min_inclusion_price));
} else {
return push_action(evm_account_name, "pushtx"_n, miner, mvo()("miner", miner)("rlptx", rlp_bytes));
}
}

transaction_trace_ptr basic_evm_tester::setversion(uint64_t version, name actor) {
Expand Down
2 changes: 1 addition & 1 deletion tests/basic_evm_tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ class basic_evm_tester : public evm_validating_tester
transaction_trace_ptr bridgeunreg(name receiver);
transaction_trace_ptr exec(const exec_input& input, const std::optional<exec_callback>& callback);
transaction_trace_ptr assertnonce(name account, uint64_t next_nonce);
transaction_trace_ptr pushtx(const silkworm::Transaction& trx, name miner = evm_account_name);
transaction_trace_ptr pushtx(const silkworm::Transaction& trx, name miner = evm_account_name, std::optional<uint64_t> min_inclusion_price={});
transaction_trace_ptr setversion(uint64_t version, name actor);
transaction_trace_ptr call(name from, const evmc::bytes& to, const evmc::bytes& value, evmc::bytes& data, uint64_t gas_limit, name actor);
transaction_trace_ptr admincall(const evmc::bytes& from, const evmc::bytes& to, const evmc::bytes& value, evmc::bytes& data, uint64_t gas_limit, name actor);
Expand Down
140 changes: 140 additions & 0 deletions tests/version_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,4 +457,144 @@ BOOST_FIXTURE_TEST_CASE(admincall_promote_pending, version_tester) try {

} FC_LOG_AND_RETHROW()


BOOST_FIXTURE_TEST_CASE(min_inclusion_price, version_tester) try {

auto config = get_config();

evm_eoa evm1;
const int64_t to_bridge = 1000000;

// Open alice internal balance
open("alice"_n);
transfer_token("alice"_n, evm_account_name, make_asset(to_bridge), "alice");
auto alice_addr = make_reserved_address("alice"_n.to_uint64_t());

// Fund evm1 address
transfer_token("alice"_n, evm_account_name, make_asset(to_bridge), evm1.address_0x());

auto old_nonce = evm1.next_nonce;
evm1.next_nonce = old_nonce;
// EVM Version 0 does not support kDynamicFee transaction type
silkworm::Transaction txin0 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = config.gas_price + 10,
.max_fee_per_gas = config.gas_price + 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin0);
BOOST_REQUIRE_EXCEPTION(pushtx(txin0, evm_account_name),
eosio_assert_message_exception,
eosio_assert_message_is("pre_validate_transaction error: 29 Unsupported transaction type"));

evm1.next_nonce = old_nonce;
// EVM Version 0 does not support kDynamicFee transaction type
silkworm::Transaction txin01 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kLegacy,
.max_priority_fee_per_gas = config.gas_price + 10,
.max_fee_per_gas = config.gas_price + 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin01);
BOOST_REQUIRE_EXCEPTION(pushtx(txin01, evm_account_name, 1),
eosio_assert_message_exception,
eosio_assert_message_is("min_inclusion_price requires evm_version >= 1"));

/// change EOS EVM VERSION => 1 ///
setversion(1, evm_account_name);
produce_blocks(2);

// Test traces of `handle_evm_transfer` (EVM VERSION=1)
transfer_token("alice"_n, evm_account_name, make_asset(to_bridge), evm1.address_0x());

evm1.next_nonce = old_nonce;
// test max priority fee too low
silkworm::Transaction txin1 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = 1,
.max_fee_per_gas = config.gas_price + 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin1);
BOOST_REQUIRE_EXCEPTION(pushtx(txin1, evm_account_name, 2),
eosio_assert_message_exception,
eosio_assert_message_is("inclusion price must >= min_inclusion_price"));

// gas fee too low: miner expect 11Gwei inclusion fee
evm1.next_nonce = old_nonce;
silkworm::Transaction txin2 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = config.gas_price,
.max_fee_per_gas = config.gas_price + 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin2);
BOOST_REQUIRE_EXCEPTION(pushtx(txin2, evm_account_name, 11),
eosio_assert_message_exception,
eosio_assert_message_is("inclusion price must >= min_inclusion_price"));

// gas fee too low: gas fee < base fee
evm1.next_nonce = old_nonce;
silkworm::Transaction txin22 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = config.gas_price - 10,
.max_fee_per_gas = config.gas_price - 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin22);
BOOST_REQUIRE_EXCEPTION(pushtx(txin22, evm_account_name),
eosio_assert_message_exception,
eosio_assert_message_is("pre_validate_transaction error: 25 Max fee per gas less than block base fee"));

// gas fee just fine. (miner expect 10Gwei inclusion fee)
evm1.next_nonce = old_nonce;
silkworm::Transaction txin3 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = config.gas_price,
.max_fee_per_gas = config.gas_price + 10,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin3);
pushtx(txin3, evm_account_name, 10);

// miner doesn't specify min_inclusion_price, default to 0
silkworm::Transaction txin4 {
silkworm::UnsignedTransaction {
.type = silkworm::TransactionType::kDynamicFee,
.max_priority_fee_per_gas = config.gas_price,
.max_fee_per_gas = config.gas_price,
.gas_limit = 10'000'000,
.to = evmc::address{},
.data = silkworm::Bytes{}
}
};
evm1.sign(txin4);
pushtx(txin4, evm_account_name);

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit b11d52c

Please sign in to comment.