Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

quorums_dkgsessionmgr.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2019 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 
7 #include <llmq/quorums_debug.h>
8 #include <llmq/quorums_init.h>
9 #include <llmq/quorums_utils.h>
10 
11 #include <chainparams.h>
12 #include <net_processing.h>
13 #include <spork.h>
14 #include <validation.h>
15 
16 namespace llmq
17 {
18 
20 
21 static const std::string DB_VVEC = "qdkg_V";
22 static const std::string DB_SKCONTRIB = "qdkg_S";
23 
25  llmqDb(_llmqDb),
26  blsWorker(_blsWorker)
27 {
28  for (const auto& qt : Params().GetConsensus().llmqs) {
29  dkgSessionHandlers.emplace(std::piecewise_construct,
30  std::forward_as_tuple(qt.first),
31  std::forward_as_tuple(qt.second, blsWorker, *this));
32  }
33 }
34 
36 {
37 }
38 
40 {
41  for (auto& it : dkgSessionHandlers) {
42  it.second.StartThread();
43  }
44 }
45 
47 {
48  for (auto& it : dkgSessionHandlers) {
49  it.second.StopThread();
50  }
51 }
52 
53 void CDKGSessionManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitialDownload)
54 {
55  const auto& consensus = Params().GetConsensus();
56 
57  CleanupCache();
58 
59  if (fInitialDownload)
60  return;
61  if (!deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight))
62  return;
64  return;
65 
66  for (auto& qt : dkgSessionHandlers) {
67  qt.second.UpdatedBlockTip(pindexNew);
68  }
69 }
70 
71 void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
72 {
74  return;
75 
76  if (strCommand != NetMsgType::QCONTRIB
77  && strCommand != NetMsgType::QCOMPLAINT
78  && strCommand != NetMsgType::QJUSTIFICATION
79  && strCommand != NetMsgType::QPCOMMITMENT
80  && strCommand != NetMsgType::QWATCH) {
81  return;
82  }
83 
84  if (strCommand == NetMsgType::QWATCH) {
85  pfrom->qwatch = true;
86  return;
87  }
88 
89  if (vRecv.size() < 1) {
90  LOCK(cs_main);
91  Misbehaving(pfrom->GetId(), 100);
92  return;
93  }
94 
95  // peek into the message and see which LLMQType it is. First byte of all messages is always the LLMQType
96  Consensus::LLMQType llmqType = (Consensus::LLMQType)*vRecv.begin();
97  if (!dkgSessionHandlers.count(llmqType)) {
98  LOCK(cs_main);
99  Misbehaving(pfrom->GetId(), 100);
100  return;
101  }
102 
103  dkgSessionHandlers.at(llmqType).ProcessMessage(pfrom, strCommand, vRecv, connman);
104 }
105 
106 bool CDKGSessionManager::AlreadyHave(const CInv& inv) const
107 {
109  return false;
110 
111  for (const auto& p : dkgSessionHandlers) {
112  auto& dkgType = p.second;
113  if (dkgType.pendingContributions.HasSeen(inv.hash)
114  || dkgType.pendingComplaints.HasSeen(inv.hash)
115  || dkgType.pendingJustifications.HasSeen(inv.hash)
116  || dkgType.pendingPrematureCommitments.HasSeen(inv.hash)) {
117  return true;
118  }
119  }
120  return false;
121 }
122 
124 {
126  return false;
127 
128  for (const auto& p : dkgSessionHandlers) {
129  auto& dkgType = p.second;
130  LOCK2(dkgType.cs, dkgType.curSession->invCs);
131  if (dkgType.phase < QuorumPhase_Initialized || dkgType.phase > QuorumPhase_Contribute) {
132  continue;
133  }
134  auto it = dkgType.curSession->contributions.find(hash);
135  if (it != dkgType.curSession->contributions.end()) {
136  ret = it->second;
137  return true;
138  }
139  }
140  return false;
141 }
142 
144 {
146  return false;
147 
148  for (const auto& p : dkgSessionHandlers) {
149  auto& dkgType = p.second;
150  LOCK2(dkgType.cs, dkgType.curSession->invCs);
151  if (dkgType.phase < QuorumPhase_Contribute || dkgType.phase > QuorumPhase_Complain) {
152  continue;
153  }
154  auto it = dkgType.curSession->complaints.find(hash);
155  if (it != dkgType.curSession->complaints.end()) {
156  ret = it->second;
157  return true;
158  }
159  }
160  return false;
161 }
162 
164 {
166  return false;
167 
168  for (const auto& p : dkgSessionHandlers) {
169  auto& dkgType = p.second;
170  LOCK2(dkgType.cs, dkgType.curSession->invCs);
171  if (dkgType.phase < QuorumPhase_Complain || dkgType.phase > QuorumPhase_Justify) {
172  continue;
173  }
174  auto it = dkgType.curSession->justifications.find(hash);
175  if (it != dkgType.curSession->justifications.end()) {
176  ret = it->second;
177  return true;
178  }
179  }
180  return false;
181 }
182 
184 {
186  return false;
187 
188  for (const auto& p : dkgSessionHandlers) {
189  auto& dkgType = p.second;
190  LOCK2(dkgType.cs, dkgType.curSession->invCs);
191  if (dkgType.phase < QuorumPhase_Justify || dkgType.phase > QuorumPhase_Commit) {
192  continue;
193  }
194  auto it = dkgType.curSession->prematureCommitments.find(hash);
195  if (it != dkgType.curSession->prematureCommitments.end() && dkgType.curSession->validCommitments.count(hash)) {
196  ret = it->second;
197  return true;
198  }
199  }
200  return false;
201 }
202 
204 {
205  llmqDb.Write(std::make_tuple(DB_VVEC, llmqType, pindexQuorum->GetBlockHash(), proTxHash), *vvec);
206 }
207 
208 void CDKGSessionManager::WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSSecretKey& skContribution)
209 {
210  llmqDb.Write(std::make_tuple(DB_SKCONTRIB, llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution);
211 }
212 
213 bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, std::vector<BLSVerificationVectorPtr>& vvecsRet, BLSSecretKeyVector& skContributionsRet)
214 {
215  auto members = CLLMQUtils::GetAllQuorumMembers(llmqType, pindexQuorum);
216 
217  memberIndexesRet.clear();
218  vvecsRet.clear();
219  skContributionsRet.clear();
220  memberIndexesRet.reserve(members.size());
221  vvecsRet.reserve(members.size());
222  skContributionsRet.reserve(members.size());
223  for (size_t i = 0; i < members.size(); i++) {
224  if (validMembers[i]) {
226  CBLSSecretKey skContribution;
227  if (!GetVerifiedContribution(llmqType, pindexQuorum, members[i]->proTxHash, vvec, skContribution)) {
228  return false;
229  }
230 
231  memberIndexesRet.emplace_back(i);
232  vvecsRet.emplace_back(vvec);
233  skContributionsRet.emplace_back(skContribution);
234  }
235  }
236  return true;
237 }
238 
239 bool CDKGSessionManager::GetVerifiedContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, BLSVerificationVectorPtr& vvecRet, CBLSSecretKey& skContributionRet)
240 {
242  ContributionsCacheKey cacheKey = {llmqType, pindexQuorum->GetBlockHash(), proTxHash};
243  auto it = contributionsCache.find(cacheKey);
244  if (it != contributionsCache.end()) {
245  vvecRet = it->second.vvec;
246  skContributionRet = it->second.skContribution;
247  return true;
248  }
249 
251  BLSVerificationVectorPtr vvecPtr;
252  CBLSSecretKey skContribution;
253  if (llmqDb.Read(std::make_tuple(DB_VVEC, llmqType, pindexQuorum->GetBlockHash(), proTxHash), vvec)) {
254  vvecPtr = std::make_shared<BLSVerificationVector>(std::move(vvec));
255  }
256  llmqDb.Read(std::make_tuple(DB_SKCONTRIB, llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution);
257 
258  it = contributionsCache.emplace(cacheKey, ContributionsCacheEntry{GetTimeMillis(), vvecPtr, skContribution}).first;
259 
260  vvecRet = it->second.vvec;
261  skContributionRet = it->second.skContribution;
262 
263  return true;
264 }
265 
267 {
269  auto curTime = GetTimeMillis();
270  for (auto it = contributionsCache.begin(); it != contributionsCache.end(); ) {
271  if (curTime - it->second.entryTime > MAX_CONTRIBUTION_CACHE_TIME) {
272  it = contributionsCache.erase(it);
273  } else {
274  ++it;
275  }
276  }
277 }
278 
279 } // namespace llmq
CCriticalSection contributionsCacheCs
std::map< Consensus::LLMQType, CDKGSessionHandler > dkgSessionHandlers
const char * QPCOMMITMENT
Definition: protocol.cpp:67
std::atomic< bool > qwatch
Definition: net.h:947
static const int64_t MAX_CONTRIBUTION_CACHE_TIME
void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &proTxHash, const CBLSSecretKey &skContribution)
CDKGSessionManager * quorumDKGSessionManager
inv message data
Definition: protocol.h:429
CCriticalSection cs_main
Definition: validation.cpp:213
CBLSWorker * blsWorker
std::vector< CBLSPublicKey > BLSVerificationVector
Definition: bls.h:465
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:103
bool GetVerifiedContribution(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &proTxHash, BLSVerificationVectorPtr &vvecRet, CBLSSecretKey &skContributionRet)
std::vector< CBLSSecretKey > BLSSecretKeyVector
Definition: bls.h:467
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
const char * QJUSTIFICATION
Definition: protocol.cpp:66
static const std::string DB_VVEC
bool GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const std::vector< bool > &validMembers, std::vector< uint16_t > &memberIndexesRet, std::vector< BLSVerificationVectorPtr > &vvecsRet, BLSSecretKeyVector &skContributionsRet)
uint256 GetBlockHash() const
Definition: chain.h:292
void Misbehaving(NodeId pnode, int howmuch, const std::string &message)
Increase a node&#39;s misbehavior score.
LLMQType
Definition: params.h:48
std::shared_ptr< BLSVerificationVector > BLSVerificationVectorPtr
Definition: bls.h:471
#define LOCK2(cs1, cs2)
Definition: sync.h:179
size_type size() const
Definition: streams.h:194
void ProcessMessage(CNode *pfrom, const std::string &strCommand, CDataStream &vRecv, CConnman &connman)
#define LOCK(cs)
Definition: sync.h:178
bool GetJustification(const uint256 &hash, CDKGJustification &ret) const
bool GetContribution(const uint256 &hash, CDKGContribution &ret) const
uint256 hash
Definition: protocol.h:456
Definition: net.h:136
static const std::string DB_SKCONTRIB
NodeId GetId() const
Definition: net.h:973
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:273
CSporkManager sporkManager
Definition: spork.cpp:29
256-bit opaque blob.
Definition: uint256.h:123
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:298
const_iterator begin() const
Definition: streams.h:190
bool GetPrematureCommitment(const uint256 &hash, CDKGPrematureCommitment &ret) const
void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum, const uint256 &proTxHash, const BLSVerificationVectorPtr &vvec)
const char * QCOMPLAINT
Definition: protocol.cpp:65
void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload)
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
const CChainParams & Params()
Return the currently selected parameters.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: utiltime.cpp:56
const char * QCONTRIB
Definition: protocol.cpp:64
CDBWrapper * llmqDb
CDKGSessionManager(CDBWrapper &_llmqDb, CBLSWorker &_blsWorker)
bool IsSporkActive(SporkId nSporkID)
IsSporkActive returns a bool for time-based sporks, and should be used to determine whether the spork...
Definition: spork.cpp:211
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:183
Information about a peer.
Definition: net.h:800
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:54
std::map< ContributionsCacheKey, ContributionsCacheEntry > contributionsCache
const char * QWATCH
Definition: protocol.cpp:68
bool GetComplaint(const uint256 &hash, CDKGComplaint &ret) const
bool AlreadyHave(const CInv &inv) const
static std::vector< CDeterministicMNCPtr > GetAllQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex *pindexQuorum)
Released under the MIT license