Merge bitcoin/bitcoin#33567: node: change a tx-relay on/off flag to enum

07a926474b node: change a tx-relay on/off flag to enum (Vasil Dimov)

Pull request description:

  Previously the `bool relay` argument to `BroadcastTransaction()` designated:

  ```
  relay=true: add to the mempool and broadcast to all peers
  relay=false: add to the mempool
  ```

  Change this to an `enum`, so it is more readable and easier to extend with a 3rd option. Consider these example call sites:

  ```cpp
  Paint(true);
  // Or
  Paint(/*is_red=*/true);
  ```

  vs

  ```cpp
  Paint(RED);
  ```

  The idea for putting `TxBroadcastMethod` into `node/types.h` by Ryan.

  ---

  This is part of [#29415 Broadcast own transactions only via short-lived Tor or I2P connections](https://github.com/bitcoin/bitcoin/pull/29415). Putting it in its own PR to reduce the size of #29415 and because it does not logically depend on the other commits from there.

ACKs for top commit:
  optout21:
    ACK 07a926474b
  kevkevinpal:
    ACK [07a9264](07a926474b)
  laanwj:
    Concept and code review ACK 07a926474b. Agree with the general reasoning and the change in #29415 is a valid motivation to change this interface.
  glozow:
    utACK 07a926474b

Tree-SHA512: ec8f6fa56a6d2422a0fbd5941ff2792685e8d8e7b9dd50bba9f3e21ed9b4a4a26c89b0d7e4895d48f30b7a635f2eddd894af26b5266410952cbdaf5c40b42966
This commit is contained in:
merge-script
2025-10-31 14:59:58 -04:00
10 changed files with 116 additions and 44 deletions

View File

@@ -31,7 +31,12 @@ static TransactionError HandleATMPError(const TxValidationState& state, std::str
}
}
TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
TransactionError BroadcastTransaction(NodeContext& node,
const CTransactionRef tx,
std::string& err_string,
const CAmount& max_tx_fee,
TxBroadcast broadcast_method,
bool wait_callback)
{
// BroadcastTransaction can be called by RPC or by the wallet.
// chainman, mempool and peerman are initialized before the RPC server and wallet are started
@@ -62,7 +67,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
// There's already a transaction in the mempool with this txid. Don't
// try to submit this transaction to the mempool (since it'll be
// rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
// transaction if relay=true.
// transaction if broadcast_method is not TxBroadcast::MEMPOOL_NO_BROADCAST.
//
// The mempool transaction may have the same or different witness (and
// wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
@@ -79,18 +84,26 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
return TransactionError::MAX_FEE_EXCEEDED;
}
}
// Try to submit the transaction to the mempool.
const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ false);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
return HandleATMPError(result.m_state, err_string);
}
// Transaction was accepted to the mempool.
switch (broadcast_method) {
case TxBroadcast::MEMPOOL_NO_BROADCAST:
case TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL:
// Try to submit the transaction to the mempool.
{
const MempoolAcceptResult result =
node.chainman->ProcessTransaction(tx, /*test_accept=*/false);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
return HandleATMPError(result.m_state, err_string);
}
}
// Transaction was accepted to the mempool.
if (relay) {
// the mempool tracks locally submitted transactions to make a
// best-effort of initial broadcast
node.mempool->AddUnbroadcastTx(txid);
if (broadcast_method == TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL) {
// the mempool tracks locally submitted transactions to make a
// best-effort of initial broadcast
node.mempool->AddUnbroadcastTx(txid);
}
break;
}
if (wait_callback && node.validation_signals) {
@@ -116,8 +129,12 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
promise.get_future().wait();
}
if (relay) {
switch (broadcast_method) {
case TxBroadcast::MEMPOOL_NO_BROADCAST:
break;
case TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL:
node.peerman->RelayTransaction(txid, wtxid);
break;
}
return TransactionError::OK;