|
8 | 8 | #include <chainparams.h> |
9 | 9 | #include <consensus/validation.h> |
10 | 10 | #include <deploymentstatus.h> |
| 11 | +#include <evo/deterministicmns.h> |
| 12 | +#include <evo/providertx.h> |
| 13 | +#include <evo/simplifiedmns.h> |
| 14 | +#include <evo/specialtx.h> |
| 15 | +#include <llmq/context.h> |
| 16 | +#include <llmq/instantsend.h> |
11 | 17 | #include <messagesigner.h> |
12 | 18 | #include <netbase.h> |
13 | 19 | #include <node/transaction.h> |
|
20 | 26 | #include <txmempool.h> |
21 | 27 | #include <validation.h> |
22 | 28 |
|
23 | | -#include <evo/deterministicmns.h> |
24 | | -#include <evo/providertx.h> |
25 | | -#include <evo/specialtx.h> |
26 | | -#include <llmq/context.h> |
27 | | -#include <llmq/instantsend.h> |
28 | | - |
29 | 29 | #include <boost/test/unit_test.hpp> |
30 | 30 |
|
| 31 | +#include <vector> |
| 32 | + |
31 | 33 | using node::GetTransaction; |
32 | 34 |
|
33 | 35 | using SimpleUTXOMap = std::map<COutPoint, std::pair<int, CAmount>>; |
@@ -836,6 +838,97 @@ void FuncVerifyDB(TestChainSetup& setup) |
836 | 838 | chainman.ActiveChainstate().CoinsTip(), *(setup.m_node.evodb), 4, 2)); |
837 | 839 | } |
838 | 840 |
|
| 841 | +static CDeterministicMNCPtr create_mock_mn(uint64_t internal_id) |
| 842 | +{ |
| 843 | + // Create a mock MN |
| 844 | + CKey ownerKey; |
| 845 | + ownerKey.MakeNewKey(true); |
| 846 | + CBLSSecretKey operatorKey; |
| 847 | + operatorKey.MakeNewKey(); |
| 848 | + |
| 849 | + auto dmnState = std::make_shared<CDeterministicMNState>(); |
| 850 | + dmnState->confirmedHash = GetRandHash(); |
| 851 | + dmnState->keyIDOwner = ownerKey.GetPubKey().GetID(); |
| 852 | + dmnState->pubKeyOperator.Set(operatorKey.GetPublicKey(), bls::bls_legacy_scheme.load()); |
| 853 | + dmnState->keyIDVoting = ownerKey.GetPubKey().GetID(); |
| 854 | + dmnState->netInfo = NetInfoInterface::MakeNetInfo(ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false)); |
| 855 | + BOOST_CHECK_EQUAL(dmnState->netInfo->AddEntry("1.1.1.1:1"), NetInfoStatus::Success); |
| 856 | + |
| 857 | + auto dmn = std::make_shared<CDeterministicMN>(internal_id, MnType::Regular); |
| 858 | + dmn->proTxHash = GetRandHash(); |
| 859 | + dmn->collateralOutpoint = COutPoint(GetRandHash(), 0); |
| 860 | + dmn->nOperatorReward = 0; |
| 861 | + dmn->pdmnState = dmnState; |
| 862 | + |
| 863 | + return dmn; |
| 864 | +} |
| 865 | + |
| 866 | +static void SmlCache(TestChainSetup& setup) |
| 867 | +{ |
| 868 | + BOOST_CHECK(setup.m_node.dmnman != nullptr); |
| 869 | + |
| 870 | + // Create empty list and verify SML cache |
| 871 | + CDeterministicMNList emptyList(uint256(), 0, 0); |
| 872 | + auto sml_empty = emptyList.to_sml(); |
| 873 | + |
| 874 | + // Should return the same cached object |
| 875 | + BOOST_CHECK(sml_empty == emptyList.to_sml()); |
| 876 | + |
| 877 | + // Should contain empty list |
| 878 | + BOOST_CHECK_EQUAL(sml_empty->mnList.size(), 0); |
| 879 | + |
| 880 | + // Copy list should return the same cached object |
| 881 | + CDeterministicMNList mn_list_1(emptyList); |
| 882 | + BOOST_CHECK(sml_empty == mn_list_1.to_sml()); |
| 883 | + |
| 884 | + // Assigning list should return the same cached object |
| 885 | + CDeterministicMNList mn_list_2 = emptyList; |
| 886 | + BOOST_CHECK(sml_empty == mn_list_2.to_sml()); |
| 887 | + |
| 888 | + auto dmn = create_mock_mn(1); |
| 889 | + |
| 890 | + // Add MN - should invalidate cache |
| 891 | + mn_list_1.AddMN(dmn, true); |
| 892 | + auto sml_add = mn_list_1.to_sml(); |
| 893 | + |
| 894 | + // Cache should be invalidated, so different pointer but equal content after regeneration |
| 895 | + BOOST_CHECK(sml_empty != sml_add); // Different pointer (cache invalidated) |
| 896 | + |
| 897 | + BOOST_CHECK_EQUAL(sml_add->mnList.size(), 1); // Should contain the added MN |
| 898 | + |
| 899 | + { |
| 900 | + // Remove MN - should invalidate cache |
| 901 | + CDeterministicMNList mn_list(mn_list_1); |
| 902 | + BOOST_CHECK(mn_list_1.to_sml() == mn_list.to_sml()); |
| 903 | + |
| 904 | + mn_list.RemoveMN(dmn->proTxHash); |
| 905 | + auto sml_remove = mn_list.to_sml(); |
| 906 | + |
| 907 | + // Cache should be invalidated |
| 908 | + BOOST_CHECK(sml_remove != sml_add); |
| 909 | + BOOST_CHECK(sml_remove != sml_empty); |
| 910 | + BOOST_CHECK_EQUAL(sml_remove->mnList.size(), 0); // Should be empty after removal |
| 911 | + } |
| 912 | + |
| 913 | + // Start with a list containing one MN mn_list_1 |
| 914 | + // Test 1: Update with same SML entry data - cache should NOT be invalidated |
| 915 | + auto unchangedState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState); |
| 916 | + unchangedState->nPoSePenalty += 10; |
| 917 | + mn_list_1.UpdateMN(*dmn, unchangedState); |
| 918 | + |
| 919 | + // Cache should NOT be invalidated since SML entry didn't change |
| 920 | + BOOST_CHECK(sml_add == mn_list_1.to_sml()); // Same pointer (cache preserved) |
| 921 | + |
| 922 | + // Test 2: Update with different SML entry data - cache SHOULD be invalidated |
| 923 | + auto changedState = std::make_shared<CDeterministicMNState>(*unchangedState); |
| 924 | + changedState->pubKeyOperator.Set(CBLSPublicKey{}, bls::bls_legacy_scheme.load()); |
| 925 | + mn_list_1.UpdateMN(*dmn, changedState); |
| 926 | + |
| 927 | + // Cache should be invalidated since SML entry changed |
| 928 | + BOOST_CHECK(sml_add != mn_list_1.to_sml()); |
| 929 | + BOOST_CHECK_EQUAL(mn_list_1.to_sml()->mnList.size(), 1); // Still one MN but with updated data |
| 930 | +} |
| 931 | + |
839 | 932 | BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests) |
840 | 933 |
|
841 | 934 | struct TestChainDIP3BeforeActivationSetup : public TestChainSetup { |
@@ -938,4 +1031,16 @@ BOOST_AUTO_TEST_CASE(verify_db_legacy) |
938 | 1031 | FuncVerifyDB(setup); |
939 | 1032 | } |
940 | 1033 |
|
| 1034 | +BOOST_AUTO_TEST_CASE(test_sml_cache_legacy) |
| 1035 | +{ |
| 1036 | + TestChainDIP3Setup setup; |
| 1037 | + SmlCache(setup); |
| 1038 | +} |
| 1039 | + |
| 1040 | +BOOST_AUTO_TEST_CASE(test_sml_cache_basic) |
| 1041 | +{ |
| 1042 | + TestChainV19Setup setup; |
| 1043 | + SmlCache(setup); |
| 1044 | +} |
| 1045 | + |
941 | 1046 | BOOST_AUTO_TEST_SUITE_END() |
0 commit comments