Skip to content

Commit 6162fdc

Browse files
switch test_db tests to TraitsTest
1 parent 18f3edd commit 6162fdc

File tree

2 files changed

+219
-39
lines changed

2 files changed

+219
-39
lines changed

category/execution/ethereum/db/test/test_db.cpp

Lines changed: 188 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <category/mpt/traverse.hpp>
4444
#include <category/mpt/traverse_util.hpp>
4545
#include <category/vm/evm/traits.hpp>
46+
#include <monad/test/traits_test.hpp>
4647

4748
#include <ethash/keccak.hpp>
4849
#include <evmc/evmc.hpp>
@@ -108,24 +109,152 @@ namespace
108109
}
109110
};
110111

111-
struct InMemoryTrieDbFixture : public ::testing::Test
112+
template <typename T, T rev>
113+
struct TrieDbFixtureTraits : public ::testing::Test
114+
{
115+
vm::VM vm;
116+
117+
static constexpr auto get_trait()
118+
{
119+
if constexpr (std::same_as<T, monad_revision>) {
120+
return monad::MonadTraits<rev>{};
121+
}
122+
else if constexpr (std::same_as<T, evmc_revision>) {
123+
return monad::EvmTraits<rev>{};
124+
}
125+
else {
126+
return std::monostate{};
127+
}
128+
}
129+
130+
using Trait = decltype(get_trait());
131+
132+
static consteval bool is_monad_revision() noexcept
133+
{
134+
return std::same_as<T, monad_revision>;
135+
}
136+
137+
static consteval bool is_evmc_revision() noexcept
138+
{
139+
return std::same_as<T, evmc_revision>;
140+
}
141+
142+
static constexpr std::string get_traits_name()
143+
{
144+
if constexpr (std::same_as<T, monad_revision>) {
145+
return "/" + std::string(monad_revision_to_string(
146+
monad::MonadTraits<rev>::monad_rev()));
147+
}
148+
else if constexpr (std::same_as<T, evmc_revision>) {
149+
return "/" + std::string(evmc_revision_to_string(
150+
monad::EvmTraits<rev>::evm_rev()));
151+
}
152+
else {
153+
return "";
154+
}
155+
}
156+
};
157+
158+
template <typename T, T rev>
159+
struct InMemoryTrieDbFixtureTraits : public TrieDbFixtureTraits<T, rev>
112160
{
113161
static constexpr bool on_disk = false;
114162

115163
InMemoryMachine machine;
116164
mpt::Db db{machine};
117-
vm::VM vm;
165+
166+
static constexpr auto get_name()
167+
{
168+
return "InMemoryTrieDbFixture" +
169+
TrieDbFixtureTraits<T, rev>::get_traits_name();
170+
}
118171
};
119172

120-
struct OnDiskTrieDbFixture : public ::testing::Test
173+
template <monad_revision rev>
174+
using MonadInMemoryTrieDbFixtureTraits =
175+
InMemoryTrieDbFixtureTraits<monad_revision, rev>;
176+
177+
template <evmc_revision rev>
178+
using EvmInMemoryTrieDbFixtureTraits =
179+
InMemoryTrieDbFixtureTraits<evmc_revision, rev>;
180+
181+
template <typename T, T rev>
182+
struct OnDiskTrieDbFixtureTraits : public TrieDbFixtureTraits<T, rev>
121183
{
122184
static constexpr bool on_disk = true;
123185

124186
OnDiskMachine machine;
125187
mpt::Db db{machine, mpt::OnDiskDbConfig{}};
126-
vm::VM vm;
188+
189+
static constexpr auto get_name()
190+
{
191+
return "OnDiskTrieDbFixture" +
192+
TrieDbFixtureTraits<T, rev>::get_traits_name();
193+
}
194+
};
195+
196+
template <monad_revision rev>
197+
using MonadOnDiskTrieDbFixtureTraits =
198+
OnDiskTrieDbFixtureTraits<monad_revision, rev>;
199+
200+
template <evmc_revision rev>
201+
using EvmOnDiskTrieDbFixtureTraits =
202+
OnDiskTrieDbFixtureTraits<evmc_revision, rev>;
203+
204+
// Helper to concatenate four ::testing::Types
205+
template <typename... Ts>
206+
struct concat_types;
207+
208+
template <
209+
typename... Ts1, typename... Ts2, typename... Ts3, typename... Ts4>
210+
struct concat_types<
211+
::testing::Types<Ts1...>, ::testing::Types<Ts2...>,
212+
::testing::Types<Ts3...>, ::testing::Types<Ts4...>>
213+
{
214+
using type = ::testing::Types<Ts1..., Ts2..., Ts3..., Ts4...>;
215+
};
216+
217+
template <typename... Ts>
218+
using concat_types_t = typename concat_types<Ts...>::type;
219+
220+
// Union of MonadRevisionTypes and EvmRevisionTypes for both InMemoryTrieDb
221+
// and OnDiskTrieDb
222+
using MonadEvmRevisionDBTypes = concat_types_t<
223+
decltype(make_monad_revision_types<MonadInMemoryTrieDbFixtureTraits>()),
224+
decltype(make_evm_revision_types<EvmInMemoryTrieDbFixtureTraits>()),
225+
decltype(make_monad_revision_types<MonadOnDiskTrieDbFixtureTraits>()),
226+
decltype(make_evm_revision_types<EvmOnDiskTrieDbFixtureTraits>())>;
227+
228+
struct RevisionTestNameGenerator
229+
{
230+
template <typename T>
231+
static std::string GetName(int)
232+
{
233+
return T::get_name();
234+
}
235+
};
236+
237+
using InMemoryTrieDbFixture =
238+
InMemoryTrieDbFixtureTraits<std::monostate, {}>;
239+
using OnDiskTrieDbFixture = OnDiskTrieDbFixtureTraits<std::monostate, {}>;
240+
241+
template <typename TDB>
242+
struct DBTest : public TDB
243+
{
244+
};
245+
246+
using DBTypes =
247+
::testing::Types<InMemoryTrieDbFixture, OnDiskTrieDbFixture>;
248+
TYPED_TEST_SUITE(DBTest, DBTypes, RevisionTestNameGenerator);
249+
250+
template <typename TDB>
251+
struct DBTraitsTest : public TDB
252+
{
127253
};
128254

255+
TYPED_TEST_SUITE(
256+
DBTraitsTest, MonadEvmRevisionDBTypes, RevisionTestNameGenerator);
257+
129258
///////////////////////////////////////////
130259
// DB Getters
131260
///////////////////////////////////////////
@@ -212,14 +341,6 @@ namespace
212341
}
213342
}
214343

215-
template <typename TDB>
216-
struct DBTest : public TDB
217-
{
218-
};
219-
220-
using DBTypes = ::testing::Types<InMemoryTrieDbFixture, OnDiskTrieDbFixture>;
221-
TYPED_TEST_SUITE(DBTest, DBTypes);
222-
223344
TEST(DBTest, read_only)
224345
{
225346
auto const name =
@@ -886,7 +1007,7 @@ TYPED_TEST(DBTest, commit_call_frames)
8861007

8871008
// test referenced from :
8881009
// https://github.com/ethereum/tests/blob/develop/BlockchainTests/GeneralStateTests/stQuadraticComplexityTest/Call50000.json
889-
TYPED_TEST(DBTest, call_frames_stress_test)
1010+
TYPED_TEST(DBTraitsTest, call_frames_stress_test)
8901011
{
8911012
using namespace intx;
8921013

@@ -959,7 +1080,7 @@ TYPED_TEST(DBTest, call_frames_stress_test)
9591080
std::make_unique<trace::StateTracer>(std::monostate{}));
9601081
}
9611082

962-
auto const receipts = execute_block<EvmTraits<EVMC_SHANGHAI>>(
1083+
auto const receipts = execute_block<typename TestFixture::Trait>(
9631084
EthereumMainnet{},
9641085
block.value(),
9651086
senders,
@@ -993,11 +1114,23 @@ TYPED_TEST(DBTest, call_frames_stress_test)
9931114
auto const actual_call_frames =
9941115
read_call_frame(this->db, tdb.get_block_number(), 0);
9951116

996-
EXPECT_EQ(actual_call_frames.size(), 35799);
1117+
if constexpr (TestFixture::is_monad_revision()) {
1118+
if constexpr (TestFixture::Trait::monad_rev() >= MONAD_FIVE) {
1119+
EXPECT_EQ(actual_call_frames.size(), 35781);
1120+
}
1121+
else {
1122+
EXPECT_EQ(actual_call_frames.size(), 35799);
1123+
}
1124+
}
1125+
else {
1126+
if constexpr (TestFixture::Trait::evm_rev() >= EVMC_BERLIN) {
1127+
EXPECT_EQ(actual_call_frames.size(), 35799);
1128+
}
1129+
}
9971130
}
9981131

999-
// This test is based on the test `DBTest.call_frames_stress_test`
1000-
TYPED_TEST(DBTest, assertion_exception)
1132+
// This test is based on the test `DBTraitsTest.call_frames_stress_test`
1133+
TYPED_TEST(DBTraitsTest, assertion_exception)
10011134
{
10021135
using namespace intx;
10031136

@@ -1024,7 +1157,7 @@ TYPED_TEST(DBTest, assertion_exception)
10241157
Account{
10251158
.balance = std::numeric_limits<uint256_t>::max(),
10261159
.code_hash = STRESS_TEST_CODE_HASH}}}}},
1027-
Code{},
1160+
Code{{STRESS_TEST_CODE_HASH, STRESS_TEST_ICODE}},
10281161
BlockHeader{.number = 0});
10291162

10301163
// clang-format off
@@ -1067,7 +1200,7 @@ TYPED_TEST(DBTest, assertion_exception)
10671200

10681201
EXPECT_THROW(
10691202
{
1070-
(void)execute_block<EvmTraits<EVMC_SHANGHAI>>(
1203+
(void)execute_block<typename TestFixture::Trait>(
10711204
EthereumMainnet{},
10721205
block.value(),
10731206
senders,
@@ -1084,7 +1217,7 @@ TYPED_TEST(DBTest, assertion_exception)
10841217

10851218
// test referenced from :
10861219
// https://github.com/ethereum/tests/blob/v10.0/BlockchainTests/GeneralStateTests/stRefundTest/refund50_1.json
1087-
TYPED_TEST(DBTest, call_frames_refund)
1220+
TYPED_TEST(DBTraitsTest, call_frames_refund)
10881221
{
10891222
TrieDb tdb{this->db};
10901223

@@ -1165,8 +1298,8 @@ TYPED_TEST(DBTest, call_frames_refund)
11651298
std::make_unique<trace::StateTracer>(std::monostate{}));
11661299
}
11671300

1168-
auto const receipts = execute_block<EvmTraits<EVMC_SHANGHAI>>(
1169-
ShanghaiEthereumMainnet{},
1301+
auto const receipts = execute_block<typename TestFixture::Trait>(
1302+
EthereumMainnet{},
11701303
block.value(),
11711304
senders,
11721305
recovered_authorities,
@@ -1200,14 +1333,46 @@ TYPED_TEST(DBTest, call_frames_refund)
12001333
read_call_frame(this->db, tdb.get_block_number(), 0);
12011334

12021335
ASSERT_EQ(actual_call_frames.size(), 1);
1336+
1337+
uint64_t const gas_used = [] {
1338+
if constexpr (TestFixture::is_evmc_revision()) {
1339+
if constexpr (TestFixture::Trait::evm_rev() <= EVMC_BERLIN) {
1340+
// value from
1341+
// https://github.com/ethereum/legacytests/blob/1f581b8ccdc4c63acf5f2c5c1b155c690c32a8eb/src/LegacyTests/Constantinople/BlockchainTestsFiller/GeneralStateTests/stRefundTest/refund50_1_d0g0v0Filler.json
1342+
// pre.0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b.balance -
1343+
// expect[0].0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b.balance
1344+
return static_cast<uint64_t>(0x186a0 - 0x012cb9);
1345+
}
1346+
else {
1347+
// value from
1348+
// https://github.com/ethereum/execution-specs/blob/v2.18.0rc5.dev1/tests/eest/static/state_tests/stRefundTest/refund50_1Filler.json
1349+
// (expect[0].result.<eoa:sender:0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b>.balance
1350+
// -
1351+
// pre.<eoa:sender:0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b>.balance)
1352+
// / transaction.gasPrice
1353+
return static_cast<uint64_t>((10'000'000 - 9'631'760) / 10);
1354+
}
1355+
}
1356+
else {
1357+
if constexpr (TestFixture::Trait::monad_rev() > MONAD_ZERO) {
1358+
// full gas_limit is charged since >=MONAD_ONE
1359+
return 0x186a0;
1360+
}
1361+
else {
1362+
static_assert(TestFixture::Trait::evm_rev() > EVMC_BERLIN);
1363+
// same cost as >EVMC_BERLIN
1364+
return static_cast<uint64_t>((10'000'000 - 9'631'760) / 10);
1365+
}
1366+
}
1367+
}();
12031368
CallFrame expected{
12041369
.type = CallType::CALL,
12051370
.flags = 0,
12061371
.from = from,
12071372
.to = ca,
12081373
.value = 0,
12091374
.gas = 0x186a0,
1210-
.gas_used = 0x8fd8,
1375+
.gas_used = gas_used,
12111376
.status = EVMC_SUCCESS,
12121377
.depth = 0,
12131378
.logs = std::vector<CallFrame::Log>{},

test/unit/common/include/monad/test/traits_test.hpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,47 @@
2727

2828
namespace detail
2929
{
30-
template <monad_revision rev>
31-
using MonadRevisionConstant = std::integral_constant<monad_revision, rev>;
32-
33-
template <evmc_revision rev>
34-
using EvmRevisionConstant = std::integral_constant<evmc_revision, rev>;
35-
36-
template <std::size_t... Is>
30+
template <template <auto> class T, std::size_t... Is>
3731
constexpr auto make_monad_revision_types(std::index_sequence<Is...>)
3832
{
39-
return ::testing::Types<
40-
MonadRevisionConstant<static_cast<monad_revision>(Is)>...>{};
33+
return ::testing::Types<T<static_cast<monad_revision>(Is)>...>{};
4134
}
4235

43-
template <std::size_t... Is>
36+
template <template <auto> class T, std::size_t... Is>
4437
constexpr auto make_evm_revision_types(std::index_sequence<Is...>)
4538
{
46-
return ::testing::Types<
47-
EvmRevisionConstant<static_cast<evmc_revision>(Is)>...>{};
39+
return ::testing::Types<T<static_cast<evmc_revision>(Is)>...>{};
4840
}
41+
}
4942

50-
using MonadRevisionTypes = decltype(make_monad_revision_types(
51-
std::make_index_sequence<MONAD_COUNT>{}));
43+
template <template <auto> class T>
44+
constexpr auto make_monad_revision_types()
45+
{
46+
return ::detail::make_monad_revision_types<T>(
47+
std::make_index_sequence<MONAD_COUNT>{});
48+
}
5249

50+
template <template <auto> class T>
51+
constexpr auto make_evm_revision_types()
52+
{
5353
// Skip over EVMC_REVISION which is EVMC_EXPERIMENTAL
54-
using EvmRevisionTypes = decltype(make_evm_revision_types(
55-
std::make_index_sequence<EVMC_MAX_REVISION>{}));
54+
return ::detail::make_evm_revision_types<T>(
55+
std::make_index_sequence<EVMC_MAX_REVISION>{});
56+
}
57+
58+
namespace detail
59+
{
60+
template <monad_revision rev>
61+
using MonadRevisionConstant = std::integral_constant<monad_revision, rev>;
62+
63+
template <evmc_revision rev>
64+
using EvmRevisionConstant = std::integral_constant<evmc_revision, rev>;
65+
66+
using MonadRevisionTypes =
67+
decltype(::make_monad_revision_types<MonadRevisionConstant>());
68+
69+
using EvmRevisionTypes =
70+
decltype(::make_evm_revision_types<EvmRevisionConstant>());
5671

5772
// Helper to concatenate two ::testing::Types
5873
template <typename... Ts>

0 commit comments

Comments
 (0)