From cd504159ab52ff515756b30dff34072d4b4dcfdb Mon Sep 17 00:00:00 2001 From: yarkin Date: Fri, 16 Aug 2024 00:49:11 +0800 Subject: [PATCH 1/2] Remove 1gwei limit when setting gas prices --- include/evm_runtime/config_wrapper.hpp | 1 + src/config_wrapper.cpp | 30 ++++++++++++++++++++------ tests/gas_fee_tests.cpp | 10 --------- tests/gas_param_tests.cpp | 6 ------ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/include/evm_runtime/config_wrapper.hpp b/include/evm_runtime/config_wrapper.hpp index 14993d25..40e54e8e 100644 --- a/include/evm_runtime/config_wrapper.hpp +++ b/include/evm_runtime/config_wrapper.hpp @@ -65,6 +65,7 @@ struct config_wrapper { void clear_dirty(); eosio::time_point get_current_time()const; + bool check_gas_overflow(uint64_t gas_txcreate, uint64_t gas_codedeposit) const; // return true if pass bool _dirty = false; bool _exists = false; diff --git a/src/config_wrapper.cpp b/src/config_wrapper.cpp index 9d1b3647..cb389a7d 100644 --- a/src/config_wrapper.cpp +++ b/src/config_wrapper.cpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace evm_runtime { @@ -189,7 +190,6 @@ void config_wrapper::set_fee_parameters(const fee_parameters& fee_params, bool allow_any_to_be_unspecified) { if (fee_params.gas_price.has_value()) { - eosio::check(*fee_params.gas_price >= one_gwei, "gas_price must >= 1Gwei"); if(get_evm_version() >= 1) { enqueue_gas_price(*fee_params.gas_price); } else { @@ -222,24 +222,31 @@ void config_wrapper::set_fee_parameters(const fee_parameters& fee_params, } void config_wrapper::update_consensus_parameters(eosio::asset ram_price_mb, uint64_t gas_price) { - + constexpr char too_big_str[] = "gas_per_byte too big"; eosio::check(ram_price_mb.symbol == get_token_symbol(), "invalid price symbol"); - eosio::check(gas_price >= one_gwei, "gas_price must >= 1Gwei"); + eosio::check(gas_price > 0, "zero gas price is not allowed"); auto miner_cut = get_evm_version() >= 1 ? 0 : _cached_config.miner_cut; + + eosio::check(miner_cut < hundred_percent, "100% miner cut is not allowed"); + + constexpr uint64_t overflow_limit = (1ull << 63) - 1; + + eosio::check((double)overflow_limit/get_minimum_natively_representable() > ram_price_mb.amount / (1024.0 * 1024.0), too_big_str); + double gas_per_byte_f = (ram_price_mb.amount / (1024.0 * 1024.0) * get_minimum_natively_representable()) / (gas_price * static_cast(hundred_percent - miner_cut) / hundred_percent); constexpr uint64_t account_bytes = 347; constexpr uint64_t contract_fixed_bytes = 606; constexpr uint64_t storage_slot_bytes = 346; - constexpr uint64_t max_gas_per_byte = (1ull << 43) - 1; - eosio::check(gas_per_byte_f >= 0.0, "gas_per_byte must >= 0"); - eosio::check(gas_per_byte_f * contract_fixed_bytes < (double)(max_gas_per_byte), "gas_per_byte too big"); uint64_t gas_per_byte = (uint64_t)(gas_per_byte_f + 1.0); + eosio::check((double)overflow_limit/gas_per_byte > contract_fixed_bytes, too_big_str); + eosio::check(check_gas_overflow(gas_per_byte * contract_fixed_bytes, gas_per_byte), too_big_str); + this->update_consensus_parameters2(account_bytes * gas_per_byte, /* gas_txnewaccount */ account_bytes * gas_per_byte, /* gas_newaccount */ contract_fixed_bytes * gas_per_byte, /*gas_txcreate*/ @@ -329,4 +336,15 @@ uint64_t config_wrapper::get_minimum_natively_representable() const { return pow10_const(evm_precision - _cached_config.ingress_bridge_fee.symbol.precision()); } +bool config_wrapper::check_gas_overflow(uint64_t gas_txcreate, uint64_t gas_codedeposit) const { + // We use 2^63 - 1 instead of 2^64 - 1 for some margin. + constexpr uint64_t overflow_limit = (1ull << 63) - 1; + + if (overflow_limit / gas_txcreate < silkworm::protocol::kMaxCodeSize) + return false; + if (overflow_limit - silkworm::protocol::kMaxCodeSize * gas_txcreate < gas_codedeposit) + return false; + return true; +} + } //namespace evm_runtime diff --git a/tests/gas_fee_tests.cpp b/tests/gas_fee_tests.cpp index cbe5cebd..e195dcf6 100644 --- a/tests/gas_fee_tests.cpp +++ b/tests/gas_fee_tests.cpp @@ -103,16 +103,6 @@ try { BOOST_CHECK_EQUAL(conf2.miner_cut, 90'000); BOOST_CHECK_EQUAL(conf2.ingress_bridge_fee, conf1.ingress_bridge_fee); - - - BOOST_REQUIRE_EXCEPTION(setfeeparams({.gas_price = 0}), - eosio_assert_message_exception, - eosio_assert_message_is("gas_price must >= 1Gwei")); - - BOOST_REQUIRE_EXCEPTION(setfeeparams({.gas_price = 999'999'999}), - eosio_assert_message_exception, - eosio_assert_message_is("gas_price must >= 1Gwei")); - // Change only gas_price to 1Gwei setfeeparams({.gas_price = 1'000'000'000}); diff --git a/tests/gas_param_tests.cpp b/tests/gas_param_tests.cpp index cd1d5ca3..b7a10804 100644 --- a/tests/gas_param_tests.cpp +++ b/tests/gas_param_tests.cpp @@ -88,12 +88,6 @@ BOOST_FIXTURE_TEST_CASE(basic, gas_param_evm_tester) try { BOOST_ASSERT(trace->action_traces.size() >= 2 && trace->action_traces[1].act.name == "evmtx"_n); } - // require miniumum gas at least 1 gwei - BOOST_REQUIRE_EXCEPTION( - updtgasparam(asset(10'0000, native_symbol), 999'999'999, evm_account_name), - eosio_assert_message_exception, - eosio_assert_message_is("gas_price must >= 1Gwei")); - // invalid symbol in ram_price_mb paramerter BOOST_REQUIRE_EXCEPTION( updtgasparam(asset(10'0000, symbol::from_string("0,EOS")), 1'000'000'000, evm_account_name), From cb63bdd87dfefe68e2739619da6507b2db3a2f8e Mon Sep 17 00:00:00 2001 From: yarkin Date: Tue, 20 Aug 2024 08:17:41 +0800 Subject: [PATCH 2/2] test for new sanity checks after we remove the 1gwei limit. --- tests/gas_param_tests.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/gas_param_tests.cpp b/tests/gas_param_tests.cpp index b7a10804..b1bbebcc 100644 --- a/tests/gas_param_tests.cpp +++ b/tests/gas_param_tests.cpp @@ -63,6 +63,18 @@ BOOST_FIXTURE_TEST_CASE(basic, gas_param_evm_tester) try { eosio_assert_message_exception, eosio_assert_message_is("evm_version must >= 1")); + // zero gas price + BOOST_REQUIRE_EXCEPTION( + updtgasparam(asset(10'0000, native_symbol), 0, evm_account_name), + eosio_assert_message_exception, + eosio_assert_message_is("zero gas price is not allowed")); + + // fee too high + BOOST_REQUIRE_EXCEPTION( + updtgasparam(asset((1ull << 62) - 1, native_symbol), 1'000'000'000, evm_account_name), + eosio_assert_message_exception, + eosio_assert_message_is("gas_per_byte too big")); + setversion(1, evm_account_name); produce_block();