Permalink
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...
petertodd committed Feb 12, 2015
1 parent 52dc8c5 commit 3e541f4779d441ac87706bed994c800d301281d8
Showing with 45 additions and 1 deletion.
  1. +19 −0 src/main.cpp
  2. +23 −1 src/net.cpp
  3. +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
{

0 comments on commit 3e541f4

Please sign in to comment.