LCOV - code coverage report
Current view: top level - src/test - llmq_hash_tests.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 111 111 100.0 %
Date: 2026-06-25 07:23:51 Functions: 47 47 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2025 The Dash Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <test/util/llmq_tests.h>
       6             : #include <test/util/setup_common.h>
       7             : 
       8             : #include <consensus/params.h>
       9             : #include <llmq/commitment.h>
      10             : #include <llmq/utils.h>
      11             : 
      12             : #include <boost/test/unit_test.hpp>
      13             : 
      14             : #include <vector>
      15             : 
      16             : using namespace llmq;
      17             : using namespace llmq::testutils;
      18             : 
      19         146 : BOOST_FIXTURE_TEST_SUITE(llmq_hash_tests, BasicTestingSetup)
      20             : 
      21             : // Get test params for use in tests
      22         146 : static const Consensus::LLMQParams& TEST_PARAMS = GetLLMQParams(Consensus::LLMQType::LLMQ_TEST_V17);
      23         146 : static const Consensus::LLMQParams& TEST_PARAMS_ALT = GetLLMQParams(Consensus::LLMQType::LLMQ_TEST);
      24             : 
      25         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_deterministic_test)
      26             : {
      27             :     // Setup test data
      28           1 :     Consensus::LLMQType llmqType = TEST_PARAMS.type;
      29           1 :     uint256 quorumHash = GetTestQuorumHash(1);
      30           1 :     std::vector<bool> validMembers = CreateBitVector(5, {0, 1, 2, 3});
      31           1 :     CBLSPublicKey quorumPubKey = CreateRandomBLSPublicKey();
      32           1 :     uint256 vvecHash = GetTestQuorumHash(2);
      33             : 
      34             :     // Generate hash multiple times with same inputs
      35           1 :     uint256 hash1 = BuildCommitmentHash(llmqType, quorumHash, validMembers, quorumPubKey, vvecHash);
      36           1 :     uint256 hash2 = BuildCommitmentHash(llmqType, quorumHash, validMembers, quorumPubKey, vvecHash);
      37           1 :     uint256 hash3 = BuildCommitmentHash(llmqType, quorumHash, validMembers, quorumPubKey, vvecHash);
      38             : 
      39             :     // All hashes should be identical (deterministic)
      40           1 :     BOOST_CHECK(hash1 == hash2);
      41           1 :     BOOST_CHECK(hash2 == hash3);
      42           1 :     BOOST_CHECK(!hash1.IsNull());
      43           1 : }
      44             : 
      45         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_sensitivity_test)
      46             : {
      47             :     // Base test data
      48           1 :     Consensus::LLMQType llmqType = TEST_PARAMS.type;
      49           1 :     uint256 quorumHash = GetTestQuorumHash(1);
      50           1 :     std::vector<bool> validMembers = CreateBitVector(5, {0, 1, 2, 3});
      51           1 :     CBLSPublicKey quorumPubKey = CreateRandomBLSPublicKey();
      52           1 :     uint256 vvecHash = GetTestQuorumHash(2);
      53             : 
      54           1 :     uint256 baseHash = BuildCommitmentHash(llmqType, quorumHash, validMembers, quorumPubKey, vvecHash);
      55             : 
      56             :     // Test sensitivity to llmqType change
      57           1 :     uint256 hashDiffType = BuildCommitmentHash(TEST_PARAMS_ALT.type, // Different type
      58             :                                                quorumHash, validMembers, quorumPubKey, vvecHash);
      59           1 :     BOOST_CHECK(baseHash != hashDiffType);
      60             : 
      61             :     // Test sensitivity to quorumHash change
      62           1 :     uint256 hashDiffQuorum = BuildCommitmentHash(llmqType,
      63           1 :                                                  GetTestQuorumHash(99), // Different quorum hash
      64             :                                                  validMembers, quorumPubKey, vvecHash);
      65           1 :     BOOST_CHECK(baseHash != hashDiffQuorum);
      66             : 
      67             :     // Test sensitivity to validMembers change
      68           1 :     std::vector<bool> differentMembers = CreateBitVector(5, {0, 1, 2}); // One less member
      69           1 :     uint256 hashDiffMembers = BuildCommitmentHash(llmqType, quorumHash,
      70             :                                                   differentMembers, // Different valid members
      71             :                                                   quorumPubKey, vvecHash);
      72           1 :     BOOST_CHECK(baseHash != hashDiffMembers);
      73             : 
      74             :     // Test sensitivity to quorumPubKey change
      75           1 :     CBLSPublicKey differentPubKey = CreateRandomBLSPublicKey();
      76           1 :     uint256 hashDiffPubKey = BuildCommitmentHash(llmqType, quorumHash, validMembers,
      77             :                                                  differentPubKey, // Different public key
      78             :                                                  vvecHash);
      79           1 :     BOOST_CHECK(baseHash != hashDiffPubKey);
      80             : 
      81             :     // Test sensitivity to vvecHash change
      82           1 :     uint256 hashDiffVvec = BuildCommitmentHash(llmqType, quorumHash, validMembers, quorumPubKey,
      83           1 :                                                GetTestQuorumHash(99) // Different vvec hash
      84             :     );
      85           1 :     BOOST_CHECK(baseHash != hashDiffVvec);
      86           1 : }
      87             : 
      88         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_edge_cases_test)
      89             : {
      90             :     // Test with empty valid members
      91           1 :     std::vector<bool> emptyMembers;
      92           2 :     uint256 hashEmpty = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), emptyMembers,
      93           1 :                                             CreateRandomBLSPublicKey(), GetTestQuorumHash(2));
      94           1 :     BOOST_CHECK(!hashEmpty.IsNull());
      95             : 
      96             :     // Test with all members valid
      97           1 :     std::vector<bool> allValid(100, true);
      98           2 :     uint256 hashAllValid = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), allValid,
      99           1 :                                                CreateRandomBLSPublicKey(), GetTestQuorumHash(2));
     100           1 :     BOOST_CHECK(!hashAllValid.IsNull());
     101             : 
     102             :     // Test with no members valid
     103           1 :     std::vector<bool> noneValid(100, false);
     104           2 :     uint256 hashNoneValid = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), noneValid,
     105           1 :                                                 CreateRandomBLSPublicKey(), GetTestQuorumHash(2));
     106           1 :     BOOST_CHECK(!hashNoneValid.IsNull());
     107             : 
     108             :     // All three should produce different hashes
     109           1 :     BOOST_CHECK(hashEmpty != hashAllValid);
     110           1 :     BOOST_CHECK(hashEmpty != hashNoneValid);
     111           1 :     BOOST_CHECK(hashAllValid != hashNoneValid);
     112           1 : }
     113             : 
     114         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_null_inputs_test)
     115             : {
     116             :     // Test with null quorum hash
     117           2 :     uint256 hashNullQuorum = BuildCommitmentHash(TEST_PARAMS.type,
     118           1 :                                                  uint256(), // Null hash
     119           1 :                                                  CreateBitVector(5, {0, 1, 2}), CreateRandomBLSPublicKey(),
     120           1 :                                                  GetTestQuorumHash(1));
     121           1 :     BOOST_CHECK(!hashNullQuorum.IsNull());
     122             : 
     123             :     // Test with invalid (but serializable) public key
     124           1 :     CBLSPublicKey invalidPubKey;
     125           2 :     uint256 hashInvalidKey = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), CreateBitVector(5, {0, 1, 2}),
     126             :                                                  invalidPubKey, // Invalid key
     127           1 :                                                  GetTestQuorumHash(2));
     128           1 :     BOOST_CHECK(!hashInvalidKey.IsNull());
     129             : 
     130             :     // Test with null vvec hash
     131           2 :     uint256 hashNullVvec = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), CreateBitVector(5, {0, 1, 2}),
     132           1 :                                                CreateRandomBLSPublicKey(),
     133           1 :                                                uint256() // Null hash
     134             :     );
     135           1 :     BOOST_CHECK(!hashNullVvec.IsNull());
     136             : 
     137             :     // All should produce different hashes
     138           1 :     BOOST_CHECK(hashNullQuorum != hashInvalidKey);
     139           1 :     BOOST_CHECK(hashNullQuorum != hashNullVvec);
     140           1 :     BOOST_CHECK(hashInvalidKey != hashNullVvec);
     141           1 : }
     142             : 
     143         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_large_data_test)
     144             : {
     145             :     // Test with maximum expected quorum size
     146           1 :     std::vector<bool> largeValidMembers(400, true); // Max quorum size
     147             : 
     148             :     // Create pattern in valid members
     149         135 :     for (size_t i = 0; i < largeValidMembers.size(); i += 3) {
     150         134 :         largeValidMembers[i] = false;
     151         134 :     }
     152             : 
     153           2 :     uint256 hashLarge = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), largeValidMembers,
     154           1 :                                             CreateRandomBLSPublicKey(), GetTestQuorumHash(2));
     155             : 
     156           1 :     BOOST_CHECK(!hashLarge.IsNull());
     157             : 
     158             :     // Slightly different pattern should produce different hash
     159           1 :     largeValidMembers[0] = !largeValidMembers[0];
     160           2 :     uint256 hashLargeDiff = BuildCommitmentHash(TEST_PARAMS.type, GetTestQuorumHash(1), largeValidMembers,
     161           1 :                                                 CreateRandomBLSPublicKey(), GetTestQuorumHash(2));
     162             : 
     163           1 :     BOOST_CHECK(!hashLargeDiff.IsNull());
     164           1 :     BOOST_CHECK(hashLarge != hashLargeDiff);
     165           1 : }
     166             : 
     167         149 : BOOST_AUTO_TEST_CASE(build_commitment_hash_bit_pattern_test)
     168             : {
     169             :     // Test that different bit patterns produce different hashes
     170           1 :     Consensus::LLMQType llmqType = TEST_PARAMS_ALT.type;
     171           1 :     uint256 quorumHash = GetTestQuorumHash(1);
     172           1 :     CBLSPublicKey quorumPubKey = CreateRandomBLSPublicKey();
     173           1 :     uint256 vvecHash = GetTestQuorumHash(2);
     174             : 
     175             :     // Create various bit patterns
     176           6 :     std::vector<std::vector<bool>> patterns = {
     177           1 :         CreateBitVector(10, {}),                             // All false
     178           1 :         CreateBitVector(10, {0}),                            // First only
     179           1 :         CreateBitVector(10, {9}),                            // Last only
     180           1 :         CreateBitVector(10, {0, 9}),                         // First and last
     181           1 :         CreateBitVector(10, {1, 3, 5, 7}),                   // Alternating
     182           1 :         CreateBitVector(10, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), // All true
     183             :     };
     184             : 
     185           1 :     std::vector<uint256> hashes;
     186           7 :     for (const auto& pattern : patterns) {
     187           6 :         uint256 hash = BuildCommitmentHash(llmqType, quorumHash, pattern, quorumPubKey, vvecHash);
     188           6 :         hashes.push_back(hash);
     189           6 :         BOOST_CHECK(!hash.IsNull());
     190             :     }
     191             : 
     192             :     // All hashes should be unique
     193           7 :     for (size_t i = 0; i < hashes.size(); ++i) {
     194          21 :         for (size_t j = i + 1; j < hashes.size(); ++j) {
     195          15 :             BOOST_CHECK(hashes[i] != hashes[j]);
     196          15 :         }
     197           6 :     }
     198           1 : }
     199             : 
     200         146 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.16