Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

quorums_signing.h
Go to the documentation of this file.
1 // Copyright (c) 2018-2020 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 DASH_QUORUMS_SIGNING_H
6 #define DASH_QUORUMS_SIGNING_H
7 
8 #include <llmq/quorums.h>
9 
10 #include <net.h>
11 #include <chainparams.h>
12 #include <saltedhasher.h>
13 #include <univalue.h>
14 #include <unordered_lru_cache.h>
15 
16 #include <unordered_map>
17 
18 namespace llmq
19 {
20 
22 {
23 public:
29 
30  // only in-memory
32 
33 public:
34 
36 
37  template <typename Stream, typename Operation>
38  inline void SerializationOp(Stream& s, Operation ser_action)
39  {
42  READWRITE(id);
44  READWRITE(sig);
45  if (ser_action.ForRead()) {
46  UpdateHash();
47  }
48  }
49 
50  void UpdateHash()
51  {
52  hash = ::SerializeHash(*this);
53  }
54 
55  const uint256& GetHash() const
56  {
57  assert(!hash.IsNull());
58  return hash;
59  }
60 
61  UniValue ToJson() const;
62 };
63 
65 {
66 private:
68 
73 
74 public:
75  explicit CRecoveredSigsDb(CDBWrapper& _db);
76 
78  void AddVoteTimeKeys();
79 
80  bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash);
81  bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id);
82  bool HasRecoveredSigForSession(const uint256& signHash);
83  bool HasRecoveredSigForHash(const uint256& hash);
84  bool GetRecoveredSigByHash(const uint256& hash, CRecoveredSig& ret);
85  bool GetRecoveredSigById(Consensus::LLMQType llmqType, const uint256& id, CRecoveredSig& ret);
86  void WriteRecoveredSig(const CRecoveredSig& recSig);
87  void RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256& id);
88  void TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256& id);
89 
90  void CleanupOldRecoveredSigs(int64_t maxAge);
91 
92  // votes are removed when the recovered sig is written to the db
93  bool HasVotedOnId(Consensus::LLMQType llmqType, const uint256& id);
94  bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet);
95  void WriteVoteForId(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash);
96 
97  void CleanupOldVotes(int64_t maxAge);
98 
99 private:
100  bool ReadRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, CRecoveredSig& ret);
101  void RemoveRecoveredSig(CDBBatch& batch, Consensus::LLMQType llmqType, const uint256& id, bool deleteHashKey, bool deleteTimeKey);
102 };
103 
105 {
106 public:
108 
109  virtual void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) = 0;
110 };
111 
113 {
114  friend class CSigSharesManager;
115  static const int64_t DEFAULT_MAX_RECOVERED_SIGS_AGE = 60 * 60 * 24 * 7; // keep them for a week
116 
117  // when selecting a quorum for signing and verification, we use CQuorumManager::SelectQuorum with this offset as
118  // starting height for scanning. This is because otherwise the resulting signatures would not be verifiable by nodes
119  // which are not 100% at the chain tip.
120  static const int SIGN_HEIGHT_OFFSET = 8;
121 
122 private:
124 
126 
127  // Incoming and not verified yet
128  std::unordered_map<NodeId, std::list<CRecoveredSig>> pendingRecoveredSigs;
129  std::unordered_map<uint256, std::pair<CRecoveredSig, CQuorumCPtr>, StaticSaltedHasher> pendingReconstructedRecoveredSigs;
130 
131  // must be protected by cs
133 
134  int64_t lastCleanupTime{0};
135 
136  std::vector<CRecoveredSigsListener*> recoveredSigsListeners;
137 
138 public:
139  CSigningManager(CDBWrapper& llmqDb, bool fMemory);
140 
141  bool AlreadyHave(const CInv& inv);
142  bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret);
143 
144  void ProcessMessage(CNode* pnode, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
145 
146  // This is called when a recovered signature was was reconstructed from another P2P message and is known to be valid
147  // This is the case for example when a signature appears as part of InstantSend or ChainLocks
148  void PushReconstructedRecoveredSig(const CRecoveredSig& recoveredSig, const CQuorumCPtr& quorum);
149 
150  // This is called when a recovered signature can be safely removed from the DB. This is only safe when some other
151  // mechanism prevents possible conflicts. As an example, ChainLocks prevent conflicts in confirmed TXs InstantSend votes
152  // This won't completely remove all traces of the recovered sig but instead leave the hash entry in the DB. This
153  // allows AlreadyHave to keep returning true. Cleanup will later remove the remains
154  void TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256& id);
155 
156 private:
157  void ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredSig& recoveredSig, CConnman& connman);
158  bool PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig& recoveredSig, bool& retBan);
159 
160  void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions,
161  std::unordered_map<NodeId, std::list<CRecoveredSig>>& retSigShares,
162  std::unordered_map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr, StaticSaltedHasher>& retQuorums);
164  bool ProcessPendingRecoveredSigs(CConnman& connman); // called from the worker thread of CSigSharesManager
165  void ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& recoveredSig, const CQuorumCPtr& quorum, CConnman& connman);
166  void Cleanup(); // called from the worker thread of CSigSharesManager
167 
168 public:
169  // public interface
172 
173  bool AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, bool allowReSign = false);
174  bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash);
175  bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id);
176  bool HasRecoveredSigForSession(const uint256& signHash);
177  bool GetRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id, CRecoveredSig& retRecSig);
178  bool IsConflicting(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash);
179 
180  bool HasVotedOnId(Consensus::LLMQType llmqType, const uint256& id);
181  bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet);
182 
183  std::vector<CQuorumCPtr> GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight);
184  CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET);
185 
186  // Verifies a recovered sig that was signed while the chain tip was at signedAtTip
187  bool VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig);
188 };
189 
191 
192 } // namespace llmq
193 
194 #endif //DASH_QUORUMS_SIGNING_H
void SerializationOp(Stream &s, Operation ser_action)
CRecoveredSigsDb db
void CleanupOldVotes(int64_t maxAge)
UniValue quorum(const JSONRPCRequest &request)
Definition: rpcquorums.cpp:492
#define READWRITE(obj)
Definition: serialize.h:165
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:49
void ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig &recoveredSig, const CQuorumCPtr &quorum, CConnman &connman)
void PushReconstructedRecoveredSig(const CRecoveredSig &recoveredSig, const CQuorumCPtr &quorum)
bool VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256 &id, const uint256 &msgHash, const CBLSSignature &sig)
void ProcessMessage(CNode *pnode, const std::string &strCommand, CDataStream &vRecv, CConnman &connman)
void TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id)
CCriticalSection cs
inv message data
Definition: protocol.h:429
void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions, std::unordered_map< NodeId, std::list< CRecoveredSig >> &retSigShares, std::unordered_map< std::pair< Consensus::LLMQType, uint256 >, CQuorumCPtr, StaticSaltedHasher > &retQuorums)
void RegisterRecoveredSigsListener(CRecoveredSigsListener *l)
std::vector< CQuorumCPtr > GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight)
CRecoveredSigsDb(CDBWrapper &_db)
bool GetRecoveredSigForId(Consensus::LLMQType llmqType, const uint256 &id, CRecoveredSig &retRecSig)
bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
void ProcessMessageRecoveredSig(CNode *pfrom, const CRecoveredSig &recoveredSig, CConnman &connman)
bool GetRecoveredSigById(Consensus::LLMQType llmqType, const uint256 &id, CRecoveredSig &ret)
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:103
CBLSLazySignature sig
bool AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash, bool allowReSign=false)
bool ReadRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id, CRecoveredSig &ret)
bool HasRecoveredSigForHash(const uint256 &hash)
bool ProcessPendingRecoveredSigs(CConnman &connman)
bool IsNull() const
Definition: uint256.h:33
bool HasVotedOnId(Consensus::LLMQType llmqType, const uint256 &id)
void UnregisterRecoveredSigsListener(CRecoveredSigsListener *l)
bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
FastRandomContext rnd
bool GetVoteForId(Consensus::LLMQType llmqType, const uint256 &id, uint256 &msgHashRet)
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object&#39;s serialization.
Definition: hash.h:254
LLMQType
Definition: params.h:48
static const int SIGN_HEIGHT_OFFSET
virtual void HandleNewRecoveredSig(const CRecoveredSig &recoveredSig)=0
std::unordered_map< NodeId, std::list< CRecoveredSig > > pendingRecoveredSigs
unordered_lru_cache< uint256, bool, StaticSaltedHasher, 30000 > hasSigForHashCache
CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256 &selectionHash, int signHeight=-1, int signOffset=SIGN_HEIGHT_OFFSET)
unordered_lru_cache< std::pair< Consensus::LLMQType, uint256 >, bool, StaticSaltedHasher, 30000 > hasSigForIdCache
Fast randomness source.
Definition: random.h:48
int64_t NodeId
Definition: net.h:109
Definition: net.h:136
bool GetRecoveredSigForGetData(const uint256 &hash, CRecoveredSig &ret)
bool GetRecoveredSigByHash(const uint256 &hash, CRecoveredSig &ret)
std::vector< CRecoveredSigsListener * > recoveredSigsListeners
bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256 &id)
void WriteVoteForId(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
void ProcessPendingReconstructedRecoveredSigs()
std::unordered_map< uint256, std::pair< CRecoveredSig, CQuorumCPtr >, StaticSaltedHasher > pendingReconstructedRecoveredSigs
static const int64_t DEFAULT_MAX_RECOVERED_SIGS_AGE
void CleanupOldRecoveredSigs(int64_t maxAge)
256-bit opaque blob.
Definition: uint256.h:123
bool IsConflicting(Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
const uint256 & GetHash() const
void RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id)
bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256 &id)
bool HasRecoveredSigForSession(const uint256 &signHash)
Consensus::LLMQType llmqType
UniValue ToJson() const
bool AlreadyHave(const CInv &inv)
std::shared_ptr< const CQuorum > CQuorumCPtr
Definition: quorums.h:73
bool HasRecoveredSigForSession(const uint256 &signHash)
CSigningManager * quorumSigningManager
CDBWrapper * llmqDb
bool HasVotedOnId(Consensus::LLMQType llmqType, const uint256 &id)
Information about a peer.
Definition: net.h:800
CCriticalSection cs
CSigningManager(CDBWrapper &llmqDb, bool fMemory)
bool PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig &recoveredSig, bool &retBan)
Wrapped mutex: supports recursive locking, but no waiting TODO: We should move away from using the re...
Definition: sync.h:94
void TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256 &id)
bool GetVoteForId(Consensus::LLMQType llmqType, const uint256 &id, uint256 &msgHashRet)
void WriteRecoveredSig(const CRecoveredSig &recSig)
unordered_lru_cache< uint256, bool, StaticSaltedHasher, 30000 > hasSigForSessionCache
Released under the MIT license