Use single-threaded scheduler for IS, CL and Governance notifications (#3954)

* Use single-threaded scheduler for IS, CL and Governance notifications

* Pass shared_ptr-s instead of objects themselves for CL, IS and Governance notifiers in CMainSignals/CValidatibnInterface

* llmq: Create shared_ptr for clsig at the root of its lifetime

* llmq: Create shared_ptr for islock clsig at the root of its lifetime

* llmq: Create shared_ptr for recSig at the root of its lifetime

Co-authored-by: xdustinface <xdustinfacex@gmail.com>
This commit is contained in:
UdjinM6 2021-01-22 07:32:15 +03:00 committed by GitHub
parent ccbf574fa3
commit 1e0cc1254c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 235 additions and 218 deletions

View File

@ -111,7 +111,7 @@ void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDet
governance.UpdateCachesAndClean();
}
void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig)
void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
llmq::quorumInstantSendManager->NotifyChainLock(pindex);
CPrivateSend::NotifyChainLock(pindex);

View File

@ -26,7 +26,7 @@ protected:
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected) override;
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) override;
void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig) override;
void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
private:
CConnman& connman;

View File

@ -212,7 +212,7 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom,
fileVotes.AddVote(vote);
fDirtyCache = true;
// SEND NOTIFICATION TO SCRIPT/ZMQ
GetMainSignals().NotifyGovernanceVote(vote);
GetMainSignals().NotifyGovernanceVote(std::make_shared<const CGovernanceVote>(vote));
return true;
}

View File

@ -339,7 +339,7 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman
CheckOrphanVotes(govobj, exception, connman);
// SEND NOTIFICATION TO SCRIPT/ZMQ
GetMainSignals().NotifyGovernanceObject(govobj);
GetMainSignals().NotifyGovernanceObject(std::make_shared<const CGovernanceObject>(govobj));
}
void CGovernanceManager::UpdateCachesAndClean()

View File

@ -490,7 +490,7 @@ void CChainLocksHandler::EnforceBestChainLock()
AssertLockNotHeld(cs);
AssertLockNotHeld(cs_main);
CChainLockSig clsig;
std::shared_ptr<CChainLockSig> clsig;
const CBlockIndex* pindex;
const CBlockIndex* currentBestChainLockBlockIndex;
{
@ -500,7 +500,7 @@ void CChainLocksHandler::EnforceBestChainLock()
return;
}
clsig = bestChainLockWithKnownBlock;
clsig = std::make_shared<CChainLockSig>(bestChainLockWithKnownBlock);
pindex = currentBestChainLockBlockIndex = this->bestChainLockBlockIndex;
if (!currentBestChainLockBlockIndex) {
@ -531,7 +531,7 @@ void CChainLocksHandler::EnforceBestChainLock()
assert(false);
}
LogPrintf("CChainLocksHandler::%s -- CLSIG (%s) marked block %s as conflicting\n",
__func__, clsig.ToString(), jt->second->GetBlockHash().ToString());
__func__, clsig->ToString(), jt->second->GetBlockHash().ToString());
}
pindex = pindex->pprev;

View File

@ -640,7 +640,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CRecoveredSig& recoveredSig)
{
CInstantSendLock islock;
CInstantSendLockPtr islock;
{
LOCK(cs);
@ -649,19 +649,19 @@ void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CReco
return;
}
islock = std::move(it->second);
islock = std::make_shared<CInstantSendLock>(std::move(it->second));
creatingInstantSendLocks.erase(it);
txToCreatingInstantSendLocks.erase(islock.txid);
txToCreatingInstantSendLocks.erase(islock->txid);
}
if (islock.txid != recoveredSig.msgHash) {
if (islock->txid != recoveredSig.msgHash) {
LogPrintf("CInstantSendManager::%s -- txid=%s: islock conflicts with %s, dropping own version\n", __func__,
islock.txid.ToString(), recoveredSig.msgHash.ToString());
islock->txid.ToString(), recoveredSig.msgHash.ToString());
return;
}
islock.sig = recoveredSig.sig;
ProcessInstantSendLock(-1, ::SerializeHash(islock), islock);
islock->sig = recoveredSig.sig;
ProcessInstantSendLock(-1, ::SerializeHash(*islock), islock);
}
void CInstantSendManager::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv)
@ -671,22 +671,22 @@ void CInstantSendManager::ProcessMessage(CNode* pfrom, const std::string& strCom
}
if (strCommand == NetMsgType::ISLOCK) {
CInstantSendLock islock;
vRecv >> islock;
CInstantSendLockPtr islock = std::make_shared<CInstantSendLock>();
vRecv >> *islock;
ProcessMessageInstantSendLock(pfrom, islock);
}
}
void CInstantSendManager::ProcessMessageInstantSendLock(CNode* pfrom, const llmq::CInstantSendLock& islock)
void CInstantSendManager::ProcessMessageInstantSendLock(CNode* pfrom, const llmq::CInstantSendLockPtr& islock)
{
auto hash = ::SerializeHash(islock);
auto hash = ::SerializeHash(*islock);
{
LOCK(cs_main);
EraseObjectRequest(pfrom->GetId(), CInv(MSG_ISLOCK, hash));
}
if (!PreVerifyInstantSendLock(islock)) {
if (!PreVerifyInstantSendLock(*islock)) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
return;
@ -701,7 +701,7 @@ void CInstantSendManager::ProcessMessageInstantSendLock(CNode* pfrom, const llmq
}
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: received islock, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), pfrom->GetId());
islock->txid.ToString(), hash.ToString(), pfrom->GetId());
pendingInstantSendLocks.emplace(hash, std::make_pair(pfrom->GetId(), islock));
}
@ -779,7 +779,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks()
return true;
}
std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLock>, StaticSaltedHasher>& pend, bool ban)
std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLockPtr>, StaticSaltedHasher>& pend, bool ban)
{
auto llmqType = Params().GetConsensus().llmqTypeInstantSend;
@ -797,15 +797,15 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
continue;
}
if (!islock.sig.Get().IsValid()) {
if (!islock->sig.Get().IsValid()) {
batchVerifier.badSources.emplace(nodeId);
continue;
}
auto id = islock.GetRequestId();
auto id = islock->GetRequestId();
// no need to verify an ISLOCK if we already have verified the recovered sig that belongs to it
if (quorumSigningManager->HasRecoveredSig(llmqType, id, islock.txid)) {
if (quorumSigningManager->HasRecoveredSig(llmqType, id, islock->txid)) {
alreadyVerified++;
continue;
}
@ -815,8 +815,8 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
// should not happen, but if one fails to select, all others will also fail to select
return {};
}
uint256 signHash = CLLMQUtils::BuildSignHash(llmqType, quorum->qc.quorumHash, id, islock.txid);
batchVerifier.PushMessage(nodeId, hash, signHash, islock.sig.Get(), quorum->qc.quorumPublicKey);
uint256 signHash = CLLMQUtils::BuildSignHash(llmqType, quorum->qc.quorumHash, id, islock->txid);
batchVerifier.PushMessage(nodeId, hash, signHash, islock->sig.Get(), quorum->qc.quorumPublicKey);
verifyCount++;
// We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which
@ -827,8 +827,8 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
recSig.llmqType = llmqType;
recSig.quorumHash = quorum->qc.quorumHash;
recSig.id = id;
recSig.msgHash = islock.txid;
recSig.sig = islock.sig;
recSig.msgHash = islock->txid;
recSig.sig = islock->sig;
recSigs.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(std::move(recSig)));
}
}
@ -857,7 +857,7 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
if (batchVerifier.badMessages.count(hash)) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: invalid sig in islock, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), nodeId);
islock->txid.ToString(), hash.ToString(), nodeId);
badISLocks.emplace(hash);
continue;
}
@ -868,11 +868,11 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
// double-verification of the sig.
auto it = recSigs.find(hash);
if (it != recSigs.end()) {
auto& recSig = it->second;
if (!quorumSigningManager->HasRecoveredSigForId(llmqType, recSig.id)) {
recSig.UpdateHash();
std::shared_ptr<CRecoveredSig> recSig = std::make_shared<CRecoveredSig>(std::move(it->second));
if (!quorumSigningManager->HasRecoveredSigForId(llmqType, recSig->id)) {
recSig->UpdateHash();
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: passing reconstructed recSig to signing mgr, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), nodeId);
islock->txid.ToString(), hash.ToString(), nodeId);
quorumSigningManager->PushReconstructedRecoveredSig(recSig);
}
}
@ -881,13 +881,13 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
return badISLocks;
}
void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLock& islock)
void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLockPtr& islock)
{
CTransactionRef tx;
uint256 hashBlock;
const CBlockIndex* pindexMined = nullptr;
// we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally
if (GetTransaction(islock.txid, tx, Params().GetConsensus(), hashBlock)) {
if (GetTransaction(islock->txid, tx, Params().GetConsensus(), hashBlock)) {
if (!hashBlock.IsNull()) {
{
LOCK(cs_main);
@ -898,7 +898,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
// we can simply ignore the islock, as the ChainLock implies locking of all TXs in that chain
if (llmq::chainLocksHandler->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);
islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from);
return;
}
}
@ -908,39 +908,39 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
LOCK(cs);
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: processsing islock, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), from);
islock->txid.ToString(), hash.ToString(), from);
creatingInstantSendLocks.erase(islock.GetRequestId());
txToCreatingInstantSendLocks.erase(islock.txid);
creatingInstantSendLocks.erase(islock->GetRequestId());
txToCreatingInstantSendLocks.erase(islock->txid);
CInstantSendLockPtr otherIsLock;
if (db.GetInstantSendLockByHash(hash)) {
return;
}
otherIsLock = db.GetInstantSendLockByTxid(islock.txid);
otherIsLock = db.GetInstantSendLockByTxid(islock->txid);
if (otherIsLock != nullptr) {
LogPrintf("CInstantSendManager::%s -- txid=%s, islock=%s: duplicate islock, other islock=%s, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), ::SerializeHash(*otherIsLock).ToString(), from);
islock->txid.ToString(), hash.ToString(), ::SerializeHash(*otherIsLock).ToString(), from);
}
for (auto& in : islock.inputs) {
for (auto& in : islock->inputs) {
otherIsLock = db.GetInstantSendLockByInput(in);
if (otherIsLock != nullptr) {
LogPrintf("CInstantSendManager::%s -- txid=%s, islock=%s: conflicting input in islock. input=%s, other islock=%s, peer=%d\n", __func__,
islock.txid.ToString(), hash.ToString(), in.ToStringShort(), ::SerializeHash(*otherIsLock).ToString(), from);
islock->txid.ToString(), hash.ToString(), in.ToStringShort(), ::SerializeHash(*otherIsLock).ToString(), from);
}
}
db.WriteNewInstantSendLock(hash, islock);
db.WriteNewInstantSendLock(hash, *islock);
if (pindexMined) {
db.WriteInstantSendLockMined(hash, pindexMined->nHeight);
}
// This will also add children TXs to pendingRetryTxs
RemoveNonLockedTx(islock.txid, true);
RemoveNonLockedTx(islock->txid, true);
// We don't need the recovered sigs for the inputs anymore. This prevents unnecessary propagation of these sigs.
// We only need the ISLOCK from now on to detect conflicts
TruncateRecoveredSigsForInputs(islock);
TruncateRecoveredSigsForInputs(*islock);
}
CInv inv(MSG_ISLOCK, hash);
@ -949,15 +949,15 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
} else {
// we don't have the TX yet, so we only filter based on txid. Later when that TX arrives, we will re-announce
// with the TX taken into account.
g_connman->RelayInvFiltered(inv, islock.txid, LLMQS_PROTO_VERSION);
g_connman->RelayInvFiltered(inv, islock->txid, LLMQS_PROTO_VERSION);
}
RemoveMempoolConflictsForLock(hash, islock);
ResolveBlockConflicts(hash, islock);
RemoveMempoolConflictsForLock(hash, *islock);
ResolveBlockConflicts(hash, *islock);
if (tx != nullptr) {
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- notify about an in-time lock for tx %s\n", __func__, tx->GetHash().ToString());
GetMainSignals().NotifyTransactionLock(*tx, islock);
GetMainSignals().NotifyTransactionLock(tx, islock);
// bump mempool counter to make sure newly locked txes are picked up by getblocktemplate
mempool.AddTransactionsUpdated(1);
}
@ -1022,7 +1022,7 @@ void CInstantSendManager::TransactionAddedToMempool(const CTransactionRef& tx)
// If the islock was received before the TX, we know we were not able to send
// the notification at that time, we need to do it now.
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- notify about an earlier received lock for tx %s\n", __func__, tx->GetHash().ToString());
GetMainSignals().NotifyTransactionLock(*tx, *islock);
GetMainSignals().NotifyTransactionLock(tx, islock);
}
}

View File

@ -97,7 +97,7 @@ private:
std::unordered_map<uint256, CInstantSendLock*, StaticSaltedHasher> txToCreatingInstantSendLocks;
// Incoming and not verified yet
std::unordered_map<uint256, std::pair<NodeId, CInstantSendLock>, StaticSaltedHasher> pendingInstantSendLocks;
std::unordered_map<uint256, std::pair<NodeId, CInstantSendLockPtr>, StaticSaltedHasher> pendingInstantSendLocks;
// TXs which are neither IS locked nor ChainLocked. We use this to determine for which TXs we need to retry IS locking
// of child TXs
@ -134,11 +134,11 @@ public:
void TrySignInstantSendLock(const CTransaction& tx);
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv);
void ProcessMessageInstantSendLock(CNode* pfrom, const CInstantSendLock& islock);
void ProcessMessageInstantSendLock(CNode* pfrom, const CInstantSendLockPtr& islock);
static bool PreVerifyInstantSendLock(const CInstantSendLock& islock);
bool ProcessPendingInstantSendLocks();
std::unordered_set<uint256> ProcessPendingInstantSendLocks(int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLock>, StaticSaltedHasher>& pend, bool ban);
void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLock& islock);
std::unordered_set<uint256> ProcessPendingInstantSendLocks(int signOffset, const std::unordered_map<uint256, std::pair<NodeId, CInstantSendLockPtr>, StaticSaltedHasher>& pend, bool ban);
void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLockPtr& islock);
void ProcessNewTransaction(const CTransactionRef& tx, const CBlockIndex* pindex, bool allowReSigning);
void TransactionAddedToMempool(const CTransactionRef& tx);

View File

@ -471,21 +471,21 @@ bool CSigningManager::GetRecoveredSigForGetData(const uint256& hash, CRecoveredS
void CSigningManager::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv)
{
if (strCommand == NetMsgType::QSIGREC) {
CRecoveredSig recoveredSig;
vRecv >> recoveredSig;
std::shared_ptr<CRecoveredSig> recoveredSig = std::make_shared<CRecoveredSig>();
vRecv >> *recoveredSig;
ProcessMessageRecoveredSig(pfrom, recoveredSig);
}
}
void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredSig& recoveredSig)
void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared_ptr<const CRecoveredSig>& recoveredSig)
{
{
LOCK(cs_main);
EraseObjectRequest(pfrom->GetId(), CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig.GetHash()));
EraseObjectRequest(pfrom->GetId(), CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash()));
}
bool ban = false;
if (!PreVerifyRecoveredSig(recoveredSig, ban)) {
if (!PreVerifyRecoveredSig(*recoveredSig, ban)) {
if (ban) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
@ -495,18 +495,18 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredS
// It's important to only skip seen *valid* sig shares here. See comment for CBatchedSigShare
// We don't receive recovered sigs in batches, but we do batched verification per node on these
if (db.HasRecoveredSigForHash(recoveredSig.GetHash())) {
if (db.HasRecoveredSigForHash(recoveredSig->GetHash())) {
return;
}
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- signHash=%s, id=%s, msgHash=%s, node=%d\n", __func__,
CLLMQUtils::BuildSignHash(recoveredSig).ToString(), recoveredSig.id.ToString(), recoveredSig.msgHash.ToString(), pfrom->GetId());
CLLMQUtils::BuildSignHash(*recoveredSig).ToString(), recoveredSig->id.ToString(), recoveredSig->msgHash.ToString(), pfrom->GetId());
LOCK(cs);
if (pendingReconstructedRecoveredSigs.count(recoveredSig.GetHash())) {
if (pendingReconstructedRecoveredSigs.count(recoveredSig->GetHash())) {
// no need to perform full verification
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- already pending reconstructed sig, signHash=%s, id=%s, msgHash=%s, node=%d\n", __func__,
CLLMQUtils::BuildSignHash(recoveredSig).ToString(), recoveredSig.id.ToString(), recoveredSig.msgHash.ToString(), pfrom->GetId());
CLLMQUtils::BuildSignHash(*recoveredSig).ToString(), recoveredSig->id.ToString(), recoveredSig->msgHash.ToString(), pfrom->GetId());
return;
}
pendingRecoveredSigs[pfrom->GetId()].emplace_back(recoveredSig);
@ -538,7 +538,7 @@ bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, b
void CSigningManager::CollectPendingRecoveredSigsToVerify(
size_t maxUniqueSessions,
std::unordered_map<NodeId, std::list<CRecoveredSig>>& retSigShares,
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>>& retSigShares,
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr, StaticSaltedHasher>& retQuorums)
{
{
@ -550,15 +550,15 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
std::unordered_set<std::pair<NodeId, uint256>, StaticSaltedHasher> uniqueSignHashes;
CLLMQUtils::IterateNodesRandom(pendingRecoveredSigs, [&]() {
return uniqueSignHashes.size() < maxUniqueSessions;
}, [&](NodeId nodeId, std::list<CRecoveredSig>& ns) {
}, [&](NodeId nodeId, std::list<std::shared_ptr<const CRecoveredSig>>& ns) {
if (ns.empty()) {
return false;
}
auto& recSig = *ns.begin();
bool alreadyHave = db.HasRecoveredSigForHash(recSig.GetHash());
bool alreadyHave = db.HasRecoveredSigForHash(recSig->GetHash());
if (!alreadyHave) {
uniqueSignHashes.emplace(nodeId, CLLMQUtils::BuildSignHash(recSig));
uniqueSignHashes.emplace(nodeId, CLLMQUtils::BuildSignHash(*recSig));
retSigShares[nodeId].emplace_back(recSig);
}
ns.erase(ns.begin());
@ -577,19 +577,19 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
for (auto it = v.begin(); it != v.end();) {
auto& recSig = *it;
auto llmqType = (Consensus::LLMQType) recSig.llmqType;
auto quorumKey = std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash);
auto llmqType = (Consensus::LLMQType) recSig->llmqType;
auto quorumKey = std::make_pair((Consensus::LLMQType)recSig->llmqType, recSig->quorumHash);
if (!retQuorums.count(quorumKey)) {
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recSig.quorumHash);
CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recSig->quorumHash);
if (!quorum) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found, node=%d\n", __func__,
recSig.quorumHash.ToString(), nodeId);
recSig->quorumHash.ToString(), nodeId);
it = v.erase(it);
continue;
}
if (!CLLMQUtils::IsQuorumActive(llmqType, quorum->qc.quorumHash)) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not active anymore, node=%d\n", __func__,
recSig.quorumHash.ToString(), nodeId);
recSig->quorumHash.ToString(), nodeId);
it = v.erase(it);
continue;
}
@ -616,7 +616,7 @@ void CSigningManager::ProcessPendingReconstructedRecoveredSigs()
bool CSigningManager::ProcessPendingRecoveredSigs()
{
std::unordered_map<NodeId, std::list<CRecoveredSig>> recSigsByNode;
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>> recSigsByNode;
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr, StaticSaltedHasher> quorums;
ProcessPendingReconstructedRecoveredSigs();
@ -637,13 +637,13 @@ bool CSigningManager::ProcessPendingRecoveredSigs()
for (auto& recSig : v) {
// we didn't verify the lazy signature until now
if (!recSig.sig.Get().IsValid()) {
if (!recSig->sig.Get().IsValid()) {
batchVerifier.badSources.emplace(nodeId);
break;
}
const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash));
batchVerifier.PushMessage(nodeId, recSig.GetHash(), CLLMQUtils::BuildSignHash(recSig), recSig.sig.Get(), quorum->qc.quorumPublicKey);
const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig->llmqType, recSig->quorumHash));
batchVerifier.PushMessage(nodeId, recSig->GetHash(), CLLMQUtils::BuildSignHash(*recSig), recSig->sig.Get(), quorum->qc.quorumPublicKey);
verifyCount++;
}
}
@ -667,7 +667,7 @@ bool CSigningManager::ProcessPendingRecoveredSigs()
}
for (auto& recSig : v) {
if (!processed.emplace(recSig.GetHash()).second) {
if (!processed.emplace(recSig->GetHash()).second) {
continue;
}
@ -679,11 +679,11 @@ bool CSigningManager::ProcessPendingRecoveredSigs()
}
// signature must be verified already
void CSigningManager::ProcessRecoveredSig(const CRecoveredSig& recoveredSig)
void CSigningManager::ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig)
{
auto llmqType = (Consensus::LLMQType)recoveredSig.llmqType;
auto llmqType = (Consensus::LLMQType)recoveredSig->llmqType;
if (db.HasRecoveredSigForHash(recoveredSig.GetHash())) {
if (db.HasRecoveredSigForHash(recoveredSig->GetHash())) {
return;
}
@ -692,20 +692,20 @@ void CSigningManager::ProcessRecoveredSig(const CRecoveredSig& recoveredSig)
LOCK(cs);
listeners = recoveredSigsListeners;
auto signHash = CLLMQUtils::BuildSignHash(recoveredSig);
auto signHash = CLLMQUtils::BuildSignHash(*recoveredSig);
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- valid recSig. signHash=%s, id=%s, msgHash=%s\n", __func__,
signHash.ToString(), recoveredSig.id.ToString(), recoveredSig.msgHash.ToString());
signHash.ToString(), recoveredSig->id .ToString(), recoveredSig->msgHash.ToString());
if (db.HasRecoveredSigForId(llmqType, recoveredSig.id)) {
if (db.HasRecoveredSigForId(llmqType, recoveredSig->id)) {
CRecoveredSig otherRecoveredSig;
if (db.GetRecoveredSigById(llmqType, recoveredSig.id, otherRecoveredSig)) {
auto otherSignHash = CLLMQUtils::BuildSignHash(recoveredSig);
if (db.GetRecoveredSigById(llmqType, recoveredSig->id, otherRecoveredSig)) {
auto otherSignHash = CLLMQUtils::BuildSignHash(*recoveredSig);
if (signHash != otherSignHash) {
// this should really not happen, as each masternode is participating in only one vote,
// even if it's a member of multiple quorums. so a majority is only possible on one quorum and one msgHash per id
LogPrintf("CSigningManager::%s -- conflicting recoveredSig for signHash=%s, id=%s, msgHash=%s, otherSignHash=%s\n", __func__,
signHash.ToString(), recoveredSig.id.ToString(), recoveredSig.msgHash.ToString(), otherSignHash.ToString());
signHash.ToString(), recoveredSig->id.ToString(), recoveredSig->msgHash.ToString(), otherSignHash.ToString());
} else {
// Looks like we're trying to process a recSig that is already known. This might happen if the same
// recSig comes in through regular QRECSIG messages and at the same time through some other message
@ -719,12 +719,12 @@ void CSigningManager::ProcessRecoveredSig(const CRecoveredSig& recoveredSig)
}
}
db.WriteRecoveredSig(recoveredSig);
db.WriteRecoveredSig(*recoveredSig);
pendingReconstructedRecoveredSigs.erase(recoveredSig.GetHash());
pendingReconstructedRecoveredSigs.erase(recoveredSig->GetHash());
}
CInv inv(MSG_QUORUM_RECOVERED_SIG, recoveredSig.GetHash());
CInv inv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash());
g_connman->ForEachNode([&](CNode* pnode) {
if (pnode->nVersion >= LLMQS_PROTO_VERSION && pnode->fSendRecSigs) {
pnode->PushInventory(inv);
@ -732,16 +732,16 @@ void CSigningManager::ProcessRecoveredSig(const CRecoveredSig& recoveredSig)
});
for (auto& l : listeners) {
l->HandleNewRecoveredSig(recoveredSig);
l->HandleNewRecoveredSig(*recoveredSig);
}
GetMainSignals().NotifyRecoveredSig(recoveredSig);
}
void CSigningManager::PushReconstructedRecoveredSig(const llmq::CRecoveredSig& recoveredSig)
void CSigningManager::PushReconstructedRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& recoveredSig)
{
LOCK(cs);
pendingReconstructedRecoveredSigs.emplace(std::piecewise_construct, std::forward_as_tuple(recoveredSig.GetHash()), std::forward_as_tuple(recoveredSig));
pendingReconstructedRecoveredSigs.emplace(std::piecewise_construct, std::forward_as_tuple(recoveredSig->GetHash()), std::forward_as_tuple(recoveredSig));
}
void CSigningManager::TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256& id)

View File

@ -125,8 +125,8 @@ private:
CRecoveredSigsDb db;
// Incoming and not verified yet
std::unordered_map<NodeId, std::list<CRecoveredSig>> pendingRecoveredSigs;
std::unordered_map<uint256, CRecoveredSig, StaticSaltedHasher> pendingReconstructedRecoveredSigs;
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>> pendingRecoveredSigs;
std::unordered_map<uint256, std::shared_ptr<const CRecoveredSig>, StaticSaltedHasher> pendingReconstructedRecoveredSigs;
// must be protected by cs
FastRandomContext rnd;
@ -145,7 +145,7 @@ public:
// This is called when a recovered signature was was reconstructed from another P2P message and is known to be valid
// This is the case for example when a signature appears as part of InstantSend or ChainLocks
void PushReconstructedRecoveredSig(const CRecoveredSig& recoveredSig);
void PushReconstructedRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig);
// This is called when a recovered signature can be safely removed from the DB. This is only safe when some other
// mechanism prevents possible conflicts. As an example, ChainLocks prevent conflicts in confirmed TXs InstantSend votes
@ -154,15 +154,15 @@ public:
void TruncateRecoveredSig(Consensus::LLMQType llmqType, const uint256& id);
private:
void ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredSig& recoveredSig);
void ProcessMessageRecoveredSig(CNode* pfrom, const std::shared_ptr<const CRecoveredSig>& recoveredSig);
static bool PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, bool& retBan);
void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions,
std::unordered_map<NodeId, std::list<CRecoveredSig>>& retSigShares,
std::unordered_map<NodeId, std::list<std::shared_ptr<const CRecoveredSig>>>& retSigShares,
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr, StaticSaltedHasher>& retQuorums);
void ProcessPendingReconstructedRecoveredSigs();
bool ProcessPendingRecoveredSigs(); // called from the worker thread of CSigSharesManager
void ProcessRecoveredSig(const CRecoveredSig& recoveredSig);
void ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig);
void Cleanup(); // called from the worker thread of CSigSharesManager
public:

View File

@ -821,19 +821,19 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- recovered signature. id=%s, msgHash=%s, time=%d\n", __func__,
id.ToString(), msgHash.ToString(), t.count());
CRecoveredSig rs;
rs.llmqType = quorum->params.type;
rs.quorumHash = quorum->qc.quorumHash;
rs.id = id;
rs.msgHash = msgHash;
rs.sig.Set(recoveredSig);
rs.UpdateHash();
std::shared_ptr<CRecoveredSig> rs = std::make_shared<CRecoveredSig>();
rs->llmqType = quorum->params.type;
rs->quorumHash = quorum->qc.quorumHash;
rs->id = id;
rs->msgHash = msgHash;
rs->sig.Set(recoveredSig);
rs->UpdateHash();
// There should actually be no need to verify the self-recovered signatures as it should always succeed. Let's
// however still verify it from time to time, so that we have a chance to catch bugs. We do only this sporadic
// verification because this is unbatched and thus slow verification that happens here.
if (((recoveredSigsCounter++) % 100) == 0) {
auto signHash = CLLMQUtils::BuildSignHash(rs);
auto signHash = CLLMQUtils::BuildSignHash(*rs);
bool valid = recoveredSig.VerifyInsecure(quorum->qc.quorumPublicKey, signHash);
if (!valid) {
// this should really not happen as we have verified all signature shares before

View File

@ -679,7 +679,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
CTransactionRef txConflict;
uint256 hashBlock;
if (GetTransaction(conflictLock->txid, txConflict, chainparams.GetConsensus(), hashBlock)) {
GetMainSignals().NotifyInstantSendDoubleSpendAttempt(tx, *txConflict);
GetMainSignals().NotifyInstantSendDoubleSpendAttempt(ptx, txConflict);
}
return state.DoS(10, error("AcceptToMemoryPool : Transaction %s conflicts with locked TX %s",
hash.ToString(), conflictLock->txid.ToString()),

View File

@ -13,6 +13,11 @@
#include <util.h>
#include <validation.h>
#include <governance/governance-vote.h>
#include <governance/governance-object.h>
#include <llmq/quorums_chainlocks.h>
#include <llmq/quorums_instantsend.h>
#include <list>
#include <atomic>
#include <future>
@ -32,13 +37,13 @@ struct MainSignalsInstance {
boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;
boost::signals2::signal<void (const CBlockIndex *)>AcceptedBlockHeader;
boost::signals2::signal<void (const CBlockIndex *, bool)>NotifyHeaderTip;
boost::signals2::signal<void (const CTransaction &tx, const llmq::CInstantSendLock& islock)>NotifyTransactionLock;
boost::signals2::signal<void (const CBlockIndex* pindex, const llmq::CChainLockSig& clsig)>NotifyChainLock;
boost::signals2::signal<void (const CGovernanceVote &vote)>NotifyGovernanceVote;
boost::signals2::signal<void (const CGovernanceObject &object)>NotifyGovernanceObject;
boost::signals2::signal<void (const CTransaction &currentTx, const CTransaction &previousTx)>NotifyInstantSendDoubleSpendAttempt;
boost::signals2::signal<void (const CTransactionRef& tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock)>NotifyTransactionLock;
boost::signals2::signal<void (const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)>NotifyChainLock;
boost::signals2::signal<void (const std::shared_ptr<const CGovernanceVote>& vote)>NotifyGovernanceVote;
boost::signals2::signal<void (const std::shared_ptr<const CGovernanceObject>& object)>NotifyGovernanceObject;
boost::signals2::signal<void (const CTransactionRef& currentTx, const CTransactionRef& previousTx)>NotifyInstantSendDoubleSpendAttempt;
boost::signals2::signal<void (bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)>NotifyMasternodeListChanged;
boost::signals2::signal<void (const llmq::CRecoveredSig& sig)>NotifyRecoveredSig;
boost::signals2::signal<void (const std::shared_ptr<const llmq::CRecoveredSig>& sig)>NotifyRecoveredSig;
// We are not allowed to assume the scheduler only runs in one thread,
// but must ensure all callbacks happen in-order, so we end up creating
// our own queue here :(
@ -231,28 +236,40 @@ void CMainSignals::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDo
m_internals->NotifyHeaderTip(pindexNew, fInitialDownload);
}
void CMainSignals::NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock) {
m_internals->NotifyTransactionLock(tx, islock);
void CMainSignals::NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock) {
m_internals->m_schedulerClient.AddToProcessQueue([tx, islock, this] {
m_internals->NotifyTransactionLock(tx, islock);
});
}
void CMainSignals::NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig) {
m_internals->NotifyChainLock(pindex, clsig);
void CMainSignals::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) {
m_internals->m_schedulerClient.AddToProcessQueue([pindex, clsig, this] {
m_internals->NotifyChainLock(pindex, clsig);
});
}
void CMainSignals::NotifyGovernanceVote(const CGovernanceVote &vote) {
m_internals->NotifyGovernanceVote(vote);
void CMainSignals::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote) {
m_internals->m_schedulerClient.AddToProcessQueue([vote, this] {
m_internals->NotifyGovernanceVote(vote);
});
}
void CMainSignals::NotifyGovernanceObject(const CGovernanceObject &object) {
m_internals->NotifyGovernanceObject(object);
void CMainSignals::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) {
m_internals->m_schedulerClient.AddToProcessQueue([object, this] {
m_internals->NotifyGovernanceObject(object);
});
}
void CMainSignals::NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) {
m_internals->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx);
void CMainSignals::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {
m_internals->m_schedulerClient.AddToProcessQueue([currentTx, previousTx, this] {
m_internals->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx);
});
}
void CMainSignals::NotifyRecoveredSig(const llmq::CRecoveredSig& sig) {
m_internals->NotifyRecoveredSig(sig);
void CMainSignals::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) {
m_internals->m_schedulerClient.AddToProcessQueue([sig, this] {
m_internals->NotifyRecoveredSig(sig);
});
}
void CMainSignals::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {

View File

@ -126,12 +126,12 @@ protected:
* Called on a background thread.
*/
virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindexDisconnected) {}
virtual void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock) {}
virtual void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig) {}
virtual void NotifyGovernanceVote(const CGovernanceVote &vote) {}
virtual void NotifyGovernanceObject(const CGovernanceObject &object) {}
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) {}
virtual void NotifyRecoveredSig(const llmq::CRecoveredSig& sig) {}
virtual void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock) {}
virtual void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) {}
virtual void NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote) {}
virtual void NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) {}
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {}
virtual void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) {}
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {}
/**
* Notifies listeners of the new active block chain on-disk.
@ -191,12 +191,12 @@ public:
void TransactionAddedToMempool(const CTransactionRef &, int64_t);
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &);
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindexDisconnected);
void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock);
void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLockSig& clsig);
void NotifyGovernanceVote(const CGovernanceVote &vote);
void NotifyGovernanceObject(const CGovernanceObject &object);
void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx);
void NotifyRecoveredSig(const llmq::CRecoveredSig &sig);
void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock);
void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig);
void NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote);
void NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object);
void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef &currentTx, const CTransactionRef &previousTx);
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig);
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff);
void SetBestChain(const CBlockLocator &);
void Broadcast(int64_t nBestBlockTime, CConnman* connman);

View File

@ -5349,11 +5349,11 @@ bool CWallet::AutoBackupWallet(const fs::path& wallet_path, std::string& strBack
return true;
}
void CWallet::NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock)
void CWallet::NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
{
LOCK(cs_wallet);
// Only notify UI if this transaction is in this wallet
uint256 txHash = tx.GetHash();
uint256 txHash = tx->GetHash();
std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txHash);
if (mi != mapWallet.end()){
NotifyTransactionChanged(this, txHash, CT_UPDATED);
@ -5368,7 +5368,7 @@ void CWallet::NotifyTransactionLock(const CTransaction &tx, const llmq::CInstant
}
}
void CWallet::NotifyChainLock(const CBlockIndex* pindexChainLock, const llmq::CChainLockSig& clsig)
void CWallet::NotifyChainLock(const CBlockIndex* pindexChainLock, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
NotifyChainLockReceived(pindexChainLock->nHeight);
}

View File

@ -1245,8 +1245,8 @@ public:
bool GetDecryptedHDChain(CHDChain& hdChainRet);
void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock) override;
void NotifyChainLock(const CBlockIndex* pindexChainLock, const llmq::CChainLockSig& clsig) override;
void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock) override;
void NotifyChainLock(const CBlockIndex* pindexChainLock, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
/** Load a CGovernanceObject into m_gobjects. */
bool LoadGovernanceObject(const CGovernanceObject& obj);

View File

@ -16,7 +16,7 @@ bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/)
return true;
}
bool CZMQAbstractNotifier::NotifyChainLock(const CBlockIndex * /*CBlockIndex*/, const llmq::CChainLockSig& /*clsig*/)
bool CZMQAbstractNotifier::NotifyChainLock(const CBlockIndex * /*CBlockIndex*/, const std::shared_ptr<const llmq::CChainLockSig> & /*clsig*/)
{
return true;
}
@ -26,27 +26,27 @@ bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/
return true;
}
bool CZMQAbstractNotifier::NotifyTransactionLock(const CTransaction &/*transaction*/, const llmq::CInstantSendLock& /*islock*/)
bool CZMQAbstractNotifier::NotifyTransactionLock(const CTransactionRef &/*transaction*/, const std::shared_ptr<const llmq::CInstantSendLock>& /*islock*/)
{
return true;
}
bool CZMQAbstractNotifier::NotifyGovernanceVote(const CGovernanceVote& /*vote*/)
bool CZMQAbstractNotifier::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote> & /*vote*/)
{
return true;
}
bool CZMQAbstractNotifier::NotifyGovernanceObject(const CGovernanceObject& /*object*/)
bool CZMQAbstractNotifier::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject> & /*object*/)
{
return true;
}
bool CZMQAbstractNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction& /*currentTx*/, const CTransaction& /*previousTx*/)
bool CZMQAbstractNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef & /*currentTx*/, const CTransactionRef & /*previousTx*/)
{
return true;
}
bool CZMQAbstractNotifier::NotifyRecoveredSig(const llmq::CRecoveredSig& /*sig*/)
bool CZMQAbstractNotifier::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> & /*sig*/)
{
return true;
}

View File

@ -41,13 +41,13 @@ public:
virtual void Shutdown() = 0;
virtual bool NotifyBlock(const CBlockIndex *pindex);
virtual bool NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig);
virtual bool NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig);
virtual bool NotifyTransaction(const CTransaction &transaction);
virtual bool NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock);
virtual bool NotifyGovernanceVote(const CGovernanceVote &vote);
virtual bool NotifyGovernanceObject(const CGovernanceObject &object);
virtual bool NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx);
virtual bool NotifyRecoveredSig(const llmq::CRecoveredSig& sig);
virtual bool NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock);
virtual bool NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote);
virtual bool NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object);
virtual bool NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx);
virtual bool NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig);
protected:
void *psocket;

View File

@ -167,7 +167,7 @@ void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, co
}
}
void CZMQNotificationInterface::NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig)
void CZMQNotificationInterface::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
{
@ -221,7 +221,7 @@ void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CB
}
}
void CZMQNotificationInterface::NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock)
void CZMQNotificationInterface::NotifyTransactionLock(const CTransactionRef& tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
{
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
{
@ -238,7 +238,7 @@ void CZMQNotificationInterface::NotifyTransactionLock(const CTransaction &tx, co
}
}
void CZMQNotificationInterface::NotifyGovernanceVote(const CGovernanceVote &vote)
void CZMQNotificationInterface::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote> &vote)
{
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); )
{
@ -255,7 +255,7 @@ void CZMQNotificationInterface::NotifyGovernanceVote(const CGovernanceVote &vote
}
}
void CZMQNotificationInterface::NotifyGovernanceObject(const CGovernanceObject &object)
void CZMQNotificationInterface::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject> &object)
{
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i != notifiers.end(); )
{
@ -272,7 +272,7 @@ void CZMQNotificationInterface::NotifyGovernanceObject(const CGovernanceObject &
}
}
void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx)
void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx)
{
for (auto it = notifiers.begin(); it != notifiers.end();) {
CZMQAbstractNotifier *notifier = *it;
@ -285,7 +285,7 @@ void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTrans
}
}
void CZMQNotificationInterface::NotifyRecoveredSig(const llmq::CRecoveredSig& sig)
void CZMQNotificationInterface::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig)
{
for (auto it = notifiers.begin(); it != notifiers.end();) {
CZMQAbstractNotifier *notifier = *it;

View File

@ -31,12 +31,12 @@ protected:
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected) override;
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
void NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig) override;
void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock& islock) override;
void NotifyGovernanceVote(const CGovernanceVote& vote) override;
void NotifyGovernanceObject(const CGovernanceObject& object) override;
void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) override;
void NotifyRecoveredSig(const llmq::CRecoveredSig& sig) override;
void NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const llmq::CInstantSendLock>& islock) override;
void NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote) override;
void NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) override;
void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) override;
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) override;
private:
CZMQNotificationInterface();

View File

@ -169,7 +169,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
return SendMessage(MSG_HASHBLOCK, data, 32);
}
bool CZMQPublishHashChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig)
bool CZMQPublishHashChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
uint256 hash = pindex->GetBlockHash();
LogPrint(BCLog::ZMQ, "zmq: Publish hashchainlock %s\n", hash.GetHex());
@ -189,9 +189,9 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t
return SendMessage(MSG_HASHTX, data, 32);
}
bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock)
bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
{
uint256 hash = transaction.GetHash();
uint256 hash = transaction->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish hashtxlock %s\n", hash.GetHex());
char data[32];
for (unsigned int i = 0; i < 32; i++)
@ -199,9 +199,9 @@ bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransa
return SendMessage(MSG_HASHTXLOCK, data, 32);
}
bool CZMQPublishHashGovernanceVoteNotifier::NotifyGovernanceVote(const CGovernanceVote &vote)
bool CZMQPublishHashGovernanceVoteNotifier::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote)
{
uint256 hash = vote.GetHash();
uint256 hash = vote->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish hashgovernancevote %s\n", hash.GetHex());
char data[32];
for (unsigned int i = 0; i < 32; i++)
@ -209,9 +209,9 @@ bool CZMQPublishHashGovernanceVoteNotifier::NotifyGovernanceVote(const CGovernan
return SendMessage(MSG_HASHGVOTE, data, 32);
}
bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const CGovernanceObject &object)
bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object)
{
uint256 hash = object.GetHash();
uint256 hash = object->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish hashgovernanceobject %s\n", hash.GetHex());
char data[32];
for (unsigned int i = 0; i < 32; i++)
@ -219,9 +219,9 @@ bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const CGove
return SendMessage(MSG_HASHGOBJ, data, 32);
}
bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx)
bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx)
{
uint256 currentHash = currentTx.GetHash(), previousHash = previousTx.GetHash();
uint256 currentHash = currentTx->GetHash(), previousHash = previousTx->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish hashinstantsenddoublespend %s conflicts against %s\n", currentHash.ToString(), previousHash.ToString());
char dataCurrentHash[32], dataPreviousHash[32];
for (unsigned int i = 0; i < 32; i++) {
@ -232,12 +232,12 @@ bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpend
&& SendMessage(MSG_HASHISCON, dataPreviousHash, 32);
}
bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const llmq::CRecoveredSig &sig)
bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig)
{
LogPrint(BCLog::ZMQ, "zmq: Publish hashrecoveredsig %s\n", sig.msgHash.ToString());
LogPrint(BCLog::ZMQ, "zmq: Publish hashrecoveredsig %s\n", sig->msgHash.ToString());
char data[32];
for (unsigned int i = 0; i < 32; i++)
data[31 - i] = sig.msgHash.begin()[i];
data[31 - i] = sig->msgHash.begin()[i];
return SendMessage(MSG_HASHRECSIG, data, 32);
}
@ -262,7 +262,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig)
bool CZMQPublishRawChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
LogPrint(BCLog::ZMQ, "zmq: Publish rawchainlock %s\n", pindex->GetBlockHash().GetHex());
@ -283,7 +283,7 @@ bool CZMQPublishRawChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex,
return SendMessage(MSG_RAWCHAINLOCK, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawChainLockSigNotifier::NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig)
bool CZMQPublishRawChainLockSigNotifier::NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
LogPrint(BCLog::ZMQ, "zmq: Publish rawchainlocksig %s\n", pindex->GetBlockHash().GetHex());
@ -299,7 +299,7 @@ bool CZMQPublishRawChainLockSigNotifier::NotifyChainLock(const CBlockIndex *pind
}
ss << block;
ss << clsig;
ss << *clsig;
}
return SendMessage(MSG_RAWCLSIG, &(*ss.begin()), ss.size());
@ -314,59 +314,59 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr
return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawTransactionLockNotifier::NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock)
bool CZMQPublishRawTransactionLockNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
{
uint256 hash = transaction.GetHash();
uint256 hash = transaction->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawtxlock %s\n", hash.GetHex());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << transaction;
ss << *transaction;
return SendMessage(MSG_RAWTXLOCK, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawTransactionLockSigNotifier::NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock)
bool CZMQPublishRawTransactionLockSigNotifier::NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock)
{
uint256 hash = transaction.GetHash();
uint256 hash = transaction->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawtxlocksig %s\n", hash.GetHex());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << transaction;
ss << islock;
ss << *transaction;
ss << *islock;
return SendMessage(MSG_RAWTXLOCKSIG, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawGovernanceVoteNotifier::NotifyGovernanceVote(const CGovernanceVote &vote)
bool CZMQPublishRawGovernanceVoteNotifier::NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote)
{
uint256 nHash = vote.GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, vote = %d\n", nHash.ToString(), vote.ToString());
uint256 nHash = vote->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, vote = %d\n", nHash.ToString(), vote->ToString());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << vote;
ss << *vote;
return SendMessage(MSG_RAWGVOTE, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawGovernanceObjectNotifier::NotifyGovernanceObject(const CGovernanceObject &govobj)
bool CZMQPublishRawGovernanceObjectNotifier::NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& govobj)
{
uint256 nHash = govobj.GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, type = %d\n", nHash.ToString(), govobj.GetObjectType());
uint256 nHash = govobj->GetHash();
LogPrint(BCLog::ZMQ, "zmq: Publish rawgovernanceobject: hash = %s, type = %d\n", nHash.ToString(), govobj->GetObjectType());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << govobj;
ss << *govobj;
return SendMessage(MSG_RAWGOBJ, &(*ss.begin()), ss.size());
}
bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx)
bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx)
{
LogPrint(BCLog::ZMQ, "zmq: Publish rawinstantsenddoublespend %s conflicts with %s\n", currentTx.GetHash().ToString(), previousTx.GetHash().ToString());
LogPrint(BCLog::ZMQ, "zmq: Publish rawinstantsenddoublespend %s conflicts with %s\n", currentTx->GetHash().ToString(), previousTx->GetHash().ToString());
CDataStream ssCurrent(SER_NETWORK, PROTOCOL_VERSION), ssPrevious(SER_NETWORK, PROTOCOL_VERSION);
ssCurrent << currentTx;
ssPrevious << previousTx;
ssCurrent << *currentTx;
ssPrevious << *previousTx;
return SendMessage(MSG_RAWISCON, &(*ssCurrent.begin()), ssCurrent.size())
&& SendMessage(MSG_RAWISCON, &(*ssPrevious.begin()), ssPrevious.size());
}
bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const llmq::CRecoveredSig& sig)
bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig)
{
LogPrint(BCLog::ZMQ, "zmq: Publish rawrecoveredsig %s\n", sig.msgHash.ToString());
LogPrint(BCLog::ZMQ, "zmq: Publish rawrecoveredsig %s\n", sig->msgHash.ToString());
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sig;
ss << *sig;
return SendMessage(MSG_RAWRECSIG, &(*ss.begin()), ss.size());
}

View File

@ -39,7 +39,7 @@ public:
class CZMQPublishHashChainLockNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig) override;
bool NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
};
class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier
@ -51,31 +51,31 @@ public:
class CZMQPublishHashTransactionLockNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock) override;
bool NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock) override;
};
class CZMQPublishHashGovernanceVoteNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyGovernanceVote(const CGovernanceVote &vote) override;
bool NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote) override;
};
class CZMQPublishHashGovernanceObjectNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
bool NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) override;
};
class CZMQPublishHashInstantSendDoubleSpendNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) override;
bool NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) override;
};
class CZMQPublishHashRecoveredSigNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyRecoveredSig(const llmq::CRecoveredSig&) override;
bool NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>&) override;
};
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
@ -87,13 +87,13 @@ public:
class CZMQPublishRawChainLockNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig) override;
bool NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
};
class CZMQPublishRawChainLockSigNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig& clsig) override;
bool NotifyChainLock(const CBlockIndex *pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig) override;
};
class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier
@ -105,36 +105,36 @@ public:
class CZMQPublishRawTransactionLockNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock) override;
bool NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock) override;
};
class CZMQPublishRawTransactionLockSigNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyTransactionLock(const CTransaction &transaction, const llmq::CInstantSendLock& islock) override;
bool NotifyTransactionLock(const CTransactionRef& transaction, const std::shared_ptr<const llmq::CInstantSendLock>& islock) override;
};
class CZMQPublishRawGovernanceVoteNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyGovernanceVote(const CGovernanceVote &vote) override;
bool NotifyGovernanceVote(const std::shared_ptr<const CGovernanceVote>& vote) override;
};
class CZMQPublishRawGovernanceObjectNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyGovernanceObject(const CGovernanceObject &object) override;
bool NotifyGovernanceObject(const std::shared_ptr<const CGovernanceObject>& object) override;
};
class CZMQPublishRawInstantSendDoubleSpendNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx) override;
bool NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) override;
};
class CZMQPublishRawRecoveredSigNotifier : public CZMQAbstractPublishNotifier
{
public:
bool NotifyRecoveredSig(const llmq::CRecoveredSig &sig) override;
bool NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig) override;
};
#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H