refactor: pass references to objects instead of using global definitions (#4988)

* fix: move chain activation logic downward to succeed LLMQ initialization

* fix: change order of initialization to reflect dependency

* llmq: pass all global pointers invoked as CDSNotificationInterface arguments

* llmq: pass reference to quorumDKGDebugManager instead of invoking global

* llmq: pass reference to quorumBlockProcessor instead of invoking global

* llmq: pass reference to quorumDKGSessionManager instead of invoking global

* llmq: pass reference to quorumManager instead of invoking global

Co-authored-by: "UdjinM6 <UdjinM6@users.noreply.github.com>"

* llmq: pass reference to quorumSigSharesManager within CSigningManager and networking

* llmq: pass reference to quorumSigSharesManager instead of invoking global

* llmq: pass reference to chainLocksHandler instead of querying global

* llmq: pass reference to quorumInstantSendManager instead of querying global

* trivial: accept argument as const where possible

* style: remove an unneeded const_cast and instead pass by const reference

* style: use const where possible

Co-authored-by: pasta <pasta@dashboost.org>
This commit is contained in:
Kittywhiskers Van Gogh 2022-09-22 16:44:48 +05:30 committed by GitHub
parent 9293d2f382
commit a35245653c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 660 additions and 386 deletions

View File

@ -117,12 +117,12 @@ bool CCoinJoinBroadcastTx::CheckSignature(const CBLSPublicKey& blsPubKey) const
return true; return true;
} }
bool CCoinJoinBroadcastTx::IsExpired(const CBlockIndex* pindex) const bool CCoinJoinBroadcastTx::IsExpired(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) const
{ {
// expire confirmed DSTXes after ~1h since confirmation or chainlocked confirmation // expire confirmed DSTXes after ~1h since confirmation or chainlocked confirmation
if (nConfirmedHeight == -1 || pindex->nHeight < nConfirmedHeight) return false; // not mined yet if (nConfirmedHeight == -1 || pindex->nHeight < nConfirmedHeight) return false; // not mined yet
if (pindex->nHeight - nConfirmedHeight > 24) return true; // mined more than an hour ago if (pindex->nHeight - nConfirmedHeight > 24) return true; // mined more than an hour ago
return llmq::chainLocksHandler->HasChainLock(pindex->nHeight, *pindex->phashBlock); return clhandler.HasChainLock(pindex->nHeight, *pindex->phashBlock);
} }
bool CCoinJoinBroadcastTx::IsValidStructure() const bool CCoinJoinBroadcastTx::IsValidStructure() const
@ -440,13 +440,13 @@ CCoinJoinBroadcastTx CCoinJoin::GetDSTX(const uint256& hash)
return (it == mapDSTX.end()) ? CCoinJoinBroadcastTx() : it->second; return (it == mapDSTX.end()) ? CCoinJoinBroadcastTx() : it->second;
} }
void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex) void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler)
{ {
AssertLockNotHeld(cs_mapdstx); AssertLockNotHeld(cs_mapdstx);
LOCK(cs_mapdstx); LOCK(cs_mapdstx);
auto it = mapDSTX.begin(); auto it = mapDSTX.begin();
while (it != mapDSTX.end()) { while (it != mapDSTX.end()) {
if (it->second.IsExpired(pindex)) { if (it->second.IsExpired(pindex, clhandler)) {
mapDSTX.erase(it++); mapDSTX.erase(it++);
} else { } else {
++it; ++it;
@ -455,17 +455,17 @@ void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex)
LogPrint(BCLog::COINJOIN, "CCoinJoin::CheckDSTXes -- mapDSTX.size()=%llu\n", mapDSTX.size()); LogPrint(BCLog::COINJOIN, "CCoinJoin::CheckDSTXes -- mapDSTX.size()=%llu\n", mapDSTX.size());
} }
void CCoinJoin::UpdatedBlockTip(const CBlockIndex* pindex) void CCoinJoin::UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler)
{ {
if (pindex && masternodeSync->IsBlockchainSynced()) { if (pindex && masternodeSync->IsBlockchainSynced()) {
CheckDSTXes(pindex); CheckDSTXes(pindex, clhandler);
} }
} }
void CCoinJoin::NotifyChainLock(const CBlockIndex* pindex) void CCoinJoin::NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler)
{ {
if (pindex && masternodeSync->IsBlockchainSynced()) { if (pindex && masternodeSync->IsBlockchainSynced()) {
CheckDSTXes(pindex); CheckDSTXes(pindex, clhandler);
} }
} }

View File

@ -23,6 +23,10 @@ class CConnman;
class CBLSPublicKey; class CBLSPublicKey;
class CBlockIndex; class CBlockIndex;
namespace llmq {
class CChainLocksHandler;
} // namespace llmq
// timeouts // timeouts
static constexpr int COINJOIN_AUTO_TIMEOUT_MIN = 5; static constexpr int COINJOIN_AUTO_TIMEOUT_MIN = 5;
static constexpr int COINJOIN_AUTO_TIMEOUT_MAX = 15; static constexpr int COINJOIN_AUTO_TIMEOUT_MAX = 15;
@ -298,7 +302,7 @@ public:
bool CheckSignature(const CBLSPublicKey& blsPubKey) const; bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
void SetConfirmedHeight(int nConfirmedHeightIn) { nConfirmedHeight = nConfirmedHeightIn; } void SetConfirmedHeight(int nConfirmedHeightIn) { nConfirmedHeight = nConfirmedHeightIn; }
bool IsExpired(const CBlockIndex* pindex) const; bool IsExpired(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) const;
bool IsValidStructure() const; bool IsValidStructure() const;
}; };
@ -374,7 +378,7 @@ private:
static Mutex cs_mapdstx; static Mutex cs_mapdstx;
static std::map<uint256, CCoinJoinBroadcastTx> mapDSTX GUARDED_BY(cs_mapdstx); static std::map<uint256, CCoinJoinBroadcastTx> mapDSTX GUARDED_BY(cs_mapdstx);
static void CheckDSTXes(const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_mapdstx); static void CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) LOCKS_EXCLUDED(cs_mapdstx);
public: public:
static constexpr std::array<CAmount, 5> GetStandardDenominations() { return vecStandardDenominations; } static constexpr std::array<CAmount, 5> GetStandardDenominations() { return vecStandardDenominations; }
@ -477,8 +481,8 @@ public:
static void AddDSTX(const CCoinJoinBroadcastTx& dstx) LOCKS_EXCLUDED(cs_mapdstx); static void AddDSTX(const CCoinJoinBroadcastTx& dstx) LOCKS_EXCLUDED(cs_mapdstx);
static CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(cs_mapdstx); static CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(cs_mapdstx);
static void UpdatedBlockTip(const CBlockIndex* pindex); static void UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler);
static void NotifyChainLock(const CBlockIndex* pindex); static void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler);
static void UpdateDSTXConfirmedHeight(const CTransactionRef& tx, int nHeight); static void UpdateDSTXConfirmedHeight(const CTransactionRef& tx, int nHeight);
static void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx); static void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx);

View File

@ -20,6 +20,13 @@
#include <llmq/instantsend.h> #include <llmq/instantsend.h>
#include <llmq/dkgsessionmgr.h> #include <llmq/dkgsessionmgr.h>
CDSNotificationInterface::CDSNotificationInterface(CConnman& _connman,
std::unique_ptr<CMasternodeSync>& _mnsync, std::unique_ptr<CDeterministicMNManager>& _dmnman,
std::unique_ptr<CGovernanceManager>& _govman, std::unique_ptr<llmq::CChainLocksHandler>& _clhandler,
std::unique_ptr<llmq::CInstantSendManager>& _isman, std::unique_ptr<llmq::CQuorumManager>& _qman,
std::unique_ptr<llmq::CDKGSessionManager>& _qdkgsman
) : connman(_connman), mnsync(_mnsync), dmnman(_dmnman), govman(_govman), clhandler(_clhandler), isman(_isman), qman(_qman), qdkgsman(_qdkgsman) {}
void CDSNotificationInterface::InitializeCurrentBlockTip() void CDSNotificationInterface::InitializeCurrentBlockTip()
{ {
SynchronousUpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload()); SynchronousUpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload());
@ -28,15 +35,15 @@ void CDSNotificationInterface::InitializeCurrentBlockTip()
void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew) void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew)
{ {
llmq::chainLocksHandler->AcceptedBlockHeader(pindexNew); clhandler->AcceptedBlockHeader(pindexNew);
if (masternodeSync != nullptr) { if (mnsync != nullptr) {
masternodeSync->AcceptedBlockHeader(pindexNew); mnsync->AcceptedBlockHeader(pindexNew);
} }
} }
void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
{ {
masternodeSync->NotifyHeaderTip(pindexNew, fInitialDownload); mnsync->NotifyHeaderTip(pindexNew, fInitialDownload);
} }
void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
@ -44,7 +51,7 @@ void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pin
if (pindexNew == pindexFork) // blocks were disconnected without any new ones if (pindexNew == pindexFork) // blocks were disconnected without any new ones
return; return;
deterministicMNManager->UpdatedBlockTip(pindexNew); dmnman->UpdatedBlockTip(pindexNew);
} }
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
@ -52,7 +59,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
if (pindexNew == pindexFork) // blocks were disconnected without any new ones if (pindexNew == pindexFork) // blocks were disconnected without any new ones
return; return;
masternodeSync->UpdatedBlockTip(pindexNew, fInitialDownload); mnsync->UpdatedBlockTip(pindexNew, fInitialDownload);
// Update global DIP0001 activation status // Update global DIP0001 activation status
fDIP0001ActiveAtTip = pindexNew->nHeight >= Params().GetConsensus().DIP0001Height; fDIP0001ActiveAtTip = pindexNew->nHeight >= Params().GetConsensus().DIP0001Height;
@ -60,32 +67,32 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
if (fInitialDownload) if (fInitialDownload)
return; return;
CCoinJoin::UpdatedBlockTip(pindexNew); CCoinJoin::UpdatedBlockTip(pindexNew, *clhandler);
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
for (auto& pair : coinJoinClientManagers) { for (auto& pair : coinJoinClientManagers) {
pair.second->UpdatedBlockTip(pindexNew); pair.second->UpdatedBlockTip(pindexNew);
} }
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew); isman->UpdatedBlockTip(pindexNew);
llmq::chainLocksHandler->UpdatedBlockTip(); clhandler->UpdatedBlockTip();
llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload); qman->UpdatedBlockTip(pindexNew, fInitialDownload);
llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload); qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload);
if (!fDisableGovernance) governance->UpdatedBlockTip(pindexNew, connman); if (!fDisableGovernance) govman->UpdatedBlockTip(pindexNew, connman);
} }
void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime) void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime)
{ {
llmq::quorumInstantSendManager->TransactionAddedToMempool(ptx); isman->TransactionAddedToMempool(ptx);
llmq::chainLocksHandler->TransactionAddedToMempool(ptx, nAcceptTime); clhandler->TransactionAddedToMempool(ptx, nAcceptTime);
CCoinJoin::TransactionAddedToMempool(ptx); CCoinJoin::TransactionAddedToMempool(ptx);
} }
void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason) void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason)
{ {
llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); isman->TransactionRemovedFromMempool(ptx);
} }
void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted) void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted)
@ -98,26 +105,26 @@ void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock
// to abandon a transaction and then have it inadvertently cleared by // to abandon a transaction and then have it inadvertently cleared by
// the notification that the conflicted transaction was evicted. // the notification that the conflicted transaction was evicted.
llmq::quorumInstantSendManager->BlockConnected(pblock, pindex, vtxConflicted); isman->BlockConnected(pblock, pindex, vtxConflicted);
llmq::chainLocksHandler->BlockConnected(pblock, pindex, vtxConflicted); clhandler->BlockConnected(pblock, pindex, vtxConflicted);
CCoinJoin::BlockConnected(pblock, pindex, vtxConflicted); CCoinJoin::BlockConnected(pblock, pindex, vtxConflicted);
} }
void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected) void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected)
{ {
llmq::quorumInstantSendManager->BlockDisconnected(pblock, pindexDisconnected); isman->BlockDisconnected(pblock, pindexDisconnected);
llmq::chainLocksHandler->BlockDisconnected(pblock, pindexDisconnected); clhandler->BlockDisconnected(pblock, pindexDisconnected);
CCoinJoin::BlockDisconnected(pblock, pindexDisconnected); CCoinJoin::BlockDisconnected(pblock, pindexDisconnected);
} }
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman) void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman)
{ {
CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, connman); CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, connman);
governance->UpdateCachesAndClean(); govman->UpdateCachesAndClean();
} }
void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{ {
llmq::quorumInstantSendManager->NotifyChainLock(pindex); isman->NotifyChainLock(pindex);
CCoinJoin::NotifyChainLock(pindex); CCoinJoin::NotifyChainLock(pindex, *clhandler);
} }

View File

@ -7,10 +7,26 @@
#include <validationinterface.h> #include <validationinterface.h>
class CConnman;
class CDeterministicMNManager;
class CGovernanceManager;
class CMasternodeSync;
namespace llmq {
class CChainLocksHandler;
class CDKGSessionManager;
class CInstantSendManager;
class CQuorumManager;
} // namespace llmq
class CDSNotificationInterface : public CValidationInterface class CDSNotificationInterface : public CValidationInterface
{ {
public: public:
explicit CDSNotificationInterface(CConnman& connmanIn): connman(connmanIn) {} explicit CDSNotificationInterface(CConnman& _connman,
std::unique_ptr<CMasternodeSync>& _mnsync, std::unique_ptr<CDeterministicMNManager>& _dmnman,
std::unique_ptr<CGovernanceManager>& _govman, std::unique_ptr<llmq::CChainLocksHandler>& _clhandler,
std::unique_ptr<llmq::CInstantSendManager>& _isman, std::unique_ptr<llmq::CQuorumManager>& _qman,
std::unique_ptr<llmq::CDKGSessionManager>& _qdkgsman);
virtual ~CDSNotificationInterface() = default; virtual ~CDSNotificationInterface() = default;
// a small helper to initialize current block height in sub-modules on startup // a small helper to initialize current block height in sub-modules on startup
@ -31,6 +47,15 @@ protected:
private: private:
CConnman& connman; CConnman& connman;
std::unique_ptr<CMasternodeSync>& mnsync;
std::unique_ptr<CDeterministicMNManager>& dmnman;
std::unique_ptr<CGovernanceManager>& govman;
std::unique_ptr<llmq::CChainLocksHandler>& clhandler;
std::unique_ptr<llmq::CInstantSendManager>& isman;
std::unique_ptr<llmq::CQuorumManager>& qman;
std::unique_ptr<llmq::CDKGSessionManager>& qdkgsman;
}; };
#endif // BITCOIN_DSNOTIFICATIONINTERFACE_H #endif // BITCOIN_DSNOTIFICATIONINTERFACE_H

View File

@ -49,7 +49,7 @@ bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidatio
} }
// This can only be done after the block has been fully processed, as otherwise we won't have the finished MN list // This can only be done after the block has been fully processed, as otherwise we won't have the finished MN list
bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view) bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const llmq::CQuorumBlockProcessor& quorum_block_processor, CValidationState& state, const CCoinsViewCache& view)
{ {
if (block.vtx[0]->nType != TRANSACTION_COINBASE) { if (block.vtx[0]->nType != TRANSACTION_COINBASE) {
return true; return true;
@ -84,7 +84,7 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValid
LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootMNList: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeMerkleMNL * 0.000001); LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootMNList: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeMerkleMNL * 0.000001);
if (cbTx.nVersion >= 2) { if (cbTx.nVersion >= 2) {
if (!CalcCbTxMerkleRootQuorums(block, pindex->pprev, calculatedMerkleRoot, state)) { if (!CalcCbTxMerkleRootQuorums(block, pindex->pprev, quorum_block_processor, calculatedMerkleRoot, state)) {
// pass the state returned by the function above // pass the state returned by the function above
return false; return false;
} }
@ -167,9 +167,9 @@ using QcIndexedHashMap = std::map<Consensus::LLMQType, std::map<int16_t, uint256
* @param pindexPrev The const CBlockIndex* (ie a block) of a block. Both the Quorum list and quorum rotation actiavtion status will be retrieved based on this block. * @param pindexPrev The const CBlockIndex* (ie a block) of a block. Both the Quorum list and quorum rotation actiavtion status will be retrieved based on this block.
* @return nullopt if quorumCommitment was unable to be found, otherwise returns the qcHashes and qcIndexedHashes that were calculated or cached * @return nullopt if quorumCommitment was unable to be found, otherwise returns the qcHashes and qcIndexedHashes that were calculated or cached
*/ */
auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev) -> auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor) ->
std::optional<std::pair<QcHashMap /*qcHashes*/, QcIndexedHashMap /*qcIndexedHashes*/>> { std::optional<std::pair<QcHashMap /*qcHashes*/, QcIndexedHashMap /*qcIndexedHashes*/>> {
auto quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(pindexPrev); auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(pindexPrev);
static Mutex cs_cache; static Mutex cs_cache;
static std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> quorums_cached GUARDED_BY(cs_cache); static std::map<Consensus::LLMQType, std::vector<const CBlockIndex*>> quorums_cached GUARDED_BY(cs_cache);
@ -194,7 +194,7 @@ auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev) ->
auto& map_indexed_hashes = qcIndexedHashes_cached[llmqType]; auto& map_indexed_hashes = qcIndexedHashes_cached[llmqType];
for (const auto& blockIndex : vecBlockIndexes) { for (const auto& blockIndex : vecBlockIndexes) {
uint256 dummyHash; uint256 dummyHash;
llmq::CFinalCommitmentPtr pqc = llmq::quorumBlockProcessor->GetMinedCommitment(llmqType, blockIndex->GetBlockHash(), dummyHash); llmq::CFinalCommitmentPtr pqc = quorum_block_processor.GetMinedCommitment(llmqType, blockIndex->GetBlockHash(), dummyHash);
if (pqc == nullptr) { if (pqc == nullptr) {
// this should never happen // this should never happen
return std::nullopt; return std::nullopt;
@ -220,7 +220,7 @@ auto CalcHashCountFromQCHashes(const QcHashMap& qcHashes)
return hash_count; return hash_count;
} }
bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state) bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, CValidationState& state)
{ {
static int64_t nTimeMined = 0; static int64_t nTimeMined = 0;
static int64_t nTimeLoop = 0; static int64_t nTimeLoop = 0;
@ -228,7 +228,7 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
int64_t nTime1 = GetTimeMicros(); int64_t nTime1 = GetTimeMicros();
auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev); auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev, quorum_block_processor);
if (retVal == std::nullopt) { if (retVal == std::nullopt) {
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "commitment-not-found"); return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "commitment-not-found");
} }

View File

@ -13,6 +13,10 @@ class CBlockIndex;
class CCoinsViewCache; class CCoinsViewCache;
class CValidationState; class CValidationState;
namespace llmq {
class CQuorumBlockProcessor;
}// namespace llmq
// coinbase transaction // coinbase transaction
class CCbTx class CCbTx
{ {
@ -51,8 +55,8 @@ public:
bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state); bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state);
bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view); bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const llmq::CQuorumBlockProcessor& quorum_block_processor, CValidationState& state, const CCoinsViewCache& view);
bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state, const CCoinsViewCache& view); bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state, const CCoinsViewCache& view);
bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state); bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, CValidationState& state);
#endif // BITCOIN_EVO_CBTX_H #endif // BITCOIN_EVO_CBTX_H

View File

@ -8,6 +8,7 @@
#include <llmq/commitment.h> #include <llmq/commitment.h>
#include <llmq/signing.h> #include <llmq/signing.h>
#include <llmq/utils.h> #include <llmq/utils.h>
#include <llmq/quorums.h>
#include <chain.h> #include <chain.h>
#include <chainparams.h> #include <chainparams.h>
@ -27,8 +28,8 @@ bool MNHFTx::Verify(const CBlockIndex* pQuorumIndex) const
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
const uint256 requestId = ::SerializeHash(std::make_pair(CBLSIG_REQUESTID_PREFIX, pQuorumIndex->nHeight)); const uint256 requestId = ::SerializeHash(std::make_pair(CBLSIG_REQUESTID_PREFIX, pQuorumIndex->nHeight));
return llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) || return llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) ||
llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, signOffset); llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, signOffset);
} }
bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main) bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)

View File

@ -130,10 +130,11 @@ CSimplifiedMNListDiff::CSimplifiedMNListDiff() = default;
CSimplifiedMNListDiff::~CSimplifiedMNListDiff() = default; CSimplifiedMNListDiff::~CSimplifiedMNListDiff() = default;
bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex) bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex,
const llmq::CQuorumBlockProcessor& quorum_block_processor)
{ {
auto baseQuorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(baseBlockIndex); auto baseQuorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(baseBlockIndex);
auto quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(blockIndex); auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(blockIndex);
std::set<std::pair<Consensus::LLMQType, uint256>> baseQuorumHashes; std::set<std::pair<Consensus::LLMQType, uint256>> baseQuorumHashes;
std::set<std::pair<Consensus::LLMQType, uint256>> quorumHashes; std::set<std::pair<Consensus::LLMQType, uint256>> quorumHashes;
@ -156,7 +157,7 @@ bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex,
for (auto& p : quorumHashes) { for (auto& p : quorumHashes) {
if (!baseQuorumHashes.count(p)) { if (!baseQuorumHashes.count(p)) {
uint256 minedBlockHash; uint256 minedBlockHash;
llmq::CFinalCommitmentPtr qc = llmq::quorumBlockProcessor->GetMinedCommitment(p.first, p.second, minedBlockHash); llmq::CFinalCommitmentPtr qc = quorum_block_processor.GetMinedCommitment(p.first, p.second, minedBlockHash);
if (qc == nullptr) { if (qc == nullptr) {
return false; return false;
} }
@ -219,7 +220,8 @@ void CSimplifiedMNListDiff::ToJson(UniValue& obj, bool extended) const
} }
} }
bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, std::string& errorRet, bool extended) bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet,
const llmq::CQuorumBlockProcessor& quorum_block_processor, std::string& errorRet, bool extended)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
mnListDiffRet = CSimplifiedMNListDiff(); mnListDiffRet = CSimplifiedMNListDiff();
@ -259,7 +261,7 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc
// null block hash was provided to get the diff from the genesis block. // null block hash was provided to get the diff from the genesis block.
mnListDiffRet.baseBlockHash = baseBlockHash; mnListDiffRet.baseBlockHash = baseBlockHash;
if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex)) { if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex, quorum_block_processor)) {
errorRet = strprintf("failed to build quorums diff"); errorRet = strprintf("failed to build quorums diff");
return false; return false;
} }

View File

@ -15,9 +15,9 @@ class CBlockIndex;
class CDeterministicMNList; class CDeterministicMNList;
class CDeterministicMN; class CDeterministicMN;
namespace llmq namespace llmq {
{ class CFinalCommitment;
class CFinalCommitment; class CQuorumBlockProcessor;
} // namespace llmq } // namespace llmq
class CSimplifiedMNListEntry class CSimplifiedMNListEntry
@ -117,11 +117,13 @@ public:
CSimplifiedMNListDiff(); CSimplifiedMNListDiff();
~CSimplifiedMNListDiff(); ~CSimplifiedMNListDiff();
bool BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex); bool BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex,
const llmq::CQuorumBlockProcessor& quorum_block_processor);
void ToJson(UniValue& obj, bool extended = false) const; void ToJson(UniValue& obj, bool extended = false) const;
}; };
bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, std::string& errorRet, bool extended = false); bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet,
const llmq::CQuorumBlockProcessor& quorum_block_processor, std::string& errorRet, bool extended = false);
#endif // BITCOIN_EVO_SIMPLIFIEDMNS_H #endif // BITCOIN_EVO_SIMPLIFIEDMNS_H

View File

@ -98,7 +98,8 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
return false; return false;
} }
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor,
CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -125,7 +126,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
nTimeLoop += nTime2 - nTime1; nTimeLoop += nTime2 - nTime1;
LogPrint(BCLog::BENCHMARK, " - Loop: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeLoop * 0.000001); LogPrint(BCLog::BENCHMARK, " - Loop: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeLoop * 0.000001);
if (!llmq::quorumBlockProcessor->ProcessBlock(block, pindex, state, fJustCheck, fCheckCbTxMerleRoots)) { if (!quorum_block_processor.ProcessBlock(block, pindex, state, fJustCheck, fCheckCbTxMerleRoots)) {
// pass the state returned by the function above // pass the state returned by the function above
return false; return false;
} }
@ -143,7 +144,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
nTimeDMN += nTime4 - nTime3; nTimeDMN += nTime4 - nTime3;
LogPrint(BCLog::BENCHMARK, " - deterministicMNManager: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeDMN * 0.000001); LogPrint(BCLog::BENCHMARK, " - deterministicMNManager: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeDMN * 0.000001);
if (fCheckCbTxMerleRoots && !CheckCbTxMerkleRoots(block, pindex, state, view)) { if (fCheckCbTxMerleRoots && !CheckCbTxMerkleRoots(block, pindex, quorum_block_processor, state, view)) {
// pass the state returned by the function above // pass the state returned by the function above
return false; return false;
} }
@ -159,7 +160,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
return true; return true;
} }
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -175,7 +176,7 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex)
return false; return false;
} }
if (!llmq::quorumBlockProcessor->UndoBlock(block, pindex)) { if (!quorum_block_processor.UndoBlock(block, pindex)) {
return false; return false;
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {

View File

@ -17,7 +17,8 @@ class CValidationState;
extern CCriticalSection cs_main; extern CCriticalSection cs_main;
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view, bool check_sigs) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view, bool check_sigs) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor,
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
#endif // BITCOIN_EVO_SPECIALTXMAN_H #endif // BITCOIN_EVO_SPECIALTXMAN_H

View File

@ -82,12 +82,15 @@
#include <evo/deterministicmns.h> #include <evo/deterministicmns.h>
#include <llmq/blockprocessor.h> #include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/init.h> #include <llmq/init.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h> #include <llmq/quorums.h>
#include <llmq/dkgsessionmgr.h> #include <llmq/dkgsessionmgr.h>
#include <llmq/signing.h> #include <llmq/signing.h>
#include <llmq/snapshot.h> #include <llmq/snapshot.h>
#include <llmq/utils.h> #include <llmq/utils.h>
#include <llmq/signing_shares.h>
#include <statsd_client.h> #include <statsd_client.h>
@ -1777,7 +1780,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
node.chainman = &g_chainman; node.chainman = &g_chainman;
ChainstateManager& chainman = *Assert(node.chainman); ChainstateManager& chainman = *Assert(node.chainman);
node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), *node.scheduler, chainman, *node.mempool, args.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61))); node.peer_logic.reset(new PeerLogicValidation(
node.connman.get(), node.banman.get(), *node.scheduler, chainman, *node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, args.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61))
);
RegisterValidationInterface(node.peer_logic.get()); RegisterValidationInterface(node.peer_logic.get());
::governance = std::make_unique<CGovernanceManager>(); ::governance = std::make_unique<CGovernanceManager>();
@ -1933,7 +1940,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
} }
#endif #endif
pdsNotificationInterface = new CDSNotificationInterface(*node.connman); pdsNotificationInterface = new CDSNotificationInterface(
*node.connman, ::masternodeSync, ::deterministicMNManager, ::governance, llmq::chainLocksHandler,
llmq::quorumInstantSendManager, llmq::quorumManager, llmq::quorumDKGSessionManager
);
RegisterValidationInterface(pdsNotificationInterface); RegisterValidationInterface(pdsNotificationInterface);
if (fMasternodeMode) { if (fMasternodeMode) {
@ -2012,7 +2022,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
try { try {
LOCK(cs_main); LOCK(cs_main);
chainman.InitializeChainstate(); chainman.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinstip_cache = nCoinCacheUsage;
chainman.m_total_coinsdb_cache = nCoinDBCache; chainman.m_total_coinsdb_cache = nCoinDBCache;

View File

@ -6,6 +6,7 @@
#include <llmq/quorums.h> #include <llmq/quorums.h>
#include <llmq/instantsend.h> #include <llmq/instantsend.h>
#include <llmq/utils.h> #include <llmq/utils.h>
#include <llmq/signing_shares.h>
#include <chain.h> #include <chain.h>
#include <chainparams.h> #include <chainparams.h>
@ -23,10 +24,8 @@ namespace llmq
{ {
std::unique_ptr<CChainLocksHandler> chainLocksHandler; std::unique_ptr<CChainLocksHandler> chainLocksHandler;
CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager) : CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman) :
scheduler(std::make_unique<CScheduler>()), scheduler(std::make_unique<CScheduler>()), mempool(_mempool), connman(_connman), spork_manager(sporkManager), sigman(_sigman), shareman(_shareman),
mempool(_mempool), connman(_connman),
spork_manager(sporkManager),
scheduler_thread(std::make_unique<std::thread>([&] { TraceThread("cl-schdlr", [&] { scheduler->serviceQueue(); }); })) scheduler_thread(std::make_unique<std::thread>([&] { TraceThread("cl-schdlr", [&] { scheduler->serviceQueue(); }); }))
{ {
} }
@ -39,7 +38,7 @@ CChainLocksHandler::~CChainLocksHandler()
void CChainLocksHandler::Start() void CChainLocksHandler::Start()
{ {
quorumSigningManager->RegisterRecoveredSigsListener(this); sigman.RegisterRecoveredSigsListener(this);
scheduler->scheduleEvery([&]() { scheduler->scheduleEvery([&]() {
CheckActiveState(); CheckActiveState();
EnforceBestChainLock(); EnforceBestChainLock();
@ -51,7 +50,7 @@ void CChainLocksHandler::Start()
void CChainLocksHandler::Stop() void CChainLocksHandler::Stop()
{ {
scheduler->stop(); scheduler->stop();
quorumSigningManager->UnregisterRecoveredSigsListener(this); sigman.UnregisterRecoveredSigsListener(this);
} }
bool CChainLocksHandler::AlreadyHave(const CInv& inv) const bool CChainLocksHandler::AlreadyHave(const CInv& inv) const
@ -117,7 +116,7 @@ void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CCha
} }
const uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, clsig.getHeight())); const uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, clsig.getHeight()));
if (!llmq::CSigningManager::VerifyRecoveredSig(Params().GetConsensus().llmqTypeChainLocks, clsig.getHeight(), requestId, clsig.getBlockHash(), clsig.getSig())) { if (!llmq::CSigningManager::VerifyRecoveredSig(Params().GetConsensus().llmqTypeChainLocks, *llmq::quorumManager, clsig.getHeight(), requestId, clsig.getBlockHash(), clsig.getSig())) {
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- invalid CLSIG (%s), peer=%d\n", __func__, clsig.ToString(), from); LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- invalid CLSIG (%s), peer=%d\n", __func__, clsig.ToString(), from);
if (from != -1) { if (from != -1) {
LOCK(cs_main); LOCK(cs_main);
@ -335,7 +334,7 @@ void CChainLocksHandler::TrySignChainTip()
lastSignedMsgHash = msgHash; lastSignedMsgHash = msgHash;
} }
quorumSigningManager->AsyncSignIfMember(Params().GetConsensus().llmqTypeChainLocks, requestId, msgHash); sigman.AsyncSignIfMember(Params().GetConsensus().llmqTypeChainLocks, shareman, requestId, msgHash);
} }
void CChainLocksHandler::TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) void CChainLocksHandler::TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime)
@ -436,19 +435,19 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const
return ret; return ret;
} }
bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const bool CChainLocksHandler::IsTxSafeForMining(const CInstantSendManager& isman, const uint256& txid) const
{ {
if (!quorumInstantSendManager->RejectConflictingBlocks()) { if (!isman.RejectConflictingBlocks()) {
return true; return true;
} }
if (!isEnabled || !isEnforced) { if (!isEnabled || !isEnforced) {
return true; return true;
} }
if (!quorumInstantSendManager->IsInstantSendEnabled()) { if (!isman.IsInstantSendEnabled()) {
return true; return true;
} }
if (quorumInstantSendManager->IsLocked(txid)) { if (isman.IsLocked(txid)) {
return true; return true;
} }

View File

@ -27,6 +27,9 @@ class CSporkManager;
namespace llmq namespace llmq
{ {
class CInstantSendManager;
class CSigningManager;
class CSigSharesManager;
class CChainLocksHandler : public CRecoveredSigsListener class CChainLocksHandler : public CRecoveredSigsListener
{ {
@ -40,6 +43,8 @@ private:
CConnman& connman; CConnman& connman;
CTxMemPool& mempool; CTxMemPool& mempool;
CSporkManager& spork_manager; CSporkManager& spork_manager;
CSigningManager& sigman;
CSigSharesManager& shareman;
std::unique_ptr<CScheduler> scheduler; std::unique_ptr<CScheduler> scheduler;
std::unique_ptr<std::thread> scheduler_thread; std::unique_ptr<std::thread> scheduler_thread;
mutable CCriticalSection cs; mutable CCriticalSection cs;
@ -72,7 +77,7 @@ private:
int64_t lastCleanupTime GUARDED_BY(cs) {0}; int64_t lastCleanupTime GUARDED_BY(cs) {0};
public: public:
explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager); explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman);
~CChainLocksHandler(); ~CChainLocksHandler();
void Start(); void Start();
@ -97,7 +102,7 @@ public:
bool HasChainLock(int nHeight, const uint256& blockHash) const; bool HasChainLock(int nHeight, const uint256& blockHash) const;
bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const; bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const;
bool IsTxSafeForMining(const uint256& txid) const; bool IsTxSafeForMining(const CInstantSendManager& isman, const uint256& txid) const;
private: private:
// these require locks to be held already // these require locks to be held already

View File

@ -101,7 +101,7 @@ bool CDKGSession::Init(const CBlockIndex* _pQuorumBaseBlockIndex, const std::vec
} }
if (!myProTxHash.IsNull()) { if (!myProTxHash.IsNull()) {
quorumDKGDebugManager->InitLocalSessionStatus(params, quorumIndex, m_quorum_base_block_index->GetBlockHash(), m_quorum_base_block_index->nHeight); dkgDebugManager.InitLocalSessionStatus(params, quorumIndex, m_quorum_base_block_index->GetBlockHash(), m_quorum_base_block_index->nHeight);
relayMembers = utils::GetQuorumRelayMembers(params, m_quorum_base_block_index, myProTxHash, true); relayMembers = utils::GetQuorumRelayMembers(params, m_quorum_base_block_index, myProTxHash, true);
std::stringstream ss; std::stringstream ss;
for (const auto& r : relayMembers) { for (const auto& r : relayMembers) {
@ -183,7 +183,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
logger.Flush(); logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentContributions = true; status.sentContributions = true;
return true; return true;
}); });
@ -266,7 +266,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
CInv inv(MSG_QUORUM_CONTRIB, hash); CInv inv(MSG_QUORUM_CONTRIB, hash);
RelayInvToParticipants(inv); RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedContribution = true; status.receivedContribution = true;
return true; return true;
}); });
@ -306,7 +306,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
if (complain) { if (complain) {
member->weComplain = true; member->weComplain = true;
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.weComplain = true; status.weComplain = true;
return true; return true;
}); });
@ -374,7 +374,7 @@ void CDKGSession::VerifyPendingContributions()
const auto& m = members[memberIndexes[i]]; const auto& m = members[memberIndexes[i]];
logger.Batch("invalid contribution from %s. will complain later", m->dmn->proTxHash.ToString()); logger.Batch("invalid contribution from %s. will complain later", m->dmn->proTxHash.ToString());
m->weComplain = true; m->weComplain = true;
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) {
status.weComplain = true; status.weComplain = true;
return true; return true;
}); });
@ -499,7 +499,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages)
logger.Flush(); logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentComplaint = true; status.sentComplaint = true;
return true; return true;
}); });
@ -572,7 +572,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan)
CInv inv(MSG_QUORUM_COMPLAINT, hash); CInv inv(MSG_QUORUM_COMPLAINT, hash);
RelayInvToParticipants(inv); RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedComplaint = true; status.receivedComplaint = true;
return true; return true;
}); });
@ -598,7 +598,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan)
if (qc.complainForMembers[i]) { if (qc.complainForMembers[i]) {
m->complaintsFromOthers.emplace(qc.proTxHash); m->complaintsFromOthers.emplace(qc.proTxHash);
m->someoneComplain = true; m->someoneComplain = true;
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) {
return status.complaintsFromMembers.emplace(member->idx).second; return status.complaintsFromMembers.emplace(member->idx).second;
}); });
if (AreWeMember() && i == myIdx) { if (AreWeMember() && i == myIdx) {
@ -693,7 +693,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const
logger.Flush(); logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentJustification = true; status.sentJustification = true;
return true; return true;
}); });
@ -783,7 +783,7 @@ void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan)
CInv inv(MSG_QUORUM_JUSTIFICATION, hash); CInv inv(MSG_QUORUM_JUSTIFICATION, hash);
RelayInvToParticipants(inv); RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedJustification = true; status.receivedJustification = true;
return true; return true;
}); });
@ -1005,7 +1005,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages)
logger.Flush(); logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentPrematureCommitment = true; status.sentPrematureCommitment = true;
return true; return true;
}); });
@ -1142,7 +1142,7 @@ void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan
CInv inv(MSG_QUORUM_PREMATURE_COMMITMENT, hash); CInv inv(MSG_QUORUM_PREMATURE_COMMITMENT, hash);
RelayInvToParticipants(inv); RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedPrematureCommitment = true; status.receivedPrematureCommitment = true;
return true; return true;
}); });
@ -1280,7 +1280,7 @@ void CDKGSession::MarkBadMember(size_t idx)
if (member->bad) { if (member->bad) {
return; return;
} }
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) { dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) {
status.bad = true; status.bad = true;
return true; return true;
}); });

View File

@ -23,6 +23,7 @@ namespace llmq
{ {
class CFinalCommitment; class CFinalCommitment;
class CDKGDebugManager;
class CDKGSession; class CDKGSession;
class CDKGSessionManager; class CDKGSessionManager;
class CDKGPendingMessages; class CDKGPendingMessages;
@ -260,6 +261,7 @@ private:
CBLSWorker& blsWorker; CBLSWorker& blsWorker;
CBLSWorkerCache cache; CBLSWorkerCache cache;
CDKGSessionManager& dkgManager; CDKGSessionManager& dkgManager;
CDKGDebugManager& dkgDebugManager;
const CBlockIndex* m_quorum_base_block_index{nullptr}; const CBlockIndex* m_quorum_base_block_index{nullptr};
int quorumIndex{0}; int quorumIndex{0};
@ -300,8 +302,8 @@ private:
std::set<uint256> validCommitments GUARDED_BY(invCs); std::set<uint256> validCommitments GUARDED_BY(invCs);
public: public:
CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CConnman& _connman) : CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CConnman& _connman) :
params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager), connman(_connman) {} params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager), dkgDebugManager(_dkgDebugManager), connman(_connman) {}
bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash, int _quorumIndex); bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash, int _quorumIndex);

View File

@ -141,7 +141,7 @@ void CDKGSessionHandler::StopThread()
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
{ {
curSession = std::make_unique<CDKGSession>(params, blsWorker, dkgManager, connman); curSession = std::make_unique<CDKGSession>(params, blsWorker, dkgManager, dkgDebugManager, connman);
if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) { if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) {
return false; return false;
@ -198,9 +198,9 @@ void CDKGSessionHandler::WaitForNextPhase(std::optional<QuorumPhase> curPhase,
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase));
if (nextPhase == QuorumPhase::Initialized) { if (nextPhase == QuorumPhase::Initialized) {
quorumDKGDebugManager->ResetLocalSessionStatus(params.type, quorumIndex); dkgDebugManager.ResetLocalSessionStatus(params.type, quorumIndex);
} else { } else {
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != (uint8_t) nextPhase; bool changed = status.phase != (uint8_t) nextPhase;
status.phase = (uint8_t) nextPhase; status.phase = (uint8_t) nextPhase;
return changed; return changed;
@ -481,7 +481,7 @@ void CDKGSessionHandler::HandleDKGRound()
throw AbortPhaseException(); throw AbortPhaseException();
} }
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != (uint8_t) QuorumPhase::Initialized; bool changed = status.phase != (uint8_t) QuorumPhase::Initialized;
status.phase = (uint8_t) QuorumPhase::Initialized; status.phase = (uint8_t) QuorumPhase::Initialized;
return changed; return changed;
@ -532,7 +532,7 @@ void CDKGSessionHandler::HandleDKGRound()
auto finalCommitments = curSession->FinalizeCommitments(); auto finalCommitments = curSession->FinalizeCommitments();
for (const auto& fqc : finalCommitments) { for (const auto& fqc : finalCommitments) {
quorumBlockProcessor->AddMineableCommitment(fqc); quorumBlockProcessor.AddMineableCommitment(fqc);
} }
} }
@ -543,7 +543,7 @@ void CDKGSessionHandler::PhaseHandlerThread()
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - starting HandleDKGRound\n", __func__, params.name, quorumIndex); LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - starting HandleDKGRound\n", __func__, params.name, quorumIndex);
HandleDKGRound(); HandleDKGRound();
} catch (AbortPhaseException& e) { } catch (AbortPhaseException& e) {
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.aborted = true; status.aborted = true;
return true; return true;
}); });

View File

@ -16,9 +16,10 @@ class CBlockIndex;
namespace llmq namespace llmq
{ {
class CDKGDebugManager;
class CDKGSession; class CDKGSession;
class CDKGSessionManager; class CDKGSessionManager;
class CQuorumBlockProcessor;
enum class QuorumPhase { enum class QuorumPhase {
Initialized = 1, Initialized = 1,
@ -113,6 +114,8 @@ private:
const int quorumIndex; const int quorumIndex;
CBLSWorker& blsWorker; CBLSWorker& blsWorker;
CDKGSessionManager& dkgManager; CDKGSessionManager& dkgManager;
CDKGDebugManager& dkgDebugManager;
CQuorumBlockProcessor& quorumBlockProcessor;
QuorumPhase phase GUARDED_BY(cs) {QuorumPhase::Idle}; QuorumPhase phase GUARDED_BY(cs) {QuorumPhase::Idle};
int currentHeight GUARDED_BY(cs) {-1}; int currentHeight GUARDED_BY(cs) {-1};
@ -128,13 +131,16 @@ private:
CDKGPendingMessages pendingPrematureCommitments; CDKGPendingMessages pendingPrematureCommitments;
public: public:
CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CConnman& _connman, int _quorumIndex) : CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager,
CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CConnman& _connman, int _quorumIndex) :
params(_params), params(_params),
blsWorker(_blsWorker), blsWorker(_blsWorker),
dkgManager(_dkgManager), dkgManager(_dkgManager),
dkgDebugManager(_dkgDebugManager),
quorumBlockProcessor(_quorumBlockProcessor),
connman(_connman), connman(_connman),
quorumIndex(_quorumIndex), quorumIndex(_quorumIndex),
curSession(std::make_unique<CDKGSession>(_params, _blsWorker, _dkgManager, _connman)), curSession(std::make_unique<CDKGSession>(_params, _blsWorker, _dkgManager, _dkgDebugManager, _connman)),
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),

View File

@ -24,9 +24,9 @@ static const std::string DB_VVEC = "qdkg_V";
static const std::string DB_SKCONTRIB = "qdkg_S"; static const std::string DB_SKCONTRIB = "qdkg_S";
static const std::string DB_ENC_CONTRIB = "qdkg_E"; static const std::string DB_ENC_CONTRIB = "qdkg_E";
CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CSporkManager& sporkManager, bool unitTests, bool fWipe) : CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, bool unitTests, bool fWipe) :
db(std::make_unique<CDBWrapper>(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)), db(std::make_unique<CDBWrapper>(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)),
blsWorker(_blsWorker), connman(_connman), spork_manager(sporkManager) blsWorker(_blsWorker), connman(_connman), dkgDebugManager(_dkgDebugManager), quorumBlockProcessor(_quorumBlockProcessor),spork_manager(sporkManager)
{ {
if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) { if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) {
// Regular nodes do not care about any DKG internals, bail out // Regular nodes do not care about any DKG internals, bail out
@ -41,7 +41,7 @@ CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorke
for (const auto i : irange::range(session_count)) { for (const auto i : irange::range(session_count)) {
dkgSessionHandlers.emplace(std::piecewise_construct, dkgSessionHandlers.emplace(std::piecewise_construct,
std::forward_as_tuple(params.type, i), std::forward_as_tuple(params.type, i),
std::forward_as_tuple(params, blsWorker, *this, connman, i)); std::forward_as_tuple(params, blsWorker, *this, dkgDebugManager, quorumBlockProcessor, connman, i));
} }
} }
} }
@ -165,7 +165,7 @@ void CDKGSessionManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fIni
} }
} }
void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv) void CDKGSessionManager::ProcessMessage(CNode* pfrom, const CQuorumManager& quorum_manager, const std::string& msg_type, CDataStream& vRecv)
{ {
static Mutex cs_indexedQuorumsCache; static Mutex cs_indexedQuorumsCache;
static std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>> indexedQuorumsCache GUARDED_BY(cs_indexedQuorumsCache); static std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>> indexedQuorumsCache GUARDED_BY(cs_indexedQuorumsCache);
@ -228,7 +228,7 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& msg_typ
return; return;
} }
if (!utils::IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) { if (!utils::IsQuorumTypeEnabled(llmqType, quorum_manager, pQuorumBaseBlockIndex->pprev)) {
LOCK(cs_main); LOCK(cs_main);
LogPrintf("CDKGSessionManager -- llmqType [%d] quorums aren't active\n", uint8_t(llmqType)); LogPrintf("CDKGSessionManager -- llmqType [%d] quorums aren't active\n", uint8_t(llmqType));
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);

View File

@ -12,10 +12,12 @@
class UniValue; class UniValue;
class CBlockIndex; class CBlockIndex;
class CDKGDebugManager;
class CSporkManager; class CSporkManager;
namespace llmq namespace llmq
{ {
class CQuorumManager;
class CDKGSessionManager class CDKGSessionManager
{ {
@ -26,6 +28,8 @@ private:
CBLSWorker& blsWorker; CBLSWorker& blsWorker;
CConnman& connman; CConnman& connman;
CSporkManager& spork_manager; CSporkManager& spork_manager;
CDKGDebugManager& dkgDebugManager;
CQuorumBlockProcessor& quorumBlockProcessor;
//TODO name struct instead of std::pair //TODO name struct instead of std::pair
std::map<std::pair<Consensus::LLMQType, int>, CDKGSessionHandler> dkgSessionHandlers; std::map<std::pair<Consensus::LLMQType, int>, CDKGSessionHandler> dkgSessionHandlers;
@ -50,7 +54,7 @@ private:
mutable std::map<ContributionsCacheKey, ContributionsCacheEntry> contributionsCache GUARDED_BY(contributionsCacheCs); mutable std::map<ContributionsCacheKey, ContributionsCacheEntry> contributionsCache GUARDED_BY(contributionsCacheCs);
public: public:
CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CSporkManager& sporkManager, bool unitTests, bool fWipe); CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, bool unitTests, bool fWipe);
~CDKGSessionManager() = default; ~CDKGSessionManager() = default;
void StartThreads(); void StartThreads();
@ -58,7 +62,7 @@ public:
void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload); void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload);
void ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv); void ProcessMessage(CNode* pfrom, const CQuorumManager& quorum_manager, const std::string& msg_type, CDataStream& vRecv);
bool AlreadyHave(const CInv& inv) const; bool AlreadyHave(const CInv& inv) const;
bool GetContribution(const uint256& hash, CDKGContribution& ret) const; bool GetContribution(const uint256& hash, CDKGContribution& ret) const;
bool GetComplaint(const uint256& hash, CDKGComplaint& ret) const; bool GetComplaint(const uint256& hash, CDKGComplaint& ret) const;

View File

@ -29,12 +29,12 @@ void InitLLMQSystem(CEvoDB& evoDb, CTxMemPool& mempool, CConnman& connman, CSpor
quorumDKGDebugManager = std::make_unique<CDKGDebugManager>(); quorumDKGDebugManager = std::make_unique<CDKGDebugManager>();
quorumBlockProcessor = std::make_unique<CQuorumBlockProcessor>(evoDb, connman); quorumBlockProcessor = std::make_unique<CQuorumBlockProcessor>(evoDb, connman);
quorumDKGSessionManager = std::make_unique<CDKGSessionManager>(connman, *blsWorker, sporkManager, unitTests, fWipe); quorumDKGSessionManager = std::make_unique<CDKGSessionManager>(connman, *blsWorker, *quorumDKGDebugManager, *quorumBlockProcessor, sporkManager, unitTests, fWipe);
quorumManager = std::make_unique<CQuorumManager>(evoDb, connman, *blsWorker, *quorumDKGSessionManager); quorumManager = std::make_unique<CQuorumManager>(evoDb, connman, *blsWorker, *quorumBlockProcessor, *quorumDKGSessionManager);
quorumSigSharesManager = std::make_unique<CSigSharesManager>(connman); quorumSigningManager = std::make_unique<CSigningManager>(connman, *quorumManager, unitTests, fWipe);
quorumSigningManager = std::make_unique<CSigningManager>(connman, unitTests, fWipe); quorumSigSharesManager = std::make_unique<CSigSharesManager>(connman, *quorumManager, *quorumSigningManager);
chainLocksHandler = std::make_unique<CChainLocksHandler>(mempool, connman, sporkManager); chainLocksHandler = std::make_unique<CChainLocksHandler>(mempool, connman, sporkManager, *quorumSigningManager, *quorumSigSharesManager);
quorumInstantSendManager = std::make_unique<CInstantSendManager>(mempool, connman, sporkManager, unitTests, fWipe); quorumInstantSendManager = std::make_unique<CInstantSendManager>(mempool, connman, sporkManager, *quorumManager, *quorumSigningManager, *quorumSigSharesManager, *chainLocksHandler, unitTests, fWipe);
// NOTE: we use this only to wipe the old db, do NOT use it for anything else // NOTE: we use this only to wipe the old db, do NOT use it for anything else
// TODO: remove it in some future version // TODO: remove it in some future version
@ -45,8 +45,8 @@ void DestroyLLMQSystem()
{ {
quorumInstantSendManager.reset(); quorumInstantSendManager.reset();
chainLocksHandler.reset(); chainLocksHandler.reset();
quorumSigningManager.reset();
quorumSigSharesManager.reset(); quorumSigSharesManager.reset();
quorumSigningManager.reset();
quorumManager.reset(); quorumManager.reset();
quorumDKGSessionManager.reset(); quorumDKGSessionManager.reset();
quorumBlockProcessor.reset(); quorumBlockProcessor.reset();

View File

@ -8,6 +8,7 @@
#include <llmq/quorums.h> #include <llmq/quorums.h>
#include <llmq/utils.h> #include <llmq/utils.h>
#include <llmq/commitment.h> #include <llmq/commitment.h>
#include <llmq/signing_shares.h>
#include <bls/bls_batchverifier.h> #include <bls/bls_batchverifier.h>
#include <chainparams.h> #include <chainparams.h>
@ -461,12 +462,12 @@ void CInstantSendManager::Start()
workThread = std::thread(&TraceThread<std::function<void()> >, "isman", std::function<void()>(std::bind(&CInstantSendManager::WorkThreadMain, this))); workThread = std::thread(&TraceThread<std::function<void()> >, "isman", std::function<void()>(std::bind(&CInstantSendManager::WorkThreadMain, this)));
quorumSigningManager->RegisterRecoveredSigsListener(this); sigman.RegisterRecoveredSigsListener(this);
} }
void CInstantSendManager::Stop() void CInstantSendManager::Stop()
{ {
quorumSigningManager->UnregisterRecoveredSigsListener(this); sigman.UnregisterRecoveredSigsListener(this);
// make sure to call InterruptWorkerThread() first // make sure to call InterruptWorkerThread() first
if (!workInterrupt) { if (!workInterrupt) {
@ -509,7 +510,7 @@ void CInstantSendManager::ProcessTx(const CTransaction& tx, bool fRetroactive, c
// block after we retroactively locked all transactions. // block after we retroactively locked all transactions.
if (!IsInstantSendMempoolSigningEnabled() && !fRetroactive) return; if (!IsInstantSendMempoolSigningEnabled() && !fRetroactive) return;
if (!TrySignInputLocks(tx, fRetroactive, utils::GetInstantSendLLMQType(WITH_LOCK(cs_main, return ::ChainActive().Tip())), params)) { if (!TrySignInputLocks(tx, fRetroactive, utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip())), params)) {
return; return;
} }
@ -530,8 +531,8 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
uint256 otherTxHash; uint256 otherTxHash;
// TODO check that we didn't vote for the other IS type also // TODO check that we didn't vote for the other IS type also
if (quorumSigningManager->GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) || if (sigman.GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) ||
quorumSigningManager->GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) { sigman.GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) {
if (otherTxHash != tx.GetHash()) { if (otherTxHash != tx.GetHash()) {
LogPrintf("CInstantSendManager::%s -- txid=%s: input %s is conflicting with previous vote for tx %s\n", __func__, LogPrintf("CInstantSendManager::%s -- txid=%s: input %s is conflicting with previous vote for tx %s\n", __func__,
tx.GetHash().ToString(), in.prevout.ToStringShort(), otherTxHash.ToString()); tx.GetHash().ToString(), in.prevout.ToStringShort(), otherTxHash.ToString());
@ -542,10 +543,10 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
// don't even try the actual signing if any input is conflicting // don't even try the actual signing if any input is conflicting
if (auto llmqs = {params.llmqTypeDIP0024InstantSend, params.llmqTypeInstantSend}; if (auto llmqs = {params.llmqTypeDIP0024InstantSend, params.llmqTypeInstantSend};
ranges::any_of(llmqs, [&id, &tx](const auto& llmqType){ ranges::any_of(llmqs, [&id, &tx, this](const auto& llmqType){
return quorumSigningManager->IsConflicting(llmqType, id, tx.GetHash());}) return sigman.IsConflicting(llmqType, id, tx.GetHash());})
) { ) {
LogPrintf("CInstantSendManager::%s -- txid=%s: quorumSigningManager->IsConflicting returned true. id=%s\n", __func__, LogPrintf("CInstantSendManager::%s -- txid=%s: sigman.IsConflicting returned true. id=%s\n", __func__,
tx.GetHash().ToString(), id.ToString()); tx.GetHash().ToString(), id.ToString());
return false; return false;
} }
@ -565,7 +566,7 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
WITH_LOCK(cs_inputReqests, inputRequestIds.emplace(id)); WITH_LOCK(cs_inputReqests, inputRequestIds.emplace(id));
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. fRetroactive=%d\n", __func__, LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. fRetroactive=%d\n", __func__,
tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), fRetroactive); tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), fRetroactive);
if (quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash(), {}, fRetroactive)) { if (sigman.AsyncSignIfMember(llmqType, shareman, id, tx.GetHash(), {}, fRetroactive)) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: voted on input %s with id %s\n", __func__, LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: voted on input %s with id %s\n", __func__,
tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString()); tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString());
} }
@ -622,7 +623,7 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu
nTxAge = ::ChainActive().Height() - pindexMined->nHeight + 1; nTxAge = ::ChainActive().Height() - pindexMined->nHeight + 1;
} }
if (nTxAge < nInstantSendConfirmationsRequired && !llmq::chainLocksHandler->HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { if (nTxAge < nInstantSendConfirmationsRequired && !clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) {
if (printDebug) { if (printDebug) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: outpoint %s too new and not ChainLocked. nTxAge=%d, nInstantSendConfirmationsRequired=%d\n", __func__, LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: outpoint %s too new and not ChainLocked. nTxAge=%d, nInstantSendConfirmationsRequired=%d\n", __func__,
txHash.ToString(), outpoint.ToStringShort(), nTxAge, nInstantSendConfirmationsRequired); txHash.ToString(), outpoint.ToStringShort(), nTxAge, nInstantSendConfirmationsRequired);
@ -683,11 +684,11 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re
void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
{ {
const auto llmqType = utils::GetInstantSendLLMQType(WITH_LOCK(cs_main, return ::ChainActive().Tip())); const auto llmqType = utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip()));
for (const auto& in : tx.vin) { for (const auto& in : tx.vin) {
auto id = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in.prevout)); auto id = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in.prevout));
if (!quorumSigningManager->HasRecoveredSig(llmqType, id, tx.GetHash())) { if (!sigman.HasRecoveredSig(llmqType, id, tx.GetHash())) {
return; return;
} }
} }
@ -713,7 +714,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
auto id = islock.GetRequestId(); auto id = islock.GetRequestId();
if (quorumSigningManager->HasRecoveredSigForId(llmqType, id)) { if (sigman.HasRecoveredSigForId(llmqType, id)) {
return; return;
} }
@ -726,7 +727,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
txToCreatingInstantSendLocks.emplace(tx.GetHash(), &e.first->second); txToCreatingInstantSendLocks.emplace(tx.GetHash(), &e.first->second);
} }
quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash()); sigman.AsyncSignIfMember(llmqType, shareman, id, tx.GetHash());
} }
void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CRecoveredSig& recoveredSig) void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CRecoveredSig& recoveredSig)
@ -852,7 +853,7 @@ bool CInstantSendManager::PreVerifyInstantSendLock(const llmq::CInstantSendLock&
bool CInstantSendManager::ProcessPendingInstantSendLocks() bool CInstantSendManager::ProcessPendingInstantSendLocks()
{ {
const CBlockIndex* pBlockIndexTip = WITH_LOCK(cs_main, return ::ChainActive().Tip()); const CBlockIndex* pBlockIndexTip = WITH_LOCK(cs_main, return ::ChainActive().Tip());
if (pBlockIndexTip && utils::GetInstantSendLLMQType(pBlockIndexTip) == Params().GetConsensus().llmqTypeDIP0024InstantSend) { if (pBlockIndexTip && utils::GetInstantSendLLMQType(qman, pBlockIndexTip) == Params().GetConsensus().llmqTypeDIP0024InstantSend) {
// Don't short circuit. Try to process deterministic and not deterministic islocks // Don't short circuit. Try to process deterministic and not deterministic islocks
return ProcessPendingInstantSendLocks(true) & ProcessPendingInstantSendLocks(false); return ProcessPendingInstantSendLocks(true) & ProcessPendingInstantSendLocks(false);
} else { } else {
@ -950,7 +951,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
auto id = islock->GetRequestId(); auto id = islock->GetRequestId();
// no need to verify an ISLOCK if we already have verified the recovered sig that belongs to it // no need to verify an ISLOCK if we already have verified the recovered sig that belongs to it
if (quorumSigningManager->HasRecoveredSig(llmqType, id, islock->txid)) { if (sigman.HasRecoveredSig(llmqType, id, islock->txid)) {
alreadyVerified++; alreadyVerified++;
continue; continue;
} }
@ -971,7 +972,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
} }
} }
auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmqType, id, nSignHeight, signOffset); auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmqType, qman, id, nSignHeight, signOffset);
if (!quorum) { if (!quorum) {
// should not happen, but if one fails to select, all others will also fail to select // should not happen, but if one fails to select, all others will also fail to select
return {}; return {};
@ -983,7 +984,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
// We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which // We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which
// avoids unnecessary double-verification of the signature. We however only do this when verification here // avoids unnecessary double-verification of the signature. We however only do this when verification here
// turns out to be good (which is checked further down) // turns out to be good (which is checked further down)
if (!quorumSigningManager->HasRecoveredSigForId(llmqType, id)) { if (!sigman.HasRecoveredSigForId(llmqType, id)) {
recSigs.try_emplace(hash, CRecoveredSig(llmqType, quorum->qc->quorumHash, id, islock->txid, islock->sig)); recSigs.try_emplace(hash, CRecoveredSig(llmqType, quorum->qc->quorumHash, id, islock->txid, islock->sig));
} }
} }
@ -1024,10 +1025,10 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
auto it = recSigs.find(hash); auto it = recSigs.find(hash);
if (it != recSigs.end()) { if (it != recSigs.end()) {
auto recSig = std::make_shared<CRecoveredSig>(std::move(it->second)); auto recSig = std::make_shared<CRecoveredSig>(std::move(it->second));
if (!quorumSigningManager->HasRecoveredSigForId(llmqType, recSig->getId())) { if (!sigman.HasRecoveredSigForId(llmqType, recSig->getId())) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: passing reconstructed recSig to signing mgr, peer=%d\n", __func__, LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: passing reconstructed recSig to signing mgr, peer=%d\n", __func__,
islock->txid.ToString(), hash.ToString(), nodeId); islock->txid.ToString(), hash.ToString(), nodeId);
quorumSigningManager->PushReconstructedRecoveredSig(recSig); sigman.PushReconstructedRecoveredSig(recSig);
} }
} }
} }
@ -1057,7 +1058,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
// Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes, // Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes,
// we can simply ignore the islock, as the ChainLock implies locking of all TXs in that chain // we can simply ignore the islock, as the ChainLock implies locking of all TXs in that chain
if (pindexMined != nullptr && llmq::chainLocksHandler->HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { if (pindexMined != nullptr && clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txlock=%s, islock=%s: dropping islock as it already got a ChainLock in block %s, peer=%d\n", __func__, LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txlock=%s, islock=%s: dropping islock as it already got a ChainLock in block %s, peer=%d\n", __func__,
islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from); islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from);
return; return;
@ -1197,7 +1198,7 @@ void CInstantSendManager::BlockConnected(const std::shared_ptr<const CBlock>& pb
continue; continue;
} }
if (!IsLocked(tx->GetHash()) && !chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { if (!IsLocked(tx->GetHash()) && !clhandler.HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
ProcessTx(*tx, true, Params().GetConsensus()); ProcessTx(*tx, true, Params().GetConsensus());
// TX is not locked, so make sure it is tracked // TX is not locked, so make sure it is tracked
AddNonLockedTx(tx, pindex); AddNonLockedTx(tx, pindex);
@ -1306,7 +1307,7 @@ void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSen
for (const auto& in : islock.inputs) { for (const auto& in : islock.inputs) {
auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in)); auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in));
WITH_LOCK(cs_inputReqests, inputRequestIds.erase(inputRequestId)); WITH_LOCK(cs_inputReqests, inputRequestIds.erase(inputRequestId));
quorumSigningManager->TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock.IsDeterministic()), inputRequestId); sigman.TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock.IsDeterministic()), inputRequestId);
} }
} }
@ -1357,7 +1358,7 @@ void CInstantSendManager::HandleFullyConfirmedBlock(const CBlockIndex* pindex)
// And we don't need the recovered sig for the ISLOCK anymore, as the block in which it got mined is considered // And we don't need the recovered sig for the ISLOCK anymore, as the block in which it got mined is considered
// fully confirmed now // fully confirmed now
quorumSigningManager->TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId()); sigman.TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId());
} }
db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100); db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100);
@ -1446,7 +1447,7 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const
bool hasChainLockedConflict = false; bool hasChainLockedConflict = false;
for (const auto& p : conflicts) { for (const auto& p : conflicts) {
const auto* pindex = p.first; const auto* pindex = p.first;
if (chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { if (clhandler.HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
hasChainLockedConflict = true; hasChainLockedConflict = true;
break; break;
} }

View File

@ -22,6 +22,10 @@ class CSporkManager;
namespace llmq namespace llmq
{ {
class CChainLocksHandler;
class CQuorumManager;
class CSigningManager;
class CSigSharesManager;
struct CInstantSendLock struct CInstantSendLock
{ {
@ -199,6 +203,10 @@ private:
CConnman& connman; CConnman& connman;
CTxMemPool& mempool; CTxMemPool& mempool;
CSporkManager& spork_manager; CSporkManager& spork_manager;
CQuorumManager& qman;
CSigningManager& sigman;
CSigSharesManager& shareman;
CChainLocksHandler& clhandler;
std::atomic<bool> fUpgradedDB{false}; std::atomic<bool> fUpgradedDB{false};
@ -246,7 +254,13 @@ private:
std::unordered_set<uint256, StaticSaltedHasher> pendingRetryTxs GUARDED_BY(cs_pendingRetry); std::unordered_set<uint256, StaticSaltedHasher> pendingRetryTxs GUARDED_BY(cs_pendingRetry);
public: public:
explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, bool unitTests, bool fWipe) : db(unitTests, fWipe), mempool(_mempool), connman(_connman), spork_manager(sporkManager) { workInterrupt.reset(); } explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CQuorumManager& _qman,
CSigningManager& _sigman, CSigSharesManager& _shareman, CChainLocksHandler& _clhandler, bool unitTests, bool fWipe) :
db(unitTests, fWipe), mempool(_mempool), connman(_connman), spork_manager(sporkManager), qman(_qman), sigman(_sigman), shareman(_shareman),
clhandler(_clhandler)
{
workInterrupt.reset();
}
~CInstantSendManager() = default; ~CInstantSendManager() = default;
void Start(); void Start();

View File

@ -186,10 +186,12 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
return true; return true;
} }
CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager) : CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor,
CDKGSessionManager& _dkgManager) :
connman(_connman), connman(_connman),
evoDb(_evoDb), evoDb(_evoDb),
blsWorker(_blsWorker), blsWorker(_blsWorker),
quorumBlockProcessor(_quorumBlockProcessor),
dkgManager(_dkgManager) dkgManager(_dkgManager)
{ {
utils::InitQuorumsCache(mapQuorumsCache); utils::InitQuorumsCache(mapQuorumsCache);
@ -362,7 +364,7 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
const uint256& quorumHash{pQuorumBaseBlockIndex->GetBlockHash()}; const uint256& quorumHash{pQuorumBaseBlockIndex->GetBlockHash()};
uint256 minedBlockHash; uint256 minedBlockHash;
CFinalCommitmentPtr qc = quorumBlockProcessor->GetMinedCommitment(llmqType, quorumHash, minedBlockHash); CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, quorumHash, minedBlockHash);
if (qc == nullptr) { if (qc == nullptr) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- No mined commitment for llmqType[%d] nHeight[%d] quorumHash[%s]\n", __func__, uint8_t(llmqType), pQuorumBaseBlockIndex->nHeight, pQuorumBaseBlockIndex->GetBlockHash().ToString()); LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- No mined commitment for llmqType[%d] nHeight[%d] quorumHash[%s]\n", __func__, uint8_t(llmqType), pQuorumBaseBlockIndex->nHeight, pQuorumBaseBlockIndex->GetBlockHash().ToString());
return nullptr; return nullptr;
@ -429,9 +431,9 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitmentPtr& fqc, co
return true; return true;
} }
bool CQuorumManager::HasQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) bool CQuorumManager::HasQuorum(Consensus::LLMQType llmqType, const CQuorumBlockProcessor& quorum_block_processor, const uint256& quorumHash)
{ {
return quorumBlockProcessor->HasMinedCommitment(llmqType, quorumHash); return quorum_block_processor.HasMinedCommitment(llmqType, quorumHash);
} }
bool CQuorumManager::RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash) const bool CQuorumManager::RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash) const
@ -487,7 +489,7 @@ std::vector<CQuorumCPtr> CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp
std::vector<CQuorumCPtr> CQuorumManager::ScanQuorums(Consensus::LLMQType llmqType, const CBlockIndex* pindexStart, size_t nCountRequested) const std::vector<CQuorumCPtr> CQuorumManager::ScanQuorums(Consensus::LLMQType llmqType, const CBlockIndex* pindexStart, size_t nCountRequested) const
{ {
if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, pindexStart)) { if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, *this, pindexStart)) {
return {}; return {};
} }
@ -522,8 +524,8 @@ std::vector<CQuorumCPtr> CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp
// Get the block indexes of the mined commitments to build the required quorums from // Get the block indexes of the mined commitments to build the required quorums from
std::vector<const CBlockIndex*> pQuorumBaseBlockIndexes{ GetLLMQParams(llmqType).useRotation ? std::vector<const CBlockIndex*> pQuorumBaseBlockIndexes{ GetLLMQParams(llmqType).useRotation ?
quorumBlockProcessor->GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) : quorumBlockProcessor.GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) :
quorumBlockProcessor->GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) quorumBlockProcessor.GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments)
}; };
vecResultQuorums.reserve(vecResultQuorums.size() + pQuorumBaseBlockIndexes.size()); vecResultQuorums.reserve(vecResultQuorums.size() + pQuorumBaseBlockIndexes.size());
@ -565,7 +567,7 @@ CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const CBlock
// we must check this before we look into the cache. Reorgs might have happened which would mean we might have // we must check this before we look into the cache. Reorgs might have happened which would mean we might have
// cached quorums which are not in the active chain anymore // cached quorums which are not in the active chain anymore
if (!HasQuorum(llmqType, quorumHash)) { if (!HasQuorum(llmqType, quorumBlockProcessor, quorumHash)) {
return nullptr; return nullptr;
} }
@ -685,7 +687,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C
} }
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted; std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted;
if (!quorumDKGSessionManager->GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), vecEncrypted)) { if (!dkgManager.GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), vecEncrypted)) {
sendQDATA(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING); sendQDATA(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING);
return; return;
} }
@ -913,7 +915,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
return; return;
} }
if (quorumManager->RequestQuorumData(pNode, pQuorum->qc->llmqType, pQuorum->m_quorum_base_block_index, nDataMask, proTxHash)) { if (RequestQuorumData(pNode, pQuorum->qc->llmqType, pQuorum->m_quorum_base_block_index, nDataMask, proTxHash)) {
nTimeLastSuccess = GetAdjustedTime(); nTimeLastSuccess = GetAdjustedTime();
printLog("Requested"); printLog("Requested");
} else { } else {

View File

@ -27,8 +27,8 @@ using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
namespace llmq namespace llmq
{ {
class CDKGSessionManager; class CDKGSessionManager;
class CQuorumBlockProcessor;
// If true, we will connect to all new quorums and watch their communication // If true, we will connect to all new quorums and watch their communication
static constexpr bool DEFAULT_WATCH_QUORUMS{false}; static constexpr bool DEFAULT_WATCH_QUORUMS{false};
@ -209,6 +209,7 @@ private:
CConnman& connman; CConnman& connman;
CBLSWorker& blsWorker; CBLSWorker& blsWorker;
CDKGSessionManager& dkgManager; CDKGSessionManager& dkgManager;
CQuorumBlockProcessor& quorumBlockProcessor;
mutable CCriticalSection cs_map_quorums; mutable CCriticalSection cs_map_quorums;
mutable std::map<Consensus::LLMQType, unordered_lru_cache<uint256, CQuorumPtr, StaticSaltedHasher>> mapQuorumsCache GUARDED_BY(cs_map_quorums); mutable std::map<Consensus::LLMQType, unordered_lru_cache<uint256, CQuorumPtr, StaticSaltedHasher>> mapQuorumsCache GUARDED_BY(cs_map_quorums);
@ -219,7 +220,8 @@ private:
mutable CThreadInterrupt quorumThreadInterrupt; mutable CThreadInterrupt quorumThreadInterrupt;
public: public:
CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager); CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor,
CDKGSessionManager& _dkgManager);
~CQuorumManager() { Stop(); }; ~CQuorumManager() { Stop(); };
void Start(); void Start();
@ -231,7 +233,7 @@ public:
void ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv); void ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv);
static bool HasQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash); static bool HasQuorum(Consensus::LLMQType llmqType, const CQuorumBlockProcessor& quorum_block_processor, const uint256& quorumHash);
bool RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash = uint256()) const; bool RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash = uint256()) const;

View File

@ -528,8 +528,8 @@ void CRecoveredSigsDb::CleanupOldVotes(int64_t maxAge)
////////////////// //////////////////
CSigningManager::CSigningManager(CConnman& _connman, bool fMemory, bool fWipe) : CSigningManager::CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe) :
db(fMemory, fWipe), connman(_connman) db(fMemory, fWipe), connman(_connman), qman(_qman)
{ {
} }
@ -553,7 +553,7 @@ bool CSigningManager::GetRecoveredSigForGetData(const uint256& hash, CRecoveredS
if (!db.GetRecoveredSigByHash(hash, ret)) { if (!db.GetRecoveredSigByHash(hash, ret)) {
return false; return false;
} }
if (!utils::IsQuorumActive(ret.getLlmqType(), ret.getQuorumHash())) { if (!utils::IsQuorumActive(ret.getLlmqType(), qman, ret.getQuorumHash())) {
// we don't want to propagate sigs from inactive quorums // we don't want to propagate sigs from inactive quorums
return false; return false;
} }
@ -577,7 +577,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared
} }
bool ban = false; bool ban = false;
if (!PreVerifyRecoveredSig(*recoveredSig, ban)) { if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) {
if (ban) { if (ban) {
LOCK(cs_main); LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
@ -604,7 +604,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared
pendingRecoveredSigs[pfrom->GetId()].emplace_back(recoveredSig); pendingRecoveredSigs[pfrom->GetId()].emplace_back(recoveredSig);
} }
bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, bool& retBan) bool CSigningManager::PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CRecoveredSig& recoveredSig, bool& retBan)
{ {
retBan = false; retBan = false;
@ -614,14 +614,14 @@ bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, b
return false; return false;
} }
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recoveredSig.getQuorumHash()); CQuorumCPtr quorum = quorum_manager.GetQuorum(llmqType, recoveredSig.getQuorumHash());
if (!quorum) { if (!quorum) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found\n", __func__, LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found\n", __func__,
recoveredSig.getQuorumHash().ToString()); recoveredSig.getQuorumHash().ToString());
return false; return false;
} }
if (!utils::IsQuorumActive(llmqType, quorum->qc->quorumHash)) { if (!utils::IsQuorumActive(llmqType, quorum_manager, quorum->qc->quorumHash)) {
return false; return false;
} }
@ -672,14 +672,14 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
auto llmqType = recSig->getLlmqType(); auto llmqType = recSig->getLlmqType();
auto quorumKey = std::make_pair(recSig->getLlmqType(), recSig->getQuorumHash()); auto quorumKey = std::make_pair(recSig->getLlmqType(), recSig->getQuorumHash());
if (!retQuorums.count(quorumKey)) { if (!retQuorums.count(quorumKey)) {
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recSig->getQuorumHash()); CQuorumCPtr quorum = qman.GetQuorum(llmqType, recSig->getQuorumHash());
if (!quorum) { if (!quorum) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found, node=%d\n", __func__, LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found, node=%d\n", __func__,
recSig->getQuorumHash().ToString(), nodeId); recSig->getQuorumHash().ToString(), nodeId);
it = v.erase(it); it = v.erase(it);
continue; continue;
} }
if (!utils::IsQuorumActive(llmqType, quorum->qc->quorumHash)) { if (!utils::IsQuorumActive(llmqType, qman, quorum->qc->quorumHash)) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not active anymore, node=%d\n", __func__, LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not active anymore, node=%d\n", __func__,
recSig->getQuorumHash().ToString(), nodeId); recSig->getQuorumHash().ToString(), nodeId);
it = v.erase(it); it = v.erase(it);
@ -872,7 +872,7 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l)
recoveredSigsListeners.erase(itRem, recoveredSigsListeners.end()); recoveredSigsListeners.erase(itRem, recoveredSigsListeners.end());
} }
bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign) bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign)
{ {
if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) { if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) {
return false; return false;
@ -885,9 +885,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint
// This gives a slight risk of not getting enough shares to recover a signature // This gives a slight risk of not getting enough shares to recover a signature
// But at least it shouldn't be possible to get conflicting recovered signatures // But at least it shouldn't be possible to get conflicting recovered signatures
// TODO fix this by re-signing when the next block arrives, but only when that block results in a change of the quorum list and no recovered signature has been created in the mean time // TODO fix this by re-signing when the next block arrives, but only when that block results in a change of the quorum list and no recovered signature has been created in the mean time
quorum = SelectQuorumForSigning(llmqType, id); quorum = SelectQuorumForSigning(llmqType, qman, id);
} else { } else {
quorum = quorumManager->GetQuorum(llmqType, quorumHash); quorum = qman.GetQuorum(llmqType, quorumHash);
} }
if (!quorum) { if (!quorum) {
@ -931,9 +931,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint
if (allowReSign) { if (allowReSign) {
// make us re-announce all known shares (other nodes might have run into a timeout) // make us re-announce all known shares (other nodes might have run into a timeout)
quorumSigSharesManager->ForceReAnnouncement(quorum, llmqType, id, msgHash); shareman.ForceReAnnouncement(quorum, llmqType, id, msgHash);
} }
quorumSigSharesManager->AsyncSign(quorum, id, msgHash); shareman.AsyncSign(quorum, id, msgHash);
return true; return true;
} }
@ -982,7 +982,7 @@ bool CSigningManager::GetVoteForId(Consensus::LLMQType llmqType, const uint256&
return db.GetVoteForId(llmqType, id, msgHashRet); return db.GetVoteForId(llmqType, id, msgHashRet);
} }
CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256& selectionHash, int signHeight, int signOffset) CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight, int signOffset)
{ {
size_t poolSize = GetLLMQParams(llmqType).signingActiveQuorumCount; size_t poolSize = GetLLMQParams(llmqType).signingActiveQuorumCount;
@ -1000,7 +1000,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
} }
if (utils::IsQuorumRotationEnabled(llmqType, pindexStart)) { if (utils::IsQuorumRotationEnabled(llmqType, pindexStart)) {
auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
if (quorums.empty()) { if (quorums.empty()) {
return nullptr; return nullptr;
} }
@ -1024,7 +1024,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
} }
return *itQuorum; return *itQuorum;
} else { } else {
auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
if (quorums.empty()) { if (quorums.empty()) {
return nullptr; return nullptr;
} }
@ -1043,9 +1043,9 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
} }
} }
bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, const int signOffset) bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, const int signOffset)
{ {
auto quorum = SelectQuorumForSigning(llmqType, id, signedAtHeight, signOffset); auto quorum = SelectQuorumForSigning(llmqType, quorum_manager, id, signedAtHeight, signOffset);
if (!quorum) { if (!quorum) {
return false; return false;
} }

View File

@ -24,14 +24,14 @@ class CNode;
namespace llmq namespace llmq
{ {
class CQuorum; class CQuorum;
using CQuorumCPtr = std::shared_ptr<const CQuorum>; using CQuorumCPtr = std::shared_ptr<const CQuorum>;
class CQuorumManager;
class CSigSharesManager;
// Keep recovered signatures for a week. This is a "-maxrecsigsage" option default. // Keep recovered signatures for a week. This is a "-maxrecsigsage" option default.
static constexpr int64_t DEFAULT_MAX_RECOVERED_SIGS_AGE{60 * 60 * 24 * 7}; static constexpr int64_t DEFAULT_MAX_RECOVERED_SIGS_AGE{60 * 60 * 24 * 7};
class CSigBase class CSigBase
{ {
protected: protected:
@ -166,6 +166,7 @@ private:
CConnman& connman; CConnman& connman;
CRecoveredSigsDb db; CRecoveredSigsDb db;
const CQuorumManager& qman;
// Incoming and not verified yet // Incoming and not verified yet
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>> pendingRecoveredSigs GUARDED_BY(cs); std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>> pendingRecoveredSigs GUARDED_BY(cs);
@ -178,7 +179,7 @@ private:
std::vector<CRecoveredSigsListener*> recoveredSigsListeners GUARDED_BY(cs); std::vector<CRecoveredSigsListener*> recoveredSigsListeners GUARDED_BY(cs);
public: public:
CSigningManager(CConnman& _connman, bool fMemory, bool fWipe); CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe);
bool AlreadyHave(const CInv& inv) const; bool AlreadyHave(const CInv& inv) const;
bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const; bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const;
@ -197,7 +198,7 @@ public:
private: private:
void ProcessMessageRecoveredSig(CNode* pfrom, const std::shared_ptr<const CRecoveredSig>& recoveredSig); void ProcessMessageRecoveredSig(CNode* pfrom, const std::shared_ptr<const CRecoveredSig>& recoveredSig);
static bool PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, bool& retBan); static bool PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CRecoveredSig& recoveredSig, bool& retBan);
void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions, void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions,
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>>& retSigShares, std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>>& retSigShares,
@ -212,7 +213,7 @@ public:
void RegisterRecoveredSigsListener(CRecoveredSigsListener* l); void RegisterRecoveredSigsListener(CRecoveredSigsListener* l);
void UnregisterRecoveredSigsListener(CRecoveredSigsListener* l); void UnregisterRecoveredSigsListener(CRecoveredSigsListener* l);
bool AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, const uint256& quorumHash = uint256(), bool allowReSign = false); bool AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash = uint256(), bool allowReSign = false);
bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash) const; bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash) const;
bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id) const; bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id) const;
bool HasRecoveredSigForSession(const uint256& signHash) const; bool HasRecoveredSigForSession(const uint256& signHash) const;
@ -222,10 +223,10 @@ public:
bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet) const; bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet) const;
static std::vector<CQuorumCPtr> GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight); static std::vector<CQuorumCPtr> GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight);
static CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET); static CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET);
// Verifies a recovered sig that was signed while the chain tip was at signedAtTip // Verifies a recovered sig that was signed while the chain tip was at signedAtTip
static bool VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, int signOffset = SIGN_HEIGHT_OFFSET); static bool VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, int signOffset = SIGN_HEIGHT_OFFSET);
}; };
extern std::unique_ptr<CSigningManager> quorumSigningManager; extern std::unique_ptr<CSigningManager> quorumSigningManager;

View File

@ -202,12 +202,12 @@ void CSigSharesManager::StopWorkerThread()
void CSigSharesManager::RegisterAsRecoveredSigsListener() void CSigSharesManager::RegisterAsRecoveredSigsListener()
{ {
quorumSigningManager->RegisterRecoveredSigsListener(this); sigman.RegisterRecoveredSigsListener(this);
} }
void CSigSharesManager::UnregisterAsRecoveredSigsListener() void CSigSharesManager::UnregisterAsRecoveredSigsListener()
{ {
quorumSigningManager->UnregisterRecoveredSigsListener(this); sigman.UnregisterRecoveredSigsListener(this);
} }
void CSigSharesManager::InterruptWorkerThread() void CSigSharesManager::InterruptWorkerThread()
@ -308,7 +308,7 @@ bool CSigSharesManager::ProcessMessageSigSesAnn(const CNode* pfrom, const CSigSe
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- ann={%s}, node=%d\n", __func__, ann.ToString(), pfrom->GetId()); LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- ann={%s}, node=%d\n", __func__, ann.ToString(), pfrom->GetId());
auto quorum = quorumManager->GetQuorum(llmqType, ann.getQuorumHash()); auto quorum = qman.GetQuorum(llmqType, ann.getQuorumHash());
if (!quorum) { if (!quorum) {
// TODO should we ban here? // TODO should we ban here?
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- quorum %s not found, node=%d\n", __func__, LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- quorum %s not found, node=%d\n", __func__,
@ -345,7 +345,7 @@ bool CSigSharesManager::ProcessMessageSigSharesInv(const CNode* pfrom, const CSi
} }
// TODO for PoSe, we should consider propagating shares even if we already have a recovered sig // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig
if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) { if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) {
return true; return true;
} }
@ -382,7 +382,7 @@ bool CSigSharesManager::ProcessMessageGetSigShares(const CNode* pfrom, const CSi
} }
// TODO for PoSe, we should consider propagating shares even if we already have a recovered sig // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig
if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) { if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) {
return true; return true;
} }
@ -407,7 +407,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const
return true; return true;
} }
if (bool ban{false}; !PreVerifyBatchedSigShares(sessionInfo, batchedSigShares, ban)) { if (bool ban{false}; !PreVerifyBatchedSigShares(qman, sessionInfo, batchedSigShares, ban)) {
return !ban; return !ban;
} }
@ -431,7 +431,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const
} }
// TODO for PoSe, we should consider propagating shares even if we already have a recovered sig // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
continue; continue;
} }
@ -456,11 +456,11 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const
void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare) void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare)
{ {
auto quorum = quorumManager->GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash()); auto quorum = qman.GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash());
if (!quorum) { if (!quorum) {
return; return;
} }
if (!utils::IsQuorumActive(sigShare.getLlmqType(), quorum->qc->quorumHash)) { if (!utils::IsQuorumActive(sigShare.getLlmqType(), qman, quorum->qc->quorumHash)) {
// quorum is too old // quorum is too old
return; return;
} }
@ -493,7 +493,7 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
return; return;
} }
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
return; return;
} }
@ -505,11 +505,11 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId); sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId);
} }
bool CSigSharesManager::PreVerifyBatchedSigShares(const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan) bool CSigSharesManager::PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan)
{ {
retBan = false; retBan = false;
if (!utils::IsQuorumActive(session.llmqType, session.quorum->qc->quorumHash)) { if (!utils::IsQuorumActive(session.llmqType, quorum_manager, session.quorum->qc->quorumHash)) {
// quorum is too old // quorum is too old
return false; return false;
} }
@ -597,7 +597,7 @@ void CSigSharesManager::CollectPendingSigSharesToVerify(
continue; continue;
} }
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, sigShare.getQuorumHash()); CQuorumCPtr quorum = qman.GetQuorum(llmqType, sigShare.getQuorumHash());
assert(quorum != nullptr); assert(quorum != nullptr);
retQuorums.try_emplace(k, quorum); retQuorums.try_emplace(k, quorum);
} }
@ -623,7 +623,7 @@ bool CSigSharesManager::ProcessPendingSigShares(const CConnman& connman)
size_t verifyCount = 0; size_t verifyCount = 0;
for (const auto& [nodeId, v] : sigSharesByNodes) { for (const auto& [nodeId, v] : sigSharesByNodes) {
for (const auto& sigShare : v) { for (const auto& sigShare : v) {
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
continue; continue;
} }
@ -701,7 +701,7 @@ void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnma
quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash()); quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash());
} }
if (quorumSigningManager->HasRecoveredSigForId(llmqType, sigShare.getId())) { if (sigman.HasRecoveredSigForId(llmqType, sigShare.getId())) {
return; return;
} }
@ -743,7 +743,7 @@ void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnma
void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash) void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash)
{ {
if (quorumSigningManager->HasRecoveredSigForId(quorum->params.type, id)) { if (sigman.HasRecoveredSigForId(quorum->params.type, id)) {
return; return;
} }
@ -800,7 +800,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
} }
} }
quorumSigningManager->ProcessRecoveredSig(rs); sigman.ProcessRecoveredSig(rs);
} }
CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorumCPtr& quorum, const uint256 &id, size_t attempt) CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorumCPtr& quorum, const uint256 &id, size_t attempt)
@ -860,7 +860,7 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, std
continue; continue;
} }
if (quorumSigningManager->HasRecoveredSigForSession(signHash)) { if (sigman.HasRecoveredSigForSession(signHash)) {
continue; continue;
} }
@ -929,7 +929,7 @@ void CSigSharesManager::CollectSigSharesToSend(std::unordered_map<NodeId, std::u
continue; continue;
} }
if (quorumSigningManager->HasRecoveredSigForSession(signHash)) { if (sigman.HasRecoveredSigForSession(signHash)) {
continue; continue;
} }
@ -1257,8 +1257,8 @@ void CSigSharesManager::Cleanup()
// Find quorums which became inactive // Find quorums which became inactive
for (auto it = quorums.begin(); it != quorums.end(); ) { for (auto it = quorums.begin(); it != quorums.end(); ) {
if (utils::IsQuorumActive(it->first.first, it->first.second)) { if (utils::IsQuorumActive(it->first.first, qman, it->first.second)) {
it->second = quorumManager->GetQuorum(it->first.first, it->first.second); it->second = qman.GetQuorum(it->first.first, it->first.second);
++it; ++it;
} else { } else {
it = quorums.erase(it); it = quorums.erase(it);
@ -1284,11 +1284,11 @@ void CSigSharesManager::Cleanup()
// Remove sessions which were successfully recovered // Remove sessions which were successfully recovered
std::unordered_set<uint256, StaticSaltedHasher> doneSessions; std::unordered_set<uint256, StaticSaltedHasher> doneSessions;
sigShares.ForEach([&doneSessions](const SigShareKey&, const CSigShare& sigShare) { sigShares.ForEach([&doneSessions, this](const SigShareKey&, const CSigShare& sigShare) {
if (doneSessions.count(sigShare.GetSignHash()) != 0) { if (doneSessions.count(sigShare.GetSignHash()) != 0) {
return; return;
} }
if (quorumSigningManager->HasRecoveredSigForSession(sigShare.GetSignHash())) { if (sigman.HasRecoveredSigForSession(sigShare.GetSignHash())) {
doneSessions.emplace(sigShare.GetSignHash()); doneSessions.emplace(sigShare.GetSignHash());
} }
}); });
@ -1441,7 +1441,7 @@ void CSigSharesManager::WorkThreadMain()
bool fMoreWork{false}; bool fMoreWork{false};
RemoveBannedNodeStates(); RemoveBannedNodeStates();
fMoreWork |= quorumSigningManager->ProcessPendingRecoveredSigs(); fMoreWork |= sigman.ProcessPendingRecoveredSigs();
fMoreWork |= ProcessPendingSigShares(connman); fMoreWork |= ProcessPendingSigShares(connman);
SignPendingSigShares(); SignPendingSigShares();
@ -1451,7 +1451,7 @@ void CSigSharesManager::WorkThreadMain()
} }
Cleanup(); Cleanup();
quorumSigningManager->Cleanup(); sigman.Cleanup();
// TODO Wakeup when pending signing is needed? // TODO Wakeup when pending signing is needed?
if (!fMoreWork && !workInterrupt.sleep_for(std::chrono::milliseconds(100))) { if (!fMoreWork && !workInterrupt.sleep_for(std::chrono::milliseconds(100))) {

View File

@ -28,6 +28,8 @@ using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
namespace llmq namespace llmq
{ {
class CSigningManager;
// <signHash, quorumMember> // <signHash, quorumMember>
using SigShareKey = std::pair<uint256, uint16_t>; using SigShareKey = std::pair<uint256, uint16_t>;
@ -395,11 +397,13 @@ private:
FastRandomContext rnd GUARDED_BY(cs); FastRandomContext rnd GUARDED_BY(cs);
CConnman& connman; CConnman& connman;
const CQuorumManager& qman;
CSigningManager& sigman;
int64_t lastCleanupTime{0}; int64_t lastCleanupTime{0};
std::atomic<uint32_t> recoveredSigsCounter{0}; std::atomic<uint32_t> recoveredSigsCounter{0};
public: public:
explicit CSigSharesManager(CConnman& _connman) : connman(_connman) explicit CSigSharesManager(CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman) : connman(_connman), qman(_qman), sigman(_sigman)
{ {
workInterrupt.reset(); workInterrupt.reset();
}; };
@ -431,7 +435,7 @@ private:
void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare); void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare);
static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv); static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv);
static bool PreVerifyBatchedSigShares(const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan); static bool PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan);
void CollectPendingSigSharesToVerify(size_t maxUniqueSessions, void CollectPendingSigSharesToVerify(size_t maxUniqueSessions,
std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares, std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares,

View File

@ -117,7 +117,8 @@ void CQuorumRotationInfo::ToJson(UniValue& obj) const
obj.pushKV("mnListDiffList", mnlistdifflist); obj.pushKV("mnListDiffList", mnlistdifflist);
} }
bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, std::string& errorRet) bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response,
const CQuorumManager& qman, const CQuorumBlockProcessor& quorumBlockProcessor, std::string& errorRet)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -153,7 +154,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
return false; return false;
} }
//Build MN list Diff always with highest baseblock //Build MN list Diff always with highest baseblock
if (!BuildSimplifiedMNListDiff(baseBlockIndexes.back()->GetBlockHash(), tipBlockIndex->GetBlockHash(), response.mnListDiffTip, errorRet)) { if (!BuildSimplifiedMNListDiff(baseBlockIndexes.back()->GetBlockHash(), tipBlockIndex->GetBlockHash(), response.mnListDiffTip, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -164,7 +165,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
} }
//Quorum rotation is enabled only for InstantSend atm. //Quorum rotation is enabled only for InstantSend atm.
Consensus::LLMQType llmqType = utils::GetInstantSendLLMQType(blockIndex); Consensus::LLMQType llmqType = utils::GetInstantSendLLMQType(qman, blockIndex);
// Since the returned quorums are in reversed order, the most recent one is at index 0 // Since the returned quorums are in reversed order, the most recent one is at index 0
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType); const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
@ -184,7 +185,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
} }
//Build MN list Diff always with highest baseblock //Build MN list Diff always with highest baseblock
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -230,7 +231,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
const CBlockIndex* pWorkBlockHMinus4CIndex = pBlockHMinus4CIndex->GetAncestor(pBlockHMinus4CIndex->nHeight - workDiff); const CBlockIndex* pWorkBlockHMinus4CIndex = pBlockHMinus4CIndex->GetAncestor(pBlockHMinus4CIndex->nHeight - workDiff);
//Checked later if extraShare is on //Checked later if extraShare is on
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinusCIndex), pWorkBlockHMinusCIndex->GetBlockHash(), response.mnListDiffAtHMinusC, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinusCIndex), pWorkBlockHMinusCIndex->GetBlockHash(), response.mnListDiffAtHMinusC, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -242,7 +243,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
response.quorumSnapshotAtHMinusC = std::move(snapshotHMinusC.value()); response.quorumSnapshotAtHMinusC = std::move(snapshotHMinusC.value());
} }
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -254,7 +255,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
response.quorumSnapshotAtHMinus2C = std::move(snapshotHMinus2C.value()); response.quorumSnapshotAtHMinus2C = std::move(snapshotHMinus2C.value());
} }
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -283,7 +284,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
} }
CSimplifiedMNListDiff mn4c; CSimplifiedMNListDiff mn4c;
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, quorumBlockProcessor, errorRet)) {
return false; return false;
} }
@ -296,11 +297,11 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
std::set<int> snapshotHeightsNeeded; std::set<int> snapshotHeightsNeeded;
std::vector<std::pair<int, const CBlockIndex*>> qdata = quorumBlockProcessor->GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0); std::vector<std::pair<int, const CBlockIndex*>> qdata = quorumBlockProcessor.GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0);
for (const auto& obj : qdata) { for (const auto& obj : qdata) {
uint256 minedBlockHash; uint256 minedBlockHash;
llmq::CFinalCommitmentPtr qc = llmq::quorumBlockProcessor->GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash); llmq::CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash);
if (qc == nullptr) { if (qc == nullptr) {
return false; return false;
} }
@ -339,7 +340,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
} }
CSimplifiedMNListDiff mnhneeded; CSimplifiedMNListDiff mnhneeded;
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, errorRet)) { if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, quorumBlockProcessor, errorRet)) {
return false; return false;
} }

View File

@ -22,6 +22,9 @@ class CDeterministicMN;
class CDeterministicMNList; class CDeterministicMNList;
namespace llmq { namespace llmq {
class CQuorumBlockProcessor;
class CQuorumManager;
//TODO use enum class (probably) //TODO use enum class (probably)
enum SnapshotSkipMode : int { enum SnapshotSkipMode : int {
MODE_NO_SKIPPING = 0, MODE_NO_SKIPPING = 0,
@ -204,7 +207,8 @@ public:
void ToJson(UniValue& obj) const; void ToJson(UniValue& obj) const;
}; };
bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& quorumRotationInfoRet, std::string& errorRet); bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response,
const CQuorumManager& qman, const CQuorumBlockProcessor& quorumBlockProcessor, std::string& errorRet);
uint256 GetLastBaseBlockHash(const std::vector<const CBlockIndex*>& baseBlockIndexes, const CBlockIndex* blockIndex); uint256 GetLastBaseBlockHash(const std::vector<const CBlockIndex*>& baseBlockIndexes, const CBlockIndex* blockIndex);
class CQuorumSnapshotManager class CQuorumSnapshotManager

View File

@ -48,7 +48,7 @@ std::vector<CDeterministicMNCPtr> GetAllQuorumMembers(Consensus::LLMQType llmqTy
static std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CDeterministicMNCPtr>, StaticSaltedHasher>> mapQuorumMembers GUARDED_BY(cs_members); static std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CDeterministicMNCPtr>, StaticSaltedHasher>> mapQuorumMembers GUARDED_BY(cs_members);
static CCriticalSection cs_indexed_members; static CCriticalSection cs_indexed_members;
static std::map<Consensus::LLMQType, unordered_lru_cache<std::pair<uint256, int>, std::vector<CDeterministicMNCPtr>, StaticSaltedHasher>> mapIndexedQuorumMembers GUARDED_BY(cs_indexed_members); static std::map<Consensus::LLMQType, unordered_lru_cache<std::pair<uint256, int>, std::vector<CDeterministicMNCPtr>, StaticSaltedHasher>> mapIndexedQuorumMembers GUARDED_BY(cs_indexed_members);
if (!IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) { if (!IsQuorumTypeEnabled(llmqType, *llmq::quorumManager, pQuorumBaseBlockIndex->pprev)) {
return {}; return {};
} }
std::vector<CDeterministicMNCPtr> quorumMembers; std::vector<CDeterministicMNCPtr> quorumMembers;
@ -577,9 +577,9 @@ bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pi
return IsDIP0024Active(pindex->GetAncestor(cycleQuorumBaseHeight - 1)); return IsDIP0024Active(pindex->GetAncestor(cycleQuorumBaseHeight - 1));
} }
Consensus::LLMQType GetInstantSendLLMQType(const CBlockIndex* pindex) Consensus::LLMQType GetInstantSendLLMQType(const CQuorumManager& qman, const CBlockIndex* pindex)
{ {
if (IsDIP0024Active(pindex) && !quorumManager->ScanQuorums(Params().GetConsensus().llmqTypeDIP0024InstantSend, pindex, 1).empty()) { if (IsDIP0024Active(pindex) && !qman.ScanQuorums(Params().GetConsensus().llmqTypeDIP0024InstantSend, pindex, 1).empty()) {
return Params().GetConsensus().llmqTypeDIP0024InstantSend; return Params().GetConsensus().llmqTypeDIP0024InstantSend;
} }
return Params().GetConsensus().llmqTypeInstantSend; return Params().GetConsensus().llmqTypeInstantSend;
@ -827,22 +827,22 @@ void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CB
} }
} }
bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash) bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, const uint256& quorumHash)
{ {
// sig shares and recovered sigs are only accepted from recent/active quorums // sig shares and recovered sigs are only accepted from recent/active quorums
// we allow one more active quorum as specified in consensus, as otherwise there is a small window where things could // we allow one more active quorum as specified in consensus, as otherwise there is a small window where things could
// fail while we are on the brink of a new quorum // fail while we are on the brink of a new quorum
auto quorums = quorumManager->ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections); auto quorums = qman.ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections);
return ranges::any_of(quorums, [&quorumHash](const auto& q){ return q->qc->quorumHash == quorumHash; }); return ranges::any_of(quorums, [&quorumHash](const auto& q){ return q->qc->quorumHash == quorumHash; });
} }
bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex) bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex)
{ {
return IsQuorumTypeEnabledInternal(llmqType, pindex, std::nullopt, std::nullopt); return IsQuorumTypeEnabledInternal(llmqType, qman, pindex, std::nullopt, std::nullopt);
} }
bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex* pindex, bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex,
std::optional<bool> optDIP0024IsActive, std::optional<bool> optHaveDIP0024Quorums) std::optional<bool> optDIP0024IsActive, std::optional<bool> optHaveDIP0024Quorums)
{ {
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();
@ -857,7 +857,7 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex
bool fDIP0024IsActive = optDIP0024IsActive.has_value() ? *optDIP0024IsActive : IsDIP0024Active(pindex); bool fDIP0024IsActive = optDIP0024IsActive.has_value() ? *optDIP0024IsActive : IsDIP0024Active(pindex);
if (fDIP0024IsActive) { if (fDIP0024IsActive) {
bool fHaveDIP0024Quorums = optHaveDIP0024Quorums.has_value() ? *optHaveDIP0024Quorums bool fHaveDIP0024Quorums = optHaveDIP0024Quorums.has_value() ? *optHaveDIP0024Quorums
: !quorumManager->ScanQuorums( : !qman.ScanQuorums(
consensusParams.llmqTypeDIP0024InstantSend, pindex, 1).empty(); consensusParams.llmqTypeDIP0024InstantSend, pindex, 1).empty();
if (fHaveDIP0024Quorums) { if (fHaveDIP0024Quorums) {
return false; return false;
@ -896,7 +896,7 @@ std::vector<Consensus::LLMQType> GetEnabledQuorumTypes(const CBlockIndex* pindex
std::vector<Consensus::LLMQType> ret; std::vector<Consensus::LLMQType> ret;
ret.reserve(Params().GetConsensus().llmqs.size()); ret.reserve(Params().GetConsensus().llmqs.size());
for (const auto& params : Params().GetConsensus().llmqs) { for (const auto& params : Params().GetConsensus().llmqs) {
if (IsQuorumTypeEnabled(params.type, pindex)) { if (IsQuorumTypeEnabled(params.type, *llmq::quorumManager, pindex)) {
ret.push_back(params.type); ret.push_back(params.type);
} }
} }
@ -909,7 +909,7 @@ std::vector<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuoru
ret.reserve(Params().GetConsensus().llmqs.size()); ret.reserve(Params().GetConsensus().llmqs.size());
std::copy_if(Params().GetConsensus().llmqs.begin(), Params().GetConsensus().llmqs.end(), std::back_inserter(ret), std::copy_if(Params().GetConsensus().llmqs.begin(), Params().GetConsensus().llmqs.end(), std::back_inserter(ret),
[&pindex](const auto& params){return IsQuorumTypeEnabled(params.type, pindex);}); [&pindex](const auto& params){return IsQuorumTypeEnabled(params.type, *llmq::quorumManager, pindex);});
return ret; return ret;
} }

View File

@ -25,6 +25,7 @@ class CBLSPublicKey;
namespace llmq namespace llmq
{ {
class CQuorumManager;
class CQuorumSnapshot; class CQuorumSnapshot;
// Use a separate cache instance instead of versionbitscache to avoid locking cs_main // Use a separate cache instance instead of versionbitscache to avoid locking cs_main
@ -80,15 +81,15 @@ std::set<size_t> CalcDeterministicWatchConnections(Consensus::LLMQType llmqType,
bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash); bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash);
void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash); void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash);
bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash); bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, const uint256& quorumHash);
bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex); bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex);
bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex* pindex, std::optional<bool> optDIP0024IsActive, std::optional<bool> optHaveDIP0024Quorums); bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex, std::optional<bool> optDIP0024IsActive, std::optional<bool> optHaveDIP0024Quorums);
std::vector<Consensus::LLMQType> GetEnabledQuorumTypes(const CBlockIndex* pindex); std::vector<Consensus::LLMQType> GetEnabledQuorumTypes(const CBlockIndex* pindex);
std::vector<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuorumParams(const CBlockIndex* pindex); std::vector<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuorumParams(const CBlockIndex* pindex);
bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex); bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex);
Consensus::LLMQType GetInstantSendLLMQType(const CBlockIndex* pindex); Consensus::LLMQType GetInstantSendLLMQType(const CQuorumManager& qman, const CBlockIndex* pindex);
Consensus::LLMQType GetInstantSendLLMQType(bool deterministic); Consensus::LLMQType GetInstantSendLLMQType(bool deterministic);
bool IsDIP0024Active(const CBlockIndex* pindex); bool IsDIP0024Active(const CBlockIndex* pindex);
static bool IsInstantSendLLMQTypeShared(); static bool IsInstantSendLLMQTypeShared();

View File

@ -28,6 +28,7 @@
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h> #include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h> #include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <llmq/utils.h> #include <llmq/utils.h>
#include <masternode/payments.h> #include <masternode/payments.h>
#include <spork.h> #include <spork.h>
@ -56,11 +57,15 @@ BlockAssembler::Options::Options() {
} }
BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager,
const CTxMemPool& mempool, const CChainParams& params, const Options& options) const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler,
llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params, const Options& options)
: spork_manager(sporkManager), : spork_manager(sporkManager),
governance_manager(governanceManager), governance_manager(governanceManager),
quorum_block_processor(quorumBlockProcessor),
chainparams(params), chainparams(params),
m_mempool(mempool) m_mempool(mempool),
m_clhandler(clhandler),
m_isman(isman)
{ {
blockMinFeeRate = options.blockMinFeeRate; blockMinFeeRate = options.blockMinFeeRate;
// Limit size to between 1K and MaxBlockSize()-1K for sanity: // Limit size to between 1K and MaxBlockSize()-1K for sanity:
@ -85,8 +90,9 @@ static BlockAssembler::Options DefaultOptions()
} }
BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager,
const CTxMemPool& mempool, const CChainParams& params) const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler,
: BlockAssembler(sporkManager, governanceManager, mempool, params, DefaultOptions()) {} llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params)
: BlockAssembler(sporkManager, governanceManager, quorumBlockProcessor, clhandler, isman, mempool, params, DefaultOptions()) {}
void BlockAssembler::resetBlock() void BlockAssembler::resetBlock()
{ {
@ -146,9 +152,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
if (fDIP0003Active_context) { if (fDIP0003Active_context) {
for (const Consensus::LLMQParams& params : llmq::utils::GetEnabledQuorumParams(pindexPrev)) { for (const Consensus::LLMQParams& params : llmq::utils::GetEnabledQuorumParams(pindexPrev)) {
std::vector<CTransactionRef> vqcTx; std::vector<CTransactionRef> vqcTx;
if (llmq::quorumBlockProcessor->GetMineableCommitmentsTx(params, if (quorum_block_processor.GetMineableCommitmentsTx(params,
nHeight, nHeight,
vqcTx)) { vqcTx)) {
for (const auto& qcTx : vqcTx) { for (const auto& qcTx : vqcTx) {
pblock->vtx.emplace_back(qcTx); pblock->vtx.emplace_back(qcTx);
pblocktemplate->vTxFees.emplace_back(0); pblocktemplate->vTxFees.emplace_back(0);
@ -206,7 +212,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, FormatStateMessage(state))); throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, FormatStateMessage(state)));
} }
if (fDIP0008Active_context) { if (fDIP0008Active_context) {
if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, cbTx.merkleRootQuorums, state)) { if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, quorum_block_processor, cbTx.merkleRootQuorums, state)) {
throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, FormatStateMessage(state))); throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, FormatStateMessage(state)));
} }
} }
@ -230,7 +236,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]); pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]);
CValidationState state; CValidationState state;
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { if (!TestBlockValidity(state, m_clhandler, chainparams, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
} }
int64_t nTime2 = GetTimeMicros(); int64_t nTime2 = GetTimeMicros();
@ -270,7 +276,7 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa
for (CTxMemPool::txiter it : package) { for (CTxMemPool::txiter it : package) {
if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff))
return false; return false;
if (!llmq::chainLocksHandler->IsTxSafeForMining(it->GetTx().GetHash())) { if (!m_clhandler.IsTxSafeForMining(m_isman, it->GetTx().GetHash())) {
return false; return false;
} }
} }

View File

@ -25,6 +25,11 @@ class CScript;
class CSporkManager; class CSporkManager;
namespace Consensus { struct Params; }; namespace Consensus { struct Params; };
namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumBlockProcessor;
} // namespace llmq
static const bool DEFAULT_PRINTPRIORITY = false; static const bool DEFAULT_PRINTPRIORITY = false;
@ -152,6 +157,9 @@ private:
const CTxMemPool& m_mempool; const CTxMemPool& m_mempool;
const CSporkManager& spork_manager; const CSporkManager& spork_manager;
CGovernanceManager& governance_manager; CGovernanceManager& governance_manager;
const llmq::CQuorumBlockProcessor& quorum_block_processor;
llmq::CChainLocksHandler& m_clhandler;
llmq::CInstantSendManager& m_isman;
public: public:
struct Options { struct Options {
@ -161,9 +169,11 @@ public:
}; };
explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager,
const CTxMemPool& mempool, const CChainParams& params); const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler,
llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params);
explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager,
const CTxMemPool& mempool, const CChainParams& params, const Options& options); const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler,
llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params, const Options& options);
/** Construct a new block template with coinbase to scriptPubKeyIn */ /** Construct a new block template with coinbase to scriptPubKeyIn */
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn); std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);

View File

@ -1268,8 +1268,15 @@ static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Para
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT); (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
} }
PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool enable_bip61) PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool,
: connman(connmanIn), m_banman(banman), m_chainman(chainman), m_mempool(pool), m_stale_tip_check_time(0), m_enable_bip61(enable_bip61) { std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor, std::unique_ptr<llmq::CDKGSessionManager>& qdkgsman,
std::unique_ptr<llmq::CQuorumManager>& qman, std::unique_ptr<llmq::CSigSharesManager>& shareman,
std::unique_ptr<llmq::CSigningManager>& sigman, std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman, bool enable_bip61) :
connman(connmanIn), m_banman(banman), m_chainman(chainman), m_mempool(pool), m_quorum_block_processor(quorum_block_processor),
m_qdkgsman(qdkgsman), m_qman(qman), m_shareman(shareman), m_sigman(sigman), m_clhandler(clhandler), m_isman(isman),
m_stale_tip_check_time(0), m_enable_bip61(enable_bip61)
{
// Initialize global variables that cannot be constructed at startup. // Initialize global variables that cannot be constructed at startup.
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
@ -1465,7 +1472,10 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta
// //
bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main) bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool, const llmq::CQuorumBlockProcessor& quorum_block_processor,
const llmq::CDKGSessionManager& qdkgsman, const llmq::CQuorumManager& qman,
const llmq::CSigSharesManager& shareman, const llmq::CSigningManager& sigman,
const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
switch (inv.type) switch (inv.type)
{ {
@ -1503,8 +1513,8 @@ bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LO
// crafted invalid DSTX-es and potentially cause high load cheaply, because // crafted invalid DSTX-es and potentially cause high load cheaply, because
// corresponding checks in ProcessMessage won't let it to send DSTX-es too often. // corresponding checks in ProcessMessage won't let it to send DSTX-es too often.
bool fIgnoreRecentRejects = inv.type == MSG_DSTX || bool fIgnoreRecentRejects = inv.type == MSG_DSTX ||
llmq::quorumInstantSendManager->IsWaitingForTx(inv.hash) || isman.IsWaitingForTx(inv.hash) ||
llmq::quorumInstantSendManager->IsLocked(inv.hash); isman.IsLocked(inv.hash);
return (!fIgnoreRecentRejects && recentRejects->contains(inv.hash)) || return (!fIgnoreRecentRejects && recentRejects->contains(inv.hash)) ||
(inv.type == MSG_DSTX && static_cast<bool>(CCoinJoin::GetDSTX(inv.hash))) || (inv.type == MSG_DSTX && static_cast<bool>(CCoinJoin::GetDSTX(inv.hash))) ||
@ -1538,19 +1548,19 @@ bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LO
return ! governance->ConfirmInventoryRequest(inv); return ! governance->ConfirmInventoryRequest(inv);
case MSG_QUORUM_FINAL_COMMITMENT: case MSG_QUORUM_FINAL_COMMITMENT:
return llmq::quorumBlockProcessor->HasMineableCommitment(inv.hash); return quorum_block_processor.HasMineableCommitment(inv.hash);
case MSG_QUORUM_CONTRIB: case MSG_QUORUM_CONTRIB:
case MSG_QUORUM_COMPLAINT: case MSG_QUORUM_COMPLAINT:
case MSG_QUORUM_JUSTIFICATION: case MSG_QUORUM_JUSTIFICATION:
case MSG_QUORUM_PREMATURE_COMMITMENT: case MSG_QUORUM_PREMATURE_COMMITMENT:
return llmq::quorumDKGSessionManager->AlreadyHave(inv); return qdkgsman.AlreadyHave(inv);
case MSG_QUORUM_RECOVERED_SIG: case MSG_QUORUM_RECOVERED_SIG:
return llmq::quorumSigningManager->AlreadyHave(inv); return sigman.AlreadyHave(inv);
case MSG_CLSIG: case MSG_CLSIG:
return llmq::chainLocksHandler->AlreadyHave(inv); return clhandler.AlreadyHave(inv);
case MSG_ISLOCK: case MSG_ISLOCK:
case MSG_ISDLOCK: case MSG_ISDLOCK:
return llmq::quorumInstantSendManager->AlreadyHave(inv); return isman.AlreadyHave(inv);
} }
// Don't know what it is, just say we already got one // Don't know what it is, just say we already got one
@ -1604,7 +1614,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma
connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
} }
void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman) void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman, llmq::CInstantSendManager& isman)
{ {
bool send = false; bool send = false;
std::shared_ptr<const CBlock> a_recent_block; std::shared_ptr<const CBlock> a_recent_block;
@ -1708,7 +1718,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::TX, *pblock->vtx[pair.first])); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::TX, *pblock->vtx[pair.first]));
} }
for (PairType &pair : merkleBlock.vMatchedTxn) { for (PairType &pair : merkleBlock.vMatchedTxn) {
auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(pair.second); auto islock = isman.GetInstantSendLockByTxid(pair.second);
if (islock != nullptr) { if (islock != nullptr) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::ISLOCK, *islock)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::ISLOCK, *islock));
} }
@ -1749,7 +1759,10 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c
} }
} }
void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, CTxMemPool& mempool, const std::atomic<bool>& interruptMsgProc) LOCKS_EXCLUDED(cs_main) void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, CTxMemPool& mempool,
llmq::CQuorumBlockProcessor &quorum_block_processor, llmq::CDKGSessionManager& qdkgsman,
llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman,
llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, const std::atomic<bool>& interruptMsgProc) LOCKS_EXCLUDED(cs_main)
{ {
AssertLockNotHeld(cs_main); AssertLockNotHeld(cs_main);
@ -1857,7 +1870,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_FINAL_COMMITMENT)) { if (!push && (inv.type == MSG_QUORUM_FINAL_COMMITMENT)) {
llmq::CFinalCommitment o; llmq::CFinalCommitment o;
if (llmq::quorumBlockProcessor->GetMineableCommitmentByHash( if (quorum_block_processor.GetMineableCommitmentByHash(
inv.hash, o)) { inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QFCOMMITMENT, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QFCOMMITMENT, o));
push = true; push = true;
@ -1866,7 +1879,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_CONTRIB)) { if (!push && (inv.type == MSG_QUORUM_CONTRIB)) {
llmq::CDKGContribution o; llmq::CDKGContribution o;
if (llmq::quorumDKGSessionManager->GetContribution(inv.hash, o)) { if (qdkgsman.GetContribution(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCONTRIB, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCONTRIB, o));
push = true; push = true;
} }
@ -1874,7 +1887,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_COMPLAINT)) { if (!push && (inv.type == MSG_QUORUM_COMPLAINT)) {
llmq::CDKGComplaint o; llmq::CDKGComplaint o;
if (llmq::quorumDKGSessionManager->GetComplaint(inv.hash, o)) { if (qdkgsman.GetComplaint(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCOMPLAINT, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCOMPLAINT, o));
push = true; push = true;
} }
@ -1882,7 +1895,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_JUSTIFICATION)) { if (!push && (inv.type == MSG_QUORUM_JUSTIFICATION)) {
llmq::CDKGJustification o; llmq::CDKGJustification o;
if (llmq::quorumDKGSessionManager->GetJustification(inv.hash, o)) { if (qdkgsman.GetJustification(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QJUSTIFICATION, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QJUSTIFICATION, o));
push = true; push = true;
} }
@ -1890,7 +1903,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_PREMATURE_COMMITMENT)) { if (!push && (inv.type == MSG_QUORUM_PREMATURE_COMMITMENT)) {
llmq::CDKGPrematureCommitment o; llmq::CDKGPrematureCommitment o;
if (llmq::quorumDKGSessionManager->GetPrematureCommitment(inv.hash, o)) { if (qdkgsman.GetPrematureCommitment(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QPCOMMITMENT, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QPCOMMITMENT, o));
push = true; push = true;
} }
@ -1898,7 +1911,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_RECOVERED_SIG)) { if (!push && (inv.type == MSG_QUORUM_RECOVERED_SIG)) {
llmq::CRecoveredSig o; llmq::CRecoveredSig o;
if (llmq::quorumSigningManager->GetRecoveredSigForGetData(inv.hash, o)) { if (sigman.GetRecoveredSigForGetData(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QSIGREC, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QSIGREC, o));
push = true; push = true;
} }
@ -1906,7 +1919,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_CLSIG)) { if (!push && (inv.type == MSG_CLSIG)) {
llmq::CChainLockSig o; llmq::CChainLockSig o;
if (llmq::chainLocksHandler->GetChainLockByHash(inv.hash, o)) { if (clhandler.GetChainLockByHash(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CLSIG, o)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CLSIG, o));
push = true; push = true;
} }
@ -1914,7 +1927,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_ISLOCK || inv.type == MSG_ISDLOCK)) { if (!push && (inv.type == MSG_ISLOCK || inv.type == MSG_ISDLOCK)) {
llmq::CInstantSendLock o; llmq::CInstantSendLock o;
if (llmq::quorumInstantSendManager->GetInstantSendLockByHash(inv.hash, o)) { if (isman.GetInstantSendLockByHash(inv.hash, o)) {
const auto msg_type = inv.type == MSG_ISLOCK ? NetMsgType::ISLOCK : NetMsgType::ISDLOCK; const auto msg_type = inv.type == MSG_ISLOCK ? NetMsgType::ISLOCK : NetMsgType::ISDLOCK;
connman->PushMessage(pfrom, msgMaker.Make(msg_type, o)); connman->PushMessage(pfrom, msgMaker.Make(msg_type, o));
push = true; push = true;
@ -1931,7 +1944,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
const CInv &inv = *it; const CInv &inv = *it;
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) { if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) {
it++; it++;
ProcessGetBlockData(pfrom, chainparams, inv, connman); ProcessGetBlockData(pfrom, chainparams, inv, connman, isman);
} }
} }
@ -2501,7 +2514,12 @@ std::pair<bool /*ret*/, bool /*do_return*/> static ValidateDSTX(CCoinJoinBroadca
return {true, false}; return {true, false};
} }
bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61) bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool,
llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CDKGSessionManager& qdkgsman,
llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman,
llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, CConnman* connman,
BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61)
{ {
LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom->GetId()); LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom->GetId());
statsClient.inc("message.received." + SanitizeString(msg_type), 1.0f); statsClient.inc("message.received." + SanitizeString(msg_type), 1.0f);
@ -2992,7 +3010,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
if (interruptMsgProc) if (interruptMsgProc)
return true; return true;
bool fAlreadyHave = AlreadyHave(inv, mempool); bool fAlreadyHave = AlreadyHave(inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman);
LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->GetId()); LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->GetId());
statsClient.inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f); statsClient.inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f);
@ -3076,7 +3094,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
} }
pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
ProcessGetData(pfrom, chainparams, connman, mempool, interruptMsgProc); ProcessGetData(pfrom, chainparams, connman, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman, interruptMsgProc);
return true; return true;
} }
@ -3323,7 +3341,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
bool fMissingInputs = false; bool fMissingInputs = false;
CValidationState state; CValidationState state;
if (!AlreadyHave(inv, mempool) && AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs /* pfMissingInputs */, if (!AlreadyHave(inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman) && AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs /* pfMissingInputs */,
false /* bypass_limits */, 0 /* nAbsurdFee */)) { false /* bypass_limits */, 0 /* nAbsurdFee */)) {
// Process custom txes, this changes AlreadyHave to "true" // Process custom txes, this changes AlreadyHave to "true"
if (nInvType == MSG_DSTX) { if (nInvType == MSG_DSTX) {
@ -3369,11 +3387,11 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
for (const CTxIn& txin : tx.vin) { for (const CTxIn& txin : tx.vin) {
CInv _inv(MSG_TX, txin.prevout.hash); CInv _inv(MSG_TX, txin.prevout.hash);
pfrom->AddInventoryKnown(_inv); pfrom->AddInventoryKnown(_inv);
if (!AlreadyHave(_inv, mempool)) RequestObject(State(pfrom->GetId()), _inv, current_time); if (!AlreadyHave(_inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman)) RequestObject(State(pfrom->GetId()), _inv, current_time);
// We don't know if the previous tx was a regular or a mixing one, try both // We don't know if the previous tx was a regular or a mixing one, try both
CInv _inv2(MSG_DSTX, txin.prevout.hash); CInv _inv2(MSG_DSTX, txin.prevout.hash);
pfrom->AddInventoryKnown(_inv2); pfrom->AddInventoryKnown(_inv2);
if (!AlreadyHave(_inv2, mempool)) RequestObject(State(pfrom->GetId()), _inv2, current_time); if (!AlreadyHave(_inv2, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman)) RequestObject(State(pfrom->GetId()), _inv2, current_time);
} }
AddOrphanTx(ptx, pfrom->GetId()); AddOrphanTx(ptx, pfrom->GetId());
@ -3388,7 +3406,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// We will continue to reject this tx since it has rejected // We will continue to reject this tx since it has rejected
// parents so avoid re-requesting it from other peers. // parents so avoid re-requesting it from other peers.
recentRejects->insert(tx.GetHash()); recentRejects->insert(tx.GetHash());
llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); isman.TransactionRemovedFromMempool(ptx);
} }
} else { } else {
assert(IsTransactionReason(state.GetReason())); assert(IsTransactionReason(state.GetReason()));
@ -3442,7 +3460,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash)); state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash));
} }
MaybePunishNode(pfrom->GetId(), state, /*via_compact_block*/ false); MaybePunishNode(pfrom->GetId(), state, /*via_compact_block*/ false);
llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); isman.TransactionRemovedFromMempool(ptx);
} }
return true; return true;
} }
@ -3615,7 +3633,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
} // cs_main } // cs_main
if (fProcessBLOCKTXN) if (fProcessBLOCKTXN)
return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, chainman, mempool, connman, banman, interruptMsgProc, enable_bip61); return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, chainman, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman, connman, banman, interruptMsgProc, enable_bip61);
if (fRevertToHeaderProcessing) { if (fRevertToHeaderProcessing) {
// Headers received from HB compact block peers are permitted to be // Headers received from HB compact block peers are permitted to be
@ -4014,7 +4032,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
CSimplifiedMNListDiff mnListDiff; CSimplifiedMNListDiff mnListDiff;
std::string strError; std::string strError;
if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, strError)) { if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, quorum_block_processor, strError)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::MNLISTDIFF, mnListDiff)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::MNLISTDIFF, mnListDiff));
} else { } else {
strError = strprintf("getmnlistdiff failed for baseBlockHash=%s, blockHash=%s. error=%s", cmd.baseBlockHash.ToString(), cmd.blockHash.ToString(), strError); strError = strprintf("getmnlistdiff failed for baseBlockHash=%s, blockHash=%s. error=%s", cmd.baseBlockHash.ToString(), cmd.blockHash.ToString(), strError);
@ -4054,7 +4072,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
llmq::CQuorumRotationInfo quorumRotationInfoRet; llmq::CQuorumRotationInfo quorumRotationInfoRet;
std::string strError; std::string strError;
if (BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, strError)) { if (BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, qman, quorum_block_processor, strError)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QUORUMROTATIONINFO, quorumRotationInfoRet)); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QUORUMROTATIONINFO, quorumRotationInfoRet));
} else { } else {
strError = strprintf("getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s", cmd.baseBlockHashes.size(), cmd.blockRequestHash.ToString(), strError); strError = strprintf("getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s", cmd.baseBlockHashes.size(), cmd.blockRequestHash.ToString(), strError);
@ -4118,13 +4136,13 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
masternodeSync->ProcessMessage(pfrom, msg_type, vRecv); masternodeSync->ProcessMessage(pfrom, msg_type, vRecv);
governance->ProcessMessage(pfrom, msg_type, vRecv, *connman, enable_bip61); governance->ProcessMessage(pfrom, msg_type, vRecv, *connman, enable_bip61);
CMNAuth::ProcessMessage(pfrom, msg_type, vRecv, *connman); CMNAuth::ProcessMessage(pfrom, msg_type, vRecv, *connman);
llmq::quorumBlockProcessor->ProcessMessage(pfrom, msg_type, vRecv); quorum_block_processor.ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumDKGSessionManager->ProcessMessage(pfrom, msg_type, vRecv); qdkgsman.ProcessMessage(pfrom, qman, msg_type, vRecv);
llmq::quorumManager->ProcessMessage(pfrom, msg_type, vRecv); qman.ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumSigSharesManager->ProcessMessage(pfrom, msg_type, vRecv, *sporkManager); shareman.ProcessMessage(pfrom, msg_type, vRecv, *sporkManager);
llmq::quorumSigningManager->ProcessMessage(pfrom, msg_type, vRecv); sigman.ProcessMessage(pfrom, msg_type, vRecv);
llmq::chainLocksHandler->ProcessMessage(pfrom, msg_type, vRecv); clhandler.ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumInstantSendManager->ProcessMessage(pfrom, msg_type, vRecv); isman.ProcessMessage(pfrom, msg_type, vRecv);
return true; return true;
} }
@ -4183,7 +4201,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
bool fMoreWork = false; bool fMoreWork = false;
if (!pfrom->vRecvGetData.empty()) if (!pfrom->vRecvGetData.empty())
ProcessGetData(pfrom, chainparams, connman, m_mempool, interruptMsgProc); ProcessGetData(pfrom, chainparams, connman, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman, interruptMsgProc);
if (!pfrom->orphan_work_set.empty()) { if (!pfrom->orphan_work_set.empty()) {
LOCK2(cs_main, g_cs_orphans); LOCK2(cs_main, g_cs_orphans);
@ -4247,7 +4265,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
bool fRet = false; bool fRet = false;
try try
{ {
fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_chainman, m_mempool, connman, m_banman, interruptMsgProc, m_enable_bip61); fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_chainman, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman, connman, m_banman, interruptMsgProc, m_enable_bip61);
if (interruptMsgProc) if (interruptMsgProc)
return false; return false;
if (!pfrom->vRecvGetData.empty()) if (!pfrom->vRecvGetData.empty())
@ -4453,6 +4471,9 @@ public:
bool PeerLogicValidation::SendMessages(CNode* pto) bool PeerLogicValidation::SendMessages(CNode* pto)
{ {
assert(m_clhandler);
assert(m_isman);
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();
{ {
// Don't send anything until the version handshake is complete // Don't send anything until the version handshake is complete
@ -4800,14 +4821,14 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
int nInvType = CCoinJoin::GetDSTX(hash) ? MSG_DSTX : MSG_TX; int nInvType = CCoinJoin::GetDSTX(hash) ? MSG_DSTX : MSG_TX;
queueAndMaybePushInv(CInv(nInvType, hash)); queueAndMaybePushInv(CInv(nInvType, hash));
const auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(hash); const auto islock = m_isman->GetInstantSendLockByTxid(hash);
if (islock == nullptr) continue; if (islock == nullptr) continue;
if (pto->nVersion < ISDLOCK_PROTO_VERSION && islock->IsDeterministic()) continue; if (pto->nVersion < ISDLOCK_PROTO_VERSION && islock->IsDeterministic()) continue;
queueAndMaybePushInv(CInv(islock->IsDeterministic() ? MSG_ISDLOCK : MSG_ISLOCK, ::SerializeHash(*islock))); queueAndMaybePushInv(CInv(islock->IsDeterministic() ? MSG_ISDLOCK : MSG_ISLOCK, ::SerializeHash(*islock)));
} }
// Send an inv for the best ChainLock we have // Send an inv for the best ChainLock we have
const auto& clsig = llmq::chainLocksHandler->GetBestChainLock(); const auto& clsig = m_clhandler->GetBestChainLock();
if (!clsig.IsNull()) { if (!clsig.IsNull()) {
uint256 chainlockHash = ::SerializeHash(clsig); uint256 chainlockHash = ::SerializeHash(clsig);
queueAndMaybePushInv(CInv(MSG_CLSIG, chainlockHash)); queueAndMaybePushInv(CInv(MSG_CLSIG, chainlockHash));
@ -5019,7 +5040,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
state.m_object_download.m_object_in_flight.erase(inv); state.m_object_download.m_object_in_flight.erase(inv);
continue; continue;
} }
if (!AlreadyHave(inv, m_mempool)) { if (!AlreadyHave(inv, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman)) {
// If this object was last requested more than GetObjectInterval ago, // If this object was last requested more than GetObjectInterval ago,
// then request. // then request.
const auto last_request_time = GetObjectRequestTime(inv.hash); const auto last_request_time = GetObjectRequestTime(inv.hash);

View File

@ -14,6 +14,16 @@
class CTxMemPool; class CTxMemPool;
class ChainstateManager; class ChainstateManager;
namespace llmq {
class CChainLocksHandler;
class CDKGSessionManager;
class CInstantSendManager;
class CQuorumBlockProcessor;
class CQuorumManager;
class CSigningManager;
class CSigSharesManager;
} // namespace llmq
extern CCriticalSection cs_main; extern CCriticalSection cs_main;
/** Default for -maxorphantxsize, maximum size in megabytes the orphan map can grow before entries are removed */ /** Default for -maxorphantxsize, maximum size in megabytes the orphan map can grow before entries are removed */
@ -31,10 +41,21 @@ private:
BanMan* const m_banman; BanMan* const m_banman;
ChainstateManager& m_chainman; ChainstateManager& m_chainman;
CTxMemPool& m_mempool; CTxMemPool& m_mempool;
std::unique_ptr<llmq::CDKGSessionManager>& m_qdkgsman;
std::unique_ptr<llmq::CQuorumBlockProcessor>& m_quorum_block_processor;
std::unique_ptr<llmq::CQuorumManager>& m_qman;
std::unique_ptr<llmq::CSigningManager>& m_sigman;
std::unique_ptr<llmq::CSigSharesManager>& m_shareman;
std::unique_ptr<llmq::CChainLocksHandler>& m_clhandler;
std::unique_ptr<llmq::CInstantSendManager>& m_isman;
bool MaybeDiscourageAndDisconnect(CNode* pnode, bool enable_bip61) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool MaybeDiscourageAndDisconnect(CNode* pnode, bool enable_bip61) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
public: public:
PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool enable_bip61); PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool,
std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor, std::unique_ptr<llmq::CDKGSessionManager>& qdkgsman,
std::unique_ptr<llmq::CQuorumManager>& qman, std::unique_ptr<llmq::CSigSharesManager>& shareman,
std::unique_ptr<llmq::CSigningManager>& sigman, std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman, bool enable_bip61);
/** /**
* Overridden from CValidationInterface. * Overridden from CValidationInterface.

View File

@ -12,6 +12,9 @@
#include <consensus/validation.h> #include <consensus/validation.h>
#include <core_io.h> #include <core_io.h>
#include <key_io.h> #include <key_io.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <net.h> #include <net.h>
#include <node/context.h> #include <node/context.h>
@ -152,7 +155,7 @@ UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool,
UniValue blockHashes(UniValue::VARR); UniValue blockHashes(UniValue::VARR);
while (nHeight < nHeightEnd && !ShutdownRequested()) while (nHeight < nHeightEnd && !ShutdownRequested())
{ {
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(*sporkManager, *governance, mempool, Params()).CreateNewBlock(coinbaseScript->reserveScript)); std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, mempool, Params()).CreateNewBlock(coinbaseScript->reserveScript));
if (!pblocktemplate.get()) if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block; CBlock *pblock = &pblocktemplate->block;
@ -362,7 +365,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
LOCK(cs_main); LOCK(cs_main);
CTxMemPool empty_mempool; CTxMemPool empty_mempool;
std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(*sporkManager, *governance, empty_mempool, chainparams).CreateNewBlock(coinbase_script)); std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, empty_mempool, chainparams).CreateNewBlock(coinbase_script));
if (!blocktemplate) { if (!blocktemplate) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
} }
@ -378,7 +381,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
LOCK(cs_main); LOCK(cs_main);
CValidationState state; CValidationState state;
if (!TestBlockValidity(state, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) { if (!TestBlockValidity(state, *llmq::chainLocksHandler, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) {
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason())); throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason()));
} }
} }
@ -664,7 +667,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (block.hashPrevBlock != pindexPrev->GetBlockHash()) if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk"; return "inconclusive-not-best-prevblk";
CValidationState state; CValidationState state;
TestBlockValidity(state, Params(), block, pindexPrev, false, true); TestBlockValidity(state, *llmq::chainLocksHandler, Params(), block, pindexPrev, false, true);
return BIP22ValidationResult(state); return BIP22ValidationResult(state);
} }
@ -769,7 +772,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// Create new block // Create new block
CScript scriptDummy = CScript() << OP_TRUE; CScript scriptDummy = CScript() << OP_TRUE;
pblocktemplate = BlockAssembler(*sporkManager, *governance, mempool, Params()).CreateNewBlock(scriptDummy); pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, mempool, Params()).CreateNewBlock(scriptDummy);
if (!pblocktemplate) if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

View File

@ -13,6 +13,7 @@
#include <evo/specialtx.h> #include <evo/specialtx.h>
#include <evo/specialtxman.h> #include <evo/specialtxman.h>
#include <index/txindex.h> #include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <masternode/meta.h> #include <masternode/meta.h>
#include <messagesigner.h> #include <messagesigner.h>
#include <netbase.h> #include <netbase.h>
@ -1176,7 +1177,7 @@ static UniValue protx_diff(const JSONRPCRequest& request)
CSimplifiedMNListDiff mnListDiff; CSimplifiedMNListDiff mnListDiff;
std::string strError; std::string strError;
if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, strError, extended)) { if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, *llmq::quorumBlockProcessor, strError, extended)) {
throw std::runtime_error(strError); throw std::runtime_error(strError);
} }

View File

@ -436,13 +436,13 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request)
fSubmit = ParseBoolV(request.params[4], "submit"); fSubmit = ParseBoolV(request.params[4], "submit");
} }
if (fSubmit) { if (fSubmit) {
return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, id, msgHash, quorumHash); return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, *llmq::quorumSigSharesManager, id, msgHash, quorumHash);
} else { } else {
llmq::CQuorumCPtr pQuorum; llmq::CQuorumCPtr pQuorum;
if (quorumHash.IsNull()) { if (quorumHash.IsNull()) {
pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id); pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id);
} else { } else {
pQuorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash); pQuorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash);
} }
@ -481,8 +481,8 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request)
} }
// First check against the current active set, if it fails check against the last active set // First check against the current active set, if it fails check against the last active set
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, 0) || return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, signOffset); llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, signOffset);
} else { } else {
uint256 quorumHash = ParseHashV(request.params[4], "quorumHash"); uint256 quorumHash = ParseHashV(request.params[4], "quorumHash");
llmq::CQuorumCPtr quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash); llmq::CQuorumCPtr quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash);
@ -539,7 +539,7 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request)
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);
auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id); auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id);
if (!quorum) { if (!quorum) {
throw JSONRPCError(RPC_MISC_ERROR, "no quorums active"); throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
} }
@ -670,7 +670,7 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request)
++idx; ++idx;
} }
LOCK(cs_main); LOCK(cs_main);
if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, strError)) { if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, *llmq::quorumManager, *llmq::quorumBlockProcessor, strError)) {
throw JSONRPCError(RPC_INVALID_REQUEST, strError); throw JSONRPCError(RPC_INVALID_REQUEST, strError);
} }
@ -776,7 +776,7 @@ static UniValue verifychainlock(const JSONRPCRequest& request)
const auto llmqType = Params().GetConsensus().llmqTypeChainLocks; const auto llmqType = Params().GetConsensus().llmqTypeChainLocks;
const uint256 nRequestId = ::SerializeHash(std::make_pair(llmq::CLSIG_REQUESTID_PREFIX, nBlockHeight)); const uint256 nRequestId = ::SerializeHash(std::make_pair(llmq::CLSIG_REQUESTID_PREFIX, nBlockHeight));
return llmq::CSigningManager::VerifyRecoveredSig(llmqType, nBlockHeight, nRequestId, nBlockHash, chainLockSig); return llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, nBlockHeight, nRequestId, nBlockHash, chainLockSig);
} }
static void verifyislock_help(const JSONRPCRequest& request) static void verifyislock_help(const JSONRPCRequest& request)
@ -841,11 +841,11 @@ static UniValue verifyislock(const JSONRPCRequest& request)
pBlockIndex = ::ChainActive()[signHeight]; pBlockIndex = ::ChainActive()[signHeight];
} }
} }
auto llmqType = llmq::utils::GetInstantSendLLMQType(pBlockIndex); auto llmqType = llmq::utils::GetInstantSendLLMQType(*llmq::quorumManager, pBlockIndex);
// First check against the current active set, if it fails check against the last active set // First check against the current active set, if it fails check against the last active set
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, 0) || return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, signOffset); llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, signOffset);
} }
// clang-format off // clang-format off
static const CRPCCommand commands[] = static const CRPCCommand commands[] =

View File

@ -20,6 +20,9 @@
#include <evo/providertx.h> #include <evo/providertx.h>
#include <evo/deterministicmns.h> #include <evo/deterministicmns.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -214,7 +217,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
BOOST_CHECK_EQUAL(VersionBitsTipState(consensus_params, deployment_id), ThresholdState::STARTED); BOOST_CHECK_EQUAL(VersionBitsTipState(consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0)); BOOST_CHECK_EQUAL(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0));
// Next block should be signaling by default // Next block should be signaling by default
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit; const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit;
BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0); BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask); BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask);
@ -281,7 +284,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
deterministicMNManager->UpdatedBlockTip(::ChainActive().Tip()); deterministicMNManager->UpdatedBlockTip(::ChainActive().Tip());
BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash())); BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash()));
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
} }
@ -292,7 +295,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
{ {
LOCK(cs_main); LOCK(cs_main);
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 13748571607); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 13748571607);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6874285801); // 0.4999999998 BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6874285801); // 0.4999999998
@ -307,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
} }
LOCK(cs_main); LOCK(cs_main);
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
} }
} }
@ -316,7 +319,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
// Reward split should reach ~60/40 after reallocation is done // Reward split should reach ~60/40 after reallocation is done
LOCK(cs_main); LOCK(cs_main);
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 10221599170); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 10221599170);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6132959502); // 0.6 BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6132959502); // 0.6
@ -330,7 +333,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
} }
LOCK(cs_main); LOCK(cs_main);
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
} }
@ -338,7 +341,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
// Reward split should reach ~60/40 after reallocation is done // Reward split should reach ~60/40 after reallocation is done
LOCK(cs_main); LOCK(cs_main);
auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 9491484944); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 9491484944);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 5694890966); // 0.6 BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 5694890966); // 0.6

View File

@ -7,6 +7,9 @@
#include <consensus/validation.h> #include <consensus/validation.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <index/blockfilterindex.h> #include <index/blockfilterindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <pow.h> #include <pow.h>
#include <script/standard.h> #include <script/standard.h>
@ -64,7 +67,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey) const CScript& scriptPubKey)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey); std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block; CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash(); block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1; block.nTime = prev->nTime + 1;

View File

@ -7,6 +7,13 @@
#include <arith_uint256.h> #include <arith_uint256.h>
#include <banman.h> #include <banman.h>
#include <chainparams.h> #include <chainparams.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/signing_shares.h>
#include <llmq/signing.h>
#include <net.h> #include <net.h>
#include <net_processing.h> #include <net_processing.h>
#include <pubkey.h> #include <pubkey.h>
@ -80,7 +87,11 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction) BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{ {
auto connman = MakeUnique<CConnman>(0x1337, 0x1337); auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); auto peerLogic = MakeUnique<PeerLogicValidation>(
connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, false
);
// Mock an outbound peer // Mock an outbound peer
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@ -151,7 +162,11 @@ static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidat
BOOST_AUTO_TEST_CASE(stale_tip_peer_management) BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
{ {
auto connman = MakeUnique<CConnmanTest>(0x1337, 0x1337); auto connman = MakeUnique<CConnmanTest>(0x1337, 0x1337);
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); auto peerLogic = MakeUnique<PeerLogicValidation>(
connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, false
);
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS; constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
@ -224,7 +239,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{ {
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337); auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); auto peerLogic = MakeUnique<PeerLogicValidation>(
connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, false
);
banman->ClearBanned(); banman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@ -279,7 +298,11 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
{ {
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337); auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); auto peerLogic = MakeUnique<PeerLogicValidation>(
connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, false
);
banman->ClearBanned(); banman->ClearBanned();
gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number
@ -326,7 +349,11 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
{ {
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337); auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); auto peerLogic = MakeUnique<PeerLogicValidation>(
connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, llmq::quorumBlockProcessor,
llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager,
llmq::chainLocksHandler, llmq::quorumInstantSendManager, false
);
banman->ClearBanned(); banman->ClearBanned();
int64_t nStartTime = GetTime(); int64_t nStartTime = GetTime();

View File

@ -7,6 +7,9 @@
#include <chainparams.h> #include <chainparams.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <script/interpreter.h> #include <script/interpreter.h>
#include <spork.h> #include <spork.h>
@ -74,7 +77,7 @@ struct TestChainDATSetup : public TestChainSetup
BOOST_CHECK_EQUAL(VersionBitsTipState(consensus_params, deployment_id), ThresholdState::STARTED); BOOST_CHECK_EQUAL(VersionBitsTipState(consensus_params, deployment_id), ThresholdState::STARTED);
BOOST_CHECK_EQUAL(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0)); BOOST_CHECK_EQUAL(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0));
// Next block should be signaling by default // Next block should be signaling by default
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit; const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit;
BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0); BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask); BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask);

View File

@ -6,6 +6,7 @@
#include <llmq/utils.h> #include <llmq/utils.h>
#include <llmq/params.h> #include <llmq/params.h>
#include <llmq/quorums.h>
#include <chainparams.h> #include <chainparams.h>
@ -20,21 +21,22 @@ void Test()
{ {
using namespace llmq::utils; using namespace llmq::utils;
const auto& consensus_params = Params().GetConsensus(); const auto& consensus_params = Params().GetConsensus();
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, nullptr, false, false), true); assert(llmq::quorumManager);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, nullptr, true, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, *llmq::quorumManager, nullptr, false, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, nullptr, true, true), false); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, *llmq::quorumManager, nullptr, true, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, nullptr, false, false), false); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeInstantSend, *llmq::quorumManager, nullptr, true, true), false);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, nullptr, true, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, *llmq::quorumManager, nullptr, false, false), false);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, nullptr, true, true), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, *llmq::quorumManager, nullptr, true, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, nullptr, false, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, *llmq::quorumManager, nullptr, true, true), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, nullptr, false, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, *llmq::quorumManager, nullptr, false, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, nullptr, true, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, *llmq::quorumManager, nullptr, false, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, nullptr, true, false), Params().IsTestChain()); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, *llmq::quorumManager, nullptr, true, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, nullptr, true, true), Params().IsTestChain()); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, *llmq::quorumManager, nullptr, true, false), Params().IsTestChain());
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, nullptr, true, true), Params().IsTestChain()); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, *llmq::quorumManager, nullptr, true, true), Params().IsTestChain());
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, nullptr, true, false), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, *llmq::quorumManager, nullptr, true, true), Params().IsTestChain());
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, nullptr, true, true), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, *llmq::quorumManager, nullptr, true, false), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, nullptr, true, true), true); BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, *llmq::quorumManager, nullptr, true, true), true);
BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, *llmq::quorumManager, nullptr, true, true), true);
} }
BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_regtest, RegTestingSetup) BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_regtest, RegTestingSetup)
@ -42,7 +44,7 @@ BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_regtest, RegTestingSetup
Test(); Test();
} }
BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_mainnet, BasicTestingSetup) BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_mainnet, TestingSetup)
{ {
Test(); Test();
} }

View File

@ -19,6 +19,14 @@
#include <validationinterface.h> #include <validationinterface.h>
#include <version.h> #include <version.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/signing.h>
#include <llmq/signing_shares.h>
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <cassert> #include <cassert>
@ -32,7 +40,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
bool ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61); bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CDKGSessionManager& qdkgsman, llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc, bool enable_bip61);
namespace { namespace {
@ -90,7 +98,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
p2p_node.SetSendVersion(PROTOCOL_VERSION); p2p_node.SetSendVersion(PROTOCOL_VERSION);
g_setup->m_node.peer_logic->InitializeNode(&p2p_node); g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
try { try {
(void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false}, true); (void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, *llmq::quorumBlockProcessor, *llmq::quorumDKGSessionManager, *llmq::quorumManager, *llmq::quorumSigSharesManager, *llmq::quorumSigningManager, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false}, true);
} catch (const std::ios_base::failure& e) { } catch (const std::ios_base::failure& e) {
const std::string exception_message{e.what()}; const std::string exception_message{e.what()};
const auto p = EXPECTED_DESERIALIZATION_EXCEPTIONS.find(exception_message); const auto p = EXPECTED_DESERIALIZATION_EXCEPTIONS.find(exception_message);

View File

@ -8,6 +8,9 @@
#include <consensus/tx_verify.h> #include <consensus/tx_verify.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <policy/policy.h> #include <policy/policy.h>
#include <pow.h> #include <pow.h>
@ -46,7 +49,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
options.blockMinFeeRate = blockMinFeeRate; options.blockMinFeeRate = blockMinFeeRate;
return BlockAssembler(*sporkManager, *governance, *m_node.mempool, params, options); return BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, params, options);
} }
constexpr static struct { constexpr static struct {

View File

@ -8,6 +8,9 @@
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <key_io.h> #include <key_io.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <node/context.h> #include <node/context.h>
#include <pow.h> #include <pow.h>
@ -76,7 +79,7 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coi
{ {
assert(node.mempool); assert(node.mempool);
auto block = std::make_shared<CBlock>( auto block = std::make_shared<CBlock>(
BlockAssembler{*sporkManager, *governance, *node.mempool, Params()} BlockAssembler{*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *node.mempool, Params()}
.CreateNewBlock(coinbase_scriptPubKey) .CreateNewBlock(coinbase_scriptPubKey)
->block); ->block);

View File

@ -15,6 +15,13 @@
#include <init.h> #include <init.h>
#include <interfaces/chain.h> #include <interfaces/chain.h>
#include <masternode/sync.h> #include <masternode/sync.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/signing_shares.h>
#include <llmq/signing.h>
#include <miner.h> #include <miner.h>
#include <net.h> #include <net.h>
#include <net_processing.h> #include <net_processing.h>
@ -165,7 +172,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
pblocktree.reset(new CBlockTreeDB(1 << 20, true)); pblocktree.reset(new CBlockTreeDB(1 << 20, true));
m_node.chainman = &::g_chainman; m_node.chainman = &::g_chainman;
m_node.chainman->InitializeChainstate(); m_node.chainman->InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
::ChainstateActive().InitCoinsDB( ::ChainstateActive().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!::ChainstateActive().CanFlushToDisk()); assert(!::ChainstateActive().CanFlushToDisk());
@ -175,21 +182,16 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
throw std::runtime_error("LoadGenesisBlock failed."); throw std::runtime_error("LoadGenesisBlock failed.");
} }
CValidationState state;
if (!ActivateBestChain(state, chainparams)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
}
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
constexpr int script_check_threads = 2;
StartScriptCheckWorkerThreads(script_check_threads);
g_parallel_script_checks = true;
m_node.mempool = &::mempool; m_node.mempool = &::mempool;
m_node.mempool->setSanityCheck(1.0); m_node.mempool->setSanityCheck(1.0);
m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests. m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
m_node.peer_logic = MakeUnique<PeerLogicValidation>(m_node.connman.get(), m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); m_node.peer_logic = MakeUnique<PeerLogicValidation>(
m_node.connman.get(), m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool,
llmq::quorumBlockProcessor, llmq::quorumDKGSessionManager, llmq::quorumManager,
llmq::quorumSigSharesManager, llmq::quorumSigningManager, llmq::chainLocksHandler,
llmq::quorumInstantSendManager, false
);
{ {
CConnman::Options options; CConnman::Options options;
options.m_msgproc = m_node.peer_logic.get(); options.m_msgproc = m_node.peer_logic.get();
@ -206,6 +208,16 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
deterministicMNManager.reset(new CDeterministicMNManager(*evoDb, *m_node.connman)); deterministicMNManager.reset(new CDeterministicMNManager(*evoDb, *m_node.connman));
llmq::InitLLMQSystem(*evoDb, *m_node.mempool, *m_node.connman, *sporkManager, true); llmq::InitLLMQSystem(*evoDb, *m_node.mempool, *m_node.connman, *sporkManager, true);
CValidationState state;
if (!ActivateBestChain(state, chainparams)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
}
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
constexpr int script_check_threads = 2;
StartScriptCheckWorkerThreads(script_check_threads);
g_parallel_script_checks = true;
} }
TestingSetup::~TestingSetup() TestingSetup::~TestingSetup()
@ -290,7 +302,7 @@ CBlock TestChainSetup::CreateAndProcessBlock(const std::vector<CMutableTransacti
CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey); std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block; CBlock& block = pblocktemplate->block;
std::vector<CTransactionRef> llmqCommitments; std::vector<CTransactionRef> llmqCommitments;
@ -318,7 +330,7 @@ CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
if (!CalcCbTxMerkleRootMNList(block, ::ChainActive().Tip(), cbTx.merkleRootMNList, state, ::ChainstateActive().CoinsTip())) { if (!CalcCbTxMerkleRootMNList(block, ::ChainActive().Tip(), cbTx.merkleRootMNList, state, ::ChainstateActive().CoinsTip())) {
BOOST_ASSERT(false); BOOST_ASSERT(false);
} }
if (!CalcCbTxMerkleRootQuorums(block, ::ChainActive().Tip(), cbTx.merkleRootQuorums, state)) { if (!CalcCbTxMerkleRootQuorums(block, ::ChainActive().Tip(), *llmq::quorumBlockProcessor, cbTx.merkleRootQuorums, state)) {
BOOST_ASSERT(false); BOOST_ASSERT(false);
} }
CMutableTransaction tmpTx{*block.vtx[0]}; CMutableTransaction tmpTx{*block.vtx[0]};

View File

@ -9,6 +9,9 @@
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <governance/governance.h> #include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h> #include <miner.h>
#include <pow.h> #include <pow.h>
#include <random.h> #include <random.h>
@ -70,7 +73,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
CScript pubKey; CScript pubKey;
pubKey << i++ << OP_TRUE; pubKey << i++ << OP_TRUE;
auto ptemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(pubKey); auto ptemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(pubKey);
auto pblock = std::make_shared<CBlock>(ptemplate->block); auto pblock = std::make_shared<CBlock>(ptemplate->block);
pblock->hashPrevBlock = prev_hash; pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time; pblock->nTime = ++time;

View File

@ -3,6 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// //
#include <index/txindex.h> #include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <random.h> #include <random.h>
#include <uint256.h> #include <uint256.h>
#include <consensus/validation.h> #include <consensus/validation.h>
@ -35,7 +38,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
return outp; return outp;
}; };
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate()); CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
c1.InitCoinsDB( c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));

View File

@ -3,8 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// //
#include <chainparams.h> #include <chainparams.h>
#include <index/txindex.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <random.h> #include <random.h>
#include <sync.h> #include <sync.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
@ -29,7 +32,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
// Create a legacy (IBD) chainstate. // Create a legacy (IBD) chainstate.
// //
CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate()); CChainState& c1 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
chainstates.push_back(&c1); chainstates.push_back(&c1);
c1.InitCoinsDB( c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@ -55,7 +58,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
// Create a snapshot-based chainstate. // Create a snapshot-based chainstate.
// //
CChainState& c2 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(GetRandHash())); CChainState& c2 = *WITH_LOCK(::cs_main, return &manager.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor, GetRandHash()));
chainstates.push_back(&c2); chainstates.push_back(&c2);
c2.InitCoinsDB( c2.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@ -113,7 +116,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
// Create a legacy (IBD) chainstate. // Create a legacy (IBD) chainstate.
// //
CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate()); CChainState& c1 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor));
chainstates.push_back(&c1); chainstates.push_back(&c1);
c1.InitCoinsDB( c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@ -130,7 +133,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
// Create a snapshot-based chainstate. // Create a snapshot-based chainstate.
// //
CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(GetRandHash())); CChainState& c2 = *WITH_LOCK(cs_main, return &manager.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor, GetRandHash()));
chainstates.push_back(&c2); chainstates.push_back(&c2);
c2.InitCoinsDB( c2.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);

View File

@ -2,6 +2,9 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// //
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <sync.h> #include <sync.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <txmempool.h> #include <txmempool.h>
@ -19,7 +22,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(getcoinscachesizestate) BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{ {
BlockManager blockman{}; BlockManager blockman{};
CChainState chainstate{blockman}; CChainState chainstate(blockman, llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false); chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false);
WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10)); WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10));
CTxMemPool tx_pool{}; CTxMemPool tx_pool{};

View File

@ -1131,8 +1131,15 @@ void CoinsViews::InitCache()
m_cacheview = MakeUnique<CCoinsViewCache>(&m_catcherview); m_cacheview = MakeUnique<CCoinsViewCache>(&m_catcherview);
} }
CChainState::CChainState(BlockManager& blockman, uint256 from_snapshot_blockhash) CChainState::CChainState(BlockManager& blockman,
std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor,
uint256 from_snapshot_blockhash)
: m_blockman(blockman), : m_blockman(blockman),
m_clhandler(clhandler),
m_isman(isman),
m_quorum_block_processor(quorum_block_processor),
m_from_snapshot_blockhash(from_snapshot_blockhash) {} m_from_snapshot_blockhash(from_snapshot_blockhash) {}
void CChainState::InitCoinsDB( void CChainState::InitCoinsDB(
@ -1615,6 +1622,7 @@ int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out)
DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view) DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(m_quorum_block_processor);
bool fDIP0003Active = pindex->nHeight >= Params().GetConsensus().DIP0003Height; bool fDIP0003Active = pindex->nHeight >= Params().GetConsensus().DIP0003Height;
if (fDIP0003Active && !evoDb->VerifyBestBlock(pindex->GetBlockHash())) { if (fDIP0003Active && !evoDb->VerifyBestBlock(pindex->GetBlockHash())) {
@ -1642,7 +1650,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex; std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
if (!UndoSpecialTxsInBlock(block, pindex)) { if (!UndoSpecialTxsInBlock(block, pindex, *m_quorum_block_processor)) {
return DISCONNECT_FAILED; return DISCONNECT_FAILED;
} }
@ -1971,6 +1979,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(pindex); assert(pindex);
assert(*pindex->phashBlock == block.GetHash()); assert(*pindex->phashBlock == block.GetHash());
assert(m_clhandler);
assert(m_isman);
assert(m_quorum_block_processor);
int64_t nTimeStart = GetTimeMicros(); int64_t nTimeStart = GetTimeMicros();
// Check it again in case a previous version let a bad block in // Check it again in case a previous version let a bad block in
@ -1996,7 +2007,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
} }
if (pindex->pprev && pindex->phashBlock && llmq::chainLocksHandler->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) { if (pindex->pprev && pindex->phashBlock && m_clhandler->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
return state.Invalid(ValidationInvalidReason::BLOCK_CHAINLOCK, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock"); return state.Invalid(ValidationInvalidReason::BLOCK_CHAINLOCK, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
} }
@ -2130,7 +2141,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height; bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height;
// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing // MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
if (!ProcessSpecialTxsInBlock(block, pindex, state, view, fJustCheck, fScriptChecks)) { if (!ProcessSpecialTxsInBlock(block, pindex, *m_quorum_block_processor, state, view, fJustCheck, fScriptChecks)) {
return error("ConnectBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s", return error("ConnectBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
pindex->GetBlockHash().ToString(), FormatStateMessage(state)); pindex->GetBlockHash().ToString(), FormatStateMessage(state));
} }
@ -2306,16 +2317,16 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// DASH : CHECK TRANSACTIONS FOR INSTANTSEND // DASH : CHECK TRANSACTIONS FOR INSTANTSEND
if (llmq::quorumInstantSendManager->RejectConflictingBlocks()) { if (m_isman->RejectConflictingBlocks()) {
// Require other nodes to comply, send them some data in case they are missing it. // Require other nodes to comply, send them some data in case they are missing it.
for (const auto& tx : block.vtx) { for (const auto& tx : block.vtx) {
// skip txes that have no inputs // skip txes that have no inputs
if (tx->vin.empty()) continue; if (tx->vin.empty()) continue;
while (llmq::CInstantSendLockPtr conflictLock = llmq::quorumInstantSendManager->GetConflictingLock(*tx)) { while (llmq::CInstantSendLockPtr conflictLock = m_isman->GetConflictingLock(*tx)) {
if (llmq::chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { if (m_clhandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n", LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n",
tx->GetHash().ToString(), ::SerializeHash(*conflictLock).ToString()); tx->GetHash().ToString(), ::SerializeHash(*conflictLock).ToString());
llmq::quorumInstantSendManager->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock); m_isman->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock);
} else { } else {
// The node which relayed this should switch to correct chain. // The node which relayed this should switch to correct chain.
// TODO: relay instantsend data/proof. // TODO: relay instantsend data/proof.
@ -4205,13 +4216,13 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
return true; return true;
} }
bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) bool TestBlockValidity(CValidationState& state, llmq::CChainLocksHandler& clhandler, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(pindexPrev && pindexPrev == ::ChainActive().Tip()); assert(pindexPrev && pindexPrev == ::ChainActive().Tip());
uint256 hash = block.GetHash(); uint256 hash = block.GetHash();
if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) { if (clhandler.HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock"); return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
} }
@ -4731,6 +4742,8 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */ /** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params)
{ {
assert(m_quorum_block_processor);
// TODO: merge with ConnectBlock // TODO: merge with ConnectBlock
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, params.GetConsensus())) { if (!ReadBlockFromDisk(block, pindex, params.GetConsensus())) {
@ -4739,7 +4752,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
// MUST process special txes before updating UTXO to ensure consistency between mempool and block processing // MUST process special txes before updating UTXO to ensure consistency between mempool and block processing
CValidationState state; CValidationState state;
if (!ProcessSpecialTxsInBlock(block, pindex, state, inputs, false /*fJustCheck*/, false /*fScriptChecks*/)) { if (!ProcessSpecialTxsInBlock(block, pindex, *m_quorum_block_processor, state, inputs, false /*fJustCheck*/, false /*fScriptChecks*/)) {
return error("RollforwardBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s", return error("RollforwardBlock(DASH): ProcessSpecialTxsInBlock for block %s failed with %s",
pindex->GetBlockHash().ToString(), FormatStateMessage(state)); pindex->GetBlockHash().ToString(), FormatStateMessage(state));
} }
@ -5528,7 +5541,10 @@ std::vector<CChainState*> ChainstateManager::GetAll()
return out; return out;
} }
CChainState& ChainstateManager::InitializeChainstate(const uint256& snapshot_blockhash) CChainState& ChainstateManager::InitializeChainstate(std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor,
const uint256& snapshot_blockhash)
{ {
bool is_snapshot = !snapshot_blockhash.IsNull(); bool is_snapshot = !snapshot_blockhash.IsNull();
std::unique_ptr<CChainState>& to_modify = std::unique_ptr<CChainState>& to_modify =
@ -5538,7 +5554,7 @@ CChainState& ChainstateManager::InitializeChainstate(const uint256& snapshot_blo
throw std::logic_error("should not be overwriting a chainstate"); throw std::logic_error("should not be overwriting a chainstate");
} }
to_modify.reset(new CChainState(m_blockman, snapshot_blockhash)); to_modify.reset(new CChainState(m_blockman, clhandler, isman, quorum_block_processor, snapshot_blockhash));
// Snapshot chainstates and initial IBD chaintates always become active. // Snapshot chainstates and initial IBD chaintates always become active.
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) { if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {

View File

@ -34,6 +34,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumBlockProcessor;
} // namespace llmq
class CChainState; class CChainState;
class CBlockIndex; class CBlockIndex;
class CBlockTreeDB; class CBlockTreeDB;
@ -329,7 +335,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true); bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
/** Check a block is completely valid from start to finish (only works on top of our current best block) */ /** Check a block is completely valid from start to finish (only works on top of our current best block) */
bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool TestBlockValidity(CValidationState& state, llmq::CChainLocksHandler& clhandler, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
class CVerifyDB { class CVerifyDB {
@ -530,8 +536,17 @@ private:
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`. //! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
std::unique_ptr<CoinsViews> m_coins_views; std::unique_ptr<CoinsViews> m_coins_views;
//! Dash
std::unique_ptr<llmq::CChainLocksHandler>& m_clhandler;
std::unique_ptr<llmq::CInstantSendManager>& m_isman;
std::unique_ptr<llmq::CQuorumBlockProcessor>& m_quorum_block_processor;
public: public:
explicit CChainState(BlockManager& blockman, uint256 from_snapshot_blockhash = uint256()); explicit CChainState(BlockManager& blockman,
std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor,
uint256 from_snapshot_blockhash = uint256());
/** /**
* Initialize the CoinsViews UTXO set database management data structures. The in-memory * Initialize the CoinsViews UTXO set database management data structures. The in-memory
@ -843,8 +858,10 @@ public:
//! //!
//! @param[in] snapshot_blockhash If given, signify that this chainstate //! @param[in] snapshot_blockhash If given, signify that this chainstate
//! is based on a snapshot. //! is based on a snapshot.
CChainState& InitializeChainstate(const uint256& snapshot_blockhash = uint256()) CChainState& InitializeChainstate(std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumBlockProcessor>& quorum_block_processor,
const uint256& snapshot_blockhash = uint256()) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
//! Get all chainstates currently being used. //! Get all chainstates currently being used.
std::vector<CChainState*> GetAll(); std::vector<CChainState*> GetAll();