Skip to content

Commit 37a4a30

Browse files
Merge pull request #5329 from kittywhiskers/dashcli_bps
backport: merge bitcoin#18574, bitcoin#18653, bitcoin#18691, bitcoin#18724, bitcoin#18594, bitcoin#19991, bitcoin#19133, bitcoin#19643, bitcoin#20002, bitcoin#19354, partial bitcoin#19998 (cli backports)
2 parents a91eace + 55621af commit 37a4a30

23 files changed

+799
-179
lines changed

doc/release-notes-18594.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## CLI
2+
3+
The `dash-cli -getinfo` command now displays the wallet name and balance for
4+
each of the loaded wallets when more than one is loaded (e.g. in multiwallet
5+
mode) and a wallet is not specified with `-rpcwallet`. (#18594)

doc/tor.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ config file): *Needed for Tor version 0.2.7.0 and older versions of Tor only. Fo
5353
versions of Tor see [Section 4](#4-automatically-listen-on-tor).*
5454

5555
HiddenServiceDir /var/lib/tor/dashcore-service/
56-
HiddenServicePort 9999 127.0.0.1:9999
57-
HiddenServicePort 19999 127.0.0.1:19999
56+
HiddenServicePort 9999 127.0.0.1:9996
57+
HiddenServicePort 19999 127.0.0.1:19996
5858

59-
The directory can be different of course, but (both) port numbers should be equal to
60-
your dashd's P2P listen port (9999 by default).
59+
The directory can be different of course, but virtual port numbers should be equal to
60+
your dashd's P2P listen port (9999 by default), and target addresses and ports
61+
should be equal to binding address and port for inbound Tor connections (127.0.0.1:9996 by default).
6162

6263
-externalip=X You can tell Dash Core about its publicly reachable address using
6364
this option, and this can be a .onion address. Given the above

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ BITCOIN_CORE_H = \
263263
reverse_iterator.h \
264264
rpc/blockchain.h \
265265
rpc/client.h \
266+
rpc/mining.h \
266267
rpc/protocol.h \
267268
rpc/rawtransaction_util.h \
268269
rpc/register.h \

src/bitcoin-cli.cpp

Lines changed: 356 additions & 65 deletions
Large diffs are not rendered by default.

src/chainparamsbase.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,20 @@ const CBaseChainParams& BaseParams()
4949
return *globalChainBaseParams;
5050
}
5151

52+
/**
53+
* Port numbers for incoming Tor connections (9996, 19996, 19796, 19896) have
54+
* been chosen arbitrarily to keep ranges of used ports tight.
55+
*/
5256
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
5357
{
5458
if (chain == CBaseChainParams::MAIN)
55-
return std::make_unique<CBaseChainParams>("", 9998);
59+
return std::make_unique<CBaseChainParams>("", 9998, 9996);
5660
else if (chain == CBaseChainParams::TESTNET)
57-
return std::make_unique<CBaseChainParams>("testnet3", 19998);
61+
return std::make_unique<CBaseChainParams>("testnet3", 19998, 19996);
5862
else if (chain == CBaseChainParams::DEVNET)
59-
return std::make_unique<CBaseChainParams>(gArgs.GetDevNetName(), 19798);
63+
return std::make_unique<CBaseChainParams>(gArgs.GetDevNetName(), 19798, 19796);
6064
else if (chain == CBaseChainParams::REGTEST)
61-
return std::make_unique<CBaseChainParams>("regtest", 19898);
65+
return std::make_unique<CBaseChainParams>("regtest", 19898, 19896);
6266
else
6367
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
6468
}

src/chainparamsbase.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ class CBaseChainParams
2626
///@}
2727

2828
const std::string& DataDir() const { return strDataDir; }
29-
uint16_t RPCPort() const { return nRPCPort; }
29+
uint16_t RPCPort() const { return m_rpc_port; }
30+
uint16_t OnionServiceTargetPort() const { return m_onion_service_target_port; }
3031

3132
CBaseChainParams() = delete;
32-
CBaseChainParams(const std::string& data_dir, int rpc_port) : nRPCPort(rpc_port), strDataDir(data_dir) {}
33+
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port, uint16_t onion_service_target_port)
34+
: m_rpc_port(rpc_port), m_onion_service_target_port(onion_service_target_port), strDataDir(data_dir) {}
3335

3436
private:
35-
uint16_t nRPCPort;
37+
const uint16_t m_rpc_port;
38+
const uint16_t m_onion_service_target_port;
3639
std::string strDataDir;
3740
};
3841

src/init.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void SetupServerArgs(NodeContext& node)
552552
argsman.AddArg("-allowprivatenet", strprintf("Allow RFC1918 addresses to be relayed and connected to (default: %u)", DEFAULT_ALLOWPRIVATENET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
553553
argsman.AddArg("-banscore=<n>", strprintf("Threshold for disconnecting and discouraging misbehaving peers (default: %u)", DEFAULT_BANSCORE_THRESHOLD), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
554554
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
555-
argsman.AddArg("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
555+
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, testnet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
556556
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);
557557
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
558558
argsman.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@@ -2480,8 +2480,6 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
24802480
}
24812481
}
24822482
LogPrintf("::ChainActive().Height() = %d\n", chain_active_height);
2483-
if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
2484-
StartTorControl();
24852483

24862484
Discover();
24872485

@@ -2506,13 +2504,39 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
25062504
connOptions.nMaxOutboundLimit = 1024 * 1024 * args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET);
25072505
connOptions.m_peer_connect_timeout = peer_connect_timeout;
25082506

2509-
for (const std::string& strBind : args.GetArgs("-bind")) {
2510-
CService addrBind;
2511-
if (!Lookup(strBind, addrBind, GetListenPort(), false)) {
2512-
return InitError(ResolveErrMsg("bind", strBind));
2507+
for (const std::string& bind_arg : args.GetArgs("-bind")) {
2508+
CService bind_addr;
2509+
const size_t index = bind_arg.rfind('=');
2510+
if (index == std::string::npos) {
2511+
if (Lookup(bind_arg, bind_addr, GetListenPort(), false)) {
2512+
connOptions.vBinds.push_back(bind_addr);
2513+
continue;
2514+
}
2515+
} else {
2516+
const std::string network_type = bind_arg.substr(index + 1);
2517+
if (network_type == "onion") {
2518+
const std::string truncated_bind_arg = bind_arg.substr(0, index);
2519+
if (Lookup(truncated_bind_arg, bind_addr, BaseParams().OnionServiceTargetPort(), false)) {
2520+
connOptions.onion_binds.push_back(bind_addr);
2521+
continue;
2522+
}
2523+
}
2524+
}
2525+
return InitError(ResolveErrMsg("bind", bind_arg));
2526+
}
2527+
2528+
if (connOptions.onion_binds.empty()) {
2529+
connOptions.onion_binds.push_back(DefaultOnionServiceTarget());
2530+
}
2531+
2532+
if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) {
2533+
const auto bind_addr = connOptions.onion_binds.front();
2534+
if (connOptions.onion_binds.size() > 1) {
2535+
InitWarning(strprintf(_("More than one onion bind address is provided. Using %s for the automatically created Tor onion service."), bind_addr.ToStringIPPort()));
25132536
}
2514-
connOptions.vBinds.push_back(addrBind);
2537+
StartTorControl(bind_addr);
25152538
}
2539+
25162540
for (const std::string& strBind : args.GetArgs("-whitebind")) {
25172541
NetWhitebindPermissions whitebind;
25182542
bilingual_str error;

src/net.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <sys/event.h>
5555
#endif
5656

57+
#include <algorithm>
5758
#include <cstdint>
5859
#include <unordered_map>
5960

@@ -99,6 +100,11 @@ enum BindFlags {
99100
BF_NONE = 0,
100101
BF_EXPLICIT = (1U << 0),
101102
BF_REPORT_ERROR = (1U << 1),
103+
/**
104+
* Do not call AddLocal() for our special addresses, e.g., for incoming
105+
* Tor connections, to prevent gossiping them over the network.
106+
*/
107+
BF_DONT_ADVERTISE = (1U << 2),
102108
};
103109

104110
#ifndef USE_WAKEUP_PIPE
@@ -580,6 +586,11 @@ std::string CNode::GetLogString() const
580586
return fLogIPs ? addr.ToString() : strprintf("%d", id);
581587
}
582588

589+
Network CNode::ConnectedThroughNetwork() const
590+
{
591+
return fInbound && m_inbound_onion ? NET_ONION : addr.GetNetClass();
592+
}
593+
583594
#undef X
584595
#define X(name) stats.name = name
585596
void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
@@ -588,6 +599,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
588599
X(nServices);
589600
X(addr);
590601
X(addrBind);
602+
stats.m_network = GetNetworkName(ConnectedThroughNetwork());
591603
stats.m_mapped_as = addr.GetMappedAS(m_asmap);
592604
if (!m_block_relay_only_peer) {
593605
LOCK(m_tx_relay->cs_filter);
@@ -1199,7 +1211,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
11991211
if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
12001212
nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
12011213
}
1202-
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
1214+
1215+
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1216+
CNode* pnode = new CNode(id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true, inbound_onion);
12031217
pnode->AddRef();
12041218
pnode->m_permissionFlags = permissionFlags;
12051219
// If this flag is present, the user probably expect that RPC and QT report it as whitelisted (backward compatibility)
@@ -2875,9 +2889,6 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError,
28752889

28762890
vhListenSocket.push_back(ListenSocket(sock->Release(), permissions));
28772891

2878-
if (addrBind.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0)
2879-
AddLocal(addrBind, LOCAL_BIND);
2880-
28812892
return true;
28822893
}
28832894

@@ -2974,10 +2985,18 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags
29742985
}
29752986
return false;
29762987
}
2988+
2989+
if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) {
2990+
AddLocal(addr, LOCAL_BIND);
2991+
}
2992+
29772993
return true;
29782994
}
29792995

2980-
bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
2996+
bool CConnman::InitBinds(
2997+
const std::vector<CService>& binds,
2998+
const std::vector<NetWhitebindPermissions>& whiteBinds,
2999+
const std::vector<CService>& onion_binds)
29813000
{
29823001
bool fBound = false;
29833002
for (const auto& addrBind : binds) {
@@ -2988,11 +3007,16 @@ bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<N
29883007
}
29893008
if (binds.empty() && whiteBinds.empty()) {
29903009
struct in_addr inaddr_any;
2991-
inaddr_any.s_addr = INADDR_ANY;
3010+
inaddr_any.s_addr = htonl(INADDR_ANY);
29923011
struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
29933012
fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
29943013
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
29953014
}
3015+
3016+
for (const auto& addr_bind : onion_binds) {
3017+
fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::PF_NONE);
3018+
}
3019+
29963020
return fBound;
29973021
}
29983022

@@ -3031,7 +3055,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
30313055
}
30323056
#endif
30333057

3034-
if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
3058+
if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds, connOptions.onion_binds)) {
30353059
if (clientInterface) {
30363060
clientInterface->ThreadSafeMessageBox(
30373061
_("Failed to listen on any port. Use -listen=0 if you want this."),
@@ -3741,7 +3765,7 @@ int CConnman::GetBestHeight() const
37413765

37423766
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
37433767

3744-
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn, bool block_relay_only)
3768+
CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn, bool block_relay_only, bool inbound_onion)
37453769
: nTimeConnected(GetSystemTimeInSeconds()),
37463770
addr(addrIn),
37473771
addrBind(addrBindIn),
@@ -3752,7 +3776,8 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
37523776
id(idIn),
37533777
nLocalHostNonce(nLocalHostNonceIn),
37543778
nLocalServices(nLocalServicesIn),
3755-
nMyStartingHeight(nMyStartingHeightIn)
3779+
nMyStartingHeight(nMyStartingHeightIn),
3780+
m_inbound_onion(inbound_onion)
37563781
{
37573782
hSocket = hSocketIn;
37583783
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;

src/net.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ friend class CNode;
178178
std::vector<NetWhitelistPermissions> vWhitelistedRange;
179179
std::vector<NetWhitebindPermissions> vWhiteBinds;
180180
std::vector<CService> vBinds;
181+
std::vector<CService> onion_binds;
181182
bool m_use_addrman_outgoing = true;
182183
std::vector<std::string> m_specified_outgoing;
183184
std::vector<std::string> m_added_nodes;
@@ -211,6 +212,7 @@ friend class CNode;
211212
vAddedNodes = connOptions.m_added_nodes;
212213
}
213214
socketEventsMode = connOptions.socketEventsMode;
215+
m_onion_binds = connOptions.onion_binds;
214216
}
215217

216218
CConnman(uint64_t seed0, uint64_t seed1, CAddrMan& addrman);
@@ -496,7 +498,11 @@ friend class CNode;
496498

497499
bool BindListenPort(const CService& bindAddr, bilingual_str& strError, NetPermissionFlags permissions);
498500
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
499-
bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds);
501+
bool InitBinds(
502+
const std::vector<CService>& binds,
503+
const std::vector<NetWhitebindPermissions>& whiteBinds,
504+
const std::vector<CService>& onion_binds);
505+
500506
void ThreadOpenAddedConnections();
501507
void AddOneShot(const std::string& strDest);
502508
void ProcessOneShot();
@@ -675,6 +681,12 @@ friend class CNode;
675681

676682
std::atomic<int64_t> m_next_send_inv_to_incoming{0};
677683

684+
/**
685+
* A vector of -bind=<address>:<port>=onion arguments each of which is
686+
* an address and port that are designated for incoming Tor connections.
687+
*/
688+
std::vector<CService> m_onion_binds;
689+
678690
friend struct CConnmanTest;
679691
friend struct ConnmanTestMsg;
680692
};
@@ -797,6 +809,8 @@ class CNodeStats
797809
CAddress addr;
798810
// Bind address of our side of the connection
799811
CAddress addrBind;
812+
// Name of the network the peer connected through
813+
std::string m_network;
800814
uint32_t m_mapped_as;
801815
// In case this is a verified MN, this value is the proTx of the MN
802816
uint256 verifiedProRegTxHash;
@@ -1010,6 +1024,18 @@ class CNode
10101024
std::atomic_bool fHasRecvData{false};
10111025
std::atomic_bool fCanSendData{false};
10121026

1027+
/**
1028+
* Get network the peer connected through.
1029+
*
1030+
* Returns Network::NET_ONION for *inbound* onion connections,
1031+
* and CNetAddr::GetNetClass() otherwise. The latter cannot be used directly
1032+
* because it doesn't detect the former, and it's not the responsibility of
1033+
* the CNetAddr class to know the actual network a peer is connected through.
1034+
*
1035+
* @return network the peer connected through.
1036+
*/
1037+
Network ConnectedThroughNetwork() const;
1038+
10131039
protected:
10141040
mapMsgCmdSize mapSendBytesPerMsgCmd;
10151041
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
@@ -1112,7 +1138,7 @@ class CNode
11121138

11131139
std::set<uint256> orphan_work_set;
11141140

1115-
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool block_relay_only = false);
1141+
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool block_relay_only = false, bool inbound_onion = false);
11161142
~CNode();
11171143
CNode(const CNode&) = delete;
11181144
CNode& operator=(const CNode&) = delete;
@@ -1150,6 +1176,9 @@ class CNode
11501176
CService addrLocal GUARDED_BY(cs_addrLocal);
11511177
mutable CCriticalSection cs_addrLocal;
11521178

1179+
//! Whether this peer connected via our Tor onion service.
1180+
const bool m_inbound_onion{false};
1181+
11531182
// Challenge sent in VERSION to be answered with MNAUTH (only happens between MNs)
11541183
mutable CCriticalSection cs_mnauth;
11551184
uint256 sentMNAuthChallenge GUARDED_BY(cs_mnauth);

src/netaddress.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ uint32_t CNetAddr::GetLinkedIPv4() const
668668
assert(false);
669669
}
670670

671-
uint32_t CNetAddr::GetNetClass() const
671+
Network CNetAddr::GetNetClass() const
672672
{
673673
// Make sure that if we return NET_IPV6, then IsIPv6() is true. The callers expect that.
674674

0 commit comments

Comments
 (0)