mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
init: introduce a new option to enable/disable private broadcast
Co-authored-by: brunoerg <brunoely.gc@gmail.com> Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
This commit is contained in:
41
src/init.cpp
41
src/init.cpp
@@ -670,6 +670,15 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||
OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
|
||||
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-privatebroadcast",
|
||||
strprintf(
|
||||
"Broadcast transactions submitted via sendrawtransaction RPC using short-lived "
|
||||
"connections through the Tor or I2P networks, without putting them in the mempool first. "
|
||||
"Transactions submitted through the wallet are not affected by this option "
|
||||
"(default: %u)",
|
||||
DEFAULT_PRIVATE_BROADCAST),
|
||||
ArgsManager::ALLOW_ANY,
|
||||
OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
|
||||
@@ -1732,13 +1741,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
}
|
||||
}
|
||||
|
||||
const bool listenonion{args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)};
|
||||
if (onion_proxy.IsValid()) {
|
||||
SetProxy(NET_ONION, onion_proxy);
|
||||
} else {
|
||||
// If -listenonion is set, then we will (try to) connect to the Tor control port
|
||||
// later from the torcontrol thread and may retrieve the onion proxy from there.
|
||||
const bool listenonion_disabled{!args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)};
|
||||
if (onlynet_used_with_onion && listenonion_disabled) {
|
||||
if (onlynet_used_with_onion && !listenonion) {
|
||||
return InitError(
|
||||
_("Outbound connections restricted to Tor (-onlynet=onion) but the proxy for "
|
||||
"reaching the Tor network is not provided: none of -proxy, -onion or "
|
||||
@@ -2119,7 +2128,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
connOptions.onion_binds.push_back(onion_service_target);
|
||||
}
|
||||
|
||||
if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) {
|
||||
if (listenonion) {
|
||||
if (connOptions.onion_binds.size() > 1) {
|
||||
InitWarning(strprintf(_("More than one onion bind address is provided. Using %s "
|
||||
"for the automatically created Tor onion service."),
|
||||
@@ -2192,6 +2201,32 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
conflict->ToStringAddrPort()));
|
||||
}
|
||||
|
||||
if (args.GetBoolArg("-privatebroadcast", DEFAULT_PRIVATE_BROADCAST)) {
|
||||
// If -listenonion is set, then NET_ONION may not be reachable now
|
||||
// but may become reachable later, thus only error here if it is not
|
||||
// reachable and will not become reachable for sure.
|
||||
const bool onion_may_become_reachable{listenonion && (!args.IsArgSet("-onlynet") || onlynet_used_with_onion)};
|
||||
if (!g_reachable_nets.Contains(NET_I2P) &&
|
||||
!g_reachable_nets.Contains(NET_ONION) &&
|
||||
!onion_may_become_reachable) {
|
||||
return InitError(_("Private broadcast of own transactions requested (-privatebroadcast), "
|
||||
"but none of Tor or I2P networks is reachable"));
|
||||
}
|
||||
if (!connOptions.m_use_addrman_outgoing) {
|
||||
return InitError(_("Private broadcast of own transactions requested (-privatebroadcast), "
|
||||
"but -connect is also configured. They are incompatible because the "
|
||||
"private broadcast needs to open new connections to randomly "
|
||||
"chosen Tor or I2P peers. Consider using -maxconnections=0 -addnode=... "
|
||||
"instead"));
|
||||
}
|
||||
if (!proxyRandomize && (g_reachable_nets.Contains(NET_ONION) || onion_may_become_reachable)) {
|
||||
InitWarning(_("Private broadcast of own transactions requested (-privatebroadcast) and "
|
||||
"-proxyrandomize is disabled. Tor circuits for private broadcast connections "
|
||||
"may be correlated to other connections over Tor. For maximum privacy set "
|
||||
"-proxyrandomize=1."));
|
||||
}
|
||||
}
|
||||
|
||||
if (!node.connman->Start(scheduler, connOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ static const std::string DEFAULT_MAX_UPLOAD_TARGET{"0M"};
|
||||
static const bool DEFAULT_BLOCKSONLY = false;
|
||||
/** -peertimeout default */
|
||||
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT = 60;
|
||||
/** Default for -privatebroadcast. */
|
||||
static constexpr bool DEFAULT_PRIVATE_BROADCAST{false};
|
||||
/** Number of file descriptors required for message capture **/
|
||||
static const int NUM_FDS_MESSAGE_CAPTURE = 1;
|
||||
/** Interval for ASMap Health Check **/
|
||||
|
||||
@@ -411,6 +411,29 @@ class ConfArgsTest(BitcoinTestFramework):
|
||||
self.restart_node(0, extra_args=[connect_arg, '-dnsseed', '-proxy=localhost:1080'])
|
||||
self.stop_node(0)
|
||||
|
||||
def test_privatebroadcast(self):
|
||||
self.log.info("Test that an invalid usage of -privatebroadcast throws an init error")
|
||||
self.stop_node(0)
|
||||
# -privatebroadcast init error: Tor/I2P not reachable at startup
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=["-privatebroadcast"],
|
||||
expected_msg=(
|
||||
"Error: Private broadcast of own transactions requested (-privatebroadcast), "
|
||||
"but none of Tor or I2P networks is reachable"))
|
||||
# -privatebroadcast init error: incompatible with -connect
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=["-privatebroadcast", "-connect=127.0.0.1:8333", "-onion=127.0.0.1:9050"],
|
||||
expected_msg=(
|
||||
"Error: Private broadcast of own transactions requested (-privatebroadcast), but -connect is also configured. "
|
||||
"They are incompatible because the private broadcast needs to open new connections to randomly "
|
||||
"chosen Tor or I2P peers. Consider using -maxconnections=0 -addnode=... instead"))
|
||||
# Warning case: private broadcast allowed, but -proxyrandomize=0 triggers a privacy warning
|
||||
self.start_node(0, extra_args=["-privatebroadcast", "-onion=127.0.0.1:9050", "-proxyrandomize=0"])
|
||||
self.stop_node(0, expected_stderr=(
|
||||
"Warning: Private broadcast of own transactions requested (-privatebroadcast) and "
|
||||
"-proxyrandomize is disabled. Tor circuits for private broadcast connections may "
|
||||
"be correlated to other connections over Tor. For maximum privacy set -proxyrandomize=1."))
|
||||
|
||||
def test_ignored_conf(self):
|
||||
self.log.info('Test error is triggered when the datadir in use contains a bitcoin.conf file that would be ignored '
|
||||
'because a conflicting -conf file argument is passed.')
|
||||
@@ -496,6 +519,7 @@ class ConfArgsTest(BitcoinTestFramework):
|
||||
self.test_seed_peers()
|
||||
self.test_networkactive()
|
||||
self.test_connect_with_seednode()
|
||||
self.test_privatebroadcast()
|
||||
|
||||
self.test_dir_config()
|
||||
self.test_negated_config()
|
||||
|
||||
Reference in New Issue
Block a user