Skip to content

Commit

Permalink
host: Don't assume the sender account exists (#731)
Browse files Browse the repository at this point in the history
This change is basically refactoring with the goal not to access
the call sender's account unnecessary.
  • Loading branch information
chfast authored Nov 23, 2023
1 parent 9e9681d commit 0bcf0c5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 22 deletions.
44 changes: 23 additions & 21 deletions test/state/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,28 +140,29 @@ address compute_new_account_address(const address& sender, uint64_t sender_nonce

std::optional<evmc_message> Host::prepare_message(evmc_message msg)
{
auto& sender_acc = m_state.get(msg.sender);
const auto sender_nonce = sender_acc.nonce;

// Bump sender nonce.
if (msg.depth == 0 || msg.kind == EVMC_CREATE || msg.kind == EVMC_CREATE2)
{
if (sender_nonce == Account::NonceMax)
return {}; // Light early exception, cannot happen for depth == 0.
++sender_acc.nonce;
}
auto& sender_acc = m_state.get(msg.sender);
const auto sender_nonce = sender_acc.nonce;

if (msg.kind == EVMC_CREATE || msg.kind == EVMC_CREATE2)
{
// Compute and fill create address.
assert(msg.recipient == address{});
assert(msg.code_address == address{});
msg.recipient = compute_new_account_address(msg.sender, sender_nonce,
(msg.kind == EVMC_CREATE2) ? std::optional{msg.create2_salt} : std::nullopt,
{msg.input_data, msg.input_size});

// By EIP-2929, the access to new created address is never reverted.
access_account(msg.recipient);
// EIP-2681 (already checked for depth 0 during transaction validation).
if (sender_nonce == Account::NonceMax)
return {}; // Light early exception.

++sender_acc.nonce; // Bump sender nonce.

if (msg.kind == EVMC_CREATE || msg.kind == EVMC_CREATE2)
{
// Compute and set the address of the account being created.
assert(msg.recipient == address{});
assert(msg.code_address == address{});
msg.recipient = compute_new_account_address(msg.sender, sender_nonce,
(msg.kind == EVMC_CREATE2) ? std::optional{msg.create2_salt} : std::nullopt,
{msg.input_data, msg.input_size});

// By EIP-2929, the access to new created address is never reverted.
access_account(msg.recipient);
}
}

return msg;
Expand Down Expand Up @@ -252,9 +253,10 @@ evmc::Result Host::execute_message(const evmc_message& msg) noexcept
auto* const dst_acc =
(msg.kind == EVMC_CALL) ? &m_state.touch(msg.recipient) : m_state.find(msg.code_address);

if (msg.kind == EVMC_CALL)
if (msg.kind == EVMC_CALL && !evmc::is_zero(msg.value))
{
// Transfer value.
// Transfer value: sender → recipient.
// The sender's balance is already checked therefore the sender account must exist.
const auto value = intx::be::load<intx::uint256>(msg.value);
assert(m_state.get(msg.sender).balance >= value);
m_state.get(msg.sender).balance -= value;
Expand Down
2 changes: 1 addition & 1 deletion test/state/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ std::variant<int64_t, std::error_code> validate_transaction(const Account& sende
if (!sender_acc.code.empty())
return make_error_code(SENDER_NOT_EOA); // Origin must not be a contract (EIP-3607).

if (sender_acc.nonce == Account::NonceMax)
if (sender_acc.nonce == Account::NonceMax) // Nonce value limit (EIP-2681).
return make_error_code(NONCE_HAS_MAX_VALUE);

if (sender_acc.nonce < tx.nonce)
Expand Down
12 changes: 12 additions & 0 deletions test/unittests/state_transition_create_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,15 @@ TEST_F(state_transition, create_tx)

expect.post[create_address].code = bytes{0xFE};
}

TEST_F(state_transition, create2_max_nonce)
{
// The address to be created by CREATE2 of the "To" sender and empty initcode.
static constexpr auto create_address = 0x36fd63ce1cb5ee2993f19d1fae4e84d52f6f1595_address;

tx.to = To;
pre.insert(*tx.to, {.nonce = ~uint64_t{0}, .code = create2()});

expect.post[*tx.to].nonce = pre.get(*tx.to).nonce; // Nonce is unchanged.
expect.post[create_address].exists = false;
}

0 comments on commit 0bcf0c5

Please sign in to comment.