Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions category/execution/ethereum/evm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ evmc::Result deploy_contract_code(
}
}

auto const deploy_cost =
static_cast<int64_t>(result.output_size) * traits::code_deposit_cost();
auto const deploy_cost = static_cast<int64_t>(result.output_size) * 200;

if (result.gas_left < deploy_cost) {
if constexpr (traits::evm_rev() == EVMC_FRONTIER) {
Expand Down
95 changes: 92 additions & 3 deletions category/execution/ethereum/evm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,7 @@ TYPED_TEST(TraitsTest, deploy_contract_code_not_enough_of_gas)
auto const r2 = deploy_contract_code<typename TestFixture::Trait>(
s, a, std::move(r));
EXPECT_EQ(r2.status_code, EVMC_SUCCESS);
EXPECT_EQ(
r2.gas_left,
gas - TestFixture::Trait::code_deposit_cost() * sizeof(code));
EXPECT_EQ(r2.gas_left, gas - 200 * sizeof(code));
EXPECT_EQ(r2.create_address, a);
auto const icode = s.get_code(a)->intercode();
EXPECT_EQ(
Expand Down Expand Up @@ -966,4 +964,95 @@ TYPED_TEST(TraitsTest, nested_call_to_delegated_precompile)
}
}

TYPED_TEST(TraitsTest, cold_account_access)
{
InMemoryMachine machine;
mpt::Db db{machine};
db_t tdb{db};
vm::VM vm;
BlockState bs{tdb, vm};
State s{bs, Incarnation{0, 0}};

static constexpr auto from{
0x00000000000000000000000000000000bbbbbbbb_address};

static constexpr auto contract{
0x00000000000000000000000000000000cccccccc_address};

// push cold address; BALANCE
auto const code =
evmc::from_hex("0x7300000000000000000000000000000000aaaaaaaa31")
.value();
auto const icode = vm::make_shared_intercode(code);
auto const code_hash = to_bytes(keccak256(code));

commit_sequential(
tdb,
StateDeltas{
{from,
StateDelta{
.account =
{std::nullopt,
Account{
.balance = 10'000'000'000,
}}}},
{contract,
StateDelta{
.account =
{std::nullopt,
Account{
.code_hash = code_hash,
}}}}},
Code{
{code_hash, icode},
},
BlockHeader{});

constexpr auto gas_limit = 1'000'000;

evmc_message const m{
.kind = EVMC_CALL,
.gas = gas_limit,
.recipient = contract,
.sender = from,
.code_address = contract,
};

BlockHashBufferFinalized const block_hash_buffer;
NoopCallTracer call_tracer;
EvmcHost<typename TestFixture::Trait> h{
call_tracer, EMPTY_TX_CONTEXT, block_hash_buffer, s};
auto const result = h.call(m);
auto const gas_used = gas_limit - result.gas_left;

constexpr auto balance_gas = [] {
if constexpr (TestFixture::is_monad_trait()) {
if constexpr (TestFixture::Trait::monad_rev() >= MONAD_NEXT) {
return 10100;
}
else {
return 2600;
}
}
else {
if constexpr (TestFixture::Trait::evm_rev() >= EVMC_BERLIN) {
return 2600;
}
else if constexpr (TestFixture::Trait::evm_rev() >= EVMC_ISTANBUL) {
return 700;
}
else if constexpr (
TestFixture::Trait::evm_rev() >= EVMC_TANGERINE_WHISTLE) {
return 400;
}
else {
return 20;
}
}
}();

EXPECT_EQ(result.status_code, EVMC_SUCCESS);
EXPECT_EQ(gas_used, balance_gas + 3); // +3 for PUSH20
}

#undef PUSH3
22 changes: 4 additions & 18 deletions category/execution/ethereum/execute_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,6 @@ evmc::Result ExecuteTransactionNoValidation<traits>::operator()(
auth_refund = process_authorizations(state, host);
}

if constexpr (!traits::eip_7702_refund_active()) {
// monad doesn't give authorization refunds
auth_refund = 0;
}

// EIP-3651
if constexpr (traits::evm_rev() >= EVMC_SHANGHAI) {
host.access_account(header_.beneficiary);
Expand Down Expand Up @@ -349,26 +344,17 @@ Receipt ExecuteTransaction<traits>::execute_final(
tx_,
static_cast<uint64_t>(result.gas_left),
static_cast<uint64_t>(result.gas_refund));
auto const refund_gas_cost =
refund_gas_price<traits>(tx_, header_.base_fee_per_gas.value_or(0));
state.add_to_balance(sender_, refund_gas_cost * gas_refund);
auto const gas_cost =
gas_price<traits>(tx_, header_.base_fee_per_gas.value_or(0));
state.add_to_balance(sender_, gas_cost * gas_refund);

auto gas_used = tx_.gas_limit;

// Monad specification §2.3: Payment Rule for User:
// The storage refund does not reduce the gas consumption of the
// transaction.
if constexpr (traits::should_refund_reduce_gas_used()) {
gas_used -= gas_refund;
}
auto gas_used = tx_.gas_limit - gas_refund;

// EIP-7623
if constexpr (traits::evm_rev() >= EVMC_PRAGUE) {
auto const floor_gas = floor_data_gas(tx_);
if (gas_used < floor_gas) {
auto const delta = floor_gas - gas_used;
auto const gas_cost =
gas_price<traits>(tx_, header_.base_fee_per_gas.value_or(0));
state.subtract_from_balance(sender_, gas_cost * delta);

gas_used = floor_gas;
Expand Down
9 changes: 1 addition & 8 deletions category/execution/ethereum/execute_transaction_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,7 @@ TYPED_TEST(TraitsTest, refunds_delete)
}();
static constexpr auto storage_refund_tx2 = [=] {
if constexpr (TestFixture::is_monad_trait()) {
if constexpr (TestFixture::Trait::monad_rev() >= MONAD_NEXT) {
return 120'000;
}
else if constexpr (TestFixture::Trait::monad_rev() > MONAD_ZERO) {
if constexpr (TestFixture::Trait::monad_rev() > MONAD_ZERO) {
return 0;
}
}
Expand Down Expand Up @@ -593,10 +590,6 @@ TYPED_TEST(TraitsTest, refunds_delete_then_set)
static constexpr auto storage_refund = [=] {
if constexpr (TestFixture::is_monad_trait()) {
if constexpr (
TestFixture::Trait::monad_rev() >= MONAD_NEXT) {
return 2800;
}
else if constexpr (
TestFixture::Trait::monad_rev() > MONAD_ZERO) {
return 0;
}
Expand Down
5 changes: 1 addition & 4 deletions category/execution/ethereum/test/test_monad_chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ TYPED_TEST(MonadTraitsTest, compute_gas_refund)
{
uint64_t const refund = compute_gas_refund<typename TestFixture::Trait>(
Transaction{.gas_limit = 21'000}, 20'000, 1'000);
if constexpr (TestFixture::REV >= MONAD_NEXT) {
EXPECT_EQ(refund, 1'000);
}
else if constexpr (TestFixture::REV >= MONAD_ONE) {
if constexpr (TestFixture::REV >= MONAD_ONE) {
EXPECT_EQ(refund, 0);
}
else {
Expand Down
9 changes: 0 additions & 9 deletions category/execution/ethereum/transaction_gas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,6 @@ uint64_t compute_gas_refund(

EXPLICIT_EVM_TRAITS(compute_gas_refund);

template <Traits traits>
uint256_t
refund_gas_price(Transaction const &tx, uint256_t const &base_fee_per_gas)
{
return gas_price<traits>(tx, base_fee_per_gas);
}

EXPLICIT_EVM_TRAITS(refund_gas_price);

template <Traits traits>
uint256_t calculate_txn_award(
Transaction const &tx, uint256_t const &base_fee_per_gas,
Expand Down
4 changes: 0 additions & 4 deletions category/execution/ethereum/transaction_gas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ template <Traits traits>
uint64_t compute_gas_refund(
Transaction const &, uint64_t gas_remaining, uint64_t refund);

template <Traits traits>
uint256_t
refund_gas_price(Transaction const &, uint256_t const &base_fee_per_gas);

template <Traits traits>
uint256_t calculate_txn_award(
Transaction const &, uint256_t const &base_fee_per_gas,
Expand Down
20 changes: 1 addition & 19 deletions category/execution/monad/monad_transaction_gas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ template <Traits traits>
uint64_t compute_gas_refund(
Transaction const &tx, uint64_t const gas_remaining, uint64_t const refund)
{
if constexpr (traits::monad_rev() >= MONAD_NEXT) {
// Monad specification §4.2: Storage Gas Cost and Refunds
return refund;
}
else if constexpr (traits::monad_rev() >= MONAD_ONE) {
if constexpr (traits::monad_rev() >= MONAD_ONE) {
return 0;
}

Expand All @@ -36,18 +32,4 @@ uint64_t compute_gas_refund(

EXPLICIT_MONAD_TRAITS(compute_gas_refund);

template <Traits traits>
uint256_t
refund_gas_price(Transaction const &tx, uint256_t const &base_fee_per_gas)
{
if constexpr (traits::monad_rev() >= MONAD_NEXT) {
// Monad specification §4.2: Storage Gas Cost and Refunds
return monad_min_base_fee_wei(traits::monad_rev());
}

return gas_price<traits>(tx, base_fee_per_gas);
}

EXPLICIT_MONAD_TRAITS(refund_gas_price);

MONAD_NAMESPACE_END
3 changes: 0 additions & 3 deletions category/execution/monad/monad_transaction_gas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,4 @@ template <Traits traits>
uint64_t compute_gas_refund(
Transaction const &, uint64_t gas_remaining, uint64_t refund);

template <Traits traits>
uint256_t refund_gas_price(Transaction const &, uint256_t const &);

MONAD_NAMESPACE_END
2 changes: 1 addition & 1 deletion category/rpc/eth_call_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ TEST_F(EthCallFixture, contract_deployment_success)
EXPECT_EQ(returned_code_vec, deployed_code_vec);
EXPECT_EQ(ctx.result->encoded_trace_len, 0);
EXPECT_EQ(ctx.result->gas_refund, 0);
EXPECT_EQ(ctx.result->gas_used, 137'137);
EXPECT_EQ(ctx.result->gas_used, 68'137);

monad_state_override_destroy(state_override);
monad_eth_call_executor_destroy(executor);
Expand Down
5 changes: 5 additions & 0 deletions category/vm/evm/explicit_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
f<::monad::MonadTraits<MONAD_FOUR>>; \
template decltype(f<::monad::MonadTraits<MONAD_FIVE>>) \
f<::monad::MonadTraits<MONAD_FIVE>>; \
template decltype(f<::monad::MonadTraits<MONAD_SIX>>) \
f<::monad::MonadTraits<MONAD_SIX>>; \
template decltype(f<::monad::MonadTraits<MONAD_NEXT>>) \
f<::monad::MonadTraits<MONAD_NEXT>>;

Expand Down Expand Up @@ -102,6 +104,7 @@
template class c<::monad::MonadTraits<MONAD_THREE>>; \
template class c<::monad::MonadTraits<MONAD_FOUR>>; \
template class c<::monad::MonadTraits<MONAD_FIVE>>; \
template class c<::monad::MonadTraits<MONAD_SIX>>; \
template class c<::monad::MonadTraits<MONAD_NEXT>>;

#define EXPLICIT_TRAITS_CLASS(c) \
Expand Down Expand Up @@ -167,6 +170,8 @@
id<::monad::MonadTraits<MONAD_FOUR>>; \
template decltype(id<::monad::MonadTraits<MONAD_FIVE>>) \
id<::monad::MonadTraits<MONAD_FIVE>>; \
template decltype(id<::monad::MonadTraits<MONAD_SIX>>) \
id<::monad::MonadTraits<MONAD_SIX>>; \
template decltype(id<::monad::MonadTraits<MONAD_NEXT>>) \
id<::monad::MonadTraits<MONAD_NEXT>>;

Expand Down
5 changes: 4 additions & 1 deletion category/vm/evm/monad/revision.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ enum monad_revision
MONAD_THREE = 3,
MONAD_FOUR = 4,
MONAD_FIVE = 5,
MONAD_NEXT = 6,
MONAD_SIX = 6,
MONAD_NEXT = 7,
MONAD_COUNT,
};

Expand All @@ -47,6 +48,8 @@ inline char const *monad_revision_to_string(enum monad_revision const rev)
return "MONAD_FOUR";
case MONAD_FIVE:
return "MONAD_FIVE";
case MONAD_SIX:
return "MONAD_SIX";
case MONAD_NEXT:
return "MONAD_NEXT";
default:
Expand Down
12 changes: 8 additions & 4 deletions category/vm/evm/opcodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,14 +806,18 @@ namespace monad::vm::compiler
return make_opcode_table<MonadTraits<MONAD_FIVE>::evm_base>();
}

template <>
consteval std::array<OpCodeInfo, 256>
make_opcode_table<MonadTraits<MONAD_SIX>>()
{
return make_opcode_table<MonadTraits<MONAD_SIX>::evm_base>();
}

template <>
consteval std::array<OpCodeInfo, 256>
make_opcode_table<MonadTraits<MONAD_NEXT>>()
{
auto table = make_opcode_table<MonadTraits<MONAD_NEXT>::evm_base>();
table[CREATE].min_gas = 160'000;
table[CREATE2].min_gas = 160'000;
return table;
return make_opcode_table<MonadTraits<MONAD_NEXT>::evm_base>();
}

/**
Expand Down
Loading
Loading