Line data Source code
1 : // Copyright (c) 2018-2019 The Dash Core developers
2 : // Copyright (c) 2021-2022 The PIVX Core developers
3 : // Distributed under the MIT/X11 software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "llmq/quorums_commitment.h"
7 :
8 : #include "bls/key_io.h"
9 : #include "chainparams.h"
10 : #include "llmq/quorums_utils.h"
11 : #include "logging.h"
12 :
13 :
14 : namespace llmq
15 : {
16 :
17 402 : CFinalCommitment::CFinalCommitment(const Consensus::LLMQParams& params, const uint256& _quorumHash) :
18 402 : llmqType(params.type),
19 : quorumHash(_quorumHash),
20 402 : signers(params.size),
21 1608 : validMembers(params.size)
22 : {
23 402 : }
24 :
25 7636 : bool CFinalCommitment::IsNull() const
26 : {
27 7636 : if (CountSigners() > 0 || CountValidMembers() > 0) {
28 701 : return false;
29 : }
30 :
31 6935 : if (quorumPublicKey.IsValid() ||
32 228855 : !quorumVvecHash.IsNull() ||
33 13870 : membersSig.IsValid() ||
34 6935 : quorumSig.IsValid()) {
35 0 : return false;
36 : }
37 :
38 : return true;
39 : }
40 :
41 68 : void CFinalCommitment::ToJson(UniValue& obj) const
42 : {
43 68 : obj.setObject();
44 68 : obj.pushKV("version", (int)nVersion);
45 68 : obj.pushKV("llmqType", (int)llmqType);
46 136 : obj.pushKV("quorumHash", quorumHash.ToString());
47 68 : obj.pushKV("signersCount", CountSigners());
48 136 : obj.pushKV("signers", utils::ToHexStr(signers));
49 68 : obj.pushKV("validMembersCount", CountValidMembers());
50 136 : obj.pushKV("validMembers", utils::ToHexStr(validMembers));
51 136 : obj.pushKV("quorumPublicKey", bls::EncodePublic(Params(), quorumPublicKey));
52 136 : obj.pushKV("quorumVvecHash", quorumVvecHash.ToString());
53 136 : obj.pushKV("quorumSig", quorumSig.ToString());
54 136 : obj.pushKV("membersSig", membersSig.ToString());
55 68 : }
56 :
57 : template<typename... Args>
58 1 : static bool errorFinalCommitment(const char* fmt, const Args&... args)
59 : {
60 : try {
61 1 : LogPrint(BCLog::LLMQ, "Invalid Final Commitment -- %s\n", tfm::format(fmt, args...));
62 0 : } catch (tinyformat::format_error &e) {
63 0 : LogPrintf("Error (%s) while formatting message %s\n", std::string(e.what()), fmt);
64 : }
65 1 : return false;
66 : }
67 :
68 332 : bool CFinalCommitment::Verify(const std::vector<CBLSPublicKey>& allkeys, const Consensus::LLMQParams& params) const
69 : {
70 332 : int count_validmembers = CountValidMembers();
71 332 : if (count_validmembers < params.minSize) {
72 0 : return errorFinalCommitment("valid members count (%d < %d)", count_validmembers, params.minSize);
73 : }
74 332 : int count_signers = CountSigners();
75 332 : if (count_signers < params.minSize) {
76 0 : return errorFinalCommitment("signers count (%d < %d)", count_signers, params.minSize);
77 : }
78 :
79 332 : if (!quorumPublicKey.IsValid()) {
80 0 : return errorFinalCommitment("public key");
81 : }
82 664 : if (quorumVvecHash.IsNull()) {
83 0 : return errorFinalCommitment("quorumVvecHash");
84 : }
85 332 : if (!membersSig.IsValid()) {
86 0 : return errorFinalCommitment("membersSig");
87 : }
88 332 : if (!quorumSig.IsValid()) {
89 0 : return errorFinalCommitment("quorumSig");
90 : }
91 :
92 332 : for (int i = allkeys.size(); i < params.size; i++) {
93 0 : if (validMembers[i]) {
94 0 : return errorFinalCommitment("validMembers bitset (bit %d should not be set)", i);
95 : }
96 0 : if (signers[i]) {
97 0 : return errorFinalCommitment("signers bitset (bit %d should not be set)", i);
98 : }
99 : }
100 :
101 : // check signatures
102 332 : uint256 commitmentHash = utils::BuildCommitmentHash(params.type, quorumHash, validMembers, quorumPublicKey, quorumVvecHash);
103 664 : std::vector<CBLSPublicKey> memberPubKeys;
104 1328 : for (size_t i = 0; i < allkeys.size(); i++) {
105 996 : if (!signers[i]) {
106 89 : continue;
107 : }
108 907 : memberPubKeys.emplace_back(allkeys[i]);
109 : }
110 332 : if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) {
111 1 : return errorFinalCommitment("aggregated members signature");
112 : }
113 331 : if (!quorumSig.VerifyInsecure(quorumPublicKey, commitmentHash)) {
114 0 : return errorFinalCommitment("invalid quorum signature");
115 : }
116 :
117 : return true;
118 : }
119 :
120 5535 : bool CFinalCommitment::VerifySizes(const Consensus::LLMQParams& params) const
121 : {
122 5535 : if ((int)signers.size() != params.size) {
123 0 : return errorFinalCommitment("signers size (%d != %d)", signers.size(), params.size);
124 : }
125 5535 : if ((int)validMembers.size() != params.size) {
126 0 : return errorFinalCommitment("validMembers size (%d != %d)", validMembers.size(), params.size);
127 : }
128 : return true;
129 : }
130 :
131 0 : void LLMQCommPL::ToJson(UniValue& obj) const
132 : {
133 0 : obj.setObject();
134 0 : obj.pushKV("version", (int)nVersion);
135 0 : obj.pushKV("height", (int)nHeight);
136 :
137 0 : UniValue qcObj;
138 0 : commitment.ToJson(qcObj);
139 0 : obj.pushKV("commitment", qcObj);
140 0 : }
141 :
142 : } // namespace llmq
|