Merge bitcoin/bitcoin#31469: [28.x] 28.1rc2 backports
Some checks failed
CI / ASan + LSan + UBSan + integer, no depends, USDT (push) Has been cancelled
CI / test each commit (push) Has been cancelled
CI / macOS 13 native, x86_64, no depends, sqlite only, gui (push) Has been cancelled
CI / Win64 native, VS 2022 (push) Has been cancelled

5576618152 doc: update release notes for 28.1rc2 (Ava Chow)
01fe07a2ce examples: Generate example bitcoin.conf (Ava Chow)
7ddfcf32da doc: Generate manpages (Ava Chow)
e0b27b234c build: Bump to 28.1rc2 (Ava Chow)
bdc6b3e531 Add release note for #31223 (Martin Zumsande)
a0585b6087 test: add functional test for -port behavior (Martin Zumsande)
bbde830b97 net, init: derive default onion port if a user specified a -port (Martin Zumsande)
227642d5af test: fix MIN macro-redefinition (0xb10c)
b8112cf422 util: use explicit cast in MultiIntBitSet::Fill() (Vasil Dimov)
2835158be0 fuzz: add cstdlib to FuzzedDataProvider (fanquake)

Pull request description:

  Backports:

  * #31223
  * #31448
  * #31431
  * #31419

ACKs for top commit:
  hodlinator:
    re-ACK 5576618152

Tree-SHA512: f99f3c5960f18f6894832c5f9a827f97fd3c6e086670341760ce1b77c304d53136492371c59148f3b4bbcfe2d5428c835fe632c61b229b40f1f6f6cf2b72cdca
This commit is contained in:
Ava Chow 2024-12-17 13:06:08 -05:00
commit 6db725662d
No known key found for this signature in database
GPG key ID: 17565732E08E5E41
20 changed files with 130 additions and 46 deletions

View file

@ -2,7 +2,7 @@ AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 28) define(_CLIENT_VERSION_MAJOR, 28)
define(_CLIENT_VERSION_MINOR, 1) define(_CLIENT_VERSION_MINOR, 1)
define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 1) define(_CLIENT_VERSION_RC, 2)
define(_CLIENT_VERSION_IS_RELEASE, true) define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2024) define(_COPYRIGHT_YEAR, 2024)
define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS,[The %s developers])

View file

@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIN-CLI "1" "December 2024" "bitcoin-cli v28.1.0rc1" "User Commands" .TH BITCOIN-CLI "1" "December 2024" "bitcoin-cli v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoin-cli \- manual page for bitcoin-cli v28.1.0rc1 bitcoin-cli \- manual page for bitcoin-cli v28.1.0rc2
.SH SYNOPSIS .SH SYNOPSIS
.B bitcoin-cli .B bitcoin-cli
[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR [\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR] \fI\,Send command to Bitcoin Core\/\fR
@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v28.1.0rc1
.B bitcoin-cli .B bitcoin-cli
[\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR [\fI\,options\/\fR] \fI\,help <command> Get help for a command\/\fR
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core RPC client version v28.1.0rc1 Bitcoin Core RPC client version v28.1.0rc2
.SH OPTIONS .SH OPTIONS
.HP .HP
\-? \-?

View file

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIN-QT "1" "December 2024" "bitcoin-qt v28.1.0rc1" "User Commands" .TH BITCOIN-QT "1" "December 2024" "bitcoin-qt v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoin-qt \- manual page for bitcoin-qt v28.1.0rc1 bitcoin-qt \- manual page for bitcoin-qt v28.1.0rc2
.SH SYNOPSIS .SH SYNOPSIS
.B bitcoin-qt .B bitcoin-qt
[\fI\,command-line options\/\fR] [\fI\,URI\/\fR] [\fI\,command-line options\/\fR] [\fI\,URI\/\fR]
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core version v28.1.0rc1 Bitcoin Core version v28.1.0rc2
.PP .PP
Optional URI is a Bitcoin address in BIP21 URI format. Optional URI is a Bitcoin address in BIP21 URI format.
.SH OPTIONS .SH OPTIONS
@ -352,7 +352,8 @@ Support filtering of blocks and transaction with bloom filters (default:
.IP .IP
Listen for connections on <port> (default: 8333, testnet3: 18333, Listen for connections on <port> (default: 8333, testnet3: 18333,
testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
I2P (see doc/i2p.md). I2P (see doc/i2p.md). If set to a value x, the default onion
listening port will be set to x+1.
.HP .HP
\fB\-proxy=\fR<ip:port|path> \fB\-proxy=\fR<ip:port|path>
.IP .IP

View file

@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIN-TX "1" "December 2024" "bitcoin-tx v28.1.0rc1" "User Commands" .TH BITCOIN-TX "1" "December 2024" "bitcoin-tx v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoin-tx \- manual page for bitcoin-tx v28.1.0rc1 bitcoin-tx \- manual page for bitcoin-tx v28.1.0rc2
.SH SYNOPSIS .SH SYNOPSIS
.B bitcoin-tx .B bitcoin-tx
[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR [\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded bitcoin transaction\/\fR
@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v28.1.0rc1
.B bitcoin-tx .B bitcoin-tx
[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded bitcoin transaction\/\fR
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core bitcoin\-tx utility version v28.1.0rc1 Bitcoin Core bitcoin\-tx utility version v28.1.0rc2
.SH OPTIONS .SH OPTIONS
.HP .HP
\-? \-?

View file

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIN-UTIL "1" "December 2024" "bitcoin-util v28.1.0rc1" "User Commands" .TH BITCOIN-UTIL "1" "December 2024" "bitcoin-util v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoin-util \- manual page for bitcoin-util v28.1.0rc1 bitcoin-util \- manual page for bitcoin-util v28.1.0rc2
.SH SYNOPSIS .SH SYNOPSIS
.B bitcoin-util .B bitcoin-util
[\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR [\fI\,options\/\fR] [\fI\,commands\/\fR] \fI\,Do stuff\/\fR
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core bitcoin\-util utility version v28.1.0rc1 Bitcoin Core bitcoin\-util utility version v28.1.0rc2
.SH OPTIONS .SH OPTIONS
.HP .HP
\-? \-?

View file

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIN-WALLET "1" "December 2024" "bitcoin-wallet v28.1.0rc1" "User Commands" .TH BITCOIN-WALLET "1" "December 2024" "bitcoin-wallet v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoin-wallet \- manual page for bitcoin-wallet v28.1.0rc1 bitcoin-wallet \- manual page for bitcoin-wallet v28.1.0rc2
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core bitcoin\-wallet version v28.1.0rc1 Bitcoin Core bitcoin\-wallet version v28.1.0rc2
.PP .PP
bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files. bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files.
By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir. By default bitcoin\-wallet will act on wallets in the default mainnet wallet directory in the datadir.

View file

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BITCOIND "1" "December 2024" "bitcoind v28.1.0rc1" "User Commands" .TH BITCOIND "1" "December 2024" "bitcoind v28.1.0rc2" "User Commands"
.SH NAME .SH NAME
bitcoind \- manual page for bitcoind v28.1.0rc1 bitcoind \- manual page for bitcoind v28.1.0rc2
.SH SYNOPSIS .SH SYNOPSIS
.B bitcoind .B bitcoind
[\fI\,options\/\fR] \fI\,Start Bitcoin Core\/\fR [\fI\,options\/\fR] \fI\,Start Bitcoin Core\/\fR
.SH DESCRIPTION .SH DESCRIPTION
Bitcoin Core version v28.1.0rc1 Bitcoin Core version v28.1.0rc2
.SH OPTIONS .SH OPTIONS
.HP .HP
\-? \-?
@ -350,7 +350,8 @@ Support filtering of blocks and transaction with bloom filters (default:
.IP .IP
Listen for connections on <port> (default: 8333, testnet3: 18333, Listen for connections on <port> (default: 8333, testnet3: 18333,
testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
I2P (see doc/i2p.md). I2P (see doc/i2p.md). If set to a value x, the default onion
listening port will be set to x+1.
.HP .HP
\fB\-proxy=\fR<ip:port|path> \fB\-proxy=\fR<ip:port|path>
.IP .IP

View file

@ -46,6 +46,19 @@ Notable changes
### P2P ### P2P
- When the `-port` configuration option is used, the default onion listening port will now
be derived to be that port + 1 instead of being set to a fixed value (8334 on mainnet).
This re-allows setups with multiple local nodes using different `-port` and not using `-bind`,
which would lead to a startup failure in v28.0 due to a port collision.
Note that a `HiddenServicePort` manually configured in `torrc` may need adjustment if used in
connection with the `-port` option.
For example, if you are using `-port=5555` with a non-standard value and not using `-bind=...=onion`,
previously Bitcoin Core would listen for incoming Tor connections on `127.0.0.1:8334`.
Now it would listen on `127.0.0.1:5556` (`-port` plus one). If you configured the hidden service manually
in torrc now you have to change it from `HiddenServicePort 8333 127.0.0.1:8334` to `HiddenServicePort 8333
127.0.0.1:5556`, or configure bitcoind with `-bind=127.0.0.1:8334=onion` to get the previous behavior.
(#31223)
- #30568 addrman: change internal id counting to int64_t - #30568 addrman: change internal id counting to int64_t
### Key ### Key
@ -59,6 +72,8 @@ Notable changes
### Test ### Test
- #31016 test: add missing sync to feature_fee_estimation.py - #31016 test: add missing sync to feature_fee_estimation.py
- #31448 fuzz: add cstdlib to FuzzedDataProvider
- #31419 test: fix MIN macro redefinition
### Doc ### Doc
@ -71,6 +86,7 @@ Notable changes
### Misc ### Misc
- #31267 refactor: Drop deprecated space in `operator""_mst` - #31267 refactor: Drop deprecated space in `operator""_mst`
- #31431 util: use explicit cast in MultiIntBitSet::Fill()
Credits Credits
======= =======

View file

@ -290,7 +290,8 @@
# Listen for connections on <port> (default: 8333, testnet3: 18333, # Listen for connections on <port> (default: 8333, testnet3: 18333,
# testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for # testnet4: 48333, signet: 38333, regtest: 18444). Not relevant for
# I2P (see doc/i2p.md). # I2P (see doc/i2p.md). If set to a value x, the default onion
# listening port will be set to x+1.
#port=<port> #port=<port>
# Connect through SOCKS5 proxy, set -noproxy to disable (default: # Connect through SOCKS5 proxy, set -noproxy to disable (default:
@ -697,9 +698,12 @@
# Options for mainnet # Options for mainnet
[main] [main]
# Options for testnet # Options for testnet3
[test] [test]
# Options for testnet4
[testnet4]
# Options for signet # Options for signet
[signet] [signet]

View file

@ -41,15 +41,15 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const ChainType chain)
{ {
switch (chain) { switch (chain) {
case ChainType::MAIN: case ChainType::MAIN:
return std::make_unique<CBaseChainParams>("", 8332, 8334); return std::make_unique<CBaseChainParams>("", 8332);
case ChainType::TESTNET: case ChainType::TESTNET:
return std::make_unique<CBaseChainParams>("testnet3", 18332, 18334); return std::make_unique<CBaseChainParams>("testnet3", 18332);
case ChainType::TESTNET4: case ChainType::TESTNET4:
return std::make_unique<CBaseChainParams>("testnet4", 48332, 48334); return std::make_unique<CBaseChainParams>("testnet4", 48332);
case ChainType::SIGNET: case ChainType::SIGNET:
return std::make_unique<CBaseChainParams>("signet", 38332, 38334); return std::make_unique<CBaseChainParams>("signet", 38332);
case ChainType::REGTEST: case ChainType::REGTEST:
return std::make_unique<CBaseChainParams>("regtest", 18443, 18445); return std::make_unique<CBaseChainParams>("regtest", 18443);
} }
assert(false); assert(false);
} }

View file

@ -22,15 +22,13 @@ class CBaseChainParams
public: public:
const std::string& DataDir() const { return strDataDir; } const std::string& DataDir() const { return strDataDir; }
uint16_t RPCPort() const { return m_rpc_port; } uint16_t RPCPort() const { return m_rpc_port; }
uint16_t OnionServiceTargetPort() const { return m_onion_service_target_port; }
CBaseChainParams() = delete; CBaseChainParams() = delete;
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port, uint16_t onion_service_target_port) CBaseChainParams(const std::string& data_dir, uint16_t rpc_port)
: m_rpc_port(rpc_port), m_onion_service_target_port(onion_service_target_port), strDataDir(data_dir) {} : m_rpc_port(rpc_port), strDataDir(data_dir) {}
private: private:
const uint16_t m_rpc_port; const uint16_t m_rpc_port;
const uint16_t m_onion_service_target_port;
std::string strDataDir; std::string strDataDir;
}; };

View file

@ -524,7 +524,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), testnet4BaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultChainParams->GetDefaultPort() + 1, testnetChainParams->GetDefaultPort() + 1, testnet4ChainParams->GetDefaultPort() + 1, signetChainParams->GetDefaultPort() + 1, regtestChainParams->GetDefaultPort() + 1), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@ -551,7 +551,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md). If set to a value x, the default onion listening port will be set to x+1.", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
#ifdef HAVE_SOCKADDR_UN #ifdef HAVE_SOCKADDR_UN
argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION); argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION);
#else #else
@ -1852,6 +1852,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
const uint16_t default_bind_port = const uint16_t default_bind_port =
static_cast<uint16_t>(args.GetIntArg("-port", Params().GetDefaultPort())); static_cast<uint16_t>(args.GetIntArg("-port", Params().GetDefaultPort()));
const uint16_t default_bind_port_onion = default_bind_port + 1;
const auto BadPortWarning = [](const char* prefix, uint16_t port) { const auto BadPortWarning = [](const char* prefix, uint16_t port) {
return strprintf(_("%s request to listen on port %u. This port is considered \"bad\" and " return strprintf(_("%s request to listen on port %u. This port is considered \"bad\" and "
"thus it is unlikely that any peer will connect to it. See " "thus it is unlikely that any peer will connect to it. See "
@ -1876,7 +1878,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
const std::string network_type = bind_arg.substr(index + 1); const std::string network_type = bind_arg.substr(index + 1);
if (network_type == "onion") { if (network_type == "onion") {
const std::string truncated_bind_arg = bind_arg.substr(0, index); const std::string truncated_bind_arg = bind_arg.substr(0, index);
bind_addr = Lookup(truncated_bind_arg, BaseParams().OnionServiceTargetPort(), false); bind_addr = Lookup(truncated_bind_arg, default_bind_port_onion, false);
if (bind_addr.has_value()) { if (bind_addr.has_value()) {
connOptions.onion_binds.push_back(bind_addr.value()); connOptions.onion_binds.push_back(bind_addr.value());
continue; continue;
@ -1912,7 +1914,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} else if (!connOptions.vBinds.empty()) { } else if (!connOptions.vBinds.empty()) {
onion_service_target = connOptions.vBinds.front(); onion_service_target = connOptions.vBinds.front();
} else { } else {
onion_service_target = DefaultOnionServiceTarget(); onion_service_target = DefaultOnionServiceTarget(default_bind_port_onion);
connOptions.onion_binds.push_back(onion_service_target); connOptions.onion_binds.push_back(onion_service_target);
} }

View file

@ -18,6 +18,7 @@
#include <climits> #include <climits>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <initializer_list> #include <initializer_list>
#include <limits> #include <limits>

View file

@ -711,9 +711,9 @@ void StopTorControl()
} }
} }
CService DefaultOnionServiceTarget() CService DefaultOnionServiceTarget(uint16_t port)
{ {
struct in_addr onion_service_target; struct in_addr onion_service_target;
onion_service_target.s_addr = htonl(INADDR_LOOPBACK); onion_service_target.s_addr = htonl(INADDR_LOOPBACK);
return {onion_service_target, BaseParams().OnionServiceTargetPort()}; return {onion_service_target, port};
} }

View file

@ -27,7 +27,7 @@ void StartTorControl(CService onion_service_target);
void InterruptTorControl(); void InterruptTorControl();
void StopTorControl(); void StopTorControl();
CService DefaultOnionServiceTarget(); CService DefaultOnionServiceTarget(uint16_t port);
/** Reply from Tor, can be single or multi-line */ /** Reply from Tor, can be single or multi-line */
class TorControlReply class TorControlReply

View file

@ -366,7 +366,7 @@ public:
if (count) { if (count) {
unsigned i = 0; unsigned i = 0;
while (count > LIMB_BITS) { while (count > LIMB_BITS) {
ret.m_val[i++] = ~I{0}; ret.m_val[i++] = I(~I{0});
count -= LIMB_BITS; count -= LIMB_BITS;
} }
ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count); ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count);

60
test/functional/feature_port.py Executable file
View file

@ -0,0 +1,60 @@
#!/usr/bin/env python3
# Copyright (c) 2024-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""
Test the -port option and its interactions with
-bind.
"""
from test_framework.test_framework import (
BitcoinTestFramework,
)
from test_framework.util import (
p2p_port,
)
class PortTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
# Avoid any -bind= on the command line.
self.bind_to_localhost_only = False
self.num_nodes = 1
def run_test(self):
node = self.nodes[0]
node.has_explicit_bind = True
port1 = p2p_port(self.num_nodes)
port2 = p2p_port(self.num_nodes + 5)
self.log.info("When starting with -port, bitcoind binds to it and uses port + 1 for an onion bind")
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port1}', f'Bound to 127.0.0.1:{port1 + 1}']):
self.restart_node(0, extra_args=["-listen", f"-port={port1}"])
self.log.info("When specifying -port multiple times, only the last one is taken")
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port2}', f'Bound to 127.0.0.1:{port2 + 1}'], unexpected_msgs=[f'Bound to 0.0.0.0:{port1}']):
self.restart_node(0, extra_args=["-listen", f"-port={port1}", f"-port={port2}"])
self.log.info("When specifying ports with both -port and -bind, the one from -port is ignored")
with node.assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port2}'], unexpected_msgs=[f'Bound to 0.0.0.0:{port1}']):
self.restart_node(0, extra_args=["-listen", f"-port={port1}", f"-bind=0.0.0.0:{port2}"])
self.log.info("When -bind specifies no port, the values from -port and -bind are combined")
with self.nodes[0].assert_debug_log(expected_msgs=[f'Bound to 0.0.0.0:{port1}']):
self.restart_node(0, extra_args=["-listen", f"-port={port1}", "-bind=0.0.0.0"])
self.log.info("When an onion bind specifies no port, the value from -port, incremented by 1, is taken")
with self.nodes[0].assert_debug_log(expected_msgs=[f'Bound to 127.0.0.1:{port1 + 1}']):
self.restart_node(0, extra_args=["-listen", f"-port={port1}", "-bind=127.0.0.1=onion"])
self.log.info("Invalid values for -port raise errors")
self.stop_node(0)
node.extra_args = ["-listen", "-port=65536"]
node.assert_start_raises_init_error(expected_msg="Error: Invalid port specified in -port: '65536'")
node.extra_args = ["-listen", "-port=0"]
node.assert_start_raises_init_error(expected_msg="Error: Invalid port specified in -port: '0'")
if __name__ == '__main__':
PortTest(__file__).main()

View file

@ -40,7 +40,8 @@ net_tracepoints_program = """
MAX_MSG_TYPE_LENGTH, MAX_MSG_TYPE_LENGTH,
MAX_MSG_DATA_LENGTH MAX_MSG_DATA_LENGTH
) + """ ) + """
#define MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) // A min() macro. Prefixed with _TRACEPOINT_TEST to avoid collision with other MIN macros.
#define _TRACEPOINT_TEST_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
struct p2p_message struct p2p_message
{ {
@ -60,7 +61,7 @@ int trace_inbound_message(struct pt_regs *ctx) {
bpf_usdt_readarg_p(3, ctx, &msg.peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH); bpf_usdt_readarg_p(3, ctx, &msg.peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH);
bpf_usdt_readarg_p(4, ctx, &msg.msg_type, MAX_MSG_TYPE_LENGTH); bpf_usdt_readarg_p(4, ctx, &msg.msg_type, MAX_MSG_TYPE_LENGTH);
bpf_usdt_readarg(5, ctx, &msg.msg_size); bpf_usdt_readarg(5, ctx, &msg.msg_size);
bpf_usdt_readarg_p(6, ctx, &msg.msg, MIN(msg.msg_size, MAX_MSG_DATA_LENGTH)); bpf_usdt_readarg_p(6, ctx, &msg.msg, _TRACEPOINT_TEST_MIN(msg.msg_size, MAX_MSG_DATA_LENGTH));
inbound_messages.perf_submit(ctx, &msg, sizeof(msg)); inbound_messages.perf_submit(ctx, &msg, sizeof(msg));
return 0; return 0;
} }
@ -73,7 +74,7 @@ int trace_outbound_message(struct pt_regs *ctx) {
bpf_usdt_readarg_p(3, ctx, &msg.peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH); bpf_usdt_readarg_p(3, ctx, &msg.peer_conn_type, MAX_PEER_CONN_TYPE_LENGTH);
bpf_usdt_readarg_p(4, ctx, &msg.msg_type, MAX_MSG_TYPE_LENGTH); bpf_usdt_readarg_p(4, ctx, &msg.msg_type, MAX_MSG_TYPE_LENGTH);
bpf_usdt_readarg(5, ctx, &msg.msg_size); bpf_usdt_readarg(5, ctx, &msg.msg_size);
bpf_usdt_readarg_p(6, ctx, &msg.msg, MIN(msg.msg_size, MAX_MSG_DATA_LENGTH)); bpf_usdt_readarg_p(6, ctx, &msg.msg, _TRACEPOINT_TEST_MIN(msg.msg_size, MAX_MSG_DATA_LENGTH));
outbound_messages.perf_submit(ctx, &msg, sizeof(msg)); outbound_messages.perf_submit(ctx, &msg, sizeof(msg));
return 0; return 0;
}; };

View file

@ -220,10 +220,9 @@ class TestNode():
extra_args = self.extra_args extra_args = self.extra_args
# If listening and no -bind is given, then bitcoind would bind P2P ports on # If listening and no -bind is given, then bitcoind would bind P2P ports on
# 0.0.0.0:P and 127.0.0.1:18445 (for incoming Tor connections), where P is # 0.0.0.0:P and 127.0.0.1:P+1 (for incoming Tor connections), where P is
# a unique port chosen by the test framework and configured as port=P in # a unique port chosen by the test framework and configured as port=P in
# bitcoin.conf. To avoid collisions on 127.0.0.1:18445, change it to # bitcoin.conf. To avoid collisions, change it to 127.0.0.1:tor_port().
# 127.0.0.1:tor_port().
will_listen = all(e != "-nolisten" and e != "-listen=0" for e in extra_args) will_listen = all(e != "-nolisten" and e != "-listen=0" for e in extra_args)
has_explicit_bind = self.has_explicit_bind or any(e.startswith("-bind=") for e in extra_args) has_explicit_bind = self.has_explicit_bind or any(e.startswith("-bind=") for e in extra_args)
if will_listen and not has_explicit_bind: if will_listen and not has_explicit_bind:

View file

@ -335,6 +335,7 @@ BASE_SCRIPTS = [
'feature_minchainwork.py', 'feature_minchainwork.py',
'rpc_estimatefee.py', 'rpc_estimatefee.py',
'rpc_getblockstats.py', 'rpc_getblockstats.py',
'feature_port.py',
'feature_bind_port_externalip.py', 'feature_bind_port_externalip.py',
'wallet_create_tx.py --legacy-wallet', 'wallet_create_tx.py --legacy-wallet',
'wallet_send.py --legacy-wallet', 'wallet_send.py --legacy-wallet',