PIVX Core  5.6.99
P2P Digital Currency
quorums_dkgsession.h
Go to the documentation of this file.
1 // Copyright (c) 2018-2021 The Dash Core developers
2 // Copyright (c) 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 #ifndef PIVX_LLMQ_QUORUMS_DKGSESSION_H
7 #define PIVX_LLMQ_QUORUMS_DKGSESSION_H
8 
9 #include "bls/bls_ies.h"
10 #include "bls/bls_worker.h"
11 #include "consensus/params.h"
12 #include "evo/deterministicmns.h"
13 #include "net.h"
14 #include "llmq/quorums_utils.h"
15 #include "logging.h"
16 
17 class UniValue;
18 
19 namespace llmq
20 {
21 
22 class CFinalCommitment;
23 class CDKGSession;
24 class CDKGSessionManager;
25 class CDKGPendingMessages;
26 
27 class CDKGLogger : public CBatchedLogger
28 {
29 public:
30  CDKGLogger(const CDKGSession& _quorumDkg, const std::string& _func);
31  CDKGLogger(const std::string& _llmqTypeName, const uint256& _quorumHash, int _height, bool _areWeMember, const std::string& _func);
32 };
33 
35 {
36 public:
37  uint8_t llmqType;
41  std::shared_ptr<CBLSIESMultiRecipientObjects<CBLSSecretKey>> contributions;
43 
44 public:
45  template<typename Stream>
46  inline void SerializeWithoutSig(Stream& s) const
47  {
48  s << llmqType;
49  s << quorumHash;
50  s << proTxHash;
51  s << *vvec;
52  s << *contributions;
53  }
54  template<typename Stream>
55  inline void Serialize(Stream& s) const
56  {
58  s << sig;
59  }
60  template<typename Stream>
61  inline void Unserialize(Stream& s)
62  {
65 
66  s >> llmqType;
67  s >> quorumHash;
68  s >> proTxHash;
69  s >> tmp1;
70  s >> tmp2;
71  s >> sig;
72 
73  vvec = std::make_shared<BLSVerificationVector>(std::move(tmp1));
74  contributions = std::make_shared<CBLSIESMultiRecipientObjects<CBLSSecretKey>>(std::move(tmp2));
75  }
76 
78  {
79  CHashWriter hw(SER_GETHASH, 0);
81  hw << CBLSSignature();
82  return hw.GetHash();
83  }
84 };
85 
87 {
88 public:
89  uint8_t llmqType;
92  std::vector<bool> badMembers;
93  std::vector<bool> complainForMembers;
95 
96 public:
98  explicit CDKGComplaint(const Consensus::LLMQParams& params);
99 
101  {
102  READWRITE(obj.llmqType);
103  READWRITE(obj.quorumHash);
104  READWRITE(obj.proTxHash);
105  READWRITE(DYNBITSET(obj.badMembers));
106  READWRITE(DYNBITSET(obj.complainForMembers));
107  READWRITE(obj.sig);
108  }
109 
111  {
112  CDKGComplaint tmp(*this);
113  tmp.sig = CBLSSignature();
115  }
116 };
117 
119 {
120 public:
121  uint8_t llmqType;
124  std::vector<std::pair<uint32_t, CBLSSecretKey>> contributions;
126 
127 public:
128 
130  {
131  READWRITE(obj.llmqType);
132  READWRITE(obj.quorumHash);
133  READWRITE(obj.proTxHash);
134  READWRITE(obj.contributions);
135  READWRITE(obj.sig);
136  }
137 
139  {
140  CDKGJustification tmp(*this);
141  tmp.sig = CBLSSignature();
143  }
144 };
145 
146 // each member commits to a single set of valid members with this message
147 // then each node aggregate all received premature commitments
148 // into a single CFinalCommitment, which is only valid if
149 // enough (>=minSize) premature commitments were aggregated
151 {
152 public:
153  uint8_t llmqType;
156  std::vector<bool> validMembers;
157 
160 
161  CBLSSignature quorumSig; // threshold sig share of quorumHash+validMembers+pubKeyHash+vvecHash
162  CBLSSignature sig; // single member sig of quorumHash+validMembers+pubKeyHash+vvecHash
163 
164 public:
166  explicit CDKGPrematureCommitment(const Consensus::LLMQParams& params);
167 
168  int CountValidMembers() const
169  {
170  return (int)std::count(validMembers.begin(), validMembers.end(), true);
171  }
172 
173 public:
174 
176  {
177  READWRITE(obj.llmqType);
178  READWRITE(obj.quorumHash);
179  READWRITE(obj.proTxHash);
180  READWRITE(DYNBITSET(obj.validMembers));
181  READWRITE(obj.quorumPublicKey);
182  READWRITE(obj.quorumVvecHash);
183  READWRITE(obj.quorumSig);
184  READWRITE(obj.sig);
185  }
186 
188  {
190  }
191 };
192 
194 {
195 public:
196  CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx);
197 
199  size_t idx;
201 
202  std::set<uint256> contributions;
203  std::set<uint256> complaints;
204  std::set<uint256> justifications;
205  std::set<uint256> prematureCommitments;
206 
207  std::set<uint256> badMemberVotes;
208  std::set<uint256> complaintsFromOthers;
209 
210  bool bad{false};
211  bool weComplain{false};
212  bool someoneComplain{false};
213 };
214 
230 {
231  friend class CDKGSessionHandler;
232  friend class CDKGSessionManager;
233  friend class CDKGLogger;
234  template<typename Message> friend class CDKGMessageHandler;
235 
236 private:
238 
242 
244 
245  std::vector<std::unique_ptr<CDKGMember>> members;
246  std::map<uint256, size_t> membersMap;
247  std::set<uint256> relayMembers;
250 
252  std::vector<BLSVerificationVectorPtr> receivedVvecs;
253  // these are not necessarily verified yet. Only trust in what was written to the DB
255 
258  size_t myIdx{(size_t)-1};
259 
260  // all indexed by msg hash
261  // we expect to only receive a single vvec and contribution per member, but we must also be able to relay
262  // conflicting messages as otherwise an attacker might be able to broadcast conflicting (valid+invalid) messages
263  // and thus split the quorum. Such members are later removed from the quorum.
265  std::map<uint256, CDKGContribution> contributions;
266  std::map<uint256, CDKGComplaint> complaints;
267  std::map<uint256, CDKGJustification> justifications;
268  std::map<uint256, CDKGPrematureCommitment> prematureCommitments;
269 
270  std::set<uint256> seenMessages;
271 
272  std::vector<size_t> pendingContributionVerifications;
273 
274  // filled by ReceivePrematureCommitment and used by FinalizeCommitments
275  std::set<uint256> validCommitments;
276 
277 public:
278  CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager) :
279  params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager) {}
280 
281  bool Init(const CBlockIndex* _pindexQuorum, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash);
282 
283  size_t GetMyMemberIndex() const { return myIdx; }
284 
298  // Phase 1: contribution
299  void Contribute(CDKGPendingMessages& pendingMessages);
300  void SendContributions(CDKGPendingMessages& pendingMessages);
301  bool PreVerifyMessage(const CDKGContribution& qc, bool& retBan) const;
302  void ReceiveMessage(const uint256& hash, const CDKGContribution& qc, bool& retBan);
304 
305  // Phase 2: complaint
306  void VerifyAndComplain(CDKGPendingMessages& pendingMessages);
308  void SendComplaint(CDKGPendingMessages& pendingMessages);
309  bool PreVerifyMessage(const CDKGComplaint& qc, bool& retBan) const;
310  void ReceiveMessage(const uint256& hash, const CDKGComplaint& qc, bool& retBan);
311 
312  // Phase 3: justification
313  void VerifyAndJustify(CDKGPendingMessages& pendingMessages);
314  void SendJustification(CDKGPendingMessages& pendingMessages, const std::set<uint256>& forMembers);
315  bool PreVerifyMessage(const CDKGJustification& qj, bool& retBan) const;
316  void ReceiveMessage(const uint256& hash, const CDKGJustification& qj, bool& retBan);
317 
318  // Phase 4: commit
319  void VerifyAndCommit(CDKGPendingMessages& pendingMessages);
320  void SendCommitment(CDKGPendingMessages& pendingMessages);
321  bool PreVerifyMessage(const CDKGPrematureCommitment& qc, bool& retBan) const;
322  void ReceiveMessage(const uint256& hash, const CDKGPrematureCommitment& qc, bool& retBan);
323 
324  // Phase 5: aggregate/finalize
325  std::vector<CFinalCommitment> FinalizeCommitments();
326 
327  bool AreWeMember() const { return !myProTxHash.IsNull(); }
328  void MarkBadMember(CDKGMember* member);
329 
330  void RelayInvToParticipants(const CInv& inv) const;
331 
332  CDKGMember* GetMember(const uint256& proTxHash) const;
333 
334 private:
335  bool ShouldSimulateError(const std::string& error_type);
336 };
337 
338 // Return false if error_type is not found
339 bool SetSimulatedDKGErrorRate(const std::string& error_type, double rate);
340 
341 }
342 
343 #endif // PIVX_LLMQ_QUORUMS_DKGSESSION_H
std::vector< CBLSId > BLSIdVector
Definition: bls_wrapper.h:408
std::vector< CBLSPublicKey > BLSVerificationVector
Definition: bls_wrapper.h:409
std::shared_ptr< BLSVerificationVector > BLSVerificationVectorPtr
Definition: bls_wrapper.h:415
std::vector< CBLSSecretKey > BLSSecretKeyVector
Definition: bls_wrapper.h:411
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
inv message data
Definition: protocol.h:466
bool IsNull() const
Definition: uint256.h:36
uint256 GetSignHash() const
std::vector< bool > badMembers
SERIALIZE_METHODS(CDKGComplaint, obj)
std::vector< bool > complainForMembers
void Serialize(Stream &s) const
std::shared_ptr< CBLSIESMultiRecipientObjects< CBLSSecretKey > > contributions
uint256 GetSignHash() const
BLSVerificationVectorPtr vvec
void Unserialize(Stream &s)
void SerializeWithoutSig(Stream &s) const
std::vector< std::pair< uint32_t, CBLSSecretKey > > contributions
SERIALIZE_METHODS(CDKGJustification, obj)
CDKGLogger(const CDKGSession &_quorumDkg, const std::string &_func)
std::set< uint256 > complaints
CDeterministicMNCPtr dmn
std::set< uint256 > complaintsFromOthers
std::set< uint256 > prematureCommitments
std::set< uint256 > justifications
std::set< uint256 > contributions
std::set< uint256 > badMemberVotes
CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx)
Acts as a FIFO queue for incoming DKG messages.
SERIALIZE_METHODS(CDKGPrematureCommitment, obj)
Handles multiple sequential sessions of one specific LLMQ type.
The DKG session is a single instance of the DKG process.
CBLSWorkerCache cache
std::map< uint256, CDKGContribution > contributions
void VerifyAndJustify(CDKGPendingMessages &pendingMessages)
std::map< uint256, CDKGPrematureCommitment > prematureCommitments
std::map< uint256, size_t > membersMap
BLSSecretKeyVector receivedSkContributions
std::set< uint256 > seenMessages
std::vector< std::unique_ptr< CDKGMember > > members
CDKGSession(const Consensus::LLMQParams &_params, CBLSWorker &_blsWorker, CDKGSessionManager &_dkgManager)
void SendJustification(CDKGPendingMessages &pendingMessages, const std::set< uint256 > &forMembers)
void VerifyAndCommit(CDKGPendingMessages &pendingMessages)
std::map< uint256, CDKGJustification > justifications
std::set< uint256 > relayMembers
bool ShouldSimulateError(const std::string &error_type)
bool AreWeMember() const
CDKGSessionManager & dkgManager
bool PreVerifyMessage(const CDKGContribution &qc, bool &retBan) const
void ReceiveMessage(const uint256 &hash, const CDKGContribution &qc, bool &retBan)
std::map< uint256, CDKGComplaint > complaints
std::vector< CFinalCommitment > FinalizeCommitments()
void Contribute(CDKGPendingMessages &pendingMessages)
The following sets of methods are for the first 4 phases handled in the session.
std::set< uint256 > validCommitments
RecursiveMutex invCs
const Consensus::LLMQParams & params
void MarkBadMember(CDKGMember *member)
void SendCommitment(CDKGPendingMessages &pendingMessages)
const CBlockIndex * pindexQuorum
friend class CDKGMessageHandler
void SendContributions(CDKGPendingMessages &pendingMessages)
std::vector< BLSVerificationVectorPtr > receivedVvecs
void VerifyAndComplain(CDKGPendingMessages &pendingMessages)
CDKGMember * GetMember(const uint256 &proTxHash) const
BLSSecretKeyVector skContributions
size_t GetMyMemberIndex() const
void SendComplaint(CDKGPendingMessages &pendingMessages)
BLSVerificationVectorPtr vvecContribution
void VerifyConnectionAndMinProtoVersions()
void RelayInvToParticipants(const CInv &inv) const
bool Init(const CBlockIndex *_pindexQuorum, const std::vector< CDeterministicMNCPtr > &mns, const uint256 &_myProTxHash)
std::vector< size_t > pendingContributionVerifications
256-bit opaque blob.
Definition: uint256.h:138
std::shared_ptr< const CDeterministicMN > CDeterministicMNCPtr
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
Definition: hash.h:289
LLMQType
Definition: params.h:90
uint256 BuildCommitmentHash(Consensus::LLMQType llmqType, const uint256 &blockHash, const std::vector< bool > &validMembers, const CBLSPublicKey &pubKey, const uint256 &vvecHash)
Definition: quorums.cpp:26
bool SetSimulatedDKGErrorRate(const std::string &error_type, double rate)
@ proTxHash
Definition: rpcevo.cpp:50
@ SER_GETHASH
Definition: serialize.h:176
#define DYNBITSET(obj)
Definition: serialize.h:533
#define READWRITE(...)
Definition: serialize.h:183