@@ -88,288 +88,6 @@ void CInstantSendManager::Stop()
8888 }
8989}
9090
91- void CInstantSendManager::ProcessTx (const CTransaction& tx, bool fRetroactive , const Consensus::Params& params)
92- {
93- if (!m_is_masternode || !IsInstantSendEnabled () || !m_mn_sync.IsBlockchainSynced ()) {
94- return ;
95- }
96-
97- if (params.llmqTypeDIP0024InstantSend == Consensus::LLMQType::LLMQ_NONE) {
98- return ;
99- }
100-
101- if (!CheckCanLock (tx, true , params)) {
102- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: CheckCanLock returned false\n " , __func__,
103- tx.GetHash ().ToString ());
104- return ;
105- }
106-
107- auto conflictingLock = GetConflictingLock (tx);
108- if (conflictingLock != nullptr ) {
109- auto conflictingLockHash = ::SerializeHash (*conflictingLock);
110- LogPrintf (" CInstantSendManager::%s -- txid=%s: conflicts with islock %s, txid=%s\n " , __func__,
111- tx.GetHash ().ToString (), conflictingLockHash.ToString (), conflictingLock->txid .ToString ());
112- return ;
113- }
114-
115- // Only sign for inlocks or islocks if mempool IS signing is enabled.
116- // However, if we are processing a tx because it was included in a block we should
117- // sign even if mempool IS signing is disabled. This allows a ChainLock to happen on this
118- // block after we retroactively locked all transactions.
119- if (!IsInstantSendMempoolSigningEnabled () && !fRetroactive ) return ;
120-
121- if (!TrySignInputLocks (tx, fRetroactive , params.llmqTypeDIP0024InstantSend , params)) {
122- return ;
123- }
124-
125- // We might have received all input locks before we got the corresponding TX. In this case, we have to sign the
126- // islock now instead of waiting for the input locks.
127- TrySignInstantSendLock (tx);
128- }
129-
130- bool CInstantSendManager::TrySignInputLocks (const CTransaction& tx, bool fRetroactive , Consensus::LLMQType llmqType, const Consensus::Params& params)
131- {
132- std::vector<uint256> ids;
133- ids.reserve (tx.vin .size ());
134-
135- size_t alreadyVotedCount = 0 ;
136- for (const auto & in : tx.vin ) {
137- auto id = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in.prevout ));
138- ids.emplace_back (id);
139-
140- uint256 otherTxHash;
141- if (sigman.GetVoteForId (params.llmqTypeDIP0024InstantSend , id, otherTxHash)) {
142- if (otherTxHash != tx.GetHash ()) {
143- LogPrintf (" CInstantSendManager::%s -- txid=%s: input %s is conflicting with previous vote for tx %s\n " , __func__,
144- tx.GetHash ().ToString (), in.prevout .ToStringShort (), otherTxHash.ToString ());
145- return false ;
146- }
147- alreadyVotedCount++;
148- }
149-
150- // don't even try the actual signing if any input is conflicting
151- if (sigman.IsConflicting (params.llmqTypeDIP0024InstantSend , id, tx.GetHash ())) {
152- LogPrintf (" CInstantSendManager::%s -- txid=%s: sigman.IsConflicting returned true. id=%s\n " , __func__,
153- tx.GetHash ().ToString (), id.ToString ());
154- return false ;
155- }
156- }
157- if (!fRetroactive && alreadyVotedCount == ids.size ()) {
158- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: already voted on all inputs, bailing out\n " , __func__,
159- tx.GetHash ().ToString ());
160- return true ;
161- }
162-
163- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: trying to vote on %d inputs\n " , __func__,
164- tx.GetHash ().ToString (), tx.vin .size ());
165-
166- for (const auto i : irange::range (tx.vin .size ())) {
167- const auto & in = tx.vin [i];
168- auto & id = ids[i];
169- WITH_LOCK (cs_inputReqests, inputRequestIds.emplace (id));
170- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. fRetroactive=%d\n " , __func__,
171- tx.GetHash ().ToString (), in.prevout .ToStringShort (), id.ToString (), fRetroactive );
172- if (sigman.AsyncSignIfMember (llmqType, shareman, id, tx.GetHash (), {}, fRetroactive )) {
173- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: voted on input %s with id %s\n " , __func__,
174- tx.GetHash ().ToString (), in.prevout .ToStringShort (), id.ToString ());
175- }
176- }
177-
178- return true ;
179- }
180-
181- bool CInstantSendManager::CheckCanLock (const CTransaction& tx, bool printDebug, const Consensus::Params& params) const
182- {
183- if (tx.vin .empty ()) {
184- // can't lock TXs without inputs (e.g. quorum commitments)
185- return false ;
186- }
187-
188- return ranges::all_of (tx.vin ,
189- [&](const auto & in) { return CheckCanLock (in.prevout , printDebug, tx.GetHash (), params); });
190- }
191-
192- bool CInstantSendManager::CheckCanLock (const COutPoint& outpoint, bool printDebug, const uint256& txHash, const Consensus::Params& params) const
193- {
194- int nInstantSendConfirmationsRequired = params.nInstantSendConfirmationsRequired ;
195-
196- if (IsLocked (outpoint.hash )) {
197- // if prevout was ix locked, allow locking of descendants (no matter if prevout is in mempool or already mined)
198- return true ;
199- }
200-
201- auto mempoolTx = mempool.get (outpoint.hash );
202- if (mempoolTx) {
203- if (printDebug) {
204- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: parent mempool TX %s is not locked\n " , __func__,
205- txHash.ToString (), outpoint.hash .ToString ());
206- }
207- return false ;
208- }
209-
210- uint256 hashBlock{};
211- const auto tx = GetTransaction (nullptr , &mempool, outpoint.hash , params, hashBlock);
212- // this relies on enabled txindex and won't work if we ever try to remove the requirement for txindex for masternodes
213- if (!tx) {
214- if (printDebug) {
215- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: failed to find parent TX %s\n " , __func__,
216- txHash.ToString (), outpoint.hash .ToString ());
217- }
218- return false ;
219- }
220-
221- const CBlockIndex* pindexMined;
222- int nTxAge;
223- {
224- LOCK (::cs_main);
225- pindexMined = m_chainstate.m_blockman .LookupBlockIndex (hashBlock);
226- nTxAge = m_chainstate.m_chain .Height () - pindexMined->nHeight + 1 ;
227- }
228-
229- if (nTxAge < nInstantSendConfirmationsRequired && !clhandler.HasChainLock (pindexMined->nHeight , pindexMined->GetBlockHash ())) {
230- if (printDebug) {
231- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: outpoint %s too new and not ChainLocked. nTxAge=%d, nInstantSendConfirmationsRequired=%d\n " , __func__,
232- txHash.ToString (), outpoint.ToStringShort (), nTxAge, nInstantSendConfirmationsRequired);
233- }
234- return false ;
235- }
236-
237- return true ;
238- }
239-
240- MessageProcessingResult CInstantSendManager::HandleNewRecoveredSig (const CRecoveredSig& recoveredSig)
241- {
242- if (!IsInstantSendEnabled ()) {
243- return {};
244- }
245-
246- if (Params ().GetConsensus ().llmqTypeDIP0024InstantSend == Consensus::LLMQType::LLMQ_NONE) {
247- return {};
248- }
249-
250- uint256 txid;
251- if (LOCK (cs_inputReqests); inputRequestIds.count (recoveredSig.getId ())) {
252- txid = recoveredSig.getMsgHash ();
253- }
254- if (!txid.IsNull ()) {
255- HandleNewInputLockRecoveredSig (recoveredSig, txid);
256- } else if (/* isInstantSendLock=*/ WITH_LOCK (cs_creating, return creatingInstantSendLocks.count (recoveredSig.getId ()))) {
257- HandleNewInstantSendLockRecoveredSig (recoveredSig);
258- }
259- return {};
260- }
261-
262- void CInstantSendManager::HandleNewInputLockRecoveredSig (const CRecoveredSig& recoveredSig, const uint256& txid)
263- {
264- if (g_txindex) {
265- g_txindex->BlockUntilSyncedToCurrentChain ();
266- }
267-
268-
269- uint256 hashBlock{};
270- const auto tx = GetTransaction (nullptr , &mempool, txid, Params ().GetConsensus (), hashBlock);
271- if (!tx) {
272- return ;
273- }
274-
275- if (LogAcceptDebug (BCLog::INSTANTSEND)) {
276- for (const auto & in : tx->vin ) {
277- auto id = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in.prevout ));
278- if (id == recoveredSig.getId ()) {
279- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: got recovered sig for input %s\n " , __func__,
280- txid.ToString (), in.prevout .ToStringShort ());
281- break ;
282- }
283- }
284- }
285-
286- TrySignInstantSendLock (*tx);
287- }
288-
289- void CInstantSendManager::TrySignInstantSendLock (const CTransaction& tx)
290- {
291- const auto llmqType = Params ().GetConsensus ().llmqTypeDIP0024InstantSend ;
292-
293- for (const auto & in : tx.vin ) {
294- auto id = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in.prevout ));
295- if (!sigman.HasRecoveredSig (llmqType, id, tx.GetHash ())) {
296- return ;
297- }
298- }
299-
300- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: got all recovered sigs, creating CInstantSendLock\n " , __func__,
301- tx.GetHash ().ToString ());
302-
303- CInstantSendLock islock;
304- islock.txid = tx.GetHash ();
305- for (const auto & in : tx.vin ) {
306- islock.inputs .emplace_back (in.prevout );
307- }
308-
309- auto id = islock.GetRequestId ();
310-
311- if (sigman.HasRecoveredSigForId (llmqType, id)) {
312- return ;
313- }
314-
315- const auto & llmq_params_opt = Params ().GetLLMQ (llmqType);
316- assert (llmq_params_opt);
317- const auto quorum = SelectQuorumForSigning (llmq_params_opt.value (), m_chainstate.m_chain , qman, id);
318-
319- if (!quorum) {
320- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- failed to select quorum. islock id=%s, txid=%s\n " ,
321- __func__, id.ToString (), tx.GetHash ().ToString ());
322- return ;
323- }
324-
325- const int cycle_height = quorum->m_quorum_base_block_index ->nHeight -
326- quorum->m_quorum_base_block_index ->nHeight % llmq_params_opt->dkgInterval ;
327- islock.cycleHash = quorum->m_quorum_base_block_index ->GetAncestor (cycle_height)->GetBlockHash ();
328-
329- {
330- LOCK (cs_creating);
331- auto e = creatingInstantSendLocks.emplace (id, std::move (islock));
332- if (!e.second ) {
333- return ;
334- }
335- txToCreatingInstantSendLocks.emplace (tx.GetHash (), &e.first ->second );
336- }
337-
338- sigman.AsyncSignIfMember (llmqType, shareman, id, tx.GetHash (), quorum->m_quorum_base_block_index ->GetBlockHash ());
339- }
340-
341- void CInstantSendManager::HandleNewInstantSendLockRecoveredSig (const llmq::CRecoveredSig& recoveredSig)
342- {
343- CInstantSendLockPtr islock;
344-
345- {
346- LOCK (cs_creating);
347- auto it = creatingInstantSendLocks.find (recoveredSig.getId ());
348- if (it == creatingInstantSendLocks.end ()) {
349- return ;
350- }
351-
352- islock = std::make_shared<CInstantSendLock>(std::move (it->second ));
353- creatingInstantSendLocks.erase (it);
354- txToCreatingInstantSendLocks.erase (islock->txid );
355- }
356-
357- if (islock->txid != recoveredSig.getMsgHash ()) {
358- LogPrintf (" CInstantSendManager::%s -- txid=%s: islock conflicts with %s, dropping own version\n " , __func__,
359- islock->txid .ToString (), recoveredSig.getMsgHash ().ToString ());
360- return ;
361- }
362-
363- islock->sig = recoveredSig.sig ;
364- auto hash = ::SerializeHash (*islock);
365-
366- if (WITH_LOCK (cs_pendingLocks, return pendingInstantSendLocks.count (hash)) || db.KnownInstantSendLock (hash)) {
367- return ;
368- }
369- LOCK (cs_pendingLocks);
370- pendingInstantSendLocks.emplace (hash, std::make_pair (-1 , islock));
371- }
372-
37391PeerMsgRet CInstantSendManager::ProcessMessage (const CNode& pfrom, PeerManager& peerman, std::string_view msg_type,
37492 CDataStream& vRecv)
37593{
@@ -1080,67 +798,6 @@ void CInstantSendManager::RemoveConflictingLock(const uint256& islockHash, const
1080798 }
1081799}
1082800
1083- void CInstantSendManager::ProcessPendingRetryLockTxs ()
1084- {
1085- const auto retryTxs = WITH_LOCK (cs_pendingRetry, return pendingRetryTxs);
1086-
1087- if (retryTxs.empty ()) {
1088- return ;
1089- }
1090-
1091- if (!IsInstantSendEnabled ()) {
1092- return ;
1093- }
1094-
1095- int retryCount = 0 ;
1096- for (const auto & txid : retryTxs) {
1097- CTransactionRef tx;
1098- {
1099- {
1100- LOCK (cs_nonLocked);
1101- auto it = nonLockedTxs.find (txid);
1102- if (it == nonLockedTxs.end ()) {
1103- continue ;
1104- }
1105- tx = it->second .tx ;
1106- }
1107- if (!tx) {
1108- continue ;
1109- }
1110-
1111- if (LOCK (cs_creating); txToCreatingInstantSendLocks.count (tx->GetHash ())) {
1112- // we're already in the middle of locking this one
1113- continue ;
1114- }
1115- if (IsLocked (tx->GetHash ())) {
1116- continue ;
1117- }
1118- if (GetConflictingLock (*tx) != nullptr ) {
1119- // should not really happen as we have already filtered these out
1120- continue ;
1121- }
1122- }
1123-
1124- // CheckCanLock is already called by ProcessTx, so we should avoid calling it twice. But we also shouldn't spam
1125- // the logs when retrying TXs that are not ready yet.
1126- if (LogAcceptDebug (BCLog::INSTANTSEND)) {
1127- if (!CheckCanLock (*tx, false , Params ().GetConsensus ())) {
1128- continue ;
1129- }
1130- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s: retrying to lock\n " , __func__,
1131- tx->GetHash ().ToString ());
1132- }
1133-
1134- ProcessTx (*tx, false , Params ().GetConsensus ());
1135- retryCount++;
1136- }
1137-
1138- if (retryCount != 0 ) {
1139- LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- retried %d TXs. nonLockedTxs.size=%d\n " , __func__,
1140- retryCount, WITH_LOCK (cs_nonLocked, return nonLockedTxs.size ()));
1141- }
1142- }
1143-
1144801bool CInstantSendManager::AlreadyHave (const CInv& inv) const
1145802{
1146803 if (!IsInstantSendEnabled ()) {
@@ -1254,11 +911,6 @@ bool CInstantSendManager::IsInstantSendEnabled() const
1254911 return !fReindex && !fImporting && spork_manager.IsSporkActive (SPORK_2_INSTANTSEND_ENABLED);
1255912}
1256913
1257- bool CInstantSendManager::IsInstantSendMempoolSigningEnabled () const
1258- {
1259- return !fReindex && !fImporting && spork_manager.GetSporkValue (SPORK_2_INSTANTSEND_ENABLED) == 0 ;
1260- }
1261-
1262914bool CInstantSendManager::RejectConflictingBlocks () const
1263915{
1264916 if (!m_mn_sync.IsBlockchainSynced ()) {
0 commit comments