@@ -246,7 +246,7 @@ void CRecoveredSigsDb::WriteRecoveredSig(const llmq::CRecoveredSig& recSig)
246246 }
247247}
248248
249- void CRecoveredSigsDb::RemoveRecoveredSig (CDBBatch& batch, Consensus::LLMQType llmqType, const uint256& id, bool deleteTimeKey)
249+ void CRecoveredSigsDb::RemoveRecoveredSig (CDBBatch& batch, Consensus::LLMQType llmqType, const uint256& id, bool deleteHashKey, bool deleteTimeKey)
250250{
251251 AssertLockHeld (cs);
252252
@@ -263,7 +263,9 @@ void CRecoveredSigsDb::RemoveRecoveredSig(CDBBatch& batch, Consensus::LLMQType l
263263 auto k4 = std::make_tuple (std::string (" rs_s" ), signHash);
264264 batch.Erase (k1);
265265 batch.Erase (k2);
266- batch.Erase (k3);
266+ if (deleteHashKey) {
267+ batch.Erase (k3);
268+ }
267269 batch.Erase (k4);
268270
269271 if (deleteTimeKey) {
@@ -279,14 +281,27 @@ void CRecoveredSigsDb::RemoveRecoveredSig(CDBBatch& batch, Consensus::LLMQType l
279281
280282 hasSigForIdCache.erase (std::make_pair ((Consensus::LLMQType)recSig.llmqType , recSig.id ));
281283 hasSigForSessionCache.erase (signHash);
282- hasSigForHashCache.erase (recSig.GetHash ());
284+ if (deleteHashKey) {
285+ hasSigForHashCache.erase (recSig.GetHash ());
286+ }
283287}
284288
289+ // Completely remove any traces of the recovered sig
285290void CRecoveredSigsDb::RemoveRecoveredSig (Consensus::LLMQType llmqType, const uint256& id)
286291{
287292 LOCK (cs);
288293 CDBBatch batch (CLIENT_VERSION | ADDRV2_FORMAT);
289- RemoveRecoveredSig (batch, llmqType, id, true );
294+ RemoveRecoveredSig (batch, llmqType, id, true , true );
295+ db.WriteBatch (batch);
296+ }
297+
298+ // Remove the recovered sig itself and all keys required to get from id -> recSig
299+ // This will leave the byHash key in-place so that HasRecoveredSigForHash still returns true
300+ void CRecoveredSigsDb::TruncateRecoveredSig (Consensus::LLMQType llmqType, const uint256& id)
301+ {
302+ LOCK (cs);
303+ CDBBatch batch (CLIENT_VERSION | ADDRV2_FORMAT);
304+ RemoveRecoveredSig (batch, llmqType, id, false , false );
290305 db.WriteBatch (batch);
291306}
292307
@@ -326,7 +341,7 @@ void CRecoveredSigsDb::CleanupOldRecoveredSigs(int64_t maxAge)
326341 {
327342 LOCK (cs);
328343 for (auto & e : toDelete) {
329- RemoveRecoveredSig (batch, e.first , e.second , false );
344+ RemoveRecoveredSig (batch, e.first , e.second , true , false );
330345
331346 if (batch.SizeEstimate () >= (1 << 24 )) {
332347 db.WriteBatch (batch);
@@ -417,8 +432,10 @@ CSigningManager::CSigningManager(CDBWrapper& llmqDb, bool fMemory) : db(llmqDb)
417432
418433bool CSigningManager::AlreadyHave (const CInv& inv)
419434{
420- LOCK (cs);
421- return inv.type == MSG_QUORUM_RECOVERED_SIG && db.HasRecoveredSigForHash (inv.hash );
435+ if (inv.type != MSG_QUORUM_RECOVERED_SIG) {
436+ return false ;
437+ }
438+ return db.HasRecoveredSigForHash (inv.hash );
422439}
423440
424441bool CSigningManager::GetRecoveredSigForGetData (const uint256& hash, CRecoveredSig& ret)
@@ -459,7 +476,8 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredS
459476 return ;
460477 }
461478
462- LogPrint (BCLog::LLMQ, " CSigningManager::%s -- signHash=%s, node=%d\n " , __func__, llmq::utils::BuildSignHash (recoveredSig).ToString (), pfrom->GetId ());
479+ LogPrint (BCLog::LLMQ, " CSigningManager::%s -- signHash=%s, id=%s, msgHash=%s, node=%d\n " , __func__,
480+ llmq::utils::BuildSignHash (recoveredSig).ToString (), recoveredSig.id .ToString (), recoveredSig.msgHash .ToString (), pfrom->GetId ());
463481
464482 LOCK (cs);
465483 pendingRecoveredSigs[pfrom->GetId ()].emplace_back (recoveredSig);
@@ -482,7 +500,7 @@ bool CSigningManager::PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig&
482500 recoveredSig.quorumHash .ToString (), nodeId);
483501 return false ;
484502 }
485- if (!llmq::utils::IsQuorumActive (llmqType, quorum->pindexQuorum -> GetBlockHash () )) {
503+ if (!llmq::utils::IsQuorumActive (llmqType, quorum->qc . quorumHash )) {
486504 return false ;
487505 }
488506
@@ -537,7 +555,7 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
537555 it = v.erase (it);
538556 continue ;
539557 }
540- if (!llmq::utils::IsQuorumActive (llmqType, quorum->pindexQuorum -> GetBlockHash () )) {
558+ if (!llmq::utils::IsQuorumActive (llmqType, quorum->qc . quorumHash )) {
541559 LogPrint (BCLog::LLMQ, " CSigningManager::%s -- quorum %s not active anymore, node=%d\n " , __func__,
542560 recSig.quorumHash .ToString (), nodeId);
543561 it = v.erase (it);
@@ -579,7 +597,7 @@ bool CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
579597 }
580598
581599 const auto & quorum = quorums.at (std::make_pair ((Consensus::LLMQType)recSig.llmqType , recSig.quorumHash ));
582- batchVerifier.PushMessage (nodeId, recSig.GetHash (), llmq::utils::BuildSignHash (recSig), recSig.sig .Get (), quorum->quorumPublicKey );
600+ batchVerifier.PushMessage (nodeId, recSig.GetHash (), llmq::utils::BuildSignHash (recSig), recSig.sig .Get (), quorum->qc . quorumPublicKey );
583601 verifyCount++;
584602 }
585603 }
@@ -624,6 +642,11 @@ void CSigningManager::ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& re
624642 LOCK (cs_main);
625643 connman.RemoveAskFor (recoveredSig.GetHash (), MSG_QUORUM_RECOVERED_SIG);
626644 }
645+
646+ if (db.HasRecoveredSigForHash (recoveredSig.GetHash ())) {
647+ return ;
648+ }
649+
627650 std::vector<CRecoveredSigsListener*> listeners;
628651 {
629652 LOCK (cs);
@@ -661,7 +684,7 @@ void CSigningManager::ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& re
661684
662685 CInv inv (MSG_QUORUM_RECOVERED_SIG, recoveredSig.GetHash ());
663686 g_connman->ForEachNode ([&](CNode* pnode) {
664- if (pnode->m_wants_recsigs ) {
687+ if (pnode->nVersion >= LLMQS_PROTO_VERSION && pnode-> m_wants_recsigs && pnode-> CanRelay () ) {
665688 pnode->PushInventory (inv);
666689 }
667690 });
@@ -670,9 +693,9 @@ void CSigningManager::ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& re
670693 }
671694}
672695
673- void CSigningManager::RemoveRecoveredSig (Consensus::LLMQType llmqType, const uint256& id)
696+ void CSigningManager::TruncateRecoveredSig (Consensus::LLMQType llmqType, const uint256& id)
674697{
675- db.RemoveRecoveredSig (llmqType, id);
698+ db.TruncateRecoveredSig (llmqType, id);
676699}
677700
678701void CSigningManager::Cleanup ()
@@ -703,7 +726,7 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l)
703726 recoveredSigsListeners.erase (itRem, recoveredSigsListeners.end ());
704727}
705728
706- bool CSigningManager::AsyncSignIfMember (Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash)
729+ bool CSigningManager::AsyncSignIfMember (Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, bool allowReSign )
707730{
708731 auto & params = Params ().GetConsensus ().llmqs .at (llmqType);
709732
@@ -714,24 +737,31 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint
714737 {
715738 LOCK (cs);
716739
717- if (db.HasVotedOnId (llmqType, id)) {
740+ bool hasVoted = db.HasVotedOnId (llmqType, id);
741+ if (hasVoted) {
718742 uint256 prevMsgHash;
719743 db.GetVoteForId (llmqType, id, prevMsgHash);
720744 if (msgHash != prevMsgHash) {
721745 LogPrintf (" CSigningManager::%s -- already voted for id=%s and msgHash=%s. Not voting on conflicting msgHash=%s\n " , __func__,
722746 id.ToString (), prevMsgHash.ToString (), msgHash.ToString ());
747+ return false ;
748+ } else if (allowReSign) {
749+ LogPrint (BCLog::LLMQ, " CSigningManager::%s -- already voted for id=%s and msgHash=%s. Resigning!\n " , __func__,
750+ id.ToString (), prevMsgHash.ToString ());
723751 } else {
724752 LogPrint (BCLog::LLMQ, " CSigningManager::%s -- already voted for id=%s and msgHash=%s. Not voting again.\n " , __func__,
725753 id.ToString (), prevMsgHash.ToString ());
754+ return false ;
726755 }
727- return false ;
728756 }
729757
730758 if (db.HasRecoveredSigForId (llmqType, id)) {
731759 // no need to sign it if we already have a recovered sig
732760 return true ;
733761 }
734- db.WriteVoteForId (llmqType, id, msgHash);
762+ if (!hasVoted) {
763+ db.WriteVoteForId (llmqType, id, msgHash);
764+ }
735765 }
736766
737767 int tipHeight;
@@ -752,10 +782,13 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint
752782 }
753783
754784 if (!quorum->IsValidMember (activeMasternodeManager->GetProTx ())) {
755- // LogPrint(BCLog::LLMQ, "CSigningManager::%s -- we're not a valid member of quorum %s\n", __func__, quorum->quorumHash.ToString());
756785 return false ;
757786 }
758787
788+ if (allowReSign) {
789+ // make us re-announce all known shares (other nodes might have run into a timeout)
790+ quorumSigSharesManager->ForceReAnnouncement (quorum, llmqType, id, msgHash);
791+ }
759792 quorumSigSharesManager->AsyncSign (quorum, id, msgHash);
760793
761794 return true ;
@@ -832,7 +865,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType
832865 for (size_t i = 0 ; i < quorums.size (); i++) {
833866 CHashWriter h (SER_NETWORK, 0 );
834867 h << (uint8_t )llmqType;
835- h << quorums[i]->pindexQuorum -> GetBlockHash () ;
868+ h << quorums[i]->qc . quorumHash ;
836869 h << selectionHash;
837870 scores.emplace_back (h.GetHash (), i);
838871 }
@@ -849,8 +882,8 @@ bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, int signe
849882 return false ;
850883 }
851884
852- uint256 signHash = llmq::utils::BuildSignHash (llmqParams.type , quorum->pindexQuorum -> GetBlockHash () , id, msgHash);
853- return sig.VerifyInsecure (quorum->quorumPublicKey , signHash);
885+ uint256 signHash = llmq::utils::BuildSignHash (llmqParams.type , quorum->qc . quorumHash , id, msgHash);
886+ return sig.VerifyInsecure (quorum->qc . quorumPublicKey , signHash);
854887}
855888
856889} // namespace llmq
0 commit comments