Skip to content

Commit

Permalink
state: Meter and limit initcode (EIP-3860)
Browse files Browse the repository at this point in the history
Co-authored-by: Paweł Bylica <[email protected]>
  • Loading branch information
rodiazet and chfast committed Dec 28, 2022
1 parent d446dd4 commit 0298d8a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
2 changes: 1 addition & 1 deletion test/state/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ evmc::Result Host::create(const evmc_message& msg) noexcept
assert(gas_left >= 0);

const bytes_view code{result.output_data, result.output_size};
if (m_rev >= EVMC_SPURIOUS_DRAGON && code.size() > 0x6000)
if (m_rev >= EVMC_SPURIOUS_DRAGON && code.size() > max_code_size)
return evmc::Result{EVMC_FAILURE};

// Code deployment cost.
Expand Down
3 changes: 3 additions & 0 deletions test/state/host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace evmone::state
{
using evmc::uint256be;

inline constexpr size_t max_code_size = 0x6000;
inline constexpr size_t max_initcode_size = 2 * max_code_size;

class Host : public evmc::Host
{
evmc_revision m_rev;
Expand Down
16 changes: 14 additions & 2 deletions test/state/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace evmone::state
{
namespace
{
inline constexpr int64_t num_words(size_t size_in_bytes) noexcept
{
return static_cast<int64_t>((size_in_bytes + 31) / 32);
}

int64_t compute_tx_data_cost(evmc_revision rev, bytes_view data) noexcept
{
constexpr int64_t zero_byte_cost = 4;
Expand All @@ -36,9 +41,13 @@ int64_t compute_tx_intrinsic_cost(evmc_revision rev, const Transaction& tx) noex
{
static constexpr auto call_tx_cost = 21000;
static constexpr auto create_tx_cost = 53000;
const bool is_create = !tx.to.has_value();
static constexpr auto initcode_word_cost = 2;
const auto is_create = !tx.to.has_value();
const auto initcode_cost =
is_create && rev >= EVMC_SHANGHAI ? initcode_word_cost * num_words(tx.data.size()) : 0;
const auto tx_cost = is_create && rev >= EVMC_HOMESTEAD ? create_tx_cost : call_tx_cost;
return tx_cost + compute_tx_data_cost(rev, tx.data) + compute_access_list_cost(tx.access_list);
return tx_cost + compute_tx_data_cost(rev, tx.data) + compute_access_list_cost(tx.access_list) +
initcode_cost;
}

/// Validates transaction and computes its execution gas limit (the amount of gas provided to EVM).
Expand Down Expand Up @@ -68,6 +77,9 @@ int64_t validate_transaction(const Account& sender_acc, const BlockInfo& block,
if (sender_acc.nonce == Account::NonceMax)
return -1;

if (rev >= EVMC_SHANGHAI && !tx.to.has_value() && tx.data.size() > max_initcode_size)
return -1; // initcode size is limited by EIP-3860.

// Compute and check if sender has enough balance for the theoretical maximum transaction cost.
// Note this is different from tx_max_cost computed with effective gas price later.
// The computation cannot overflow if done with 512-bit precision.
Expand Down

0 comments on commit 0298d8a

Please sign in to comment.