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- 
223344TEST (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>{},
0 commit comments