Skip to content

Commit 8cbcf78

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 8cbcf78

File tree

1 file changed

+111
-6
lines changed

1 file changed

+111
-6
lines changed

src/test/evo_deterministicmns_tests.cpp

Lines changed: 111 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,97 @@ 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(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+
839932
BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests)
840933

841934
struct TestChainDIP3BeforeActivationSetup : public TestChainSetup {
@@ -938,4 +1031,16 @@ BOOST_AUTO_TEST_CASE(verify_db_legacy)
9381031
FuncVerifyDB(setup);
9391032
}
9401033

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+
9411046
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)