Skip to content

Commit 9c38b35

Browse files
Merge pull request dashpay#5842 from kwvg/bps_jan_03
backport: merge bitcoin#19289, bitcoin#19998, bitcoin#17775, bitcoin#19401, bitcoin#20167, bitcoin#20187, bitcoin#19961, bitcoin#21114, bitcoin#21170 (auxiliary backports: part 12)
2 parents 052b689 + bb02a88 commit 9c38b35

20 files changed

+297
-156
lines changed

doc/tor.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ may not. In particular, the Tor Browser Bundle defaults to listening on port 915
88
See [Tor Project FAQ:TBBSocksPort](https://www.torproject.org/docs/faq.html.en#TBBSocksPort)
99
for how to properly configure Tor.
1010

11+
## How to see information about your Tor configuration via Dash Core
12+
13+
There are several ways to see your local onion address in Dash Core:
14+
- in the debug log (grep for "tor:" or "AddLocal")
15+
- in the output of RPC `getnetworkinfo` in the "localaddresses" section
16+
- in the output of the CLI `-netinfo` peer connections dashboard
17+
18+
You may set the `-debug=tor` config logging option to have additional
19+
information in the debug log about your Tor configuration.
20+
1121

1222
## 1. Run Dash Core behind a Tor proxy
1323

@@ -160,14 +170,19 @@ The directory can be different of course, but virtual port numbers should be equ
160170
your dashd's P2P listen port (9999 by default), and target addresses and ports
161171
should be equal to binding address and port for inbound Tor connections (127.0.0.1:9996 by default).
162172

163-
-externalip=X You can tell Dash Core about its publicly reachable address using
164-
this option, and this can be a .onion address. Given the above
165-
configuration, you can find your .onion address in
173+
-externalip=X You can tell Dash Core about its publicly reachable addresses using
174+
this option, and this can be an onion address. Given the above
175+
configuration, you can find your onion address in
166176
/var/lib/tor/dashcore-service/hostname. For connections
167177
coming from unroutable addresses (such as 127.0.0.1, where the
168-
Tor proxy typically runs), .onion addresses are given
178+
Tor proxy typically runs), onion addresses are given
169179
preference for your node to advertise itself with.
170180

181+
You can set multiple local addresses with -externalip. The
182+
one that will be rumoured to a particular peer is the most
183+
compatible one and also using heuristics, e.g. the address
184+
with the most incoming connections, etc.
185+
171186
-listen You'll need to enable listening for incoming connections, as this
172187
is off by default behind a proxy.
173188

@@ -180,7 +195,7 @@ should be equal to binding address and port for inbound Tor connections (127.0.0
180195

181196
In a typical situation, where you're only reachable via Tor, this should suffice:
182197

183-
./dashd -proxy=127.0.0.1:9050 -externalip=ssapp53tmftyjmjb.onion -listen
198+
./dashd -proxy=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -listen
184199

185200
(obviously, replace the .onion address with your own). It should be noted that you still
186201
listen on all devices and another node could establish a clearnet connection, when knowing
@@ -198,7 +213,7 @@ and open port 9999 on your firewall (or use port mapping, i.e., `-upnp` or `-nat
198213
If you only want to use Tor to reach .onion addresses, but not use it as a proxy
199214
for normal IPv4/IPv6 communication, use:
200215

201-
./dashd -onion=127.0.0.1:9050 -externalip=ssapp53tmftyjmjb.onion -discover
216+
./dashd -onion=127.0.0.1:9050 -externalip=7zvj7a2imdgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -discover
202217

203218

204219
## 3.1. List of known Dash Core Tor relays

src/bench/rpc_blockchain.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,49 @@
1515

1616
#include <univalue.h>
1717

18-
static void BlockToJsonVerbose(benchmark::Bench& bench) {
18+
namespace {
19+
20+
struct TestBlockAndIndex {
1921
TestingSetup test_setup{};
22+
CBlock block{};
23+
uint256 blockHash{};
24+
CBlockIndex blockindex{};
25+
26+
TestBlockAndIndex()
27+
{
28+
CDataStream stream(benchmark::data::block813851, SER_NETWORK, PROTOCOL_VERSION);
29+
char a = '\0';
30+
stream.write(&a, 1); // Prevent compaction
2031

21-
CDataStream stream(benchmark::data::block813851, SER_NETWORK, PROTOCOL_VERSION);
22-
char a = '\0';
23-
stream.write(&a, 1); // Prevent compaction
32+
stream >> block;
2433

25-
CBlock block;
26-
stream >> block;
34+
blockHash = block.GetHash();
35+
blockindex.phashBlock = &blockHash;
36+
blockindex.nBits = 403014710;
37+
}
38+
};
2739

28-
CBlockIndex blockindex;
29-
const uint256 blockHash = block.GetHash();
30-
blockindex.phashBlock = &blockHash;
31-
blockindex.nBits = 403014710;
40+
} // namespace
3241

42+
static void BlockToJsonVerbose(benchmark::Bench& bench)
43+
{
44+
TestBlockAndIndex data;
3345
bench.run([&] {
34-
(void)blockToJSON(block, &blockindex, &blockindex, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, /*verbose*/ true);
46+
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, /*verbose*/ true);
47+
ankerl::nanobench::doNotOptimizeAway(univalue);
3548
});
3649
}
3750

3851
BENCHMARK(BlockToJsonVerbose);
52+
53+
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
54+
{
55+
TestBlockAndIndex data;
56+
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, /*verbose*/ true);
57+
bench.run([&] {
58+
auto str = univalue.write();
59+
ankerl::nanobench::doNotOptimizeAway(str);
60+
});
61+
}
62+
63+
BENCHMARK(BlockToJsonVerboseWrite);

src/core_io.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct CSpentIndexTxInfo;
2424
// core_read.cpp
2525
CScript ParseScript(const std::string& s);
2626
std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
27-
[[nodiscard]] bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx);
27+
[[nodiscard]] bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx);
2828
[[nodiscard]] bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
2929
bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
3030
/**

src/core_read.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,25 +100,31 @@ CScript ParseScript(const std::string& s)
100100
return result;
101101
}
102102

103-
bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx)
103+
static bool DecodeTx(CMutableTransaction& tx, const std::vector<unsigned char>& tx_data)
104104
{
105-
if (!IsHex(strHexTx))
106-
return false;
107-
108-
std::vector<unsigned char> txData(ParseHex(strHexTx));
109-
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
105+
CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION);
110106
try {
111107
ssData >> tx;
112-
if (!ssData.empty())
108+
if (!ssData.empty()) {
113109
return false;
114-
}
115-
catch (const std::exception&) {
110+
}
111+
} catch (const std::exception&) {
116112
return false;
117113
}
118114

119115
return true;
120116
}
121117

118+
bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx)
119+
{
120+
if (!IsHex(hex_tx)) {
121+
return false;
122+
}
123+
124+
std::vector<unsigned char> txData(ParseHex(hex_tx));
125+
return DecodeTx(tx, txData);
126+
}
127+
122128
bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header)
123129
{
124130
if (!IsHex(hex_header)) return false;

src/net.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ CNode* CConnman::FindNode(const CService& addr, bool fExcludeDisconnecting)
385385
return nullptr;
386386
}
387387

388+
bool CConnman::AlreadyConnectedToAddress(const CAddress& addr)
389+
{
390+
return FindNode(addr.ToStringIPPort());
391+
}
392+
388393
bool CConnman::CheckIncomingNonce(uint64_t nonce)
389394
{
390395
LOCK(cs_vNodes);
@@ -2397,11 +2402,30 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
23972402
if (nTries > 100)
23982403
break;
23992404

2400-
CAddrInfo addr = addrman.SelectTriedCollision();
2405+
CAddrInfo addr;
24012406

2402-
// SelectTriedCollision returns an invalid address if it is empty.
2403-
if (!fFeeler || !addr.IsValid()) {
2404-
addr = addrman.Select(fFeeler);
2407+
if (fFeeler) {
2408+
// First, try to get a tried table collision address. This returns
2409+
// an empty (invalid) address if there are no collisions to try.
2410+
addr = addrman.SelectTriedCollision();
2411+
2412+
if (!addr.IsValid()) {
2413+
// No tried table collisions. Select a new table address
2414+
// for our feeler.
2415+
addr = addrman.Select(true);
2416+
} else if (AlreadyConnectedToAddress(addr)) {
2417+
// If test-before-evict logic would have us connect to a
2418+
// peer that we're already connected to, just mark that
2419+
// address as Good(). We won't be able to initiate the
2420+
// connection anyway, so this avoids inadvertently evicting
2421+
// a currently-connected peer.
2422+
addrman.Good(addr);
2423+
// Select a new table address for our feeler instead.
2424+
addr = addrman.Select(true);
2425+
}
2426+
} else {
2427+
// Not a feeler
2428+
addr = addrman.Select();
24052429
}
24062430

24072431
auto dmn = mnList.GetMNByService(addr);
@@ -2768,7 +2792,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
27682792

27692793
if (!pszDest) {
27702794
// banned, discouraged or exact match?
2771-
if ((m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect))) || FindNode(addrConnect.ToStringIPPort()))
2795+
if ((m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect))) || AlreadyConnectedToAddress(addrConnect))
27722796
return;
27732797
// local and not a connection to itself?
27742798
bool fAllowLocal = Params().AllowMultiplePorts() && addrConnect.GetPort() != GetListenPort();

src/net.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,12 @@ friend class CNode;
625625
CNode* FindNode(const std::string& addrName, bool fExcludeDisconnecting = true);
626626
CNode* FindNode(const CService& addr, bool fExcludeDisconnecting = true);
627627

628+
/**
629+
* Determine whether we're already connected to a given address, in order to
630+
* avoid initiating duplicate connections.
631+
*/
632+
bool AlreadyConnectedToAddress(const CAddress& addr);
633+
628634
bool AttemptToEvictConnection();
629635
CNode* ConnectNode(CAddress addrConnect, const char *pszDest = nullptr, bool fCountFailure = false, ConnectionType conn_type = ConnectionType::OUTBOUND_FULL_RELAY);
630636
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;

src/net_processing.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,14 +3017,8 @@ void PeerManagerImpl::ProcessMessage(
30173017
// empty and no one will know who we are, so these mechanisms are
30183018
// important to help us connect to the network.
30193019
//
3020-
// We also update the addrman to record connection success for
3021-
// these peers (which include OUTBOUND_FULL_RELAY and FEELER
3022-
// connections) so that addrman will have an up-to-date notion of
3023-
// which peers are online and available.
3024-
//
3025-
// We skip these operations for BLOCK_RELAY peers to avoid
3026-
// potentially leaking information about our BLOCK_RELAY
3027-
// connections via the addrman or address relay.
3020+
// We skip this for BLOCK_RELAY peers to avoid potentially leaking
3021+
// information about our BLOCK_RELAY connections via address relay.
30283022
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
30293023
{
30303024
CAddress addr = GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices());
@@ -3043,11 +3037,24 @@ void PeerManagerImpl::ProcessMessage(
30433037
// Get recent addresses
30443038
m_connman.PushMessage(&pfrom, CNetMsgMaker(greatest_common_version).Make(NetMsgType::GETADDR));
30453039
pfrom.fGetAddr = true;
3040+
}
30463041

3047-
// Moves address from New to Tried table in Addrman, resolves
3048-
// tried-table collisions, etc.
3042+
if (!pfrom.IsInboundConn()) {
3043+
// For non-inbound connections, we update the addrman to record
3044+
// connection success so that addrman will have an up-to-date
3045+
// notion of which peers are online and available.
3046+
//
3047+
// While we strive to not leak information about block-relay-only
3048+
// connections via the addrman, not moving an address to the tried
3049+
// table is also potentially detrimental because new-table entries
3050+
// are subject to eviction in the event of addrman collisions. We
3051+
// mitigate the information-leak by never calling
3052+
// CAddrMan::Connected() on block-relay-only peers; see
3053+
// FinalizeNode().
3054+
//
3055+
// This moves an address from New to Tried table in Addrman,
3056+
// resolves tried-table collisions, etc.
30493057
m_addrman.Good(pfrom.addr);
3050-
30513058
}
30523059

30533060
std::string remoteAddr;

src/rpc/blockchain.cpp

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -214,20 +214,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
214214

215215
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, bool txDetails)
216216
{
217-
// Serialize passed information without accessing chain state of the active chain!
218-
AssertLockNotHeld(cs_main); // For performance reasons
217+
UniValue result = blockheaderToJSON(tip, blockindex, clhandler, isman);
219218

220-
UniValue result(UniValue::VOBJ);
221-
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
222-
const CBlockIndex* pnext;
223-
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
224-
result.pushKV("confirmations", confirmations);
225219
result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
226-
result.pushKV("height", blockindex->nHeight);
227-
result.pushKV("version", block.nVersion);
228-
result.pushKV("versionHex", strprintf("%08x", block.nVersion));
229-
result.pushKV("merkleroot", block.hashMerkleRoot.GetHex());
230-
bool chainLock = clhandler.HasChainLock(blockindex->nHeight, blockindex->GetBlockHash());
231220
UniValue txs(UniValue::VARR);
232221
for(const auto& tx : block.vtx)
233222
{
@@ -236,7 +225,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
236225
UniValue objTx(UniValue::VOBJ);
237226
TxToUniv(*tx, uint256(), objTx, true);
238227
bool fLocked = isman.IsLocked(tx->GetHash());
239-
objTx.pushKV("instantlock", fLocked || chainLock);
228+
objTx.pushKV("instantlock", fLocked || result["chainlock"].get_bool());
240229
objTx.pushKV("instantlock_internal", fLocked);
241230
txs.push_back(objTx);
242231
}
@@ -249,20 +238,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
249238
result.pushKV("cbTx", opt_cbTx->ToJson());
250239
}
251240
}
252-
result.pushKV("time", block.GetBlockTime());
253-
result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast());
254-
result.pushKV("nonce", (uint64_t)block.nNonce);
255-
result.pushKV("bits", strprintf("%08x", block.nBits));
256-
result.pushKV("difficulty", GetDifficulty(blockindex));
257-
result.pushKV("chainwork", blockindex->nChainWork.GetHex());
258-
result.pushKV("nTx", (uint64_t)blockindex->nTx);
259-
260-
if (blockindex->pprev)
261-
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
262-
if (pnext)
263-
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
264-
265-
result.pushKV("chainlock", chainLock);
266241

267242
return result;
268243
}
@@ -1168,11 +1143,20 @@ static UniValue getblock(const JSONRPCRequest& request)
11681143
{
11691144
{RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"},
11701145
{RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"},
1171-
{RPCResult::Type::NUM, "size", "The block size"},
11721146
{RPCResult::Type::NUM, "height", "The block height or index"},
11731147
{RPCResult::Type::NUM, "version", "The block version"},
11741148
{RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"},
11751149
{RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
1150+
{RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
1151+
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
1152+
{RPCResult::Type::NUM, "nonce", "The nonce"},
1153+
{RPCResult::Type::STR_HEX, "bits", "The bits"},
1154+
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
1155+
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"},
1156+
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
1157+
{RPCResult::Type::STR_HEX, "previousblockhash", /* optional */ true, "The hash of the previous block (if available)"},
1158+
{RPCResult::Type::STR_HEX, "nextblockhash", /* optional */ true, "The hash of the next block (if available)"},
1159+
{RPCResult::Type::NUM, "size", "The block size"},
11761160
{RPCResult::Type::ARR, "tx", "The transaction ids",
11771161
{{RPCResult::Type::STR_HEX, "", "The transaction id"}}},
11781162
{RPCResult::Type::OBJ, "cbTx", "The coinbase special transaction",
@@ -1182,15 +1166,6 @@ static UniValue getblock(const JSONRPCRequest& request)
11821166
{RPCResult::Type::STR_HEX, "merkleRootMNList", "The merkle root of the masternode list"},
11831167
{RPCResult::Type::STR_HEX, "merkleRootQuorums", "The merkle root of the quorum list"},
11841168
}},
1185-
{RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
1186-
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
1187-
{RPCResult::Type::NUM, "nonce", "The nonce"},
1188-
{RPCResult::Type::STR_HEX, "bits", "The bits"},
1189-
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
1190-
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"},
1191-
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
1192-
{RPCResult::Type::STR_HEX, "previousblockhash", "The hash of the previous block"},
1193-
{RPCResult::Type::STR_HEX, "nextblockhash", "The hash of the next block"},
11941169
}},
11951170
RPCResult{"for verbosity = 2",
11961171
RPCResult::Type::OBJ, "", "",

0 commit comments

Comments
 (0)