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

pull vasild wants to merge 1 commits into bitcoin:master from vasild:TxBroadcastMethod changing 10 files +116 −44
  1. vasild commented at 3:11 pm on October 7, 2025: contributor

    Previously the bool relay argument to BroadcastTransaction() designated:

    0relay=true: add to the mempool and broadcast to all peers
    1relay=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:

    0Paint(true);
    1// Or
    2Paint(/*is_red=*/true);
    

    vs

    0Paint(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. 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.

  2. DrahtBot commented at 3:11 pm on October 7, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33567.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK optout21, kevkevinpal, laanwj, glozow
    Concept NACK Raimo33

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30343 (wallet, logging: Replace WalletLogPrintf() with LogInfo() by ryanofsky)
    • #29700 (kernel, refactor: return error status on all fatal errors by ryanofsky)
    • #29415 (Broadcast own transactions only via short-lived Tor or I2P connections by vasild)
    • #29278 (Wallet: Add maxfeerate wallet startup option by ismaelsadeeq)
    • #27865 (wallet: Track no-longer-spendable TXOs separately by achow101)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • “wait until callbacks have been processed to avoid stale result due to a sequentially RPC.” -> “wait until callbacks have been processed to avoid stale result due to a sequential RPC.” [“sequentially” is an adverb and misused here; “sequential” (adjective) correctly modifies “RPC” and restores grammatical sense.]

    drahtbot_id_5_m

  3. glozow added the label Refactoring on Oct 7, 2025
  4. in src/interfaces/chain.h:210 in 1197919eab
    206@@ -206,13 +207,19 @@ class Chain
    207     //! Check if transaction has descendants in mempool.
    208     virtual bool hasDescendantsInMempool(const Txid& txid) = 0;
    209 
    210-    //! Transaction is added to memory pool, if the transaction fee is below the
    211-    //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
    212-    //! Return false if the transaction could not be added due to the fee or for another reason.
    213+    //! Consume a local transaction, optionally adding it to the mempool and
    


    andrewtoth commented at 4:17 pm on October 9, 2025:
    The transaction is passed by const ref, so it’s not really “consuming” it. Perhaps “Process a local transaction”?

    vasild commented at 6:58 am on October 15, 2025:
    Done.
  5. in src/node/types.h:106 in 1197919eab
     97@@ -97,6 +98,18 @@ struct BlockCheckOptions {
     98      */
     99     bool check_pow{true};
    100 };
    101+
    102+/**
    103+ * Methods to broadcast a local transaction.
    104+ * Used to influence `BroadcastTransaction()` and its callers.
    105+ */
    106+enum TxBroadcastMethod : uint8_t {
    


    luke-jr commented at 2:17 am on October 10, 2025:
    Probably should use class enums for new things?

    vasild commented at 6:59 am on October 15, 2025:
    Done. Also shortened the names a little bit because now values have to be prefixed by the enum name.

    ajtowns commented at 9:39 am on October 21, 2025:
    (Adding using enum TxBroadcastMethod would keep the type safety without requiring the prefix)
  6. bitcoin deleted a comment on Oct 10, 2025
  7. in src/node/types.h:103 in 1197919eab
     97@@ -97,6 +98,18 @@ struct BlockCheckOptions {
     98      */
     99     bool check_pow{true};
    100 };
    101+
    102+/**
    103+ * Methods to broadcast a local transaction.
    


    kevkevinpal commented at 9:46 pm on October 10, 2025:

    This isn’t a method

    0 * Enum to signal to broadcast a local transaction.
    

    vasild commented at 7:01 am on October 15, 2025:
    It isn’t a C++ method, but is a method, “a way, technique, or process of or for doing something”.

    kevkevinpal commented at 7:03 pm on October 15, 2025:
    gotcha that works then!
  8. in src/node/transaction.cpp:90 in 1197919eab
    91-            }
    92 
    93-            // Transaction was accepted to the mempool.
    94+            switch (broadcast_method) {
    95+            case ADD_TO_MEMPOOL_NO_BROADCAST:
    96+            case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
    


    kevkevinpal commented at 9:49 pm on October 10, 2025:
    Maybe I’m confused but why include this switch statement if previously we didnt need to? I don’t see any if statement for relay here

    vasild commented at 7:03 am on October 15, 2025:
    To make sure that if a new enum value is added it will be handled properly - this snippet will be updated. If it is forgotten, then there will be a compiler warning about unhandled enum value.
  9. in src/wallet/wallet.cpp:1987 in 1197919eab outdated
    1984+        break;
    1985+    case node::ADD_TO_MEMPOOL_NO_BROADCAST:
    1986+        what = "to mempool without broadcast";
    1987+        break;
    1988+    }
    1989+    WalletLogPrintf("Submitting wtx %s %s\n", wtx.GetHash().ToString(), what);
    


    kevkevinpal commented at 9:57 pm on October 10, 2025:

    I don’t think we need the what variable if it’s just used as a string to print directly after the if block

    0    switch (broadcast_method) {
    1    case node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
    2        WalletLogPrintf("Submitting wtx %s to mempool and for broadcast to peers\n", wtx.GetHash().ToString());
    3        break;
    4    case node::ADD_TO_MEMPOOL_NO_BROADCAST:
    5        WalletLogPrintf("Submitting wtx %s to mempool without broadcast\n", wtx.GetHash().ToString());
    6        break;
    7    }
    8    
    

    vasild commented at 7:04 am on October 15, 2025:
    I prefer to avoid duplicating WalletLogPrintf("Submitting wtx...", wtx.GetHash().ToString());

    laanwj commented at 6:36 am on October 21, 2025:
    i also prefer mapping the enum value to a string, instead of repeating the log call.
  10. kevkevinpal commented at 9:59 pm on October 10, 2025: contributor

    Concept ACK

    I think it makes sense to change to an enum instead of just a bool. I added a few comments but I have still yet to pull and build on my local machine

  11. Raimo33 commented at 8:40 am on October 14, 2025: contributor

    Concept NACK.

    what would be a third option? it’s either relay or not.

  12. node: change a tx-relay on/off flag to enum
    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.
    
    Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
    07a926474b
  13. in src/node/transaction.cpp:88 in 1197919eab outdated
    89-            if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
    90-                return HandleATMPError(result.m_state, err_string);
    91-            }
    92 
    93-            // Transaction was accepted to the mempool.
    94+            switch (broadcast_method) {
    


    optout21 commented at 9:26 am on October 14, 2025:

    For better readability, I suggest deciding upfront if mempool-adding and relaying is required respectively, and working accordingly. This avoids repeating case statements. In fact this logic (for a certain enum option mempool-adding/relaying is needed) could go as a method into the enum.

     0diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
     1index 5da4e878ab..e2d0ba76e2 100644
     2--- a/src/node/transaction.cpp
     3+++ b/src/node/transaction.cpp
     4@@ -49,6 +49,18 @@ TransactionError BroadcastTransaction(NodeContext& node,
     5     Txid txid = tx->GetHash();
     6     Wtxid wtxid = tx->GetWitnessHash();
     7     bool callback_set = false;
     8+    bool need_add_to_mempool{false};
     9+    bool need_broadcast{false};
    10+    switch (broadcast_method) {
    11+        case ADD_TO_MEMPOOL_NO_BROADCAST:
    12+            need_add_to_mempool = true;
    13+            need_broadcast = false;
    14+            break;
    15+        case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
    16+            need_add_to_mempool = true;
    17+            need_broadcast = true;
    18+            break;
    19+    }
    20 
    21     {
    22         LOCK(cs_main);
    23@@ -85,9 +97,7 @@ TransactionError BroadcastTransaction(NodeContext& node,
    24                 }
    25             }
    26 
    27-            switch (broadcast_method) {
    28-            case ADD_TO_MEMPOOL_NO_BROADCAST:
    29-            case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
    30+            if (need_add_to_mempool) {
    31                 // Try to submit the transaction to the mempool.
    32                 {
    33                     const MempoolAcceptResult result =
    34@@ -98,12 +108,11 @@ TransactionError BroadcastTransaction(NodeContext& node,
    35                 }
    36                 // Transaction was accepted to the mempool.
    37 
    38-                if (broadcast_method == ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL) {
    39+                if (need_broadcast) {
    40                     // the mempool tracks locally submitted transactions to make a
    41                     // best-effort of initial broadcast
    42                     node.mempool->AddUnbroadcastTx(txid);
    43                 }
    44-                break;
    45             }
    46 
    47             if (wait_callback && node.validation_signals) {
    48@@ -129,12 +138,8 @@ TransactionError BroadcastTransaction(NodeContext& node,
    49         promise.get_future().wait();
    50     }
    51 
    52-    switch (broadcast_method) {
    53-    case ADD_TO_MEMPOOL_NO_BROADCAST:
    54-        break;
    55-    case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
    56+    if (need_broadcast) {
    57         node.peerman->RelayTransaction(txid, wtxid);
    58-        break;
    59     }
    60 
    61     return TransactionError::OK;
    

    vasild commented at 9:52 am on October 15, 2025:
    A boolean need_broadcast does not fit the need for “don’t broadcast”, “broadcast to everybody” and “private broadcast”.
  14. vasild force-pushed on Oct 15, 2025
  15. vasild commented at 6:57 am on October 15, 2025: contributor

    1197919eab...07a926474b: address some suggestions @Raimo33

    what would be a third option? it’s either relay or not.

    I think that this change makes sense even without a third option, see the “paint red” example in the OP. A third option is added in #29415, in commit node: extend node::TxBroadcastMethod with a 3rd option.

  16. optout21 commented at 11:44 am on October 15, 2025: none
    ACK 07a926474b5a6fa1d3d4656362a0117611f6da2f
  17. DrahtBot requested review from kevkevinpal on Oct 15, 2025
  18. kevkevinpal commented at 7:09 pm on October 15, 2025: contributor
    ACK 07a9264
  19. laanwj commented at 6:39 am on October 21, 2025: member
    Concept and code review ACK 07a926474b5a6fa1d3d4656362a0117611f6da2f. Agree with the general reasoning and the change in #29415 is a valid motivation to change this interface.
  20. ajtowns commented at 2:49 pm on October 23, 2025: contributor
    -1 on splitting this out for me; I don’t think this makes #29415 much easier to review, and if you ignore that PR then I’m not sure this is an improvement on /*relay=*/true. Largely agree with that PR though, so no big objection to merging this early, just don’t think it’s super helpful.
  21. in src/interfaces/chain.h:210 in 07a926474b
    206@@ -206,13 +207,19 @@ class Chain
    207     //! Check if transaction has descendants in mempool.
    208     virtual bool hasDescendantsInMempool(const Txid& txid) = 0;
    209 
    210-    //! Transaction is added to memory pool, if the transaction fee is below the
    211-    //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
    212-    //! Return false if the transaction could not be added due to the fee or for another reason.
    213+    //! Process a local transaction, optionally adding it to the mempool and
    


    glozow commented at 5:17 pm on October 31, 2025:
    Awkward part about splitting this off: adding it to mempool is not actually optional at this point in time.
  22. in src/wallet/wallet.cpp:1978 in 07a926474b
    1974@@ -1973,8 +1975,16 @@ bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string
    1975     // Don't try to submit conflicted or confirmed transactions.
    1976     if (GetTxDepthInMainChain(wtx) != 0) return false;
    1977 
    1978-    // Submit transaction to mempool for relay
    1979-    WalletLogPrintf("Submitting wtx %s to mempool for relay\n", wtx.GetHash().ToString());
    1980+    const char* what{""};
    


    glozow commented at 5:19 pm on October 31, 2025:
    nit: “what” is a pretty unhelpful variable name
  23. glozow commented at 6:59 pm on October 31, 2025: member
    utACK 07a926474b5a6fa1d3d4656362a0117611f6da2f
  24. glozow merged this on Oct 31, 2025
  25. glozow closed this on Oct 31, 2025


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-11-02 12:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me