Repository: bitcoin/bitcoin
File: src/txrequest.h (C/C++)

Code before:
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_TXREQUEST_H
#define BITCOIN_TXREQUEST_H

#include <primitives/transaction.h>
#include <net.h>
#include <uint256.h>

#include <chrono>
#include <cstdint>
#include <memory>
#include <vector>

/** Data structure to keep track of, and schedule, transaction downloads from peers.
 *
 * === Specification ===
 *
 * We keep track of which peers have announced which transactions, and use that to determine which requests
 * should go to which peer, when, and in what order.
 *
 * The following information is tracked per peer/tx combination ("announcement"):
 * - Which peer announced it (through their NodeId)
 * - The txid or wtxid of the transaction (collectively called "txhash" in what follows)
 * - Whether it was a tx or wtx announcement (see BIP339).
 * - What the earliest permitted time is that that transaction can be requested from that peer (called "reqtime").
 * - Whether it's from a "preferred" peer or not. Which announcements get this flag is determined by the caller, but
 *   this is designed for outbound peers, or other peers that we have a higher level of trust in. Even when the
 *   peers' preferredness changes, the preferred flag of existing announcements from that peer won't change.
 * - Whether or not the transaction was requested already, and if so, when it times out (called "expiry").
 * - Whether or not the transaction request failed already (timed out, or invalid transaction or NOTFOUND was
 *   received).
 *
 * Transaction requests are then assigned to peers, following these rules:
 *
 * - No transaction is requested as long as another request for the same txhash is outstanding (it needs to fail
 *   first by passing expiry, or a NOTFOUND or invalid transaction has to be received for it).
 *
 *   Rationale: to avoid wasting bandwidth on multiple copies of the same transaction. Note that this only works
 *              per txhash, so if the same transaction is announced both through txid and wtxid, we have no means
 *              to prevent fetching both (the caller can however mitigate this by delaying one, see further).
 *
 * - The same transaction is never requested twice from the same peer, unless the announcement was forgotten in
 *   between, and re-announced. Announcements are forgotten only:
 *   - If a peer goes offline, all its announcements are forgotten.
 *   - If a transaction has been successfully received, or is otherwise no longer needed, the caller can call
 *     ForgetTxHash, which removes all announcements across all peers with the specified txhash.
 *   - If for a given txhash only already-failed announcements remain, they are all forgotten.
 *
 *   Rationale: giving a peer multiple chances to announce a transaction would allow them to bias requests in their
 *              favor, worsening transaction censoring attacks. The flip side is that as long as an attacker manages

Review comment (suggestion):
nit: I suggest making it even more concise:
`The earliest permissible request time for that transaction from that peer ("reqtime").`

Code after:
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_TXREQUEST_H
#define BITCOIN_TXREQUEST_H

#include <primitives/transaction.h>
#include <net.h>
#include <uint256.h>

#include <chrono>
#include <cstdint>
#include <memory>
#include <vector>

/** Data structure to keep track of, and schedule, transaction downloads from peers.
 *
 * === Specification ===
 *
 * We keep track of which peers have announced which transactions, and use that to determine which requests
 * should go to which peer, when, and in what order.
 *
 * The following information is tracked per peer/tx combination ("announcement"):
 * - Which peer announced it (through their NodeId)
 * - The txid or wtxid of the transaction (collectively called "txhash" in what follows)
 * - Whether it was a tx or wtx announcement (see BIP339).
 * - What the earliest permitted time is that the transaction can be requested from that peer (called "reqtime").
 * - Whether it's from a "preferred" peer or not. Which announcements get this flag is determined by the caller, but
 *   this is designed for outbound peers, or other peers that we have a higher level of trust in. Even when the
 *   peers' preferredness changes, the preferred flag of existing announcements from that peer won't change.
 * - Whether or not the transaction was requested already, and if so, when it times out (called "expiry").
 * - Whether or not the transaction request failed already (timed out, or invalid transaction or NOTFOUND was
 *   received).
 *
 * Transaction requests are then assigned to peers, following these rules:
 *
 * - No transaction is requested as long as another request for the same txhash is outstanding (it needs to fail
 *   first by passing expiry, or a NOTFOUND or invalid transaction has to be received for it).
 *
 *   Rationale: to avoid wasting bandwidth on multiple copies of the same transaction. Note that this only works
 *              per txhash, so if the same transaction is announced both through txid and wtxid, we have no means
 *              to prevent fetching both (the caller can however mitigate this by delaying one, see further).
 *
 * - The same transaction is never requested twice from the same peer, unless the announcement was forgotten in
 *   between, and re-announced. Announcements are forgotten only:
 *   - If a peer goes offline, all its announcements are forgotten.
 *   - If a transaction has been successfully received, or is otherwise no longer needed, the caller can call
 *     ForgetTxHash, which removes all announcements across all peers with the specified txhash.
 *   - If for a given txhash only already-failed announcements remain, they are all forgotten.
 *
 *   Rationale: giving a peer multiple chances to announce a transaction would allow them to bias requests in their
 *              favor, worsening transaction censoring attacks. The flip side is that as long as an attacker manages