Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Pectra Eip-7623 #2634

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions silkworm/core/protocol/intrinsic_gas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ intx::uint128 intrinsic_gas(const UnsignedTransaction& txn, const evmc_revision
gas += fee::kGTxCreate;
}

const uint64_t data_len{txn.data.length()};
if (data_len > 0) {
const intx::uint128 non_zero_bytes{std::ranges::count_if(txn.data, [](uint8_t c) { return c != 0; })};
const intx::uint128 non_zero_gas{rev >= EVMC_ISTANBUL ? fee::kGTxDataNonZeroIstanbul : fee::kGTxDataNonZeroFrontier};
gas += non_zero_bytes * non_zero_gas;
const intx::uint128 zero_bytes{data_len - non_zero_bytes};
gas += zero_bytes * fee::kGTxDataZero;

// EIP-3860: Limit and meter initcode
if (contract_creation && rev >= EVMC_SHANGHAI) {
gas += num_words(data_len) * fee::kInitCodeWordCost;
}

if (rev >= EVMC_PRAGUE) {
// EIP-7623: Increase calldata cost
const intx::uint128 floor_cost = fee::kGTransaction + (zero_bytes + non_zero_bytes * 4) * fee::kTotalCostFloorPerToken;
gas = std::max(gas, floor_cost);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not exactly correct. The floor cost is not a part of intrinsic cost. However, the transaction gas limit must be big enough to cover the floor cost just in case.

After the transaction execution you need another modification: if the gas used by the transaction is lower than the floor cost, bump it to the floor cost.

}
}

// EIP-2930: Optional access lists
gas += intx::uint128{txn.access_list.size()} * fee::kAccessListAddressCost;
intx::uint128 total_num_of_storage_keys{0};
Expand All @@ -38,22 +58,6 @@ intx::uint128 intrinsic_gas(const UnsignedTransaction& txn, const evmc_revision
}
gas += total_num_of_storage_keys * fee::kAccessListStorageKeyCost;

const uint64_t data_len{txn.data.length()};
if (data_len == 0) {
return gas;
}

const intx::uint128 non_zero_bytes{std::ranges::count_if(txn.data, [](uint8_t c) { return c != 0; })};
const intx::uint128 non_zero_gas{rev >= EVMC_ISTANBUL ? fee::kGTxDataNonZeroIstanbul : fee::kGTxDataNonZeroFrontier};
gas += non_zero_bytes * non_zero_gas;
const intx::uint128 zero_bytes{data_len - non_zero_bytes};
gas += zero_bytes * fee::kGTxDataZero;

// EIP-3860: Limit and meter initcode
if (contract_creation && rev >= EVMC_SHANGHAI) {
gas += num_words(data_len) * fee::kInitCodeWordCost;
}

return gas;
}

Expand Down
19 changes: 19 additions & 0 deletions silkworm/core/protocol/intrinsic_gas_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ namespace protocol {
CHECK(g0 == fee::kGTransaction + 2 * fee::kAccessListAddressCost + 2 * fee::kAccessListStorageKeyCost);
}

TEST_CASE("EIP-7623 intrinsic gas") {
// EIP-7623 rules should take precedence

const Bytes calldata = Bytes(22 * 1024, 1);
UnsignedTransaction txn{
.type = TransactionType::kDynamicFee,
.chain_id = kSepoliaConfig.chain_id,
.nonce = 7,
.max_priority_fee_per_gas = 30000000000,
.max_fee_per_gas = 30000000000,
.gas_limit = 25748100,
.value = 2 * kEther,
.data = calldata};

intx::uint128 g0{intrinsic_gas(txn, EVMC_PRAGUE)};
// Calldata contains only 'ones' and the cost per EIP-7623 is higher
CHECK(g0 == fee::kGTransaction + 4 * calldata.size() * fee::kTotalCostFloorPerToken);
}

} // namespace protocol

} // namespace silkworm
2 changes: 2 additions & 0 deletions silkworm/core/protocol/param.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace fee {

inline constexpr uint64_t kInitCodeWordCost{2}; // EIP-3860

inline constexpr uint64_t kTotalCostFloorPerToken{10}; // EIP-7623: Increase calldata cost

} // namespace fee

inline constexpr uint64_t kMinGasLimit{5000};
Expand Down
Loading