Repository: bitcoin/bitcoin
File: src/node/transaction.cpp (C++)

Code before:
            // 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.
            //
            // The mempool transaction may have the same or different witness (and
            // wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
            wtxid = mempool_tx->GetWitnessHash();
        } else {
            // Transaction is not already in the mempool.
            if (max_tx_fee > 0) {
                // First, call ATMP with test_accept and check the fee. If ATMP
                // fails here, return error immediately.
                const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
                if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
                    return HandleATMPError(result.m_state, err_string);
                } else if (result.m_base_fees.value() > max_tx_fee) {
                    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.

            if (relay) {
                // the mempool tracks locally submitted transactions to make a
                // best-effort of initial broadcast
                node.mempool->AddUnbroadcastTx(txid);
            }

            if (wait_callback && node.validation_signals) {
                // For transactions broadcast from outside the wallet, make sure
                // that the wallet has been notified of the transaction before
                // continuing.
                //
                // This prevents a race where a user might call sendrawtransaction
                // with a transaction to/from their wallet, immediately call some
                // wallet RPC, and get a stale result because callbacks have not
                // yet been processed.
                node.validation_signals->CallFunctionInValidationInterfaceQueue([&promise] {
                    promise.set_value();
                });
                callback_set = true;
            }
        }
    } // cs_main

    if (callback_set) {

Review comment (suggestion):
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.

```diff
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
index 5da4e878ab..e2d0ba76e2 100644
--- a/src/node/transaction.cpp
+++ b/src/node/transaction.cpp
@@ -49,6 +49,18 @@ TransactionError BroadcastTransaction(NodeContext& node,
     Txid txid = tx->GetHash();
     Wtxid wtxid = tx->GetWitnessHash();
     bool callback_set = false;
+    bool need_add_to_mempool{false};
+    bool need_broadcast{false};
+    switch (broadcast_method) {
+        case ADD_TO_MEMPOOL_NO_BROADCAST:
+            need_add_to_mempool = true;
+            need_broadcast = false;
+            break;
+        case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
+            need_add_to_mempool = true;
+            need_broadcast = true;
+            break;
+    }
 
     {
         LOCK(cs_main);
@@ -85,9 +97,7 @@ TransactionError BroadcastTransaction(NodeContext& node,
                 }
             }
 
-            switch (broadcast_method) {
-            case ADD_TO_MEMPOOL_NO_BROADCAST:
-            case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
+            if (need_add_to_mempool) {
                 // Try to submit the transaction to the mempool.
                 {
                     const MempoolAcceptResult result =
@@ -98,12 +108,11 @@ TransactionError BroadcastTransaction(NodeContext& node,
                 }
                 // Transaction was accepted to the mempool.
 
-                if (broadcast_method == ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL) {
+                if (need_broadcast) {
                     // 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) {
@@ -129,12 +138,8 @@ TransactionError BroadcastTransaction(NodeContext& node,
         promise.get_future().wait();
     }
 
-    switch (broadcast_method) {
-    case ADD_TO_MEMPOOL_NO_BROADCAST:
-        break;
-    case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
+    if (need_broadcast) {
         node.peerman->RelayTransaction(txid, wtxid);
-        break;
     }
 
     return TransactionError::OK;

```

Code after:
            if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_UTXO_SET;
        }

        if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
            // 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 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.
            wtxid = mempool_tx->GetWitnessHash();
        } else {
            // Transaction is not already in the mempool.
            if (max_tx_fee > 0) {
                // First, call ATMP with test_accept and check the fee. If ATMP
                // fails here, return error immediately.
                const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
                if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
                    return HandleATMPError(result.m_state, err_string);
                } else if (result.m_base_fees.value() > max_tx_fee) {
                    return TransactionError::MAX_FEE_EXCEEDED;
                }
            }

            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 (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) {
                // For transactions broadcast from outside the wallet, make sure
                // that the wallet has been notified of the transaction before
                // continuing.
                //