Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Preferentially peer with doublespend-relaying nodes
Tries to maintain 8 outgoing connections and reserves 3/4 of the
incoming connections for nodes that relay doublespends.
- Loading branch information
Showing
with
45 additions
and
1 deletion.
-
+19
−0
src/main.cpp
-
+23
−1
src/net.cpp
-
+3
−0
src/protocol.h
|
@@ -4256,6 +4256,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, |
|
|
return false; |
|
|
} |
|
|
|
|
|
// Disconnect if we have already met our quota of non-doublespend-relaying nodes. |
|
|
if (!(pfrom->nServices & NODE_RELAYS_DOUBLESPENDS)) |
|
|
{ |
|
|
int nNonDoubleSpendRelaying = 0; |
|
|
|
|
|
LOCK(cs_vNodes); |
|
|
BOOST_FOREACH(CNode* pnode, vNodes) { |
|
|
if (!(pnode->nServices & NODE_RELAYS_DOUBLESPENDS)) |
|
|
nNonDoubleSpendRelaying++; |
|
|
} |
|
|
|
|
|
if (nNonDoubleSpendRelaying > nMaxConnections / 4) { |
|
|
LogPrint("net", "reached quota of non-doublespend-relaying nodes; disconnecting %s\n", |
|
|
pfrom->addr.ToString()); |
|
|
pfrom->fDisconnect = true; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
if (pfrom->nVersion == 10300) |
|
|
pfrom->nVersion = 300; |
|
|
if (!vRecv.empty()) |
|
|
|
@@ -59,7 +59,10 @@ |
|
|
using namespace std; |
|
|
|
|
|
namespace { |
|
|
const int MAX_OUTBOUND_CONNECTIONS = 8; |
|
|
const int MAX_STD_OUTBOUND_CONNECTIONS = 8; |
|
|
const int MIN_REPLACE_BY_FEE_OUTBOUND_CONNECTIONS = 8; |
|
|
|
|
|
const int MAX_OUTBOUND_CONNECTIONS = MAX_STD_OUTBOUND_CONNECTIONS + MIN_REPLACE_BY_FEE_OUTBOUND_CONNECTIONS; |
|
|
|
|
|
struct ListenSocket { |
|
|
SOCKET socket; |
|
@@ -1555,13 +1558,17 @@ void ThreadOpenConnections() |
|
|
// Only connect out to one peer per network group (/16 for IPv4). |
|
|
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect. |
|
|
int nOutbound = 0; |
|
|
int nDoubleSpendRelayingOutbound = 0; |
|
|
set<vector<unsigned char> > setConnected; |
|
|
{ |
|
|
LOCK(cs_vNodes); |
|
|
BOOST_FOREACH(CNode* pnode, vNodes) { |
|
|
if (!pnode->fInbound) { |
|
|
setConnected.insert(pnode->addr.GetGroup()); |
|
|
nOutbound++; |
|
|
|
|
|
if (pnode->nServices & NODE_RELAYS_DOUBLESPENDS) |
|
|
nDoubleSpendRelayingOutbound++; |
|
|
} |
|
|
} |
|
|
} |
|
@@ -1595,6 +1602,21 @@ void ThreadOpenConnections() |
|
|
if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) |
|
|
continue; |
|
|
|
|
|
// Reserve some outbound connections for nodes that relay |
|
|
// double-spends. |
|
|
// |
|
|
// Unfortunately nServices seems to end up corrupted at times, |
|
|
// leading us to adding more nodes than expected, so this is a more |
|
|
// strict test than might otherwise be expected. |
|
|
// |
|
|
// Also, we'll still end up with too many at times, because we'll |
|
|
// find out afterwords that what we thought was a node's nServices |
|
|
// was incorrect; Bitcoin Core will even stay connected to nodes |
|
|
// not advertising NODE_NETWORK in this case. |
|
|
if (!((addr.nServices & NODE_RELAYS_DOUBLESPENDS) && (addr.nServices & ~NODE_RELAYS_DOUBLESPENDS) == NODE_NETWORK) |
|
|
&& (nOutbound - nDoubleSpendRelayingOutbound >= MAX_STD_OUTBOUND_CONNECTIONS)) |
|
|
continue; |
|
|
|
|
|
addrConnect = addr; |
|
|
break; |
|
|
} |
|
|
|
@@ -230,6 +230,7 @@ enum { |
|
|
// set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want |
|
|
// network services but don't provide them. |
|
|
NODE_NETWORK = (1 << 0), |
|
|
|
|
|
// NODE_GETUTXO means the node is capable of responding to the getutxo protocol request. |
|
|
// Bitcoin Core does not support this but a patch set called Bitcoin XT does. |
|
|
// See BIP 64 for details on how this is implemented. |
|
@@ -250,6 +251,8 @@ enum { |
|
|
NODE_REPLACE_BY_FEE = (1 << 26), |
|
|
}; |
|
|
|
|
|
const uint64_t NODE_RELAYS_DOUBLESPENDS = NODE_REPLACE_BY_FEE; |
|
|
|
|
|
/** A CService with information about it as peer */ |
|
|
class CAddress : public CService |
|
|
{ |
|
|