| 123 | } |
| 124 | |
| 125 | bool TxDownloadManagerImpl::AlreadyHaveTx(const GenTxid& gtxid, bool include_reconsiderable) |
| 126 | { |
| 127 | const uint256& hash = gtxid.ToUint256(); |
| 128 | |
| 129 | // Never query by txid: it is possible that the transaction in the orphanage has the same |
| 130 | // txid but a different witness, which would give us a false positive result. If we decided |
| 131 | // not to request the transaction based on this result, an attacker could prevent us from |
| 132 | // downloading a transaction by intentionally creating a malleated version of it. While |
| 133 | // only one (or none!) of these transactions can ultimately be confirmed, we have no way of |
| 134 | // discerning which one that is, so the orphanage can store multiple transactions with the |
| 135 | // same txid. |
| 136 | // |
| 137 | // While we won't query by txid, we can try to "guess" what the wtxid is based on the txid. |
| 138 | // A non-segwit transaction's txid == wtxid. Query this txhash "casted" to a wtxid. This will |
| 139 | // help us find non-segwit transactions, saving bandwidth, and should have no false positives. |
| 140 | if (m_orphanage->HaveTx(Wtxid::FromUint256(hash))) return true; |
| 141 | |
| 142 | if (include_reconsiderable && RecentRejectsReconsiderableFilter().contains(hash)) return true; |
| 143 | |
| 144 | if (RecentConfirmedTransactionsFilter().contains(hash)) return true; |
| 145 | |
| 146 | return RecentRejectsFilter().contains(hash) || std::visit([&](const auto& id) { return m_opts.m_mempool.exists(id); }, gtxid); |
| 147 | } |
| 148 | |
| 149 | void TxDownloadManagerImpl::ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo& info) |
| 150 | { |
no test coverage detected