mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
feat: aim to have 2 onion connections when possible, guard them from eviction
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! 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. 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. 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. 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.
This commit is contained in:
parent
7ebd7785d6
commit
127a4d23a5
@ -2341,6 +2341,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
connOptions.nMaxConnections = nMaxConnections;
|
connOptions.nMaxConnections = nMaxConnections;
|
||||||
connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.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_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.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
|
||||||
connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
|
connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
|
||||||
connOptions.uiInterface = &uiInterface;
|
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
|
// This is only done for mainnet and testnet
|
||||||
int nOutboundFullRelay = 0;
|
int nOutboundFullRelay = 0;
|
||||||
int nOutboundBlockRelay = 0;
|
int nOutboundBlockRelay = 0;
|
||||||
|
int nOutboundOnionRelay = 0;
|
||||||
std::set<std::vector<unsigned char> > setConnected;
|
std::set<std::vector<unsigned char> > setConnected;
|
||||||
if (!Params().AllowMultipleAddressesFromGroup()) {
|
if (!Params().AllowMultipleAddressesFromGroup()) {
|
||||||
LOCK(m_nodes_mutex);
|
LOCK(m_nodes_mutex);
|
||||||
for (const CNode* pnode : m_nodes) {
|
for (const CNode* pnode : m_nodes) {
|
||||||
if (pnode->IsFullOutboundConn() && !pnode->m_masternode_connection) nOutboundFullRelay++;
|
if (pnode->IsFullOutboundConn() && !pnode->m_masternode_connection) nOutboundFullRelay++;
|
||||||
if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
|
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
|
// 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
|
// 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>();
|
auto now = GetTime<std::chrono::microseconds>();
|
||||||
bool anchor = false;
|
bool anchor = false;
|
||||||
bool fFeeler = false;
|
bool fFeeler = false;
|
||||||
|
bool onion_only = false;
|
||||||
|
|
||||||
// Determine what type of connection to open. Opening
|
// Determine what type of connection to open. Opening
|
||||||
// BLOCK_RELAY connections to addresses from anchors.dat gets the highest
|
// 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);
|
next_feeler = PoissonNextSend(now, FEELER_INTERVAL);
|
||||||
conn_type = ConnectionType::FEELER;
|
conn_type = ConnectionType::FEELER;
|
||||||
fFeeler = true;
|
fFeeler = true;
|
||||||
|
} else if (nOutboundOnionRelay < m_max_outbound_onion && IsReachable(Network::NET_ONION)) {
|
||||||
|
onion_only = true;
|
||||||
} else {
|
} else {
|
||||||
// skip to next iteration of while loop
|
// skip to next iteration of while loop
|
||||||
continue;
|
continue;
|
||||||
@ -2744,6 +2749,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
|||||||
|
|
||||||
if (!IsReachable(addr))
|
if (!IsReachable(addr))
|
||||||
continue;
|
continue;
|
||||||
|
if (onion_only && !addr.IsTor()) continue;
|
||||||
|
|
||||||
// only consider very recently tried nodes after 30 failed attempts
|
// only consider very recently tried nodes after 30 failed attempts
|
||||||
if (nANow - addr_last_try < 600 && nTries < 30)
|
if (nANow - addr_last_try < 600 && nTries < 30)
|
||||||
@ -3951,6 +3957,10 @@ size_t CConnman::GetMaxOutboundNodeCount()
|
|||||||
{
|
{
|
||||||
return m_max_outbound;
|
return m_max_outbound;
|
||||||
}
|
}
|
||||||
|
size_t CConnman::GetMaxOutboundOnionNodeCount()
|
||||||
|
{
|
||||||
|
return m_max_outbound_onion;
|
||||||
|
}
|
||||||
|
|
||||||
void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
|
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};
|
static const auto INBOUND_EVICTION_PROTECTION_TIME{1s};
|
||||||
/** Maximum number of block-relay-only outgoing connections */
|
/** Maximum number of block-relay-only outgoing connections */
|
||||||
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS = 2;
|
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 */
|
/** Maximum number of feeler connections */
|
||||||
static const int MAX_FEELER_CONNECTIONS = 1;
|
static const int MAX_FEELER_CONNECTIONS = 1;
|
||||||
/** -listen default */
|
/** -listen default */
|
||||||
@ -873,6 +875,7 @@ public:
|
|||||||
int nMaxConnections = 0;
|
int nMaxConnections = 0;
|
||||||
int m_max_outbound_full_relay = 0;
|
int m_max_outbound_full_relay = 0;
|
||||||
int m_max_outbound_block_relay = 0;
|
int m_max_outbound_block_relay = 0;
|
||||||
|
int m_max_outbound_onion = 0;
|
||||||
int nMaxAddnode = 0;
|
int nMaxAddnode = 0;
|
||||||
int nMaxFeeler = 0;
|
int nMaxFeeler = 0;
|
||||||
CClientUIInterface* uiInterface = nullptr;
|
CClientUIInterface* uiInterface = nullptr;
|
||||||
@ -905,6 +908,7 @@ public:
|
|||||||
nMaxConnections = connOptions.nMaxConnections;
|
nMaxConnections = connOptions.nMaxConnections;
|
||||||
m_max_outbound_full_relay = std::min(connOptions.m_max_outbound_full_relay, 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_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;
|
m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
|
||||||
nMaxAddnode = connOptions.nMaxAddnode;
|
nMaxAddnode = connOptions.nMaxAddnode;
|
||||||
nMaxFeeler = connOptions.nMaxFeeler;
|
nMaxFeeler = connOptions.nMaxFeeler;
|
||||||
@ -1179,6 +1183,7 @@ public:
|
|||||||
|
|
||||||
size_t GetNodeCount(ConnectionDirection) const;
|
size_t GetNodeCount(ConnectionDirection) const;
|
||||||
size_t GetMaxOutboundNodeCount();
|
size_t GetMaxOutboundNodeCount();
|
||||||
|
size_t GetMaxOutboundOnionNodeCount();
|
||||||
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
|
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
|
||||||
bool DisconnectNode(const std::string& node);
|
bool DisconnectNode(const std::string& node);
|
||||||
bool DisconnectNode(const CSubNet& subnet);
|
bool DisconnectNode(const CSubNet& subnet);
|
||||||
@ -1515,6 +1520,9 @@ private:
|
|||||||
// We do not relay tx or addr messages with these peers
|
// We do not relay tx or addr messages with these peers
|
||||||
int m_max_outbound_block_relay;
|
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 nMaxAddnode;
|
||||||
int nMaxFeeler;
|
int nMaxFeeler;
|
||||||
int m_max_outbound;
|
int m_max_outbound;
|
||||||
|
@ -5179,9 +5179,12 @@ void PeerManagerImpl::EvictExtraOutboundPeers(std::chrono::seconds now)
|
|||||||
NodeId worst_peer = -1;
|
NodeId worst_peer = -1;
|
||||||
int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
|
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) {
|
m_connman.ForEachNode([&](CNode* pnode) {
|
||||||
LockAssertion lock(::cs_main);
|
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
|
// Don't disconnect masternodes just because they were slow in block announcement
|
||||||
if (pnode->m_masternode_connection) return;
|
if (pnode->m_masternode_connection) return;
|
||||||
// Only consider outbound-full-relay peers that are not already
|
// Only consider outbound-full-relay peers that are not already
|
||||||
|
Loading…
Reference in New Issue
Block a user