@@ -582,6 +582,15 @@ class PeerManagerImpl final : public PeerManager
582
582
*/
583
583
bool MaybeDiscourageAndDisconnect (CNode& pnode, Peer& peer);
584
584
585
+ /* * Handle a transaction whose result was not MempoolAcceptResult::ResultType::VALID.
586
+ * @param[in] maybe_add_extra_compact_tx Whether this tx should be added to vExtraTxnForCompact.
587
+ * Set to false if the tx has already been rejected before,
588
+ * e.g. is an orphan, to avoid adding duplicate entries.
589
+ * Updates m_txrequest, m_recent_rejects, m_orphanage, and vExtraTxnForCompact. */
590
+ void ProcessInvalidTx (NodeId nodeid, const CTransactionRef& tx, const TxValidationState& result,
591
+ bool maybe_add_extra_compact_tx)
592
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
593
+
585
594
/* * Handle a transaction whose result was MempoolAcceptResult::ResultType::VALID.
586
595
* Updates m_txrequest, m_orphanage, and vExtraTxnForCompact. Also queues the tx for relay. */
587
596
void ProcessValidTx (NodeId nodeid, const CTransactionRef& tx, const std::list<CTransactionRef>& replaced_transactions)
@@ -3037,6 +3046,63 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
3037
3046
return ;
3038
3047
}
3039
3048
3049
+ void PeerManagerImpl::ProcessInvalidTx (NodeId nodeid, const CTransactionRef& ptx, const TxValidationState& state,
3050
+ bool maybe_add_extra_compact_tx)
3051
+ {
3052
+ AssertLockNotHeld (m_peer_mutex);
3053
+ AssertLockHeld (g_msgproc_mutex);
3054
+ AssertLockHeld (cs_main);
3055
+
3056
+ LogDebug (BCLog::MEMPOOLREJ, " %s (wtxid=%s) from peer=%d was not accepted: %s\n " ,
3057
+ ptx->GetHash ().ToString (),
3058
+ ptx->GetWitnessHash ().ToString (),
3059
+ nodeid,
3060
+ state.ToString ());
3061
+
3062
+ if (state.GetResult () == TxValidationResult::TX_MISSING_INPUTS) {
3063
+ return ;
3064
+ } else if (state.GetResult () != TxValidationResult::TX_WITNESS_STRIPPED) {
3065
+ // We can add the wtxid of this transaction to our reject filter.
3066
+ // Do not add txids of witness transactions or witness-stripped
3067
+ // transactions to the filter, as they can have been malleated;
3068
+ // adding such txids to the reject filter would potentially
3069
+ // interfere with relay of valid transactions from peers that
3070
+ // do not support wtxid-based relay. See
3071
+ // https://github.com/bitcoin/bitcoin/issues/8279 for details.
3072
+ // We can remove this restriction (and always add wtxids to
3073
+ // the filter even for witness stripped transactions) once
3074
+ // wtxid-based relay is broadly deployed.
3075
+ // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
3076
+ // for concerns around weakening security of unupgraded nodes
3077
+ // if we start doing this too early.
3078
+ m_recent_rejects.insert (ptx->GetWitnessHash ().ToUint256 ());
3079
+ m_txrequest.ForgetTxHash (ptx->GetWitnessHash ());
3080
+ // If the transaction failed for TX_INPUTS_NOT_STANDARD,
3081
+ // then we know that the witness was irrelevant to the policy
3082
+ // failure, since this check depends only on the txid
3083
+ // (the scriptPubKey being spent is covered by the txid).
3084
+ // Add the txid to the reject filter to prevent repeated
3085
+ // processing of this transaction in the event that child
3086
+ // transactions are later received (resulting in
3087
+ // parent-fetching by txid via the orphan-handling logic).
3088
+ if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && ptx->HasWitness ()) {
3089
+ m_recent_rejects.insert (ptx->GetHash ().ToUint256 ());
3090
+ m_txrequest.ForgetTxHash (ptx->GetHash ());
3091
+ }
3092
+ if (maybe_add_extra_compact_tx && RecursiveDynamicUsage (*ptx) < 100000 ) {
3093
+ AddToCompactExtraTransactions (ptx);
3094
+ }
3095
+ }
3096
+
3097
+ MaybePunishNodeForTx (nodeid, state);
3098
+
3099
+ // If the tx failed in ProcessOrphanTx, it should be removed from the orphanage unless the
3100
+ // tx was still missing inputs. If the tx was not in the orphanage, EraseTx does nothing and returns 0.
3101
+ if (Assume (state.GetResult () != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx (ptx->GetHash ()) > 0 ) {
3102
+ LogDebug (BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n " , ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
3103
+ }
3104
+ }
3105
+
3040
3106
void PeerManagerImpl::ProcessValidTx (NodeId nodeid, const CTransactionRef& tx, const std::list<CTransactionRef>& replaced_transactions)
3041
3107
{
3042
3108
AssertLockNotHeld (m_peer_mutex);
@@ -3085,53 +3151,18 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
3085
3151
ProcessValidTx (peer.m_id , porphanTx, result.m_replaced_transactions .value_or (empty_replacement_list));
3086
3152
return true ;
3087
3153
} else if (state.GetResult () != TxValidationResult::TX_MISSING_INPUTS) {
3088
- if (state.IsInvalid ()) {
3089
- LogPrint (BCLog::TXPACKAGES, " invalid orphan tx %s (wtxid=%s) from peer=%d. %s\n " ,
3090
- orphanHash.ToString (),
3091
- orphan_wtxid.ToString (),
3092
- peer.m_id ,
3093
- state.ToString ());
3094
- LogPrint (BCLog::MEMPOOLREJ, " %s (wtxid=%s) from peer=%d was not accepted: %s\n " ,
3095
- orphanHash.ToString (),
3096
- orphan_wtxid.ToString (),
3097
- peer.m_id ,
3098
- state.ToString ());
3099
- // Maybe punish peer that gave us an invalid orphan tx
3100
- MaybePunishNodeForTx (peer.m_id , state);
3101
- }
3102
- // Has inputs but not accepted to mempool
3103
- // Probably non-standard or insufficient fee
3104
- LogPrint (BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n " , orphanHash.ToString (), orphan_wtxid.ToString ());
3105
- if (state.GetResult () != TxValidationResult::TX_WITNESS_STRIPPED) {
3106
- // We can add the wtxid of this transaction to our reject filter.
3107
- // Do not add txids of witness transactions or witness-stripped
3108
- // transactions to the filter, as they can have been malleated;
3109
- // adding such txids to the reject filter would potentially
3110
- // interfere with relay of valid transactions from peers that
3111
- // do not support wtxid-based relay. See
3112
- // https://github.com/bitcoin/bitcoin/issues/8279 for details.
3113
- // We can remove this restriction (and always add wtxids to
3114
- // the filter even for witness stripped transactions) once
3115
- // wtxid-based relay is broadly deployed.
3116
- // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
3117
- // for concerns around weakening security of unupgraded nodes
3118
- // if we start doing this too early.
3119
- m_recent_rejects.insert (porphanTx->GetWitnessHash ().ToUint256 ());
3120
- // If the transaction failed for TX_INPUTS_NOT_STANDARD,
3121
- // then we know that the witness was irrelevant to the policy
3122
- // failure, since this check depends only on the txid
3123
- // (the scriptPubKey being spent is covered by the txid).
3124
- // Add the txid to the reject filter to prevent repeated
3125
- // processing of this transaction in the event that child
3126
- // transactions are later received (resulting in
3127
- // parent-fetching by txid via the orphan-handling logic).
3128
- if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->HasWitness ()) {
3129
- // We only add the txid if it differs from the wtxid, to
3130
- // avoid wasting entries in the rolling bloom filter.
3131
- m_recent_rejects.insert (porphanTx->GetHash ().ToUint256 ());
3132
- }
3154
+ LogPrint (BCLog::TXPACKAGES, " invalid orphan tx %s (wtxid=%s) from peer=%d. %s\n " ,
3155
+ orphanHash.ToString (),
3156
+ orphan_wtxid.ToString (),
3157
+ peer.m_id ,
3158
+ state.ToString ());
3159
+
3160
+ if (Assume (state.IsInvalid () &&
3161
+ state.GetResult () != TxValidationResult::TX_UNKNOWN &&
3162
+ state.GetResult () != TxValidationResult::TX_NO_MEMPOOL &&
3163
+ state.GetResult () != TxValidationResult::TX_RESULT_UNSET)) {
3164
+ ProcessInvalidTx (peer.m_id , porphanTx, state, /* maybe_add_extra_compact_tx=*/ false );
3133
3165
}
3134
- m_orphanage.EraseTx (orphanHash);
3135
3166
return true ;
3136
3167
}
3137
3168
}
@@ -4363,48 +4394,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
4363
4394
m_txrequest.ForgetTxHash (tx.GetHash ());
4364
4395
m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
4365
4396
}
4366
- } else {
4367
- if (state.GetResult () != TxValidationResult::TX_WITNESS_STRIPPED) {
4368
- // We can add the wtxid of this transaction to our reject filter.
4369
- // Do not add txids of witness transactions or witness-stripped
4370
- // transactions to the filter, as they can have been malleated;
4371
- // adding such txids to the reject filter would potentially
4372
- // interfere with relay of valid transactions from peers that
4373
- // do not support wtxid-based relay. See
4374
- // https://github.com/bitcoin/bitcoin/issues/8279 for details.
4375
- // We can remove this restriction (and always add wtxids to
4376
- // the filter even for witness stripped transactions) once
4377
- // wtxid-based relay is broadly deployed.
4378
- // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
4379
- // for concerns around weakening security of unupgraded nodes
4380
- // if we start doing this too early.
4381
- m_recent_rejects.insert (tx.GetWitnessHash ().ToUint256 ());
4382
- m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
4383
- // If the transaction failed for TX_INPUTS_NOT_STANDARD,
4384
- // then we know that the witness was irrelevant to the policy
4385
- // failure, since this check depends only on the txid
4386
- // (the scriptPubKey being spent is covered by the txid).
4387
- // Add the txid to the reject filter to prevent repeated
4388
- // processing of this transaction in the event that child
4389
- // transactions are later received (resulting in
4390
- // parent-fetching by txid via the orphan-handling logic).
4391
- if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.HasWitness ()) {
4392
- m_recent_rejects.insert (tx.GetHash ().ToUint256 ());
4393
- m_txrequest.ForgetTxHash (tx.GetHash ());
4394
- }
4395
- if (RecursiveDynamicUsage (*ptx) < 100000 ) {
4396
- AddToCompactExtraTransactions (ptx);
4397
- }
4398
- }
4399
4397
}
4400
-
4401
4398
if (state.IsInvalid ()) {
4402
- LogPrint (BCLog::MEMPOOLREJ, " %s (wtxid=%s) from peer=%d was not accepted: %s\n " ,
4403
- tx.GetHash ().ToString (),
4404
- tx.GetWitnessHash ().ToString (),
4405
- pfrom.GetId (),
4406
- state.ToString ());
4407
- MaybePunishNodeForTx (pfrom.GetId (), state);
4399
+ ProcessInvalidTx (pfrom.GetId (), ptx, state, /* maybe_add_extra_compact_tx=*/ true );
4408
4400
}
4409
4401
return ;
4410
4402
}
0 commit comments