|
8 | 8 | #include <node/mempool_persist.h> |
9 | 9 |
|
10 | 10 | #include <chainparams.h> |
| 11 | +#include <common/args.h> |
11 | 12 | #include <consensus/validation.h> |
12 | 13 | #include <core_io.h> |
13 | 14 | #include <kernel/mempool_entry.h> |
14 | 15 | #include <net_processing.h> |
| 16 | +#include <netbase.h> // for g_reachable_nets |
15 | 17 | #include <node/mempool_persist_args.h> |
16 | 18 | #include <node/types.h> |
17 | 19 | #include <policy/rbf.h> |
@@ -44,11 +46,21 @@ static RPCHelpMan sendrawtransaction() |
44 | 46 | { |
45 | 47 | return RPCHelpMan{ |
46 | 48 | "sendrawtransaction", |
47 | | - "Submit a raw transaction (serialized, hex-encoded) to local node and network.\n" |
48 | | - "\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n" |
49 | | - "for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n" |
50 | | - "nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n" |
| 49 | + "Submit a raw transaction (serialized, hex-encoded) to the network.\n" |
| 50 | + |
| 51 | + "\nIf -privatebroadcast is disabled, then the transaction will be put into the\n" |
| 52 | + "local mempool of the node and will be sent unconditionally to all currently\n" |
| 53 | + "connected peers, so using sendrawtransaction for manual rebroadcast will degrade\n" |
| 54 | + "privacy by leaking the transaction's origin, as nodes will normally not\n" |
| 55 | + "rebroadcast non-wallet transactions already in their mempool.\n" |
| 56 | + |
| 57 | + "\nIf -privatebroadcast is enabled, then the transaction will be sent only via\n" |
| 58 | + "dedicated, short-lived connections to Tor or I2P peers or IPv4/IPv6 peers\n" |
| 59 | + "through the Tor network. This conceals the transaction origin. The transaction\n" |
| 60 | + "will only enter the local mempool when it is received back from the network.\n" |
| 61 | + |
51 | 62 | "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_UTXO_SET, may throw if the transaction cannot be added to the mempool.\n" |
| 63 | + |
52 | 64 | "\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n", |
53 | 65 | { |
54 | 66 | {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, |
@@ -98,11 +110,23 @@ static RPCHelpMan sendrawtransaction() |
98 | 110 | std::string err_string; |
99 | 111 | AssertLockNotHeld(cs_main); |
100 | 112 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 113 | + const bool private_broadcast_enabled{gArgs.GetBoolArg("-privatebroadcast", DEFAULT_PRIVATE_BROADCAST)}; |
| 114 | + if (private_broadcast_enabled && |
| 115 | + !g_reachable_nets.Contains(NET_ONION) && |
| 116 | + !g_reachable_nets.Contains(NET_I2P)) { |
| 117 | + throw JSONRPCError(RPC_MISC_ERROR, |
| 118 | + "-privatebroadcast is enabled, but none of the Tor or I2P networks is " |
| 119 | + "reachable. Maybe the location of the Tor proxy couldn't be retrieved " |
| 120 | + "from the Tor daemon at startup. Check whether the Tor daemon is running " |
| 121 | + "and that -torcontrol, -torpassword and -i2psam are configured properly."); |
| 122 | + } |
| 123 | + const auto method = private_broadcast_enabled ? node::TxBroadcast::NO_MEMPOOL_PRIVATE_BROADCAST |
| 124 | + : node::TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL; |
101 | 125 | const TransactionError err = BroadcastTransaction(node, |
102 | 126 | tx, |
103 | 127 | err_string, |
104 | 128 | max_raw_tx_fee, |
105 | | - node::TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL, |
| 129 | + method, |
106 | 130 | /*wait_callback=*/true); |
107 | 131 | if (TransactionError::OK != err) { |
108 | 132 | throw JSONRPCTransactionError(err, err_string); |
|
0 commit comments