@@ -1041,4 +1041,104 @@ BOOST_AUTO_TEST_CASE(test_sml_cache_basic)
10411041 SmlCache (setup);
10421042}
10431043
1044+ BOOST_AUTO_TEST_CASE (field_bit_migration_validation)
1045+ {
1046+ // Test individual field mappings for ALL 19 fields
1047+ struct FieldMapping {
1048+ uint32_t legacyBit;
1049+ uint32_t newBit;
1050+ std::string name;
1051+ };
1052+
1053+ std::vector<FieldMapping> mappings = {
1054+ {0x0001 , CDeterministicMNStateDiff::Field_nRegisteredHeight, " nRegisteredHeight" },
1055+ {0x0002 , CDeterministicMNStateDiff::Field_nLastPaidHeight, " nLastPaidHeight" },
1056+ {0x0004 , CDeterministicMNStateDiff::Field_nPoSePenalty, " nPoSePenalty" },
1057+ {0x0008 , CDeterministicMNStateDiff::Field_nPoSeRevivedHeight, " nPoSeRevivedHeight" },
1058+ {0x0010 , CDeterministicMNStateDiff::Field_nPoSeBanHeight, " nPoSeBanHeight" },
1059+ {0x0020 , CDeterministicMNStateDiff::Field_nRevocationReason, " nRevocationReason" },
1060+ {0x0040 , CDeterministicMNStateDiff::Field_confirmedHash, " confirmedHash" },
1061+ {0x0080 , CDeterministicMNStateDiff::Field_confirmedHashWithProRegTxHash, " confirmedHashWithProRegTxHash" },
1062+ {0x0100 , CDeterministicMNStateDiff::Field_keyIDOwner, " keyIDOwner" },
1063+ {0x0200 , CDeterministicMNStateDiff::Field_pubKeyOperator, " pubKeyOperator" },
1064+ {0x0400 , CDeterministicMNStateDiff::Field_keyIDVoting, " keyIDVoting" },
1065+ {0x0800 , CDeterministicMNStateDiff::Field_netInfo, " netInfo" },
1066+ {0x1000 , CDeterministicMNStateDiff::Field_scriptPayout, " scriptPayout" },
1067+ {0x2000 , CDeterministicMNStateDiff::Field_scriptOperatorPayout, " scriptOperatorPayout" },
1068+ {0x4000 , CDeterministicMNStateDiff::Field_nConsecutivePayments, " nConsecutivePayments" },
1069+ {0x8000 , CDeterministicMNStateDiff::Field_platformNodeID, " platformNodeID" },
1070+ {0x10000 , CDeterministicMNStateDiff::Field_platformP2PPort, " platformP2PPort" },
1071+ {0x20000 , CDeterministicMNStateDiff::Field_platformHTTPPort, " platformHTTPPort" },
1072+ {0x40000 , CDeterministicMNStateDiff::Field_nVersion, " nVersion" },
1073+ };
1074+
1075+ // Verify each field mapping is correct
1076+ for (const auto & mapping : mappings) {
1077+ // Test individual field conversion
1078+ CDeterministicMNStateDiffLegacy legacyDiff;
1079+ legacyDiff.fields |= mapping.legacyBit ;
1080+ // Convert to new format
1081+ auto newDiff = legacyDiff.ToNewFormat ();
1082+ BOOST_CHECK_MESSAGE (newDiff.fields == mapping.newBit , strprintf (" Field %s: legacy 0x%x should convert to 0x%x" ,
1083+ mapping.name , mapping.legacyBit , mapping.newBit ));
1084+ }
1085+
1086+ // Test complex multi-field scenarios
1087+ uint32_t complexLegacyFields = 0x0200 | // Legacy Field_pubKeyOperator
1088+ 0x0800 | // Legacy Field_netInfo
1089+ 0x1000 | // Legacy Field_scriptPayout
1090+ 0x40000 ; // Legacy Field_nVersion
1091+
1092+ uint32_t expectedNewFields = CDeterministicMNStateDiff::Field_nVersion | // 0x0001
1093+ CDeterministicMNStateDiff::Field_pubKeyOperator | // 0x0400 (was 0x0200)
1094+ CDeterministicMNStateDiff::Field_netInfo | // 0x1000 (was 0x0800)
1095+ CDeterministicMNStateDiff::Field_scriptPayout; // 0x2000 (was 0x1000)
1096+
1097+ CDeterministicMNStateDiffLegacy legacyDiff;
1098+ legacyDiff.fields |= complexLegacyFields;
1099+ // Convert to new format
1100+ auto newDiff = legacyDiff.ToNewFormat ();
1101+ BOOST_CHECK_EQUAL (newDiff.fields , expectedNewFields);
1102+
1103+ // Verify no bit conflicts exist in new field layout
1104+ std::set<uint32_t > usedBits;
1105+ for (const auto & mapping : mappings) {
1106+ BOOST_CHECK_MESSAGE (usedBits.find (mapping.newBit ) == usedBits.end (),
1107+ strprintf (" Duplicate bit 0x%x found for field %s" , mapping.newBit , mapping.name ));
1108+ usedBits.insert (mapping.newBit );
1109+ }
1110+
1111+ // Verify all 19 fields have unique bit assignments
1112+ BOOST_CHECK_EQUAL (usedBits.size (), 19 );
1113+ }
1114+
1115+ BOOST_AUTO_TEST_CASE (migration_logic_validation)
1116+ {
1117+ // Test the database migration logic for nVersion-first format conversion.
1118+ // Migration logic is handled at CDeterministicMNListDiff level
1119+ // using CDeterministicMNStateDiffLegacy for legacy format deserialization.
1120+
1121+ // Create sample legacy format state diff
1122+ CDeterministicMNStateDiffLegacy legacyDiff;
1123+ legacyDiff.fields = 0x40000 | 0x0200 | 0x0800 ; // Legacy: nVersion, pubKeyOperator, netInfo
1124+ legacyDiff.state .nVersion = ProTxVersion::BasicBLS;
1125+ legacyDiff.state .pubKeyOperator .Set (CBLSPublicKey{}, false );
1126+ legacyDiff.state .netInfo = NetInfoInterface::MakeNetInfo (ProTxVersion::BasicBLS);
1127+
1128+ // Test legacy class conversion (this would normally be done by CDeterministicMNListDiff)
1129+ CDataStream ss (SER_DISK, CLIENT_VERSION);
1130+ ss << legacyDiff;
1131+
1132+ CDeterministicMNStateDiffLegacy legacyDeserializer (deserialize, ss);
1133+ CDeterministicMNStateDiff convertedDiff = legacyDeserializer.ToNewFormat ();
1134+
1135+ // Verify conversion worked correctly
1136+ uint32_t expectedNewFields = CDeterministicMNStateDiff::Field_nVersion | // 0x0001
1137+ CDeterministicMNStateDiff::Field_pubKeyOperator | // 0x0400
1138+ CDeterministicMNStateDiff::Field_netInfo; // 0x1000
1139+
1140+ BOOST_CHECK_EQUAL (convertedDiff.fields , expectedNewFields);
1141+ BOOST_CHECK_EQUAL (convertedDiff.state .nVersion , ProTxVersion::BasicBLS);
1142+ }
1143+
10441144BOOST_AUTO_TEST_SUITE_END ()
0 commit comments