refactor: Misc LLMQ refactoring (#4590)

* use unique_ptr instead of shared

Signed-off-by: pasta <pasta@dashboost.org>

* unique_ptr over shared_ptr

Signed-off-by: pasta <pasta@dashboost.org>

* remove unneeded ptr

Signed-off-by: pasta <pasta@dashboost.org>

* Adjust IsTxSafeForMining checks

Signed-off-by: pasta <pasta@dashboost.org>

* use const ref

Signed-off-by: pasta <pasta@dashboost.org>

* add a todo

Signed-off-by: pasta <pasta@dashboost.org>

* use optional instead of magic max value

fixes a hypothetical bug where myIdx is not "initialized" (ie max), and we sleep forever

Signed-off-by: pasta <pasta@dashboost.org>

* simplify relay check

Signed-off-by: pasta <pasta@dashboost.org>

* use count_if instead of a loop

Signed-off-by: pasta <pasta@dashboost.org>

* add a few vector reserves

Signed-off-by: pasta <pasta@dashboost.org>
This commit is contained in:
PastaPastaPasta 2021-11-29 00:12:09 -05:00 committed by GitHub
parent 850806e6e7
commit 5cf97c1b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 40 additions and 48 deletions

View File

@ -67,7 +67,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew); llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);
llmq::chainLocksHandler->UpdatedBlockTip(pindexNew); llmq::chainLocksHandler->UpdatedBlockTip();
llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload); llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload);
llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload); llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload);

View File

@ -431,7 +431,7 @@ CFinalCommitmentPtr CQuorumBlockProcessor::GetMinedCommitment(Consensus::LLMQTyp
return nullptr; return nullptr;
} }
retMinedBlockHash = p.second; retMinedBlockHash = p.second;
return std::make_shared<CFinalCommitment>(p.first); return std::make_unique<CFinalCommitment>(p.first);
} }
// The returned quorums are in reversed order, so the most recent one is at index 0 // The returned quorums are in reversed order, so the most recent one is at index 0

View File

@ -27,7 +27,7 @@ namespace llmq
{ {
class CFinalCommitment; class CFinalCommitment;
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>; using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
class CQuorumBlockProcessor class CQuorumBlockProcessor
{ {

View File

@ -202,7 +202,7 @@ void CChainLocksHandler::AcceptedBlockHeader(const CBlockIndex* pindexNew)
} }
} }
void CChainLocksHandler::UpdatedBlockTip(const CBlockIndex* pindexNew) void CChainLocksHandler::UpdatedBlockTip()
{ {
// don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is // don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is
// never locked and TrySignChainTip is not called twice in parallel. Also avoids recursive calls due to // never locked and TrySignChainTip is not called twice in parallel. Also avoids recursive calls due to
@ -460,10 +460,14 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const
if (!RejectConflictingBlocks()) { if (!RejectConflictingBlocks()) {
return true; return true;
} }
if (!isEnabled || !isEnforced) {
return true;
}
if (!IsInstantSendEnabled()) { if (!IsInstantSendEnabled()) {
return true; return true;
} }
if (!isEnabled || !isEnforced) { if (quorumInstantSendManager->IsLocked(txid)) {
return true; return true;
} }
@ -476,10 +480,7 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const
} }
} }
if (txAge < WAIT_FOR_ISLOCK_TIMEOUT && !quorumInstantSendManager->IsLocked(txid)) { return txAge >= WAIT_FOR_ISLOCK_TIMEOUT;
return false;
}
return true;
} }
// WARNING: cs_main and cs should not be held! // WARNING: cs_main and cs should not be held!

View File

@ -97,7 +97,7 @@ public:
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv); void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv);
void ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash); void ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash);
void AcceptedBlockHeader(const CBlockIndex* pindexNew); void AcceptedBlockHeader(const CBlockIndex* pindexNew);
void UpdatedBlockTip(const CBlockIndex* pindexNew); void UpdatedBlockTip();
void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime); void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime);
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted); void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted);
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected); void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected);

View File

@ -101,7 +101,7 @@ public:
obj.pushKV("membersSig", membersSig.ToString()); obj.pushKV("membersSig", membersSig.ToString());
} }
}; };
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>; using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
class CFinalCommitmentTxPayload class CFinalCommitmentTxPayload
{ {

View File

@ -82,7 +82,7 @@ CDKGPrematureCommitment::CDKGPrematureCommitment(const Consensus::LLMQParams& pa
{ {
} }
CDKGMember::CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx) : CDKGMember::CDKGMember(const CDeterministicMNCPtr& _dmn, size_t _idx) :
dmn(_dmn), dmn(_dmn),
idx(_idx), idx(_idx),
id(_dmn->proTxHash) id(_dmn->proTxHash)
@ -321,7 +321,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
bool complain = false; bool complain = false;
CBLSSecretKey skContribution; CBLSSecretKey skContribution;
if (!qc.contributions->Decrypt(myIdx, WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator), skContribution, PROTOCOL_VERSION)) { if (!qc.contributions->Decrypt(*myIdx, WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator), skContribution, PROTOCOL_VERSION)) {
logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString()); logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString());
complain = true; complain = true;
} else if (member->idx != myIdx && ShouldSimulateError("complain-lie")) { } else if (member->idx != myIdx && ShouldSimulateError("complain-lie")) {
@ -670,7 +670,7 @@ void CDKGSession::VerifyAndJustify(CDKGPendingMessages& pendingMessages)
} }
const auto& qc = WITH_LOCK(invCs, return std::move(complaints.at(*m->complaints.begin()))); const auto& qc = WITH_LOCK(invCs, return std::move(complaints.at(*m->complaints.begin())));
if (qc.complainForMembers[myIdx]) { if (qc.complainForMembers[*myIdx]) {
justifyFor.emplace(qc.proTxHash); justifyFor.emplace(qc.proTxHash);
} }
} }
@ -874,18 +874,12 @@ void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan)
} }
} }
int receivedCount = 0; auto receivedCount = std::count_if(members.cbegin(), members.cend(), [](const auto& m){
int expectedCount = 0; return !m->justifications.empty();
});
for (const auto& m : members) { auto expectedCount = std::count_if(members.cbegin(), members.cend(), [](const auto& m){
if (!m->justifications.empty()) { return m->someoneComplain;
receivedCount++; });
}
if (m->someoneComplain) {
expectedCount++;
}
}
logger.Batch("verified justification: received=%d/%d time=%d", receivedCount, expectedCount, t1.count()); logger.Batch("verified justification: received=%d/%d time=%d", receivedCount, expectedCount, t1.count());
} }
@ -899,7 +893,9 @@ void CDKGSession::VerifyAndCommit(CDKGPendingMessages& pendingMessages)
CDKGLogger logger(*this, __func__); CDKGLogger logger(*this, __func__);
std::vector<size_t> badMembers; std::vector<size_t> badMembers;
badMembers.reserve(members.size());
std::vector<size_t> openComplaintMembers; std::vector<size_t> openComplaintMembers;
openComplaintMembers.reserve(members.size());
for (const auto& m : members) { for (const auto& m : members) {
if (m->bad) { if (m->bad) {
@ -1319,14 +1315,8 @@ void CDKGSession::MarkBadMember(size_t idx)
void CDKGSession::RelayInvToParticipants(const CInv& inv) const void CDKGSession::RelayInvToParticipants(const CInv& inv) const
{ {
g_connman->ForEachNode([&](CNode* pnode) { g_connman->ForEachNode([&](CNode* pnode) {
bool relay = false; if (pnode->qwatch ||
auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash(); (!pnode->GetVerifiedProRegTxHash().IsNull() && relayMembers.count(pnode->GetVerifiedProRegTxHash()))) {
if (pnode->qwatch) {
relay = true;
} else if (!verifiedProRegTxHash.IsNull() && relayMembers.count(verifiedProRegTxHash)) {
relay = true;
}
if (relay) {
pnode->PushInventory(inv); pnode->PushInventory(inv);
} }
}); });

View File

@ -122,6 +122,7 @@ public:
Consensus::LLMQType llmqType; Consensus::LLMQType llmqType;
uint256 quorumHash; uint256 quorumHash;
uint256 proTxHash; uint256 proTxHash;
// TODO make this pair a struct with named fields
std::vector<std::pair<uint32_t, CBLSSecretKey>> contributions; std::vector<std::pair<uint32_t, CBLSSecretKey>> contributions;
CBLSSignature sig; CBLSSignature sig;
@ -190,7 +191,7 @@ public:
class CDKGMember class CDKGMember
{ {
public: public:
CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx); CDKGMember(const CDeterministicMNCPtr& _dmn, size_t _idx);
CDeterministicMNCPtr dmn; CDeterministicMNCPtr dmn;
size_t idx; size_t idx;
@ -255,7 +256,7 @@ private:
uint256 myProTxHash; uint256 myProTxHash;
CBLSId myId; CBLSId myId;
size_t myIdx{(size_t)-1}; std::optional<size_t> myIdx;
// all indexed by msg hash // all indexed by msg hash
// we expect to only receive a single vvec and contribution per member, but we must also be able to relay // we expect to only receive a single vvec and contribution per member, but we must also be able to relay
@ -279,7 +280,7 @@ public:
bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash); bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash);
size_t GetMyMemberIndex() const { return myIdx; } std::optional<size_t> GetMyMemberIndex() const { return myIdx; }
/** /**
* The following sets of methods are for the first 4 phases handled in the session. The flow of message calls * The following sets of methods are for the first 4 phases handled in the session. The flow of message calls

View File

@ -90,7 +90,7 @@ CDKGSessionHandler::CDKGSessionHandler(const Consensus::LLMQParams& _params, CBL
params(_params), params(_params),
blsWorker(_blsWorker), blsWorker(_blsWorker),
dkgManager(_dkgManager), dkgManager(_dkgManager),
curSession(std::make_shared<CDKGSession>(_params, _blsWorker, _dkgManager)), curSession(std::make_unique<CDKGSession>(_params, _blsWorker, _dkgManager)),
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages) pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT), pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION), pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
@ -158,7 +158,7 @@ void CDKGSessionHandler::StopThread()
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
{ {
curSession = std::make_shared<CDKGSession>(params, blsWorker, dkgManager); curSession = std::make_unique<CDKGSession>(params, blsWorker, dkgManager);
if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) { if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) {
return false; return false;
@ -271,7 +271,7 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
// Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor) // Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor; double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex()); int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex().value_or(0));
int64_t endTime = GetTimeMillis() + sleepTime; int64_t endTime = GetTimeMillis() + sleepTime;
int heightTmp{-1}; int heightTmp{-1};
int heightStart{-1}; int heightStart{-1};

View File

@ -114,7 +114,7 @@ private:
int currentHeight GUARDED_BY(cs) {-1}; int currentHeight GUARDED_BY(cs) {-1};
uint256 quorumHash GUARDED_BY(cs); uint256 quorumHash GUARDED_BY(cs);
std::shared_ptr<CDKGSession> curSession; std::unique_ptr<CDKGSession> curSession;
std::thread phaseHandlerThread; std::thread phaseHandlerThread;
// Do not guard these, they protect their internals themselves // Do not guard these, they protect their internals themselves

View File

@ -51,9 +51,9 @@ CQuorum::CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker) :
CQuorum::~CQuorum() = default; CQuorum::~CQuorum() = default;
void CQuorum::Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members) void CQuorum::Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members)
{ {
qc = _qc; qc = std::move(_qc);
m_quorum_base_block_index = _pQuorumBaseBlockIndex; m_quorum_base_block_index = _pQuorumBaseBlockIndex;
members = _members; members = _members;
minedBlockHash = _minedBlockHash; minedBlockHash = _minedBlockHash;
@ -315,17 +315,17 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
auto quorum = std::make_shared<CQuorum>(llmqParams, blsWorker); auto quorum = std::make_shared<CQuorum>(llmqParams, blsWorker);
auto members = CLLMQUtils::GetAllQuorumMembers(llmqParams, pQuorumBaseBlockIndex); auto members = CLLMQUtils::GetAllQuorumMembers(llmqParams, pQuorumBaseBlockIndex);
quorum->Init(qc, pQuorumBaseBlockIndex, minedBlockHash, members); quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members);
bool hasValidVvec = false; bool hasValidVvec = false;
if (quorum->ReadContributions(evoDb)) { if (quorum->ReadContributions(evoDb)) {
hasValidVvec = true; hasValidVvec = true;
} else { } else {
if (BuildQuorumContributions(qc, quorum)) { if (BuildQuorumContributions(quorum->qc, quorum)) {
quorum->WriteContributions(evoDb); quorum->WriteContributions(evoDb);
hasValidVvec = true; hasValidVvec = true;
} else { } else {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- quorum.ReadContributions and BuildQuorumContributions for block %s failed\n", __func__, qc->quorumHash.ToString()); LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- quorum.ReadContributions and BuildQuorumContributions for block %s failed\n", __func__, quorum->qc->quorumHash.ToString());
} }
} }

View File

@ -144,7 +144,7 @@ using CQuorumPtr = std::shared_ptr<CQuorum>;
using CQuorumCPtr = std::shared_ptr<const CQuorum>; using CQuorumCPtr = std::shared_ptr<const CQuorum>;
class CFinalCommitment; class CFinalCommitment;
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>; using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
class CQuorum class CQuorum
@ -171,7 +171,7 @@ private:
public: public:
CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker); CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker);
~CQuorum(); ~CQuorum();
void Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members); void Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members);
bool SetVerificationVector(const BLSVerificationVector& quorumVecIn); bool SetVerificationVector(const BLSVerificationVector& quorumVecIn);
bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare); bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare);