diff --git a/silkworm b/silkworm index 9e0bfac1..39aed561 160000 --- a/silkworm +++ b/silkworm @@ -1 +1 @@ -Subproject commit 9e0bfac1ab4e6f29f7fb0ea9808138deac3ca655 +Subproject commit 39aed561ce75070d4398312586550047a3661de6 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 839a8908..fb200a10 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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=34816) + target_link_options(evm_runtime PUBLIC --stack-size=34768) endif() diff --git a/src/actions.cpp b/src/actions.cpp index 9afa80a2..7663a6ab 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -248,11 +248,18 @@ Receipt evm_contract::execute_tx(const runtime_config& rc, eosio::name miner, Bl std::optional gas_fee_miner_portion; if (miner) { uint64_t tx_gas_used = receipt.cumulative_gas_used; // Only transaction in the "block" so cumulative_gas_used is the tx gas_used. - intx::uint512 gas_fee = intx::uint256(tx_gas_used) * tx.max_fee_per_gas; - check(gas_fee < std::numeric_limits::max(), "too much gas"); - gas_fee *= _config->get_miner_cut(); - gas_fee /= hundred_percent; - gas_fee_miner_portion.emplace(static_cast(gas_fee)); + if(_config->get_evm_version() >= 1) { + eosio::check(ep.evm().block().header.base_fee_per_gas.has_value(), "no base fee"); + intx::uint512 gas_fee = intx::uint256(tx_gas_used) * tx.priority_fee_per_gas(ep.evm().block().header.base_fee_per_gas.value()); + check(gas_fee < std::numeric_limits::max(), "too much gas"); + gas_fee_miner_portion.emplace(static_cast(gas_fee)); + } else { + intx::uint512 gas_fee = intx::uint256(tx_gas_used) * tx.max_fee_per_gas; + check(gas_fee < std::numeric_limits::max(), "too much gas"); + gas_fee *= _config->get_miner_cut(); + gas_fee /= hundred_percent; + gas_fee_miner_portion.emplace(static_cast(gas_fee)); + } } if (rc.abort_on_failure) diff --git a/src/config_wrapper.cpp b/src/config_wrapper.cpp index db72a7f5..7e3140dd 100644 --- a/src/config_wrapper.cpp +++ b/src/config_wrapper.cpp @@ -149,7 +149,10 @@ uint64_t config_wrapper::get_evm_version_and_maybe_promote() { if(_cached_config.evm_version.has_value()) { std::tie(current_version, promoted) = _cached_config.evm_version->get_version_and_maybe_promote(_cached_config.genesis_time, get_current_time()); } - if(promoted) set_dirty(); + if(promoted) { + if(current_version >=1 && _cached_config.miner_cut != 0) _cached_config.miner_cut = 0; + set_dirty(); + } return current_version; } @@ -176,6 +179,7 @@ void config_wrapper::set_fee_parameters(const fee_parameters& fee_params, } if (fee_params.miner_cut.has_value()) { + eosio::check(get_evm_version() == 0, "can't set miner_cut"); eosio::check(*fee_params.miner_cut <= ninety_percent, "miner_cut must <= 90%"); _cached_config.miner_cut = *fee_params.miner_cut; } else { @@ -197,7 +201,8 @@ void config_wrapper::update_consensus_parameters(eosio::asset ram_price_mb, uint eosio::check(ram_price_mb.symbol == token_symbol, "invalid price symbol"); eosio::check(gas_price >= one_gwei, "gas_price must >= 1Gwei"); - double gas_per_byte_f = (ram_price_mb.amount / (1024.0 * 1024.0) * minimum_natively_representable_f) / (gas_price * static_cast(hundred_percent - _cached_config.miner_cut) / hundred_percent); + auto miner_cut = get_evm_version() >= 1 ? 0 : _cached_config.miner_cut; + double gas_per_byte_f = (ram_price_mb.amount / (1024.0 * 1024.0) * minimum_natively_representable_f) / (gas_price * static_cast(hundred_percent - miner_cut) / hundred_percent); constexpr uint64_t account_bytes = 347; constexpr uint64_t contract_fixed_bytes = 606; diff --git a/tests/gas_fee_tests.cpp b/tests/gas_fee_tests.cpp index dd1b61f4..da1107c5 100644 --- a/tests/gas_fee_tests.cpp +++ b/tests/gas_fee_tests.cpp @@ -389,4 +389,66 @@ try { } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_FIXTURE_TEST_CASE(miner_cut_calculation_v1, gas_fee_evm_tester) +try { + static constexpr uint64_t base_gas_price = 300'000'000'000; // 300 gwei + + init(); + + auto miner_account = "miner"_n; + create_accounts({miner_account}); + open(miner_account); + + // Set base price + setfeeparams({.gas_price=base_gas_price}); + + auto config = get_config(); + BOOST_REQUIRE(config.miner_cut == suggested_miner_cut); + + // Set version 1 + setversion(1, evm_account_name); + + produce_blocks(3); + + // Fund evm1 address with 10.0000 EOS / trigger version change and sets miner_cut to 0 + evm_eoa evm1; + transfer_token("alice"_n, evm_account_name, make_asset(10'0000), evm1.address_0x()); + + config = get_config(); + BOOST_REQUIRE(config.miner_cut == 0); + + // miner_cut can't be changed when version >= 1 + BOOST_REQUIRE_EXCEPTION(setfeeparams({.miner_cut=10'0000}), + eosio_assert_message_exception, + [](const eosio_assert_message_exception& e) {return testing::expect_assert_message(e, "assertion failure with message: can't set miner_cut");}); + + auto inclusion_price = 50'000'000'000; // 50 gwei + + evm_eoa evm2; + auto tx = generate_tx(evm2.address, 1); + tx.type = silkworm::TransactionType::kDynamicFee; + tx.max_priority_fee_per_gas = inclusion_price*2; + tx.max_fee_per_gas = base_gas_price + inclusion_price; + + BOOST_REQUIRE(vault_balance(miner_account) == (balance_and_dust{make_asset(0), 0ULL})); + + evm1.sign(tx); + pushtx(tx, miner_account); + + //21'000 * 50'000'000'000 = 0.00105 + BOOST_REQUIRE(vault_balance(miner_account) == (balance_and_dust{make_asset(10), 50'000'000'000'000ULL})); + + tx = generate_tx(evm2.address, 1); + tx.type = silkworm::TransactionType::kDynamicFee; + tx.max_priority_fee_per_gas = 0; + tx.max_fee_per_gas = base_gas_price + inclusion_price; + + evm1.sign(tx); + pushtx(tx, miner_account); + + //0.00105 + 0 + BOOST_REQUIRE(vault_balance(miner_account) == (balance_and_dust{make_asset(10), 50'000'000'000'000ULL})); +} +FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END()