diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 487f88d414..5195a0d18a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3626,10 +3626,25 @@ void PeerManagerImpl::ProcessMessage( LOCK2(cs_main, g_cs_orphans); + if (AlreadyHave(inv)) { + if (pfrom.HasPermission(PF_FORCERELAY)) { + // Always relay transactions received from peers with forcerelay permission, even + // if they were already in the mempool, + // allowing the node to function as a gateway for + // nodes hidden behind it. + if (!m_mempool.exists(tx.GetHash())) { + LogPrintf("Not relaying non-mempool transaction %s from forcerelay peer=%d\n", tx.GetHash().ToString(), pfrom.GetId()); + } else { + LogPrintf("Force relaying tx %s from peer=%d\n", tx.GetHash().ToString(), pfrom.GetId()); + RelayTransaction(tx.GetHash()); + } + } + return; + } + TxValidationState state; - if (!AlreadyHave(inv) && AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, state, ptx, - false /* bypass_limits */)) { + if (AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, state, ptx, false /* bypass_limits */)) { // Process custom txes, this changes AlreadyHave to "true" if (nInvType == MSG_DSTX) { LogPrint(BCLog::COINJOIN, "DSTX -- Masternode transaction accepted, txid=%s, peer=%d\n", @@ -3700,19 +3715,6 @@ void PeerManagerImpl::ProcessMessage( if (RecursiveDynamicUsage(*ptx) < 100000) { AddToCompactExtraTransactions(ptx); } - - if (pfrom.HasPermission(PF_FORCERELAY)) { - // Always relay transactions received from peers with forcerelay permission, even - // if they were already in the mempool, - // allowing the node to function as a gateway for - // nodes hidden behind it. - if (!m_mempool.exists(tx.GetHash())) { - LogPrintf("Not relaying non-mempool transaction %s from forcerelay peer=%d\n", tx.GetHash().ToString(), pfrom.GetId()); - } else { - LogPrintf("Force relaying tx %s from peer=%d\n", tx.GetHash().ToString(), pfrom.GetId()); - RelayTransaction(tx.GetHash()); - } - } } // If a tx has been detected by m_recent_rejects, we will have reached diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py index 3847c2d08c..d2801db92b 100755 --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -143,11 +143,20 @@ class P2PPermissionsTests(BitcoinTestFramework): self.log.debug("Check that node[1] will not send an invalid tx to node[0]") tx.vout[0].nValue += 1 txid = tx.rehash() + # Send the transaction twice. The first time, it'll be rejected by ATMP because it conflicts + # with a mempool transaction. The second time, it'll be in the recentRejects filter. p2p_rebroadcast_wallet.send_txs_and_test( [tx], self.nodes[1], success=False, - reject_reason='Not relaying non-mempool transaction {} from forcerelay peer=0'.format(txid), + reject_reason='{} from peer=0 was not accepted: txn-mempool-conflict'.format(txid) + ) + + p2p_rebroadcast_wallet.send_txs_and_test( + [tx], + self.nodes[1], + success=False, + reject_reason='Not relaying non-mempool transaction {} from forcerelay peer=0'.format(txid) ) def checkpermission(self, args, expectedPermissions, whitelisted):