Skip to content

Commit 3a82148

Browse files
PastaPastaPastaknst
authored andcommitted
test: add comprehensive unit tests for SML caching mechanism
Add extensive unit tests to verify the SML caching functionality: - Test basic cache functionality and cache hits - Test cache invalidation on AddMN operations - Test cache invalidation on RemoveMN operations - Test conditional cache invalidation on UpdateMN operations - Test cache behavior with copy constructor and assignment operator These tests ensure the cache works correctly and efficiently, validating: - Cache is properly shared when no changes occur - Cache is invalidated when MN list changes - Cache preserves optimization in UpdateMN when SML entry doesn't change - Cache is properly copied/shared during object copying This provides comprehensive coverage of the caching mechanism's correctness.
1 parent 0fe1973 commit 3a82148

File tree

1 file changed

+112
-6
lines changed

1 file changed

+112
-6
lines changed

src/test/evo_deterministicmns_tests.cpp

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
#include <chainparams.h>
99
#include <consensus/validation.h>
1010
#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>
1117
#include <messagesigner.h>
1218
#include <netbase.h>
1319
#include <node/transaction.h>
@@ -20,14 +26,10 @@
2026
#include <txmempool.h>
2127
#include <validation.h>
2228

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-
2929
#include <boost/test/unit_test.hpp>
3030

31+
#include <vector>
32+
3133
using node::GetTransaction;
3234

3335
using SimpleUTXOMap = std::map<COutPoint, std::pair<int, CAmount>>;
@@ -836,6 +838,98 @@ void FuncVerifyDB(TestChainSetup& setup)
836838
chainman.ActiveChainstate().CoinsTip(), *(setup.m_node.evodb), 4, 2));
837839
}
838840

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(
855+
ProTxVersion::GetMax(!bls::bls_legacy_scheme, /*is_extended_addr=*/false));
856+
BOOST_CHECK_EQUAL(dmnState->netInfo->AddEntry("1.1.1.1:1"), NetInfoStatus::Success);
857+
858+
auto dmn = std::make_shared<CDeterministicMN>(internal_id, MnType::Regular);
859+
dmn->proTxHash = GetRandHash();
860+
dmn->collateralOutpoint = COutPoint(GetRandHash(), 0);
861+
dmn->nOperatorReward = 0;
862+
dmn->pdmnState = dmnState;
863+
864+
return dmn;
865+
}
866+
867+
static void SmlCache(TestChainSetup& setup)
868+
{
869+
BOOST_CHECK(setup.m_node.dmnman != nullptr);
870+
871+
// Create empty list and verify SML cache
872+
CDeterministicMNList emptyList(uint256(), 0, 0);
873+
auto sml_empty = emptyList.to_sml();
874+
875+
// Should return the same cached object
876+
BOOST_CHECK(sml_empty == emptyList.to_sml());
877+
878+
// Should contain empty list
879+
BOOST_CHECK_EQUAL(sml_empty->mnList.size(), 0);
880+
881+
// Copy list should return the same cached object
882+
CDeterministicMNList mn_list_1(emptyList);
883+
BOOST_CHECK(sml_empty == mn_list_1.to_sml());
884+
885+
// Assigning list should return the same cached object
886+
CDeterministicMNList mn_list_2 = emptyList;
887+
BOOST_CHECK(sml_empty == mn_list_2.to_sml());
888+
889+
auto dmn = create_mock_mn(1);
890+
891+
// Add MN - should invalidate cache
892+
mn_list_1.AddMN(dmn, true);
893+
auto sml_add = mn_list_1.to_sml();
894+
895+
// Cache should be invalidated, so different pointer but equal content after regeneration
896+
BOOST_CHECK(sml_empty != sml_add); // Different pointer (cache invalidated)
897+
898+
BOOST_CHECK_EQUAL(sml_add->mnList.size(), 1); // Should contain the added MN
899+
900+
{
901+
// Remove MN - should invalidate cache
902+
CDeterministicMNList mn_list(mn_list_1);
903+
BOOST_CHECK(mn_list_1.to_sml() == mn_list.to_sml());
904+
905+
mn_list.RemoveMN(dmn->proTxHash);
906+
auto sml_remove = mn_list.to_sml();
907+
908+
// Cache should be invalidated
909+
BOOST_CHECK(sml_remove != sml_add);
910+
BOOST_CHECK(sml_remove != sml_empty);
911+
BOOST_CHECK_EQUAL(sml_remove->mnList.size(), 0); // Should be empty after removal
912+
}
913+
914+
// Start with a list containing one MN mn_list_1
915+
// Test 1: Update with same SML entry data - cache should NOT be invalidated
916+
auto unchangedState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState);
917+
unchangedState->nPoSePenalty += 10;
918+
mn_list_1.UpdateMN(*dmn, unchangedState);
919+
920+
// Cache should NOT be invalidated since SML entry didn't change
921+
BOOST_CHECK(sml_add == mn_list_1.to_sml()); // Same pointer (cache preserved)
922+
923+
// Test 2: Update with different SML entry data - cache SHOULD be invalidated
924+
auto changedState = std::make_shared<CDeterministicMNState>(*unchangedState);
925+
changedState->pubKeyOperator.Set(CBLSPublicKey{}, bls::bls_legacy_scheme.load());
926+
mn_list_1.UpdateMN(*dmn, changedState);
927+
928+
// Cache should be invalidated since SML entry changed
929+
BOOST_CHECK(sml_add != mn_list_1.to_sml());
930+
BOOST_CHECK_EQUAL(mn_list_1.to_sml()->mnList.size(), 1); // Still one MN but with updated data
931+
}
932+
839933
BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests)
840934

841935
struct TestChainDIP3BeforeActivationSetup : public TestChainSetup {
@@ -938,4 +1032,16 @@ BOOST_AUTO_TEST_CASE(verify_db_legacy)
9381032
FuncVerifyDB(setup);
9391033
}
9401034

1035+
BOOST_AUTO_TEST_CASE(test_sml_cache_legacy)
1036+
{
1037+
TestChainDIP3Setup setup;
1038+
SmlCache(setup);
1039+
}
1040+
1041+
BOOST_AUTO_TEST_CASE(test_sml_cache_basic)
1042+
{
1043+
TestChainV19Setup setup;
1044+
SmlCache(setup);
1045+
}
1046+
9411047
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)