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;
}
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
if (nConfirmedHeight == -1 || pindex->nHeight < nConfirmedHeight) return false; // not mined yet
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
@ -440,13 +440,13 @@ CCoinJoinBroadcastTx CCoinJoin::GetDSTX(const uint256& hash)
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);
LOCK(cs_mapdstx);
auto it = mapDSTX.begin();
while (it != mapDSTX.end()) {
if (it->second.IsExpired(pindex)) {
if (it->second.IsExpired(pindex, clhandler)) {
mapDSTX.erase(it++);
} else {
++it;
@ -455,17 +455,17 @@ void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex)
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()) {
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()) {
CheckDSTXes(pindex);
CheckDSTXes(pindex, clhandler);
}
}

View File

@ -23,6 +23,10 @@ class CConnman;
class CBLSPublicKey;
class CBlockIndex;
namespace llmq {
class CChainLocksHandler;
} // namespace llmq
// timeouts
static constexpr int COINJOIN_AUTO_TIMEOUT_MIN = 5;
static constexpr int COINJOIN_AUTO_TIMEOUT_MAX = 15;
@ -298,7 +302,7 @@ public:
bool CheckSignature(const CBLSPublicKey& blsPubKey) const;
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;
};
@ -374,7 +378,7 @@ private:
static Mutex 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:
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 CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(cs_mapdstx);
static void UpdatedBlockTip(const CBlockIndex* pindex);
static void NotifyChainLock(const CBlockIndex* pindex);
static void UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler);
static void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler);
static void UpdateDSTXConfirmedHeight(const CTransactionRef& tx, int nHeight);
static void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx);

View File

@ -20,6 +20,13 @@
#include <llmq/instantsend.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()
{
SynchronousUpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload());
@ -28,15 +35,15 @@ void CDSNotificationInterface::InitializeCurrentBlockTip()
void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew)
{
llmq::chainLocksHandler->AcceptedBlockHeader(pindexNew);
if (masternodeSync != nullptr) {
masternodeSync->AcceptedBlockHeader(pindexNew);
clhandler->AcceptedBlockHeader(pindexNew);
if (mnsync != nullptr) {
mnsync->AcceptedBlockHeader(pindexNew);
}
}
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)
@ -44,7 +51,7 @@ void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pin
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
return;
deterministicMNManager->UpdatedBlockTip(pindexNew);
dmnman->UpdatedBlockTip(pindexNew);
}
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
return;
masternodeSync->UpdatedBlockTip(pindexNew, fInitialDownload);
mnsync->UpdatedBlockTip(pindexNew, fInitialDownload);
// Update global DIP0001 activation status
fDIP0001ActiveAtTip = pindexNew->nHeight >= Params().GetConsensus().DIP0001Height;
@ -60,32 +67,32 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
if (fInitialDownload)
return;
CCoinJoin::UpdatedBlockTip(pindexNew);
CCoinJoin::UpdatedBlockTip(pindexNew, *clhandler);
#ifdef ENABLE_WALLET
for (auto& pair : coinJoinClientManagers) {
pair.second->UpdatedBlockTip(pindexNew);
}
#endif // ENABLE_WALLET
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);
llmq::chainLocksHandler->UpdatedBlockTip();
isman->UpdatedBlockTip(pindexNew);
clhandler->UpdatedBlockTip();
llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload);
llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload);
qman->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)
{
llmq::quorumInstantSendManager->TransactionAddedToMempool(ptx);
llmq::chainLocksHandler->TransactionAddedToMempool(ptx, nAcceptTime);
isman->TransactionAddedToMempool(ptx);
clhandler->TransactionAddedToMempool(ptx, nAcceptTime);
CCoinJoin::TransactionAddedToMempool(ptx);
}
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)
@ -98,26 +105,26 @@ void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock
// to abandon a transaction and then have it inadvertently cleared by
// the notification that the conflicted transaction was evicted.
llmq::quorumInstantSendManager->BlockConnected(pblock, pindex, vtxConflicted);
llmq::chainLocksHandler->BlockConnected(pblock, pindex, vtxConflicted);
isman->BlockConnected(pblock, pindex, vtxConflicted);
clhandler->BlockConnected(pblock, pindex, vtxConflicted);
CCoinJoin::BlockConnected(pblock, pindex, vtxConflicted);
}
void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected)
{
llmq::quorumInstantSendManager->BlockDisconnected(pblock, pindexDisconnected);
llmq::chainLocksHandler->BlockDisconnected(pblock, pindexDisconnected);
isman->BlockDisconnected(pblock, pindexDisconnected);
clhandler->BlockDisconnected(pblock, pindexDisconnected);
CCoinJoin::BlockDisconnected(pblock, pindexDisconnected);
}
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& 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)
{
llmq::quorumInstantSendManager->NotifyChainLock(pindex);
CCoinJoin::NotifyChainLock(pindex);
isman->NotifyChainLock(pindex);
CCoinJoin::NotifyChainLock(pindex, *clhandler);
}

View File

@ -7,10 +7,26 @@
#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
{
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;
// a small helper to initialize current block height in sub-modules on startup
@ -31,6 +47,15 @@ protected:
private:
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

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
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) {
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);
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
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.
* @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*/>> {
auto quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(pindexPrev);
auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(pindexPrev);
static Mutex 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];
for (const auto& blockIndex : vecBlockIndexes) {
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) {
// this should never happen
return std::nullopt;
@ -220,7 +220,7 @@ auto CalcHashCountFromQCHashes(const QcHashMap& qcHashes)
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 nTimeLoop = 0;
@ -228,7 +228,7 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
int64_t nTime1 = GetTimeMicros();
auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev);
auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev, quorum_block_processor);
if (retVal == std::nullopt) {
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "commitment-not-found");
}

View File

@ -13,6 +13,10 @@ class CBlockIndex;
class CCoinsViewCache;
class CValidationState;
namespace llmq {
class CQuorumBlockProcessor;
}// namespace llmq
// coinbase transaction
class CCbTx
{
@ -51,8 +55,8 @@ public:
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 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

View File

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

View File

@ -130,10 +130,11 @@ 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 quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(blockIndex);
auto baseQuorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(baseBlockIndex);
auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(blockIndex);
std::set<std::pair<Consensus::LLMQType, uint256>> baseQuorumHashes;
std::set<std::pair<Consensus::LLMQType, uint256>> quorumHashes;
@ -156,7 +157,7 @@ bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex,
for (auto& p : quorumHashes) {
if (!baseQuorumHashes.count(p)) {
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) {
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);
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.
mnListDiffRet.baseBlockHash = baseBlockHash;
if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex)) {
if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex, quorum_block_processor)) {
errorRet = strprintf("failed to build quorums diff");
return false;
}

View File

@ -15,9 +15,9 @@ class CBlockIndex;
class CDeterministicMNList;
class CDeterministicMN;
namespace llmq
{
class CFinalCommitment;
namespace llmq {
class CFinalCommitment;
class CQuorumBlockProcessor;
} // namespace llmq
class CSimplifiedMNListEntry
@ -117,11 +117,13 @@ public:
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;
};
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

View File

@ -98,7 +98,8 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
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);
@ -125,7 +126,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
nTimeLoop += nTime2 - nTime1;
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
return false;
}
@ -143,7 +144,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
nTimeDMN += nTime4 - nTime3;
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
return false;
}
@ -159,7 +160,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV
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);
@ -175,7 +176,7 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex)
return false;
}
if (!llmq::quorumBlockProcessor->UndoBlock(block, pindex)) {
if (!quorum_block_processor.UndoBlock(block, pindex)) {
return false;
}
} catch (const std::exception& e) {

View File

@ -17,7 +17,8 @@ class CValidationState;
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 ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor,
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

View File

@ -82,12 +82,15 @@
#include <evo/deterministicmns.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/init.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/signing.h>
#include <llmq/snapshot.h>
#include <llmq/utils.h>
#include <llmq/signing_shares.h>
#include <statsd_client.h>
@ -1777,7 +1780,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
node.chainman = &g_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());
::governance = std::make_unique<CGovernanceManager>();
@ -1933,7 +1940,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
}
#endif
pdsNotificationInterface = new CDSNotificationInterface(*node.connman);
pdsNotificationInterface = new CDSNotificationInterface(
*node.connman, ::masternodeSync, ::deterministicMNManager, ::governance, llmq::chainLocksHandler,
llmq::quorumInstantSendManager, llmq::quorumManager, llmq::quorumDKGSessionManager
);
RegisterValidationInterface(pdsNotificationInterface);
if (fMasternodeMode) {
@ -2012,7 +2022,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
try {
LOCK(cs_main);
chainman.InitializeChainstate();
chainman.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
chainman.m_total_coinstip_cache = nCoinCacheUsage;
chainman.m_total_coinsdb_cache = nCoinDBCache;

View File

@ -6,6 +6,7 @@
#include <llmq/quorums.h>
#include <llmq/instantsend.h>
#include <llmq/utils.h>
#include <llmq/signing_shares.h>
#include <chain.h>
#include <chainparams.h>
@ -23,10 +24,8 @@ namespace llmq
{
std::unique_ptr<CChainLocksHandler> chainLocksHandler;
CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager) :
scheduler(std::make_unique<CScheduler>()),
mempool(_mempool), connman(_connman),
spork_manager(sporkManager),
CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman) :
scheduler(std::make_unique<CScheduler>()), mempool(_mempool), connman(_connman), spork_manager(sporkManager), sigman(_sigman), shareman(_shareman),
scheduler_thread(std::make_unique<std::thread>([&] { TraceThread("cl-schdlr", [&] { scheduler->serviceQueue(); }); }))
{
}
@ -39,7 +38,7 @@ CChainLocksHandler::~CChainLocksHandler()
void CChainLocksHandler::Start()
{
quorumSigningManager->RegisterRecoveredSigsListener(this);
sigman.RegisterRecoveredSigsListener(this);
scheduler->scheduleEvery([&]() {
CheckActiveState();
EnforceBestChainLock();
@ -51,7 +50,7 @@ void CChainLocksHandler::Start()
void CChainLocksHandler::Stop()
{
scheduler->stop();
quorumSigningManager->UnregisterRecoveredSigsListener(this);
sigman.UnregisterRecoveredSigsListener(this);
}
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()));
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);
if (from != -1) {
LOCK(cs_main);
@ -335,7 +334,7 @@ void CChainLocksHandler::TrySignChainTip()
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)
@ -436,19 +435,19 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const
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;
}
if (!isEnabled || !isEnforced) {
return true;
}
if (!quorumInstantSendManager->IsInstantSendEnabled()) {
if (!isman.IsInstantSendEnabled()) {
return true;
}
if (quorumInstantSendManager->IsLocked(txid)) {
if (isman.IsLocked(txid)) {
return true;
}

View File

@ -27,6 +27,9 @@ class CSporkManager;
namespace llmq
{
class CInstantSendManager;
class CSigningManager;
class CSigSharesManager;
class CChainLocksHandler : public CRecoveredSigsListener
{
@ -40,6 +43,8 @@ private:
CConnman& connman;
CTxMemPool& mempool;
CSporkManager& spork_manager;
CSigningManager& sigman;
CSigSharesManager& shareman;
std::unique_ptr<CScheduler> scheduler;
std::unique_ptr<std::thread> scheduler_thread;
mutable CCriticalSection cs;
@ -72,7 +77,7 @@ private:
int64_t lastCleanupTime GUARDED_BY(cs) {0};
public:
explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager);
explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman);
~CChainLocksHandler();
void Start();
@ -97,7 +102,7 @@ public:
bool HasChainLock(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:
// 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()) {
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);
std::stringstream ss;
for (const auto& r : relayMembers) {
@ -183,7 +183,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages)
logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentContributions = true;
return true;
});
@ -266,7 +266,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
CInv inv(MSG_QUORUM_CONTRIB, hash);
RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedContribution = true;
return true;
});
@ -306,7 +306,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
if (complain) {
member->weComplain = true;
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.weComplain = true;
return true;
});
@ -374,7 +374,7 @@ void CDKGSession::VerifyPendingContributions()
const auto& m = members[memberIndexes[i]];
logger.Batch("invalid contribution from %s. will complain later", m->dmn->proTxHash.ToString());
m->weComplain = true;
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) {
status.weComplain = true;
return true;
});
@ -499,7 +499,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages)
logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentComplaint = true;
return true;
});
@ -572,7 +572,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan)
CInv inv(MSG_QUORUM_COMPLAINT, hash);
RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedComplaint = true;
return true;
});
@ -598,7 +598,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan)
if (qc.complainForMembers[i]) {
m->complaintsFromOthers.emplace(qc.proTxHash);
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;
});
if (AreWeMember() && i == myIdx) {
@ -693,7 +693,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const
logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentJustification = true;
return true;
});
@ -783,7 +783,7 @@ void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan)
CInv inv(MSG_QUORUM_JUSTIFICATION, hash);
RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedJustification = true;
return true;
});
@ -1005,7 +1005,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages)
logger.Flush();
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.sentPrematureCommitment = true;
return true;
});
@ -1142,7 +1142,7 @@ void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan
CInv inv(MSG_QUORUM_PREMATURE_COMMITMENT, hash);
RelayInvToParticipants(inv);
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) {
status.receivedPrematureCommitment = true;
return true;
});
@ -1280,7 +1280,7 @@ void CDKGSession::MarkBadMember(size_t idx)
if (member->bad) {
return;
}
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) {
dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) {
status.bad = true;
return true;
});

View File

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

View File

@ -141,7 +141,7 @@ void CDKGSessionHandler::StopThread()
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)) {
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));
if (nextPhase == QuorumPhase::Initialized) {
quorumDKGDebugManager->ResetLocalSessionStatus(params.type, quorumIndex);
dkgDebugManager.ResetLocalSessionStatus(params.type, quorumIndex);
} else {
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != (uint8_t) nextPhase;
status.phase = (uint8_t) nextPhase;
return changed;
@ -481,7 +481,7 @@ void CDKGSessionHandler::HandleDKGRound()
throw AbortPhaseException();
}
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
bool changed = status.phase != (uint8_t) QuorumPhase::Initialized;
status.phase = (uint8_t) QuorumPhase::Initialized;
return changed;
@ -532,7 +532,7 @@ void CDKGSessionHandler::HandleDKGRound()
auto finalCommitments = curSession->FinalizeCommitments();
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);
HandleDKGRound();
} catch (AbortPhaseException& e) {
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) {
status.aborted = true;
return true;
});

View File

@ -16,9 +16,10 @@ class CBlockIndex;
namespace llmq
{
class CDKGDebugManager;
class CDKGSession;
class CDKGSessionManager;
class CQuorumBlockProcessor;
enum class QuorumPhase {
Initialized = 1,
@ -113,6 +114,8 @@ private:
const int quorumIndex;
CBLSWorker& blsWorker;
CDKGSessionManager& dkgManager;
CDKGDebugManager& dkgDebugManager;
CQuorumBlockProcessor& quorumBlockProcessor;
QuorumPhase phase GUARDED_BY(cs) {QuorumPhase::Idle};
int currentHeight GUARDED_BY(cs) {-1};
@ -128,13 +131,16 @@ private:
CDKGPendingMessages pendingPrematureCommitments;
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),
blsWorker(_blsWorker),
dkgManager(_dkgManager),
dkgDebugManager(_dkgDebugManager),
quorumBlockProcessor(_quorumBlockProcessor),
connman(_connman),
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)
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
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_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)),
blsWorker(_blsWorker), connman(_connman), spork_manager(sporkManager)
blsWorker(_blsWorker), connman(_connman), dkgDebugManager(_dkgDebugManager), quorumBlockProcessor(_quorumBlockProcessor),spork_manager(sporkManager)
{
if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) {
// 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)) {
dkgSessionHandlers.emplace(std::piecewise_construct,
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 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;
}
if (!utils::IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) {
if (!utils::IsQuorumTypeEnabled(llmqType, quorum_manager, pQuorumBaseBlockIndex->pprev)) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- llmqType [%d] quorums aren't active\n", uint8_t(llmqType));
Misbehaving(pfrom->GetId(), 100);

View File

@ -12,10 +12,12 @@
class UniValue;
class CBlockIndex;
class CDKGDebugManager;
class CSporkManager;
namespace llmq
{
class CQuorumManager;
class CDKGSessionManager
{
@ -26,6 +28,8 @@ private:
CBLSWorker& blsWorker;
CConnman& connman;
CSporkManager& spork_manager;
CDKGDebugManager& dkgDebugManager;
CQuorumBlockProcessor& quorumBlockProcessor;
//TODO name struct instead of std::pair
std::map<std::pair<Consensus::LLMQType, int>, CDKGSessionHandler> dkgSessionHandlers;
@ -50,7 +54,7 @@ private:
mutable std::map<ContributionsCacheKey, ContributionsCacheEntry> contributionsCache GUARDED_BY(contributionsCacheCs);
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;
void StartThreads();
@ -58,7 +62,7 @@ public:
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 GetContribution(const uint256& hash, CDKGContribution& 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>();
quorumBlockProcessor = std::make_unique<CQuorumBlockProcessor>(evoDb, connman);
quorumDKGSessionManager = std::make_unique<CDKGSessionManager>(connman, *blsWorker, sporkManager, unitTests, fWipe);
quorumManager = std::make_unique<CQuorumManager>(evoDb, connman, *blsWorker, *quorumDKGSessionManager);
quorumSigSharesManager = std::make_unique<CSigSharesManager>(connman);
quorumSigningManager = std::make_unique<CSigningManager>(connman, unitTests, fWipe);
chainLocksHandler = std::make_unique<CChainLocksHandler>(mempool, connman, sporkManager);
quorumInstantSendManager = std::make_unique<CInstantSendManager>(mempool, connman, sporkManager, unitTests, fWipe);
quorumDKGSessionManager = std::make_unique<CDKGSessionManager>(connman, *blsWorker, *quorumDKGDebugManager, *quorumBlockProcessor, sporkManager, unitTests, fWipe);
quorumManager = std::make_unique<CQuorumManager>(evoDb, connman, *blsWorker, *quorumBlockProcessor, *quorumDKGSessionManager);
quorumSigningManager = std::make_unique<CSigningManager>(connman, *quorumManager, unitTests, fWipe);
quorumSigSharesManager = std::make_unique<CSigSharesManager>(connman, *quorumManager, *quorumSigningManager);
chainLocksHandler = std::make_unique<CChainLocksHandler>(mempool, connman, sporkManager, *quorumSigningManager, *quorumSigSharesManager);
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
// TODO: remove it in some future version
@ -45,8 +45,8 @@ void DestroyLLMQSystem()
{
quorumInstantSendManager.reset();
chainLocksHandler.reset();
quorumSigningManager.reset();
quorumSigSharesManager.reset();
quorumSigningManager.reset();
quorumManager.reset();
quorumDKGSessionManager.reset();
quorumBlockProcessor.reset();

View File

@ -8,6 +8,7 @@
#include <llmq/quorums.h>
#include <llmq/utils.h>
#include <llmq/commitment.h>
#include <llmq/signing_shares.h>
#include <bls/bls_batchverifier.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)));
quorumSigningManager->RegisterRecoveredSigsListener(this);
sigman.RegisterRecoveredSigsListener(this);
}
void CInstantSendManager::Stop()
{
quorumSigningManager->UnregisterRecoveredSigsListener(this);
sigman.UnregisterRecoveredSigsListener(this);
// make sure to call InterruptWorkerThread() first
if (!workInterrupt) {
@ -509,7 +510,7 @@ void CInstantSendManager::ProcessTx(const CTransaction& tx, bool fRetroactive, c
// block after we retroactively locked all transactions.
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;
}
@ -530,8 +531,8 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
uint256 otherTxHash;
// TODO check that we didn't vote for the other IS type also
if (quorumSigningManager->GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) ||
quorumSigningManager->GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) {
if (sigman.GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) ||
sigman.GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) {
if (otherTxHash != tx.GetHash()) {
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());
@ -542,10 +543,10 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
// don't even try the actual signing if any input is conflicting
if (auto llmqs = {params.llmqTypeDIP0024InstantSend, params.llmqTypeInstantSend};
ranges::any_of(llmqs, [&id, &tx](const auto& llmqType){
return quorumSigningManager->IsConflicting(llmqType, id, tx.GetHash());})
ranges::any_of(llmqs, [&id, &tx, this](const auto& llmqType){
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());
return false;
}
@ -565,7 +566,7 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa
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__,
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__,
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;
}
if (nTxAge < nInstantSendConfirmationsRequired && !llmq::chainLocksHandler->HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) {
if (nTxAge < nInstantSendConfirmationsRequired && !clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) {
if (printDebug) {
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);
@ -683,11 +684,11 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re
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) {
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;
}
}
@ -713,7 +714,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
auto id = islock.GetRequestId();
if (quorumSigningManager->HasRecoveredSigForId(llmqType, id)) {
if (sigman.HasRecoveredSigForId(llmqType, id)) {
return;
}
@ -726,7 +727,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
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)
@ -852,7 +853,7 @@ bool CInstantSendManager::PreVerifyInstantSendLock(const llmq::CInstantSendLock&
bool CInstantSendManager::ProcessPendingInstantSendLocks()
{
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
return ProcessPendingInstantSendLocks(true) & ProcessPendingInstantSendLocks(false);
} else {
@ -950,7 +951,7 @@ std::unordered_set<uint256, StaticSaltedHasher> CInstantSendManager::ProcessPend
auto id = islock->GetRequestId();
// 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++;
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) {
// should not happen, but if one fails to select, all others will also fail to select
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
// 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)
if (!quorumSigningManager->HasRecoveredSigForId(llmqType, id)) {
if (!sigman.HasRecoveredSigForId(llmqType, id)) {
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);
if (it != recSigs.end()) {
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__,
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,
// 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__,
islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from);
return;
@ -1197,7 +1198,7 @@ void CInstantSendManager::BlockConnected(const std::shared_ptr<const CBlock>& pb
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());
// TX is not locked, so make sure it is tracked
AddNonLockedTx(tx, pindex);
@ -1306,7 +1307,7 @@ void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSen
for (const auto& in : islock.inputs) {
auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in));
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
// fully confirmed now
quorumSigningManager->TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId());
sigman.TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId());
}
db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100);
@ -1446,7 +1447,7 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const
bool hasChainLockedConflict = false;
for (const auto& p : conflicts) {
const auto* pindex = p.first;
if (chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
if (clhandler.HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
hasChainLockedConflict = true;
break;
}

View File

@ -22,6 +22,10 @@ class CSporkManager;
namespace llmq
{
class CChainLocksHandler;
class CQuorumManager;
class CSigningManager;
class CSigSharesManager;
struct CInstantSendLock
{
@ -199,6 +203,10 @@ private:
CConnman& connman;
CTxMemPool& mempool;
CSporkManager& spork_manager;
CQuorumManager& qman;
CSigningManager& sigman;
CSigSharesManager& shareman;
CChainLocksHandler& clhandler;
std::atomic<bool> fUpgradedDB{false};
@ -246,7 +254,13 @@ private:
std::unordered_set<uint256, StaticSaltedHasher> pendingRetryTxs GUARDED_BY(cs_pendingRetry);
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;
void Start();

View File

@ -186,10 +186,12 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
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),
evoDb(_evoDb),
blsWorker(_blsWorker),
quorumBlockProcessor(_quorumBlockProcessor),
dkgManager(_dkgManager)
{
utils::InitQuorumsCache(mapQuorumsCache);
@ -362,7 +364,7 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
const uint256& quorumHash{pQuorumBaseBlockIndex->GetBlockHash()};
uint256 minedBlockHash;
CFinalCommitmentPtr qc = quorumBlockProcessor->GetMinedCommitment(llmqType, quorumHash, minedBlockHash);
CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, quorumHash, minedBlockHash);
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());
return nullptr;
@ -429,9 +431,9 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitmentPtr& fqc, co
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
@ -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
{
if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, pindexStart)) {
if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, *this, pindexStart)) {
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
std::vector<const CBlockIndex*> pQuorumBaseBlockIndexes{ GetLLMQParams(llmqType).useRotation ?
quorumBlockProcessor->GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) :
quorumBlockProcessor->GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments)
quorumBlockProcessor.GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) :
quorumBlockProcessor.GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments)
};
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
// cached quorums which are not in the active chain anymore
if (!HasQuorum(llmqType, quorumHash)) {
if (!HasQuorum(llmqType, quorumBlockProcessor, quorumHash)) {
return nullptr;
}
@ -685,7 +687,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C
}
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);
return;
}
@ -913,7 +915,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
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();
printLog("Requested");
} else {

View File

@ -27,8 +27,8 @@ using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
namespace llmq
{
class CDKGSessionManager;
class CQuorumBlockProcessor;
// If true, we will connect to all new quorums and watch their communication
static constexpr bool DEFAULT_WATCH_QUORUMS{false};
@ -209,6 +209,7 @@ private:
CConnman& connman;
CBLSWorker& blsWorker;
CDKGSessionManager& dkgManager;
CQuorumBlockProcessor& quorumBlockProcessor;
mutable CCriticalSection 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;
public:
CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager);
CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor,
CDKGSessionManager& _dkgManager);
~CQuorumManager() { Stop(); };
void Start();
@ -231,7 +233,7 @@ public:
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;

View File

@ -528,8 +528,8 @@ void CRecoveredSigsDb::CleanupOldVotes(int64_t maxAge)
//////////////////
CSigningManager::CSigningManager(CConnman& _connman, bool fMemory, bool fWipe) :
db(fMemory, fWipe), connman(_connman)
CSigningManager::CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe) :
db(fMemory, fWipe), connman(_connman), qman(_qman)
{
}
@ -553,7 +553,7 @@ bool CSigningManager::GetRecoveredSigForGetData(const uint256& hash, CRecoveredS
if (!db.GetRecoveredSigByHash(hash, ret)) {
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
return false;
}
@ -577,7 +577,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared
}
bool ban = false;
if (!PreVerifyRecoveredSig(*recoveredSig, ban)) {
if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) {
if (ban) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
@ -604,7 +604,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared
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;
@ -614,14 +614,14 @@ bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, b
return false;
}
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recoveredSig.getQuorumHash());
CQuorumCPtr quorum = quorum_manager.GetQuorum(llmqType, recoveredSig.getQuorumHash());
if (!quorum) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found\n", __func__,
recoveredSig.getQuorumHash().ToString());
return false;
}
if (!utils::IsQuorumActive(llmqType, quorum->qc->quorumHash)) {
if (!utils::IsQuorumActive(llmqType, quorum_manager, quorum->qc->quorumHash)) {
return false;
}
@ -672,14 +672,14 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
auto llmqType = recSig->getLlmqType();
auto quorumKey = std::make_pair(recSig->getLlmqType(), recSig->getQuorumHash());
if (!retQuorums.count(quorumKey)) {
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recSig->getQuorumHash());
CQuorumCPtr quorum = qman.GetQuorum(llmqType, recSig->getQuorumHash());
if (!quorum) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found, node=%d\n", __func__,
recSig->getQuorumHash().ToString(), nodeId);
it = v.erase(it);
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__,
recSig->getQuorumHash().ToString(), nodeId);
it = v.erase(it);
@ -872,7 +872,7 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l)
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())) {
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
// 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
quorum = SelectQuorumForSigning(llmqType, id);
quorum = SelectQuorumForSigning(llmqType, qman, id);
} else {
quorum = quorumManager->GetQuorum(llmqType, quorumHash);
quorum = qman.GetQuorum(llmqType, quorumHash);
}
if (!quorum) {
@ -931,9 +931,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint
if (allowReSign) {
// 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;
}
@ -982,7 +982,7 @@ bool CSigningManager::GetVoteForId(Consensus::LLMQType llmqType, const uint256&
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;
@ -1000,7 +1000,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
}
if (utils::IsQuorumRotationEnabled(llmqType, pindexStart)) {
auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize);
auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
if (quorums.empty()) {
return nullptr;
}
@ -1024,7 +1024,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
}
return *itQuorum;
} else {
auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize);
auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize);
if (quorums.empty()) {
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) {
return false;
}

View File

@ -24,14 +24,14 @@ class CNode;
namespace llmq
{
class CQuorum;
using CQuorumCPtr = std::shared_ptr<const CQuorum>;
class CQuorumManager;
class CSigSharesManager;
// 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};
class CSigBase
{
protected:
@ -166,6 +166,7 @@ private:
CConnman& connman;
CRecoveredSigsDb db;
const CQuorumManager& qman;
// Incoming and not verified yet
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);
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 GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const;
@ -197,7 +198,7 @@ public:
private:
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,
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>>& retSigShares,
@ -212,7 +213,7 @@ public:
void RegisterRecoveredSigsListener(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 HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id) const;
bool HasRecoveredSigForSession(const uint256& signHash) const;
@ -222,10 +223,10 @@ public:
bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet) const;
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
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;

View File

@ -202,12 +202,12 @@ void CSigSharesManager::StopWorkerThread()
void CSigSharesManager::RegisterAsRecoveredSigsListener()
{
quorumSigningManager->RegisterRecoveredSigsListener(this);
sigman.RegisterRecoveredSigsListener(this);
}
void CSigSharesManager::UnregisterAsRecoveredSigsListener()
{
quorumSigningManager->UnregisterRecoveredSigsListener(this);
sigman.UnregisterRecoveredSigsListener(this);
}
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());
auto quorum = quorumManager->GetQuorum(llmqType, ann.getQuorumHash());
auto quorum = qman.GetQuorum(llmqType, ann.getQuorumHash());
if (!quorum) {
// TODO should we ban here?
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
if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) {
if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) {
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
if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) {
if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) {
return true;
}
@ -407,7 +407,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const
return true;
}
if (bool ban{false}; !PreVerifyBatchedSigShares(sessionInfo, batchedSigShares, ban)) {
if (bool ban{false}; !PreVerifyBatchedSigShares(qman, sessionInfo, batchedSigShares, 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
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
continue;
}
@ -456,11 +456,11 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const
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) {
return;
}
if (!utils::IsQuorumActive(sigShare.getLlmqType(), quorum->qc->quorumHash)) {
if (!utils::IsQuorumActive(sigShare.getLlmqType(), qman, quorum->qc->quorumHash)) {
// quorum is too old
return;
}
@ -493,7 +493,7 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
return;
}
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
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);
}
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;
if (!utils::IsQuorumActive(session.llmqType, session.quorum->qc->quorumHash)) {
if (!utils::IsQuorumActive(session.llmqType, quorum_manager, session.quorum->qc->quorumHash)) {
// quorum is too old
return false;
}
@ -597,7 +597,7 @@ void CSigSharesManager::CollectPendingSigSharesToVerify(
continue;
}
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, sigShare.getQuorumHash());
CQuorumCPtr quorum = qman.GetQuorum(llmqType, sigShare.getQuorumHash());
assert(quorum != nullptr);
retQuorums.try_emplace(k, quorum);
}
@ -623,7 +623,7 @@ bool CSigSharesManager::ProcessPendingSigShares(const CConnman& connman)
size_t verifyCount = 0;
for (const auto& [nodeId, v] : sigSharesByNodes) {
for (const auto& sigShare : v) {
if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) {
continue;
}
@ -701,7 +701,7 @@ void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnma
quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash());
}
if (quorumSigningManager->HasRecoveredSigForId(llmqType, sigShare.getId())) {
if (sigman.HasRecoveredSigForId(llmqType, sigShare.getId())) {
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)
{
if (quorumSigningManager->HasRecoveredSigForId(quorum->params.type, id)) {
if (sigman.HasRecoveredSigForId(quorum->params.type, id)) {
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)
@ -860,7 +860,7 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, std
continue;
}
if (quorumSigningManager->HasRecoveredSigForSession(signHash)) {
if (sigman.HasRecoveredSigForSession(signHash)) {
continue;
}
@ -929,7 +929,7 @@ void CSigSharesManager::CollectSigSharesToSend(std::unordered_map<NodeId, std::u
continue;
}
if (quorumSigningManager->HasRecoveredSigForSession(signHash)) {
if (sigman.HasRecoveredSigForSession(signHash)) {
continue;
}
@ -1257,8 +1257,8 @@ void CSigSharesManager::Cleanup()
// Find quorums which became inactive
for (auto it = quorums.begin(); it != quorums.end(); ) {
if (utils::IsQuorumActive(it->first.first, it->first.second)) {
it->second = quorumManager->GetQuorum(it->first.first, it->first.second);
if (utils::IsQuorumActive(it->first.first, qman, it->first.second)) {
it->second = qman.GetQuorum(it->first.first, it->first.second);
++it;
} else {
it = quorums.erase(it);
@ -1284,11 +1284,11 @@ void CSigSharesManager::Cleanup()
// Remove sessions which were successfully recovered
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) {
return;
}
if (quorumSigningManager->HasRecoveredSigForSession(sigShare.GetSignHash())) {
if (sigman.HasRecoveredSigForSession(sigShare.GetSignHash())) {
doneSessions.emplace(sigShare.GetSignHash());
}
});
@ -1441,7 +1441,7 @@ void CSigSharesManager::WorkThreadMain()
bool fMoreWork{false};
RemoveBannedNodeStates();
fMoreWork |= quorumSigningManager->ProcessPendingRecoveredSigs();
fMoreWork |= sigman.ProcessPendingRecoveredSigs();
fMoreWork |= ProcessPendingSigShares(connman);
SignPendingSigShares();
@ -1451,7 +1451,7 @@ void CSigSharesManager::WorkThreadMain()
}
Cleanup();
quorumSigningManager->Cleanup();
sigman.Cleanup();
// TODO Wakeup when pending signing is needed?
if (!fMoreWork && !workInterrupt.sleep_for(std::chrono::milliseconds(100))) {

View File

@ -28,6 +28,8 @@ using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
namespace llmq
{
class CSigningManager;
// <signHash, quorumMember>
using SigShareKey = std::pair<uint256, uint16_t>;
@ -395,11 +397,13 @@ private:
FastRandomContext rnd GUARDED_BY(cs);
CConnman& connman;
const CQuorumManager& qman;
CSigningManager& sigman;
int64_t lastCleanupTime{0};
std::atomic<uint32_t> recoveredSigsCounter{0};
public:
explicit CSigSharesManager(CConnman& _connman) : connman(_connman)
explicit CSigSharesManager(CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman) : connman(_connman), qman(_qman), sigman(_sigman)
{
workInterrupt.reset();
};
@ -431,7 +435,7 @@ private:
void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare);
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,
std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares,

View File

@ -117,7 +117,8 @@ void CQuorumRotationInfo::ToJson(UniValue& obj) const
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);
@ -153,7 +154,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
return false;
}
//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;
}
@ -164,7 +165,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
}
//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
const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType);
@ -184,7 +185,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
}
//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;
}
@ -230,7 +231,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
const CBlockIndex* pWorkBlockHMinus4CIndex = pBlockHMinus4CIndex->GetAncestor(pBlockHMinus4CIndex->nHeight - workDiff);
//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;
}
@ -242,7 +243,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
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;
}
@ -254,7 +255,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
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;
}
@ -283,7 +284,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
}
CSimplifiedMNListDiff mn4c;
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, errorRet)) {
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, quorumBlockProcessor, errorRet)) {
return false;
}
@ -296,11 +297,11 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
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) {
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) {
return false;
}
@ -339,7 +340,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat
}
CSimplifiedMNListDiff mnhneeded;
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, errorRet)) {
if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, quorumBlockProcessor, errorRet)) {
return false;
}

View File

@ -22,6 +22,9 @@ class CDeterministicMN;
class CDeterministicMNList;
namespace llmq {
class CQuorumBlockProcessor;
class CQuorumManager;
//TODO use enum class (probably)
enum SnapshotSkipMode : int {
MODE_NO_SKIPPING = 0,
@ -204,7 +207,8 @@ public:
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);
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 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);
if (!IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) {
if (!IsQuorumTypeEnabled(llmqType, *llmq::quorumManager, pQuorumBaseBlockIndex->pprev)) {
return {};
}
std::vector<CDeterministicMNCPtr> quorumMembers;
@ -577,9 +577,9 @@ bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pi
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().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
// 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
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; });
}
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,
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)
{
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);
if (fDIP0024IsActive) {
bool fHaveDIP0024Quorums = optHaveDIP0024Quorums.has_value() ? *optHaveDIP0024Quorums
: !quorumManager->ScanQuorums(
: !qman.ScanQuorums(
consensusParams.llmqTypeDIP0024InstantSend, pindex, 1).empty();
if (fHaveDIP0024Quorums) {
return false;
@ -896,7 +896,7 @@ std::vector<Consensus::LLMQType> GetEnabledQuorumTypes(const CBlockIndex* pindex
std::vector<Consensus::LLMQType> ret;
ret.reserve(Params().GetConsensus().llmqs.size());
for (const auto& params : Params().GetConsensus().llmqs) {
if (IsQuorumTypeEnabled(params.type, pindex)) {
if (IsQuorumTypeEnabled(params.type, *llmq::quorumManager, pindex)) {
ret.push_back(params.type);
}
}
@ -909,7 +909,7 @@ std::vector<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuoru
ret.reserve(Params().GetConsensus().llmqs.size());
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;
}

View File

@ -25,6 +25,7 @@ class CBLSPublicKey;
namespace llmq
{
class CQuorumManager;
class CQuorumSnapshot;
// 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);
void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash);
bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash);
bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex);
bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex* pindex, std::optional<bool> optDIP0024IsActive, std::optional<bool> optHaveDIP0024Quorums);
bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, const uint256& quorumHash);
bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex);
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<std::reference_wrapper<const Consensus::LLMQParams>> GetEnabledQuorumParams(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);
bool IsDIP0024Active(const CBlockIndex* pindex);
static bool IsInstantSendLLMQTypeShared();

View File

@ -28,6 +28,7 @@
#include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <llmq/utils.h>
#include <masternode/payments.h>
#include <spork.h>
@ -56,11 +57,15 @@ BlockAssembler::Options::Options() {
}
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),
governance_manager(governanceManager),
quorum_block_processor(quorumBlockProcessor),
chainparams(params),
m_mempool(mempool)
m_mempool(mempool),
m_clhandler(clhandler),
m_isman(isman)
{
blockMinFeeRate = options.blockMinFeeRate;
// 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,
const CTxMemPool& mempool, const CChainParams& params)
: BlockAssembler(sporkManager, governanceManager, mempool, params, DefaultOptions()) {}
const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler,
llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params)
: BlockAssembler(sporkManager, governanceManager, quorumBlockProcessor, clhandler, isman, mempool, params, DefaultOptions()) {}
void BlockAssembler::resetBlock()
{
@ -146,9 +152,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
if (fDIP0003Active_context) {
for (const Consensus::LLMQParams& params : llmq::utils::GetEnabledQuorumParams(pindexPrev)) {
std::vector<CTransactionRef> vqcTx;
if (llmq::quorumBlockProcessor->GetMineableCommitmentsTx(params,
nHeight,
vqcTx)) {
if (quorum_block_processor.GetMineableCommitmentsTx(params,
nHeight,
vqcTx)) {
for (const auto& qcTx : vqcTx) {
pblock->vtx.emplace_back(qcTx);
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)));
}
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)));
}
}
@ -230,7 +236,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]);
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)));
}
int64_t nTime2 = GetTimeMicros();
@ -270,7 +276,7 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa
for (CTxMemPool::txiter it : package) {
if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff))
return false;
if (!llmq::chainLocksHandler->IsTxSafeForMining(it->GetTx().GetHash())) {
if (!m_clhandler.IsTxSafeForMining(m_isman, it->GetTx().GetHash())) {
return false;
}
}

View File

@ -25,6 +25,11 @@ class CScript;
class CSporkManager;
namespace Consensus { struct Params; };
namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumBlockProcessor;
} // namespace llmq
static const bool DEFAULT_PRINTPRIORITY = false;
@ -152,6 +157,9 @@ private:
const CTxMemPool& m_mempool;
const CSporkManager& spork_manager;
CGovernanceManager& governance_manager;
const llmq::CQuorumBlockProcessor& quorum_block_processor;
llmq::CChainLocksHandler& m_clhandler;
llmq::CInstantSendManager& m_isman;
public:
struct Options {
@ -161,9 +169,11 @@ public:
};
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,
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 */
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);
}
PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool enable_bip61)
: connman(connmanIn), m_banman(banman), m_chainman(chainman), m_mempool(pool), m_stale_tip_check_time(0), m_enable_bip61(enable_bip61) {
PeerLogicValidation::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) :
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.
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)
{
@ -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
// corresponding checks in ProcessMessage won't let it to send DSTX-es too often.
bool fIgnoreRecentRejects = inv.type == MSG_DSTX ||
llmq::quorumInstantSendManager->IsWaitingForTx(inv.hash) ||
llmq::quorumInstantSendManager->IsLocked(inv.hash);
isman.IsWaitingForTx(inv.hash) ||
isman.IsLocked(inv.hash);
return (!fIgnoreRecentRejects && recentRejects->contains(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);
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_COMPLAINT:
case MSG_QUORUM_JUSTIFICATION:
case MSG_QUORUM_PREMATURE_COMMITMENT:
return llmq::quorumDKGSessionManager->AlreadyHave(inv);
return qdkgsman.AlreadyHave(inv);
case MSG_QUORUM_RECOVERED_SIG:
return llmq::quorumSigningManager->AlreadyHave(inv);
return sigman.AlreadyHave(inv);
case MSG_CLSIG:
return llmq::chainLocksHandler->AlreadyHave(inv);
return clhandler.AlreadyHave(inv);
case MSG_ISLOCK:
case MSG_ISDLOCK:
return llmq::quorumInstantSendManager->AlreadyHave(inv);
return isman.AlreadyHave(inv);
}
// 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));
}
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;
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]));
}
for (PairType &pair : merkleBlock.vMatchedTxn) {
auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(pair.second);
auto islock = isman.GetInstantSendLockByTxid(pair.second);
if (islock != nullptr) {
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);
@ -1857,7 +1870,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_FINAL_COMMITMENT)) {
llmq::CFinalCommitment o;
if (llmq::quorumBlockProcessor->GetMineableCommitmentByHash(
if (quorum_block_processor.GetMineableCommitmentByHash(
inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QFCOMMITMENT, o));
push = true;
@ -1866,7 +1879,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_CONTRIB)) {
llmq::CDKGContribution o;
if (llmq::quorumDKGSessionManager->GetContribution(inv.hash, o)) {
if (qdkgsman.GetContribution(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCONTRIB, o));
push = true;
}
@ -1874,7 +1887,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_COMPLAINT)) {
llmq::CDKGComplaint o;
if (llmq::quorumDKGSessionManager->GetComplaint(inv.hash, o)) {
if (qdkgsman.GetComplaint(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCOMPLAINT, o));
push = true;
}
@ -1882,7 +1895,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_JUSTIFICATION)) {
llmq::CDKGJustification o;
if (llmq::quorumDKGSessionManager->GetJustification(inv.hash, o)) {
if (qdkgsman.GetJustification(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QJUSTIFICATION, o));
push = true;
}
@ -1890,7 +1903,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_PREMATURE_COMMITMENT)) {
llmq::CDKGPrematureCommitment o;
if (llmq::quorumDKGSessionManager->GetPrematureCommitment(inv.hash, o)) {
if (qdkgsman.GetPrematureCommitment(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QPCOMMITMENT, o));
push = true;
}
@ -1898,7 +1911,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_QUORUM_RECOVERED_SIG)) {
llmq::CRecoveredSig o;
if (llmq::quorumSigningManager->GetRecoveredSigForGetData(inv.hash, o)) {
if (sigman.GetRecoveredSigForGetData(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QSIGREC, o));
push = true;
}
@ -1906,7 +1919,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
if (!push && (inv.type == MSG_CLSIG)) {
llmq::CChainLockSig o;
if (llmq::chainLocksHandler->GetChainLockByHash(inv.hash, o)) {
if (clhandler.GetChainLockByHash(inv.hash, o)) {
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CLSIG, o));
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)) {
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;
connman->PushMessage(pfrom, msgMaker.Make(msg_type, o));
push = true;
@ -1931,7 +1944,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm
const CInv &inv = *it;
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) {
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};
}
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());
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)
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());
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());
ProcessGetData(pfrom, chainparams, connman, mempool, interruptMsgProc);
ProcessGetData(pfrom, chainparams, connman, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman, interruptMsgProc);
return true;
}
@ -3323,7 +3341,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
bool fMissingInputs = false;
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 */)) {
// Process custom txes, this changes AlreadyHave to "true"
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) {
CInv _inv(MSG_TX, txin.prevout.hash);
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
CInv _inv2(MSG_DSTX, txin.prevout.hash);
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());
@ -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
// parents so avoid re-requesting it from other peers.
recentRejects->insert(tx.GetHash());
llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx);
isman.TransactionRemovedFromMempool(ptx);
}
} else {
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));
}
MaybePunishNode(pfrom->GetId(), state, /*via_compact_block*/ false);
llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx);
isman.TransactionRemovedFromMempool(ptx);
}
return true;
}
@ -3615,7 +3633,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
} // cs_main
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) {
// 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;
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));
} else {
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;
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));
} else {
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);
governance->ProcessMessage(pfrom, msg_type, vRecv, *connman, enable_bip61);
CMNAuth::ProcessMessage(pfrom, msg_type, vRecv, *connman);
llmq::quorumBlockProcessor->ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumDKGSessionManager->ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumManager->ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumSigSharesManager->ProcessMessage(pfrom, msg_type, vRecv, *sporkManager);
llmq::quorumSigningManager->ProcessMessage(pfrom, msg_type, vRecv);
llmq::chainLocksHandler->ProcessMessage(pfrom, msg_type, vRecv);
llmq::quorumInstantSendManager->ProcessMessage(pfrom, msg_type, vRecv);
quorum_block_processor.ProcessMessage(pfrom, msg_type, vRecv);
qdkgsman.ProcessMessage(pfrom, qman, msg_type, vRecv);
qman.ProcessMessage(pfrom, msg_type, vRecv);
shareman.ProcessMessage(pfrom, msg_type, vRecv, *sporkManager);
sigman.ProcessMessage(pfrom, msg_type, vRecv);
clhandler.ProcessMessage(pfrom, msg_type, vRecv);
isman.ProcessMessage(pfrom, msg_type, vRecv);
return true;
}
@ -4183,7 +4201,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
bool fMoreWork = false;
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()) {
LOCK2(cs_main, g_cs_orphans);
@ -4247,7 +4265,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
bool fRet = false;
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)
return false;
if (!pfrom->vRecvGetData.empty())
@ -4453,6 +4471,9 @@ public:
bool PeerLogicValidation::SendMessages(CNode* pto)
{
assert(m_clhandler);
assert(m_isman);
const Consensus::Params& consensusParams = Params().GetConsensus();
{
// 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;
queueAndMaybePushInv(CInv(nInvType, hash));
const auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(hash);
const auto islock = m_isman->GetInstantSendLockByTxid(hash);
if (islock == nullptr) continue;
if (pto->nVersion < ISDLOCK_PROTO_VERSION && islock->IsDeterministic()) continue;
queueAndMaybePushInv(CInv(islock->IsDeterministic() ? MSG_ISDLOCK : MSG_ISLOCK, ::SerializeHash(*islock)));
}
// Send an inv for the best ChainLock we have
const auto& clsig = llmq::chainLocksHandler->GetBestChainLock();
const auto& clsig = m_clhandler->GetBestChainLock();
if (!clsig.IsNull()) {
uint256 chainlockHash = ::SerializeHash(clsig);
queueAndMaybePushInv(CInv(MSG_CLSIG, chainlockHash));
@ -5019,7 +5040,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
state.m_object_download.m_object_in_flight.erase(inv);
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,
// then request.
const auto last_request_time = GetObjectRequestTime(inv.hash);

View File

@ -14,6 +14,16 @@
class CTxMemPool;
class ChainstateManager;
namespace llmq {
class CChainLocksHandler;
class CDKGSessionManager;
class CInstantSendManager;
class CQuorumBlockProcessor;
class CQuorumManager;
class CSigningManager;
class CSigSharesManager;
} // namespace llmq
extern CCriticalSection cs_main;
/** 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;
ChainstateManager& m_chainman;
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);
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.

View File

@ -12,6 +12,9 @@
#include <consensus/validation.h>
#include <core_io.h>
#include <key_io.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <net.h>
#include <node/context.h>
@ -152,7 +155,7 @@ UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool,
UniValue blockHashes(UniValue::VARR);
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())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block;
@ -362,7 +365,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
LOCK(cs_main);
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) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
}
@ -378,7 +381,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
LOCK(cs_main);
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()));
}
}
@ -664,7 +667,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk";
CValidationState state;
TestBlockValidity(state, Params(), block, pindexPrev, false, true);
TestBlockValidity(state, *llmq::chainLocksHandler, Params(), block, pindexPrev, false, true);
return BIP22ValidationResult(state);
}
@ -769,7 +772,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// Create new block
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)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

View File

@ -13,6 +13,7 @@
#include <evo/specialtx.h>
#include <evo/specialtxman.h>
#include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <masternode/meta.h>
#include <messagesigner.h>
#include <netbase.h>
@ -1176,7 +1177,7 @@ static UniValue protx_diff(const JSONRPCRequest& request)
CSimplifiedMNListDiff mnListDiff;
std::string strError;
if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, strError, extended)) {
if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, *llmq::quorumBlockProcessor, strError, extended)) {
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");
}
if (fSubmit) {
return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, id, msgHash, quorumHash);
return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, *llmq::quorumSigSharesManager, id, msgHash, quorumHash);
} else {
llmq::CQuorumCPtr pQuorum;
if (quorumHash.IsNull()) {
pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id);
pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id);
} else {
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
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, signOffset);
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, signOffset);
} else {
uint256 quorumHash = ParseHashV(request.params[4], "quorumHash");
llmq::CQuorumCPtr quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash);
@ -539,7 +539,7 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request)
UniValue ret(UniValue::VOBJ);
auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id);
auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id);
if (!quorum) {
throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
}
@ -670,7 +670,7 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request)
++idx;
}
LOCK(cs_main);
if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, strError)) {
if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, *llmq::quorumManager, *llmq::quorumBlockProcessor, strError)) {
throw JSONRPCError(RPC_INVALID_REQUEST, strError);
}
@ -776,7 +776,7 @@ static UniValue verifychainlock(const JSONRPCRequest& request)
const auto llmqType = Params().GetConsensus().llmqTypeChainLocks;
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)
@ -841,11 +841,11 @@ static UniValue verifyislock(const JSONRPCRequest& request)
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
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, signOffset);
return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, 0) ||
llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, signOffset);
}
// clang-format off
static const CRPCCommand commands[] =

View File

@ -20,6 +20,9 @@
#include <evo/providertx.h>
#include <evo/deterministicmns.h>
#include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#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(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0));
// 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;
BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask);
@ -281,7 +284,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
deterministicMNManager->UpdatedBlockTip(::ChainActive().Tip());
BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash()));
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);
}
@ -292,7 +295,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
{
LOCK(cs_main);
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->voutMasternodePayments[0].nValue, masternode_payment);
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);
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);
}
}
@ -316,7 +319,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
// Reward split should reach ~60/40 after reallocation is done
LOCK(cs_main);
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->voutMasternodePayments[0].nValue, masternode_payment);
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);
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);
}
@ -338,7 +341,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
// Reward split should reach ~60/40 after reallocation is done
LOCK(cs_main);
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->voutMasternodePayments[0].nValue, masternode_payment);
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 5694890966); // 0.6

View File

@ -7,6 +7,9 @@
#include <consensus/validation.h>
#include <governance/governance.h>
#include <index/blockfilterindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <pow.h>
#include <script/standard.h>
@ -64,7 +67,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey)
{
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;
block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1;

View File

@ -7,6 +7,13 @@
#include <arith_uint256.h>
#include <banman.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_processing.h>
#include <pubkey.h>
@ -80,7 +87,11 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{
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
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)
{
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();
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 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();
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 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();
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 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();
int64_t nStartTime = GetTime();

View File

@ -7,6 +7,9 @@
#include <chainparams.h>
#include <consensus/validation.h>
#include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <script/interpreter.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(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0));
// 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;
BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask);

View File

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

View File

@ -19,6 +19,14 @@
#include <validationinterface.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 <atomic>
#include <cassert>
@ -32,7 +40,7 @@
#include <string>
#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 {
@ -90,7 +98,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
p2p_node.SetSendVersion(PROTOCOL_VERSION);
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
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) {
const std::string exception_message{e.what()};
const auto p = EXPECTED_DESERIALIZATION_EXCEPTIONS.find(exception_message);

View File

@ -8,6 +8,9 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <policy/policy.h>
#include <pow.h>
@ -46,7 +49,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
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 {

View File

@ -8,6 +8,9 @@
#include <consensus/merkle.h>
#include <governance/governance.h>
#include <key_io.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <node/context.h>
#include <pow.h>
@ -76,7 +79,7 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coi
{
assert(node.mempool);
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)
->block);

View File

@ -15,6 +15,13 @@
#include <init.h>
#include <interfaces/chain.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 <net.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));
m_node.chainman = &::g_chainman;
m_node.chainman->InitializeChainstate();
m_node.chainman->InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor);
::ChainstateActive().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!::ChainstateActive().CanFlushToDisk());
@ -175,21 +182,16 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
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->setSanityCheck(1.0);
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.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;
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));
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()
@ -290,7 +302,7 @@ CBlock TestChainSetup::CreateAndProcessBlock(const std::vector<CMutableTransacti
CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
{
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;
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())) {
BOOST_ASSERT(false);
}
if (!CalcCbTxMerkleRootQuorums(block, ::ChainActive().Tip(), cbTx.merkleRootQuorums, state)) {
if (!CalcCbTxMerkleRootQuorums(block, ::ChainActive().Tip(), *llmq::quorumBlockProcessor, cbTx.merkleRootQuorums, state)) {
BOOST_ASSERT(false);
}
CMutableTransaction tmpTx{*block.vtx[0]};

View File

@ -9,6 +9,9 @@
#include <consensus/merkle.h>
#include <consensus/validation.h>
#include <governance/governance.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <miner.h>
#include <pow.h>
#include <random.h>
@ -70,7 +73,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
CScript pubKey;
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);
pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time;

View File

@ -3,6 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include <index/txindex.h>
#include <llmq/blockprocessor.h>
#include <llmq/chainlocks.h>
#include <llmq/instantsend.h>
#include <random.h>
#include <uint256.h>
#include <consensus/validation.h>
@ -35,7 +38,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
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(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
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.
//
#include <chainparams.h>
#include <index/txindex.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 <sync.h>
#include <test/util/setup_common.h>
@ -29,7 +32,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
// 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);
c1.InitCoinsDB(
/* 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.
//
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);
c2.InitCoinsDB(
/* 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.
//
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);
c1.InitCoinsDB(
/* 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.
//
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);
c2.InitCoinsDB(
/* 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
// 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 <test/util/setup_common.h>
#include <txmempool.h>
@ -19,7 +22,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{
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);
WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10));
CTxMemPool tx_pool{};

View File

@ -1131,8 +1131,15 @@ void CoinsViews::InitCache()
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_clhandler(clhandler),
m_isman(isman),
m_quorum_block_processor(quorum_block_processor),
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
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)
{
AssertLockHeld(cs_main);
assert(m_quorum_block_processor);
bool fDIP0003Active = pindex->nHeight >= Params().GetConsensus().DIP0003Height;
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<CSpentIndexKey, CSpentIndexValue> > spentIndex;
if (!UndoSpecialTxsInBlock(block, pindex)) {
if (!UndoSpecialTxsInBlock(block, pindex, *m_quorum_block_processor)) {
return DISCONNECT_FAILED;
}
@ -1971,6 +1979,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
AssertLockHeld(cs_main);
assert(pindex);
assert(*pindex->phashBlock == block.GetHash());
assert(m_clhandler);
assert(m_isman);
assert(m_quorum_block_processor);
int64_t nTimeStart = GetTimeMicros();
// 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));
}
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");
}
@ -2130,7 +2141,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
bool fDIP0001Active_context = pindex->nHeight >= Params().GetConsensus().DIP0001Height;
// 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",
pindex->GetBlockHash().ToString(), FormatStateMessage(state));
}
@ -2306,16 +2317,16 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// 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.
for (const auto& tx : block.vtx) {
// skip txes that have no inputs
if (tx->vin.empty()) continue;
while (llmq::CInstantSendLockPtr conflictLock = llmq::quorumInstantSendManager->GetConflictingLock(*tx)) {
if (llmq::chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
while (llmq::CInstantSendLockPtr conflictLock = m_isman->GetConflictingLock(*tx)) {
if (m_clhandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) {
LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n",
tx->GetHash().ToString(), ::SerializeHash(*conflictLock).ToString());
llmq::quorumInstantSendManager->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock);
m_isman->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock);
} else {
// The node which relayed this should switch to correct chain.
// TODO: relay instantsend data/proof.
@ -4205,13 +4216,13 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
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);
assert(pindexPrev && pindexPrev == ::ChainActive().Tip());
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");
}
@ -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. */
bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params)
{
assert(m_quorum_block_processor);
// TODO: merge with ConnectBlock
CBlock block;
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
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",
pindex->GetBlockHash().ToString(), FormatStateMessage(state));
}
@ -5528,7 +5541,10 @@ std::vector<CChainState*> ChainstateManager::GetAll()
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();
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");
}
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.
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {

View File

@ -34,6 +34,12 @@
#include <utility>
#include <vector>
namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumBlockProcessor;
} // namespace llmq
class CChainState;
class CBlockIndex;
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);
/** 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 */
class CVerifyDB {
@ -530,8 +536,17 @@ private:
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
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:
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
@ -843,8 +858,10 @@ public:
//!
//! @param[in] snapshot_blockhash If given, signify that this chainstate
//! is based on a snapshot.
CChainState& InitializeChainstate(const uint256& snapshot_blockhash = uint256())
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
CChainState& 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 = uint256()) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
//! Get all chainstates currently being used.
std::vector<CChainState*> GetAll();