Skip to content

Commit 9d28979

Browse files
authored
state: Simplify code modification indicator in StateDiff (#1117)
Use `std::optional` to indicate that an account's code has changed in the state diff.
1 parent f9f328b commit 9d28979

File tree

5 files changed

+27
-20
lines changed

5 files changed

+27
-20
lines changed

test/state/account.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ struct Account
7373
/// The account has been created in the current transaction.
7474
bool just_created = false;
7575

76+
// This account's code has been modified.
77+
bool code_changed = false;
78+
7679
evmc_access_status access_status = EVMC_ACCESS_COLD;
7780

7881
[[nodiscard]] bool is_empty() const noexcept

test/state/host.cpp

+19-15
Original file line numberDiff line numberDiff line change
@@ -377,26 +377,30 @@ evmc::Result Host::create(const evmc_message& msg) noexcept
377377
evmc::Result{EVMC_FAILURE};
378378
}
379379

380-
if (!code.empty() && code[0] == 0xEF)
380+
if (!code.empty())
381381
{
382-
if (m_rev >= EVMC_OSAKA)
382+
if (code[0] == 0xEF)
383383
{
384-
// Only EOFCREATE/EOF-creation-tx is allowed to deploy code starting with EF.
385-
// It must be valid EOF, which was validated before execution.
386-
if (msg.kind != EVMC_EOFCREATE)
384+
if (m_rev >= EVMC_OSAKA)
385+
{
386+
// Only EOFCREATE/EOF-creation-tx is allowed to deploy code starting with EF.
387+
// It must be valid EOF, which was validated before execution.
388+
if (msg.kind != EVMC_EOFCREATE)
389+
return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE};
390+
assert(validate_eof(m_rev, ContainerKind::runtime, code) ==
391+
EOFValidationError::success);
392+
}
393+
else if (m_rev >= EVMC_LONDON)
394+
{
395+
// EIP-3541: Reject EF code.
387396
return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE};
388-
assert(
389-
validate_eof(m_rev, ContainerKind::runtime, code) == EOFValidationError::success);
390-
}
391-
else if (m_rev >= EVMC_LONDON)
392-
{
393-
// EIP-3541: Reject EF code.
394-
return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE};
397+
}
395398
}
396-
}
397399

398-
new_acc->code_hash = keccak256(code);
399-
new_acc->code = code;
400+
new_acc->code_hash = keccak256(code);
401+
new_acc->code = code;
402+
new_acc->code_changed = true;
403+
}
400404

401405
return evmc::Result{result.status_code, gas_left, result.gas_refund, msg.recipient};
402406
}

test/state/state.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ StateDiff State::build_diff(evmc_revision rev) const
130130

131131
// Output only the new code.
132132
// TODO: Output also the code hash. It will be needed for DB update and MPT hash.
133-
if (m.just_created && !m.code.empty())
133+
if (m.code_changed)
134134
a.code = m.code;
135135

136136
for (const auto& [k, v] : m.storage)

test/state/state_diff.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ struct StateDiff
3030
/// TODO: Currently it is not guaranteed the value is different from the initial one.
3131
uint256 balance;
3232

33-
/// New account code. If empty, it means the code has not changed.
34-
bytes code;
33+
/// New or modified account code. If bytes are empty, it means the code has been cleared.
34+
std::optional<bytes> code;
3535

3636
/// The list of the account's storage modifications: key => new value.
3737
/// The value 0 means the storage entry is deleted.

test/state/test_state.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ void TestState::apply(const state::StateDiff& diff)
3434
auto& a = (*this)[m.addr];
3535
a.nonce = m.nonce;
3636
a.balance = m.balance;
37-
if (!m.code.empty())
38-
a.code = m.code; // TODO: Consider taking rvalue ref to avoid code copy.
37+
if (m.code.has_value())
38+
a.code = *m.code; // TODO: Consider taking rvalue ref to avoid code copy.
3939
for (const auto& [k, v] : m.modified_storage)
4040
{
4141
if (v)

0 commit comments

Comments
 (0)