mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Merge #6147: feat: aim to have at least 2 onion connections, guard them from eviction
e775b74d5e
docs: add release notes for 6147 (pasta)127a4d23a5
feat: aim to have 2 onion connections when possible, guard them from eviction (pasta) Pull request description: ## Issue being fixed or feature implemented In the past I've noticed that even when using `-proxy` over tor, I wouldn't actually gain any onion connections over time. This is even worse when using -onion. Sure it may expose an onion service, but you wouldn't gain any onion connections (in my experience)! The goal here is to minimize easy-ish censorship and improve network-wide resistance to partitioning. It is not unimaginable that port 9999 could be blocked at large scale. This could potentially result in severe partitioning, and subsequent issues. In an attempt to avoid this, we should always try to have at least 2 outbound onion connections when at all possible. Hopefully this also makes onion addresses gossip better. This also adds a benefit of p2p encryption for these peers. As a result, there is improved plausible deniability that you produced a transaction, as it is possible you received it over onion and simply rebroadcast it over ipv4. I don't think there is any real downside to this patch, stuff like masternode / quorum connections will still always happen over ipv4, but with this, blocks and transactions would continue to propogate across the network even if (non-onion) ipv4 traffic was all dropped. Arguably, it's not **ideal** to send so much traffic over tor, but hopefully as latency is higher, we will generally receive messages over ipv4 first and therefor not request them over the onion connections. ## What was done? We will always try to get 2 onion nodes (full or block only); and guard them from eviction ## How Has This Been Tested? Run a node; see over time that you start with 0 onion nodes, and over time you progress to having two of them! ## Breaking Changes None ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ Top commit has no ACKs. Tree-SHA512: cd15565751ae845302c71cac084ffba66340033d379ffa78d0aa6fa4ad8f65ddeccd55fa623dfaf7daeed5e38b5b2ec27683991275cf2b6edfbd8e114a1bfe60
This commit is contained in:
commit
84179f7e0e
12
doc/release-notes-6147.md
Normal file
12
doc/release-notes-6147.md
Normal file
@ -0,0 +1,12 @@
|
||||
P2P and Network Changes
|
||||
-----------------------
|
||||
|
||||
### Improved Onion Connectivity
|
||||
|
||||
To enhance censorship resistance and mitigate network partitioning risks, Dash Core now aims to maintain at least two
|
||||
outbound onion connections and generally protects these connections from eviction. As a result of the low percentage
|
||||
of gossiped addresses being onion nodes, it was often the case where, unless you specify `onlynet=onion`, a node
|
||||
would rarely if ever establish any outbound onion connections. This change ensures that nodes which can access the
|
||||
onion network maintain a few onion connections. As a result, network messages could continue to propagate across
|
||||
the network even if non-onion IPv4 traffic is blocked, reducing the risk of partitioning. Additionally, this update improves
|
||||
security by enabling p2p encryption for these peers. (#6147)
|
@ -2341,6 +2341,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
connOptions.nMaxConnections = nMaxConnections;
|
||||
connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.nMaxConnections);
|
||||
connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
|
||||
connOptions.m_max_outbound_onion = std::min(MAX_DESIRED_ONION_CONNECTIONS, connOptions.nMaxConnections / 2);
|
||||
connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
|
||||
connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
|
||||
connOptions.uiInterface = &uiInterface;
|
||||
|
10
src/net.cpp
10
src/net.cpp
@ -2573,12 +2573,14 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
// This is only done for mainnet and testnet
|
||||
int nOutboundFullRelay = 0;
|
||||
int nOutboundBlockRelay = 0;
|
||||
int nOutboundOnionRelay = 0;
|
||||
std::set<std::vector<unsigned char> > setConnected;
|
||||
if (!Params().AllowMultipleAddressesFromGroup()) {
|
||||
LOCK(m_nodes_mutex);
|
||||
for (const CNode* pnode : m_nodes) {
|
||||
if (pnode->IsFullOutboundConn() && !pnode->m_masternode_connection) nOutboundFullRelay++;
|
||||
if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
|
||||
if (pnode->IsFullOutboundConn() && pnode->ConnectedThroughNetwork() == Network::NET_ONION) nOutboundOnionRelay++;
|
||||
|
||||
// Netgroups for inbound and manual peers are not excluded because our goal here
|
||||
// is to not use multiple of our limited outbound slots on a single netgroup
|
||||
@ -2613,6 +2615,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
auto now = GetTime<std::chrono::microseconds>();
|
||||
bool anchor = false;
|
||||
bool fFeeler = false;
|
||||
bool onion_only = false;
|
||||
|
||||
// Determine what type of connection to open. Opening
|
||||
// BLOCK_RELAY connections to addresses from anchors.dat gets the highest
|
||||
@ -2662,6 +2665,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
next_feeler = PoissonNextSend(now, FEELER_INTERVAL);
|
||||
conn_type = ConnectionType::FEELER;
|
||||
fFeeler = true;
|
||||
} else if (nOutboundOnionRelay < m_max_outbound_onion && IsReachable(Network::NET_ONION)) {
|
||||
onion_only = true;
|
||||
} else {
|
||||
// skip to next iteration of while loop
|
||||
continue;
|
||||
@ -2744,6 +2749,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
|
||||
if (!IsReachable(addr))
|
||||
continue;
|
||||
if (onion_only && !addr.IsTor()) continue;
|
||||
|
||||
// only consider very recently tried nodes after 30 failed attempts
|
||||
if (nANow - addr_last_try < 600 && nTries < 30)
|
||||
@ -3951,6 +3957,10 @@ size_t CConnman::GetMaxOutboundNodeCount()
|
||||
{
|
||||
return m_max_outbound;
|
||||
}
|
||||
size_t CConnman::GetMaxOutboundOnionNodeCount()
|
||||
{
|
||||
return m_max_outbound_onion;
|
||||
}
|
||||
|
||||
void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
|
||||
{
|
||||
|
@ -85,6 +85,8 @@ static const int MAX_ADDNODE_CONNECTIONS = 8;
|
||||
static const auto INBOUND_EVICTION_PROTECTION_TIME{1s};
|
||||
/** Maximum number of block-relay-only outgoing connections */
|
||||
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS = 2;
|
||||
/** Maximum number of onion connections we will try harder to connect to / protect from eviction */
|
||||
static const int MAX_DESIRED_ONION_CONNECTIONS = 2;
|
||||
/** Maximum number of feeler connections */
|
||||
static const int MAX_FEELER_CONNECTIONS = 1;
|
||||
/** -listen default */
|
||||
@ -873,6 +875,7 @@ public:
|
||||
int nMaxConnections = 0;
|
||||
int m_max_outbound_full_relay = 0;
|
||||
int m_max_outbound_block_relay = 0;
|
||||
int m_max_outbound_onion = 0;
|
||||
int nMaxAddnode = 0;
|
||||
int nMaxFeeler = 0;
|
||||
CClientUIInterface* uiInterface = nullptr;
|
||||
@ -905,6 +908,7 @@ public:
|
||||
nMaxConnections = connOptions.nMaxConnections;
|
||||
m_max_outbound_full_relay = std::min(connOptions.m_max_outbound_full_relay, connOptions.nMaxConnections);
|
||||
m_max_outbound_block_relay = connOptions.m_max_outbound_block_relay;
|
||||
m_max_outbound_onion = connOptions.m_max_outbound_onion;
|
||||
m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
|
||||
nMaxAddnode = connOptions.nMaxAddnode;
|
||||
nMaxFeeler = connOptions.nMaxFeeler;
|
||||
@ -1179,6 +1183,7 @@ public:
|
||||
|
||||
size_t GetNodeCount(ConnectionDirection) const;
|
||||
size_t GetMaxOutboundNodeCount();
|
||||
size_t GetMaxOutboundOnionNodeCount();
|
||||
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
|
||||
bool DisconnectNode(const std::string& node);
|
||||
bool DisconnectNode(const CSubNet& subnet);
|
||||
@ -1515,6 +1520,9 @@ private:
|
||||
// We do not relay tx or addr messages with these peers
|
||||
int m_max_outbound_block_relay;
|
||||
|
||||
// How many onion outbound peers we want; don't care if full or block only; does not increase m_max_outbound
|
||||
int m_max_outbound_onion;
|
||||
|
||||
int nMaxAddnode;
|
||||
int nMaxFeeler;
|
||||
int m_max_outbound;
|
||||
|
@ -5179,9 +5179,12 @@ void PeerManagerImpl::EvictExtraOutboundPeers(std::chrono::seconds now)
|
||||
NodeId worst_peer = -1;
|
||||
int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
|
||||
|
||||
// We want to prevent recently connected to Onion peers from being disconnected here, protect them as long as
|
||||
// there are more non_onion nodes than onion nodes so far
|
||||
size_t onion_count = 0;
|
||||
m_connman.ForEachNode([&](CNode* pnode) {
|
||||
LockAssertion lock(::cs_main);
|
||||
|
||||
if (pnode->addr.IsTor() && ++onion_count <= m_connman.GetMaxOutboundOnionNodeCount()) return;
|
||||
// Don't disconnect masternodes just because they were slow in block announcement
|
||||
if (pnode->m_masternode_connection) return;
|
||||
// Only consider outbound-full-relay peers that are not already
|
||||
|
Loading…
Reference in New Issue
Block a user