@@ -311,10 +311,14 @@ CInstantSendLockPtr CInstantSendDb::GetInstantSendLockByHash(const uint256& hash
311311 return ret;
312312 }
313313
314- ret = std::make_shared<CInstantSendLock>();
314+ ret = std::make_shared<CInstantSendLock>(CInstantSendLock::isdlock_version );
315315 bool exists = db->Read (std::make_tuple (DB_ISLOCK_BY_HASH, hash), *ret);
316316 if (!exists) {
317- ret = nullptr ;
317+ ret = std::make_shared<CInstantSendLock>();
318+ exists = db->Read (std::make_tuple (DB_ISLOCK_BY_HASH, hash), *ret);
319+ if (!exists) {
320+ ret = nullptr ;
321+ }
318322 }
319323 islockCache.insert (hash, ret);
320324 return ret;
@@ -668,7 +672,7 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re
668672
669673void CInstantSendManager::TrySignInstantSendLock (const CTransaction& tx)
670674{
671- auto llmqType = Params ().GetConsensus ().llmqTypeInstantSend ;
675+ const auto llmqType = Params ().GetConsensus ().llmqTypeInstantSend ;
672676
673677 for (auto & in : tx.vin ) {
674678 auto id = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in.prevout ));
@@ -680,12 +684,20 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx)
680684 LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: got all recovered sigs, creating CInstantSendLock\n " , __func__,
681685 tx.GetHash ().ToString ());
682686
683- CInstantSendLock islock;
687+ CInstantSendLock islock (CInstantSendLock::isdlock_version) ;
684688 islock.txid = tx.GetHash ();
685689 for (auto & in : tx.vin ) {
686690 islock.inputs .emplace_back (in.prevout );
687691 }
688692
693+ // compute cycle hash
694+ {
695+ LOCK (cs_main);
696+ const auto dkgInterval = GetLLMQParams (llmqType).dkgInterval ;
697+ const auto quorumHeight = chainActive.Height () - (chainActive.Height () % dkgInterval);
698+ islock.cycleHash = chainActive[quorumHeight]->GetBlockHash ();
699+ }
700+
689701 auto id = islock.GetRequestId ();
690702
691703 if (quorumSigningManager->HasRecoveredSigForId (llmqType, id)) {
@@ -736,8 +748,9 @@ void CInstantSendManager::ProcessMessage(CNode* pfrom, const std::string& strCom
736748 return ;
737749 }
738750
739- if (strCommand == NetMsgType::ISLOCK) {
740- auto islock = std::make_shared<CInstantSendLock>();
751+ if (strCommand == NetMsgType::ISLOCK || strCommand == NetMsgType::ISDLOCK) {
752+ const auto islock_version = strCommand == NetMsgType::ISLOCK ? CInstantSendLock::islock_version : CInstantSendLock::isdlock_version;
753+ const auto islock = std::make_shared<CInstantSendLock>(islock_version);
741754 vRecv >> *islock;
742755 ProcessMessageInstantSendLock (pfrom, islock);
743756 }
@@ -749,7 +762,7 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode* pfrom, cons
749762
750763 {
751764 LOCK (cs_main);
752- EraseObjectRequest (pfrom->GetId (), CInv (MSG_ISLOCK, hash));
765+ EraseObjectRequest (pfrom->GetId (), CInv (islock-> IsDeterministic () ? MSG_ISDLOCK : MSG_ISLOCK, hash));
753766 }
754767
755768 if (!PreVerifyInstantSendLock (*islock)) {
@@ -788,6 +801,16 @@ bool CInstantSendManager::PreVerifyInstantSendLock(const llmq::CInstantSendLock&
788801 }
789802 }
790803
804+ if (islock.IsDeterministic ()) {
805+ LOCK (cs_main);
806+ const auto llmqType = Params ().GetConsensus ().llmqTypeInstantSend ;
807+ const auto dkgInterval = GetLLMQParams (llmqType).dkgInterval ;
808+ const auto blockIndex = LookupBlockIndex (islock.cycleHash );
809+ if (blockIndex == nullptr || blockIndex->nHeight % dkgInterval != 0 ) {
810+ return false ;
811+ }
812+ }
813+
791814 return true ;
792815}
793816
@@ -875,7 +898,23 @@ std::unordered_set<uint256> CInstantSendManager::ProcessPendingInstantSendLocks(
875898 continue ;
876899 }
877900
878- auto quorum = llmq::CSigningManager::SelectQuorumForSigning (llmqType, id, -1 , signOffset);
901+ int nSignHeight{-1 };
902+ if (islock->IsDeterministic ()) {
903+ LOCK (cs_main);
904+
905+ const auto blockIndex = LookupBlockIndex (islock->cycleHash );
906+ if (blockIndex == nullptr ) {
907+ batchVerifier.badSources .emplace (nodeId);
908+ continue ;
909+ }
910+
911+ const auto dkgInterval = GetLLMQParams (Params ().GetConsensus ().llmqTypeInstantSend ).dkgInterval ;
912+ if (blockIndex->nHeight + dkgInterval < chainActive.Height ()) {
913+ nSignHeight = blockIndex->nHeight + dkgInterval - 1 ;
914+ }
915+ }
916+
917+ auto quorum = llmq::CSigningManager::SelectQuorumForSigning (llmqType, id, nSignHeight, signOffset);
879918 if (!quorum) {
880919 // should not happen, but if one fails to select, all others will also fail to select
881920 return {};
@@ -1009,13 +1048,14 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
10091048 TruncateRecoveredSigsForInputs (*islock);
10101049 }
10111050
1012- CInv inv (MSG_ISLOCK, hash);
1051+ const auto is_det = islock->IsDeterministic ();
1052+ CInv inv (is_det ? MSG_ISDLOCK : MSG_ISLOCK, hash);
10131053 if (tx != nullptr ) {
1014- g_connman->RelayInvFiltered (inv, *tx, LLMQS_PROTO_VERSION);
1054+ g_connman->RelayInvFiltered (inv, *tx, is_det ? ISDLOCK_PROTO_VERSION : LLMQS_PROTO_VERSION);
10151055 } else {
10161056 // we don't have the TX yet, so we only filter based on txid. Later when that TX arrives, we will re-announce
10171057 // with the TX taken into account.
1018- g_connman->RelayInvFiltered (inv, islock->txid , LLMQS_PROTO_VERSION);
1058+ g_connman->RelayInvFiltered (inv, islock->txid , is_det ? ISDLOCK_PROTO_VERSION : LLMQS_PROTO_VERSION);
10191059 }
10201060
10211061 ResolveBlockConflicts (hash, *islock);
@@ -1054,8 +1094,8 @@ void CInstantSendManager::TransactionAddedToMempool(const CTransactionRef& tx)
10541094 }
10551095 // In case the islock was received before the TX, filtered announcement might have missed this islock because
10561096 // we were unable to check for filter matches deep inside the TX. Now we have the TX, so we should retry.
1057- CInv inv (MSG_ISLOCK, ::SerializeHash (*islock));
1058- g_connman->RelayInvFiltered (inv, *tx, LLMQS_PROTO_VERSION);
1097+ CInv inv (islock-> IsDeterministic () ? MSG_ISDLOCK : MSG_ISLOCK, ::SerializeHash (*islock));
1098+ g_connman->RelayInvFiltered (inv, *tx, islock-> IsDeterministic () ? ISDLOCK_PROTO_VERSION : LLMQS_PROTO_VERSION);
10591099 // If the islock was received before the TX, we know we were not able to send
10601100 // the notification at that time, we need to do it now.
10611101 LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- notify about an earlier received lock for tx %s\n " , __func__, tx->GetHash ().ToString ());
0 commit comments