Skip to content

Commit a9f62c4

Browse files
committed
state: Refactor compute_new_account_address() to match 𝐀𝐃𝐃𝐑 from Yellow Paper.
Refactor compute_new_account_address() to match 𝐀𝐃𝐃𝐑 from Yellow Paper. This makes it a separate utility independent of evmc_message.
1 parent f30e4f0 commit a9f62c4

File tree

3 files changed

+48
-61
lines changed

3 files changed

+48
-61
lines changed

β€Žtest/state/host.cpp

+15-14
Original file line numberDiff line numberDiff line change
@@ -110,27 +110,26 @@ bool Host::selfdestruct(const address& addr, const address& beneficiary) noexcep
110110
return !std::exchange(acc.destructed, true);
111111
}
112112

113-
address compute_new_account_address(const evmc_message& msg, uint64_t sender_nonce) noexcept
113+
address compute_new_account_address(const address& sender, uint64_t sender_nonce,
114+
const std::optional<bytes32>& salt, bytes_view init_code) noexcept
114115
{
115116
hash256 addr_base_hash;
116-
if (msg.kind == EVMC_CREATE)
117+
if (!salt.has_value()) // CREATE
117118
{
118119
// TODO: Compute CREATE address without using RLP library.
119-
const auto rlp_list = rlp::encode_tuple(address{msg.sender}, sender_nonce);
120+
const auto rlp_list = rlp::encode_tuple(sender, sender_nonce);
120121
addr_base_hash = keccak256(rlp_list);
121122
}
122-
else
123+
else // CREATE2
123124
{
124-
assert(msg.kind == EVMC_CREATE2);
125-
const auto init_code_hash = keccak256({msg.input_data, msg.input_size});
126-
uint8_t buffer[1 + sizeof(msg.sender) + sizeof(msg.create2_salt) + sizeof(init_code_hash)];
125+
const auto init_code_hash = keccak256(init_code);
126+
uint8_t buffer[1 + sizeof(sender) + sizeof(*salt) + sizeof(init_code_hash)];
127127
static_assert(std::size(buffer) == 85);
128128
buffer[0] = 0xff;
129-
std::copy_n(msg.sender.bytes, sizeof(msg.sender), &buffer[1]);
130-
std::copy_n(
131-
msg.create2_salt.bytes, sizeof(msg.create2_salt), &buffer[1 + sizeof(msg.sender)]);
129+
std::copy_n(sender.bytes, sizeof(sender), &buffer[1]);
130+
std::copy_n(salt->bytes, sizeof(salt->bytes), &buffer[1 + sizeof(sender)]);
132131
std::copy_n(init_code_hash.bytes, sizeof(init_code_hash),
133-
&buffer[1 + sizeof(msg.sender) + sizeof(msg.create2_salt)]);
132+
&buffer[1 + sizeof(sender) + sizeof(salt->bytes)]);
134133
addr_base_hash = keccak256({buffer, std::size(buffer)});
135134
}
136135
evmc_address new_addr{};
@@ -156,7 +155,9 @@ std::optional<evmc_message> Host::prepare_message(evmc_message msg)
156155
// Compute and fill create address.
157156
assert(msg.recipient == address{});
158157
assert(msg.code_address == address{});
159-
msg.recipient = compute_new_account_address(msg, sender_nonce);
158+
msg.recipient = compute_new_account_address(msg.sender, sender_nonce,
159+
(msg.kind == EVMC_CREATE2) ? std::optional{msg.create2_salt} : std::nullopt,
160+
{msg.input_data, msg.input_size});
160161

161162
// By EIP-2929, the access to new created address is never reverted.
162163
access_account(msg.recipient);
@@ -183,8 +184,8 @@ evmc::Result Host::create(const evmc_message& msg) noexcept
183184

184185
// Clear the new account storage, but keep the access status (from tx access list).
185186
// This is only needed for tests and cannot happen in real networks.
186-
for (auto& [_, v] : new_acc.storage)
187-
[[unlikely]] v = StorageValue{.access_status = v.access_status};
187+
for (auto& [_, v] : new_acc.storage) [[unlikely]]
188+
v = StorageValue{.access_status = v.access_status};
188189

189190
auto& sender_acc = m_state.get(msg.sender); // TODO: Duplicated account lookup.
190191
const auto value = intx::be::load<intx::uint256>(msg.value);

β€Žtest/state/host.hpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ inline constexpr size_t max_initcode_size = 2 * max_code_size;
1818
/// Computes the address of to-be-created contract.
1919
///
2020
/// Computes the new account address for the contract creation context
21-
/// as defined by `ADDR()` in Yellow Paper, 7. Contract Creation, (86).
22-
address compute_new_account_address(const evmc_message& msg, uint64_t sender_nonce) noexcept;
21+
/// as defined by 𝐀𝐃𝐃𝐑 in Yellow Paper, 7. Contract Creation, (86).
22+
///
23+
/// @param sender The address of the message sender. YP: 𝑠.
24+
/// @param sender_nonce The sender's nonce before the increase. YP: 𝑛.
25+
/// @param salt The salt for CREATE2. If null, CREATE address is computed. YP: ΞΆ.
26+
/// @param init_code The contract creation init code. Value only affects CREATE2. YP: 𝐒.
27+
/// @return The computed address for CREATE or CREATE2 scheme.
28+
address compute_new_account_address(const address& sender, uint64_t sender_nonce,
29+
const std::optional<bytes32>& salt, bytes_view init_code) noexcept;
2330

2431
class Host : public evmc::Host
2532
{

β€Žtest/unittests/state_new_account_address_test.cpp

+24-45
Original file line numberDiff line numberDiff line change
@@ -18,63 +18,42 @@ inline constexpr bytes32 salts[] = {
1818

1919
TEST(state_new_account_address, create)
2020
{
21-
evmc_message msg{};
22-
msg.kind = EVMC_CREATE;
23-
2421
for (const auto& ic : init_codes) // Init-code doesn't affect CREATE.
2522
{
26-
msg.input_data = ic.data();
27-
msg.input_size = ic.size();
28-
29-
msg.sender = senders[0];
30-
EXPECT_EQ(addr(msg, nonces[0]), 0xbd770416a3345f91e4b34576cb804a576fa48eb1_address);
31-
EXPECT_EQ(addr(msg, nonces[3]), 0x1262d73ea59d3a661bf8751d16cf1a5377149e75_address);
32-
33-
msg.sender = senders[1];
34-
EXPECT_EQ(addr(msg, nonces[0]), 0x522b3294e6d06aa25ad0f1b8891242e335d3b459_address);
35-
EXPECT_EQ(addr(msg, nonces[1]), 0x535b3d7a252fa034ed71f0c53ec0c6f784cb64e1_address);
36-
EXPECT_EQ(addr(msg, nonces[2]), 0x09c1ef8f55c61b94e8b92a55d0891d408a991e18_address);
37-
EXPECT_EQ(addr(msg, nonces[3]), 0x001567239734aeadea21023c2a7c0d9bb9ae4af9_address);
38-
39-
msg.sender = senders[2];
40-
EXPECT_EQ(addr(msg, nonces[0]), 0x3cb1045aee4a06f522ea2b69e4f3d21ed3c135d1_address);
41-
EXPECT_EQ(addr(msg, nonces[3]), 0xe1aa03e4a7b6991d69aff8ece53ceafdf347082e_address);
42-
43-
msg.sender = 0xb20a608c624Ca5003905aA834De7156C68b2E1d0_address;
44-
const auto beacon_deposit_address = addr(msg, 0);
23+
auto s = senders[0];
24+
EXPECT_EQ(addr(s, nonces[0], {}, ic), 0xbd770416a3345f91e4b34576cb804a576fa48eb1_address);
25+
EXPECT_EQ(addr(s, nonces[3], {}, ic), 0x1262d73ea59d3a661bf8751d16cf1a5377149e75_address);
26+
27+
s = senders[1];
28+
EXPECT_EQ(addr(s, nonces[0], {}, ic), 0x522b3294e6d06aa25ad0f1b8891242e335d3b459_address);
29+
EXPECT_EQ(addr(s, nonces[1], {}, ic), 0x535b3d7a252fa034ed71f0c53ec0c6f784cb64e1_address);
30+
EXPECT_EQ(addr(s, nonces[2], {}, ic), 0x09c1ef8f55c61b94e8b92a55d0891d408a991e18_address);
31+
EXPECT_EQ(addr(s, nonces[3], {}, ic), 0x001567239734aeadea21023c2a7c0d9bb9ae4af9_address);
32+
33+
s = senders[2];
34+
EXPECT_EQ(addr(s, nonces[0], {}, ic), 0x3cb1045aee4a06f522ea2b69e4f3d21ed3c135d1_address);
35+
EXPECT_EQ(addr(s, nonces[3], {}, ic), 0xe1aa03e4a7b6991d69aff8ece53ceafdf347082e_address);
36+
37+
const auto beacon_deposit_address =
38+
addr(0xb20a608c624Ca5003905aA834De7156C68b2E1d0_address, 0, {}, ic);
4539
EXPECT_EQ(beacon_deposit_address, 0x00000000219ab540356cbb839cbe05303d7705fa_address);
4640
}
4741
}
4842

4943
TEST(state_new_account_address, create2)
5044
{
51-
evmc_message msg{};
52-
msg.kind = EVMC_CREATE2;
53-
5445
for (const auto n : nonces) // Nonce doesn't affect CREATE2.
5546
{
56-
msg.sender = senders[0];
57-
msg.input_data = init_codes[0].data();
58-
msg.input_size = init_codes[0].size();
59-
msg.create2_salt = salts[0];
60-
EXPECT_EQ(addr(msg, n), 0xe33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0_address);
47+
EXPECT_EQ(addr(senders[0], n, salts[0], init_codes[0]),
48+
0xe33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0_address);
6149

62-
msg.sender = senders[2];
63-
msg.input_data = init_codes[1].data();
64-
msg.input_size = init_codes[1].size();
65-
msg.create2_salt = salts[0];
66-
EXPECT_EQ(addr(msg, n), 0x3517dea701ed18fc4a99dc111c5946e1f1541dad_address);
50+
EXPECT_EQ(addr(senders[2], n, salts[0], init_codes[1]),
51+
0x3517dea701ed18fc4a99dc111c5946e1f1541dad_address);
6752

68-
msg.sender = senders[1];
69-
msg.input_data = init_codes[0].data();
70-
msg.input_size = init_codes[0].size();
71-
msg.create2_salt = salts[1];
72-
EXPECT_EQ(addr(msg, n), 0x7be1c1cb3b8298f21c56add66defce03e2d32604_address);
53+
EXPECT_EQ(addr(senders[1], n, salts[1], init_codes[0]),
54+
0x7be1c1cb3b8298f21c56add66defce03e2d32604_address);
7355

74-
msg.sender = senders[2];
75-
msg.input_data = init_codes[1].data();
76-
msg.input_size = init_codes[1].size();
77-
msg.create2_salt = salts[1];
78-
EXPECT_EQ(addr(msg, n), 0x8f459e65c8f00a9c0c0493de7b0c61c3c27f7384_address);
56+
EXPECT_EQ(addr(senders[2], n, salts[1], init_codes[1]),
57+
0x8f459e65c8f00a9c0c0493de7b0c61c3c27f7384_address);
7958
}
8059
}

0 commit comments

Comments
Β (0)