Skip to content

Commit 6f18e82

Browse files
committed
test: Add EIP-2929 unit tests
1 parent 6fdeba8 commit 6f18e82

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed

test/unittests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_executable(evmone-unittests
1313
evm_fixture.hpp
1414
evm_test.cpp
1515
evm_calls_test.cpp
16+
evm_eip2929_test.cpp
1617
evm_state_test.cpp
1718
evm_other_test.cpp
1819
evmone_test.cpp

test/unittests/evm_eip2929_test.cpp

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
// evmone: Fast Ethereum Virtual Machine implementation
2+
// Copyright 2021 The evmone Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
/// This file contains EVM unit tests for EIP-2929 "Gas cost increases for state access opcodes"
6+
/// https://eips.ethereum.org/EIPS/eip-2929
7+
8+
#include "evm_fixture.hpp"
9+
10+
using namespace evmc::literals;
11+
using evmone::test::evm;
12+
13+
TEST_P(evm, eip2929_case1)
14+
{
15+
// https://gist.github.com/holiman/174548cad102096858583c6fbbb0649a#case-1
16+
rev = EVMC_BERLIN;
17+
msg.sender = 0x0000000000000000000000000000000000000000_address;
18+
msg.destination = 0x000000000000000000000000636F6E7472616374_address;
19+
const auto code =
20+
"0x60013f5060023b506003315060f13f5060f23b5060f3315060f23f5060f33b5060f1315032315030315000";
21+
22+
execute(code);
23+
EXPECT_GAS_USED(EVMC_SUCCESS, 8653);
24+
EXPECT_EQ(result.output_size, 0);
25+
26+
const auto& r = host.recorded_account_accesses;
27+
ASSERT_EQ(r.size(), 24);
28+
EXPECT_EQ(r[0], msg.sender);
29+
EXPECT_EQ(r[1], msg.destination);
30+
EXPECT_EQ(r[2], 0x0000000000000000000000000000000000000001_address);
31+
EXPECT_EQ(r[3], 0x0000000000000000000000000000000000000001_address);
32+
EXPECT_EQ(r[4], 0x0000000000000000000000000000000000000002_address);
33+
EXPECT_EQ(r[5], 0x0000000000000000000000000000000000000002_address);
34+
EXPECT_EQ(r[6], 0x0000000000000000000000000000000000000003_address);
35+
EXPECT_EQ(r[7], 0x0000000000000000000000000000000000000003_address);
36+
EXPECT_EQ(r[8], 0x00000000000000000000000000000000000000f1_address);
37+
EXPECT_EQ(r[9], 0x00000000000000000000000000000000000000f1_address);
38+
EXPECT_EQ(r[10], 0x00000000000000000000000000000000000000f2_address);
39+
EXPECT_EQ(r[11], 0x00000000000000000000000000000000000000f2_address);
40+
EXPECT_EQ(r[12], 0x00000000000000000000000000000000000000f3_address);
41+
EXPECT_EQ(r[13], 0x00000000000000000000000000000000000000f3_address);
42+
EXPECT_EQ(r[14], 0x00000000000000000000000000000000000000f2_address);
43+
EXPECT_EQ(r[15], 0x00000000000000000000000000000000000000f2_address);
44+
EXPECT_EQ(r[16], 0x00000000000000000000000000000000000000f3_address);
45+
EXPECT_EQ(r[17], 0x00000000000000000000000000000000000000f3_address);
46+
EXPECT_EQ(r[18], 0x00000000000000000000000000000000000000f1_address);
47+
EXPECT_EQ(r[19], 0x00000000000000000000000000000000000000f1_address);
48+
EXPECT_EQ(r[20], 0x0000000000000000000000000000000000000000_address);
49+
EXPECT_EQ(r[21], 0x0000000000000000000000000000000000000000_address);
50+
EXPECT_EQ(r[22], msg.destination);
51+
EXPECT_EQ(r[23], msg.destination);
52+
}
53+
54+
TEST_P(evm, eip2929_case2)
55+
{
56+
// https://gist.github.com/holiman/174548cad102096858583c6fbbb0649a#case-2
57+
rev = EVMC_BERLIN;
58+
msg.sender = 0x0000000000000000000000000000000000000000_address;
59+
msg.destination = 0x000000000000000000000000636F6E7472616374_address;
60+
const auto code = "0x60006000600060ff3c60006000600060ff3c600060006000303c00";
61+
62+
execute(code);
63+
EXPECT_GAS_USED(EVMC_SUCCESS, 2835);
64+
EXPECT_EQ(result.output_size, 0);
65+
66+
const auto& r = host.recorded_account_accesses;
67+
ASSERT_EQ(r.size(), 8);
68+
EXPECT_EQ(r[0], msg.sender);
69+
EXPECT_EQ(r[1], msg.destination);
70+
EXPECT_EQ(r[2], 0x00000000000000000000000000000000000000ff_address);
71+
EXPECT_EQ(r[3], 0x00000000000000000000000000000000000000ff_address);
72+
EXPECT_EQ(r[4], 0x00000000000000000000000000000000000000ff_address);
73+
EXPECT_EQ(r[5], 0x00000000000000000000000000000000000000ff_address);
74+
EXPECT_EQ(r[6], msg.destination);
75+
EXPECT_EQ(r[7], msg.destination);
76+
}
77+
78+
TEST_P(evm, eip2929_case3)
79+
{
80+
// https://gist.github.com/holiman/174548cad102096858583c6fbbb0649a#case-3
81+
rev = EVMC_BERLIN;
82+
msg.sender = 0x0000000000000000000000000000000000000000_address;
83+
msg.destination = 0x000000000000000000000000636F6E7472616374_address;
84+
const auto code = "0x60015450601160015560116002556011600255600254600154";
85+
86+
execute(code);
87+
EXPECT_GAS_USED(EVMC_SUCCESS, 44529);
88+
EXPECT_EQ(result.output_size, 0);
89+
}
90+
91+
TEST_P(evm, eip2929_case4)
92+
{
93+
// https://gist.github.com/holiman/174548cad102096858583c6fbbb0649a#case-4
94+
rev = EVMC_BERLIN;
95+
msg.sender = 0x0000000000000000000000000000000000000000_address;
96+
msg.destination = 0x000000000000000000000000636F6E7472616374_address;
97+
const auto code = "0x60008080808060046000f15060008080808060ff6000f15060008080808060ff6000fa50";
98+
99+
execute(code);
100+
EXPECT_GAS_USED(EVMC_SUCCESS, 2869);
101+
EXPECT_EQ(result.output_size, 0);
102+
}
103+
104+
TEST_P(evm, eip2929_balance_oog)
105+
{
106+
rev = EVMC_BERLIN;
107+
const auto code = push(0x0a) + OP_BALANCE;
108+
109+
execute(2603, code);
110+
EXPECT_GAS_USED(EVMC_SUCCESS, 2603);
111+
112+
host.recorded_account_accesses.clear();
113+
execute(2602, code);
114+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 2602);
115+
}
116+
117+
TEST_P(evm, eip2929_extcodesize_oog)
118+
{
119+
rev = EVMC_BERLIN;
120+
const auto code = push(0x0a) + OP_EXTCODESIZE;
121+
122+
execute(2603, code);
123+
EXPECT_GAS_USED(EVMC_SUCCESS, 2603);
124+
125+
host.recorded_account_accesses.clear();
126+
execute(2602, code);
127+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 2602);
128+
}
129+
130+
TEST_P(evm, eip2929_extcodecopy_oog)
131+
{
132+
rev = EVMC_BERLIN;
133+
const auto code = push(0) + OP_DUP1 + OP_DUP1 + push(0x0a) + OP_EXTCODECOPY;
134+
135+
execute(2612, code);
136+
EXPECT_GAS_USED(EVMC_SUCCESS, 2612);
137+
138+
host.recorded_account_accesses.clear();
139+
execute(2611, code);
140+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 2611);
141+
}
142+
143+
TEST_P(evm, eip2929_extcodehash_oog)
144+
{
145+
rev = EVMC_BERLIN;
146+
const auto code = push(0x0a) + OP_EXTCODEHASH;
147+
148+
execute(2603, code);
149+
EXPECT_GAS_USED(EVMC_SUCCESS, 2603);
150+
151+
host.recorded_account_accesses.clear();
152+
execute(2602, code);
153+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 2602);
154+
}
155+
156+
TEST_P(evm, eip2929_sload_cold)
157+
{
158+
rev = EVMC_BERLIN;
159+
const auto code = push(1) + OP_SLOAD;
160+
161+
const evmc::bytes32 key{1};
162+
host.accounts[msg.destination].storage[key] = evmc::bytes32{2};
163+
ASSERT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_COLD);
164+
execute(2103, code);
165+
EXPECT_GAS_USED(EVMC_SUCCESS, 2103);
166+
EXPECT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_WARM);
167+
168+
host.accounts[msg.destination].storage[key].access_status = EVMC_ACCESS_COLD;
169+
execute(2102, code);
170+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 2102);
171+
}
172+
173+
TEST_P(evm, eip2929_sload_warm)
174+
{
175+
rev = EVMC_BERLIN;
176+
const auto code = push(1) + OP_SLOAD;
177+
178+
const evmc::bytes32 key{1};
179+
host.accounts[msg.destination].storage[key] = {evmc::bytes32{2}, EVMC_ACCESS_WARM};
180+
ASSERT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_WARM);
181+
execute(103, code);
182+
EXPECT_GAS_USED(EVMC_SUCCESS, 103);
183+
EXPECT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_WARM);
184+
185+
execute(102, code);
186+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 102);
187+
}
188+
189+
TEST_P(evm, eip2929_sstore_modify_cold)
190+
{
191+
rev = EVMC_BERLIN;
192+
const auto code = sstore(1, 3);
193+
194+
const evmc::bytes32 key{1};
195+
host.accounts[msg.destination].storage[key] = evmc::bytes32{2};
196+
execute(5006, code);
197+
EXPECT_GAS_USED(EVMC_SUCCESS, 5006);
198+
EXPECT_EQ(host.accounts[msg.destination].storage[key].value, evmc::bytes32{3});
199+
EXPECT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_WARM);
200+
201+
host.accounts[msg.destination].storage[key] = evmc::bytes32{2};
202+
execute(5005, code);
203+
EXPECT_GAS_USED(EVMC_OUT_OF_GAS, 5005);
204+
// The storage will be modified anyway, because the cost is checked after.
205+
EXPECT_EQ(host.accounts[msg.destination].storage[key].value, evmc::bytes32{3});
206+
EXPECT_EQ(host.accounts[msg.destination].storage[key].access_status, EVMC_ACCESS_WARM);
207+
}

test/unittests/evm_fixture.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ class evm : public testing::TestWithParam<evmc::VM*>
7272
msg.input_size = input.size();
7373
msg.gas = gas;
7474

75+
if (rev >= EVMC_BERLIN) // Add EIP-2929 tweak.
76+
{
77+
host.access_account(msg.sender);
78+
host.access_account(msg.destination);
79+
}
80+
7581
result = vm.execute(host, rev, msg, code.data(), code.size());
7682
output = {result.output_data, result.output_size};
7783
gas_used = msg.gas - result.gas_left;

0 commit comments

Comments
 (0)