Line data Source code
1 : // Copyright (c) 2018-2025 The Dash Core developers 2 : // Distributed under the MIT/X11 software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_LLMQ_COMMITMENT_H 6 : #define BITCOIN_LLMQ_COMMITMENT_H 7 : 8 : #include <bls/bls.h> 9 : #include <llmq/params.h> 10 : #include <llmq/types.h> 11 : #include <util/helpers.h> 12 : #include <util/std23.h> 13 : 14 : #include <primitives/transaction.h> 15 : #include <util/strencodings.h> 16 : 17 : #include <gsl/pointers.h> 18 : #include <univalue.h> 19 : 20 : #include <algorithm> 21 : #include <limits> 22 : #include <memory> 23 : #include <string> 24 : #include <vector> 25 : 26 : class CBlockIndex; 27 : class CDeterministicMNManager; 28 : class ChainstateManager; 29 : class TxValidationState; 30 : template <typename T> 31 : class CCheckQueueControl; 32 : struct RPCResult; 33 : namespace llmq { 34 : class CQuorumSnapshotManager; 35 : struct UtilParameters; 36 : namespace utils { 37 : struct BlsCheck; 38 : } // namespace utils 39 : } // namespace llmq 40 : 41 : namespace llmq { 42 : // This message is an aggregation of all received premature commitments and only valid if 43 : // enough (>=threshold) premature commitments were aggregated 44 : // This is mined on-chain as part of TRANSACTION_QUORUM_COMMITMENT 45 14586 : class CFinalCommitment 46 : { 47 : public: 48 : static constexpr uint16_t LEGACY_BLS_NON_INDEXED_QUORUM_VERSION = 1; 49 : static constexpr uint16_t LEGACY_BLS_INDEXED_QUORUM_VERSION = 2; 50 : static constexpr uint16_t BASIC_BLS_NON_INDEXED_QUORUM_VERSION = 3; 51 : static constexpr uint16_t BASIC_BLS_INDEXED_QUORUM_VERSION = 4; 52 : 53 203487 : uint16_t nVersion{LEGACY_BLS_NON_INDEXED_QUORUM_VERSION}; 54 203487 : Consensus::LLMQType llmqType{Consensus::LLMQType::LLMQ_NONE}; 55 : uint256 quorumHash; 56 203487 : int16_t quorumIndex{0}; 57 : std::vector<bool> signers; 58 : std::vector<bool> validMembers; 59 : 60 : CBLSPublicKey quorumPublicKey; 61 : uint256 quorumVvecHash; 62 : 63 : CBLSSignature quorumSig; // recovered threshold sig of blockHash+validMembers+pubKeyHash+vvecHash 64 : CBLSSignature membersSig; // aggregated member sig of blockHash+validMembers+pubKeyHash+vvecHash 65 : 66 : public: 67 813948 : CFinalCommitment() = default; 68 : CFinalCommitment(const Consensus::LLMQParams& params, const uint256& _quorumHash); 69 : 70 29061 : int CountSigners() const 71 : { 72 29061 : return int(std::count(signers.begin(), signers.end(), true)); 73 : } 74 29061 : int CountValidMembers() const 75 : { 76 29061 : return int(std::count(validMembers.begin(), validMembers.end(), true)); 77 : } 78 : 79 : bool VerifySignatureAsync(const llmq::UtilParameters& util_params, 80 : CCheckQueueControl<utils::BlsCheck>* queue_control) const; 81 : bool Verify(const llmq::UtilParameters& util_params, bool checkSigs) const; 82 : bool VerifyNull() const; 83 : bool VerifySizes(const Consensus::LLMQParams& params) const; 84 : 85 14589 : [[nodiscard]] static constexpr uint16_t GetVersion(const bool is_rotation_enabled, const bool is_basic_scheme_active) 86 : { 87 14589 : if (is_rotation_enabled) 88 6818 : return is_basic_scheme_active ? BASIC_BLS_INDEXED_QUORUM_VERSION : LEGACY_BLS_INDEXED_QUORUM_VERSION; 89 : else 90 7771 : return is_basic_scheme_active ? BASIC_BLS_NON_INDEXED_QUORUM_VERSION : LEGACY_BLS_NON_INDEXED_QUORUM_VERSION; 91 14589 : } 92 : 93 : public: 94 : 95 566682 : SERIALIZE_METHODS(CFinalCommitment, obj) 96 : { 97 188894 : READWRITE( 98 : obj.nVersion, 99 : obj.llmqType, 100 : obj.quorumHash 101 : ); 102 188894 : if (obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION || obj.nVersion == BASIC_BLS_INDEXED_QUORUM_VERSION) { 103 88320 : READWRITE( 104 : obj.quorumIndex 105 : ); 106 88320 : } 107 188894 : READWRITE( 108 : DYNBITSET(obj.signers), 109 : DYNBITSET(obj.validMembers), 110 : CBLSPublicKeyVersionWrapper(const_cast<CBLSPublicKey&>(obj.quorumPublicKey), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION)), 111 : obj.quorumVvecHash, 112 : CBLSSignatureVersionWrapper(const_cast<CBLSSignature&>(obj.quorumSig), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION)), 113 : CBLSSignatureVersionWrapper(const_cast<CBLSSignature&>(obj.membersSig), (obj.nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || obj.nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION)) 114 : ); 115 188894 : } 116 : 117 : public: 118 261464 : bool IsNull() const 119 : { 120 261464 : if (std::count(signers.begin(), signers.end(), true) || 121 261460 : std::count(validMembers.begin(), validMembers.end(), true)) { 122 5 : return false; 123 : } 124 522915 : if (quorumPublicKey.IsValid() || 125 261458 : !quorumVvecHash.IsNull() || 126 261457 : membersSig.IsValid() || 127 261456 : quorumSig.IsValid()) { 128 4 : return false; 129 : } 130 261455 : return true; 131 261464 : } 132 : 133 : [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional); 134 : [[nodiscard]] UniValue ToJson() const; 135 : 136 : private: 137 12 : static std::string BitsVectorToHexStr(const std::vector<bool>& vBits) 138 : { 139 12 : std::vector<uint8_t> vBytes((vBits.size() + 7) / 8); 140 76 : for (const auto i : util::irange(vBits.size())) { 141 64 : vBytes[i / 8] |= vBits[i] << (i % 8); 142 : } 143 12 : return HexStr(vBytes); 144 12 : } 145 : }; 146 : 147 188889 : class CFinalCommitmentTxPayload 148 : { 149 : public: 150 : static constexpr auto SPECIALTX_TYPE = TRANSACTION_QUORUM_COMMITMENT; 151 : static constexpr uint16_t CURRENT_VERSION = 1; 152 : public: 153 188889 : uint16_t nVersion{CURRENT_VERSION}; 154 188889 : uint32_t nHeight{std::numeric_limits<uint32_t>::max()}; 155 : CFinalCommitment commitment; 156 : 157 : public: 158 566664 : SERIALIZE_METHODS(CFinalCommitmentTxPayload, obj) 159 : { 160 188888 : READWRITE(obj.nVersion, obj.nHeight, obj.commitment); 161 188888 : } 162 : 163 : [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional); 164 : [[nodiscard]] UniValue ToJson() const; 165 : }; 166 : 167 : bool CheckLLMQCommitment(const llmq::UtilParameters& util_params, const CTransaction& tx, TxValidationState& state); 168 : 169 : uint256 BuildCommitmentHash(Consensus::LLMQType llmqType, const uint256& blockHash, const std::vector<bool>& validMembers, const CBLSPublicKey& pubKey, const uint256& vvecHash); 170 : 171 : } // namespace llmq 172 : 173 : #endif // BITCOIN_LLMQ_COMMITMENT_H