Skip to content

Commit 3e541f4

Browse files
committed
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.
1 parent 52dc8c5 commit 3e541f4

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

src/main.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,6 +4256,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
42564256
return false;
42574257
}
42584258

4259+
// Disconnect if we have already met our quota of non-doublespend-relaying nodes.
4260+
if (!(pfrom->nServices & NODE_RELAYS_DOUBLESPENDS))
4261+
{
4262+
int nNonDoubleSpendRelaying = 0;
4263+
4264+
LOCK(cs_vNodes);
4265+
BOOST_FOREACH(CNode* pnode, vNodes) {
4266+
if (!(pnode->nServices & NODE_RELAYS_DOUBLESPENDS))
4267+
nNonDoubleSpendRelaying++;
4268+
}
4269+
4270+
if (nNonDoubleSpendRelaying > nMaxConnections / 4) {
4271+
LogPrint("net", "reached quota of non-doublespend-relaying nodes; disconnecting %s\n",
4272+
pfrom->addr.ToString());
4273+
pfrom->fDisconnect = true;
4274+
return false;
4275+
}
4276+
}
4277+
42594278
if (pfrom->nVersion == 10300)
42604279
pfrom->nVersion = 300;
42614280
if (!vRecv.empty())

src/net.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@
5959
using namespace std;
6060

6161
namespace {
62-
const int MAX_OUTBOUND_CONNECTIONS = 8;
62+
const int MAX_STD_OUTBOUND_CONNECTIONS = 8;
63+
const int MIN_REPLACE_BY_FEE_OUTBOUND_CONNECTIONS = 8;
64+
65+
const int MAX_OUTBOUND_CONNECTIONS = MAX_STD_OUTBOUND_CONNECTIONS + MIN_REPLACE_BY_FEE_OUTBOUND_CONNECTIONS;
6366

6467
struct ListenSocket {
6568
SOCKET socket;
@@ -1555,13 +1558,17 @@ void ThreadOpenConnections()
15551558
// Only connect out to one peer per network group (/16 for IPv4).
15561559
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
15571560
int nOutbound = 0;
1561+
int nDoubleSpendRelayingOutbound = 0;
15581562
set<vector<unsigned char> > setConnected;
15591563
{
15601564
LOCK(cs_vNodes);
15611565
BOOST_FOREACH(CNode* pnode, vNodes) {
15621566
if (!pnode->fInbound) {
15631567
setConnected.insert(pnode->addr.GetGroup());
15641568
nOutbound++;
1569+
1570+
if (pnode->nServices & NODE_RELAYS_DOUBLESPENDS)
1571+
nDoubleSpendRelayingOutbound++;
15651572
}
15661573
}
15671574
}
@@ -1595,6 +1602,21 @@ void ThreadOpenConnections()
15951602
if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
15961603
continue;
15971604

1605+
// Reserve some outbound connections for nodes that relay
1606+
// double-spends.
1607+
//
1608+
// Unfortunately nServices seems to end up corrupted at times,
1609+
// leading us to adding more nodes than expected, so this is a more
1610+
// strict test than might otherwise be expected.
1611+
//
1612+
// Also, we'll still end up with too many at times, because we'll
1613+
// find out afterwords that what we thought was a node's nServices
1614+
// was incorrect; Bitcoin Core will even stay connected to nodes
1615+
// not advertising NODE_NETWORK in this case.
1616+
if (!((addr.nServices & NODE_RELAYS_DOUBLESPENDS) && (addr.nServices & ~NODE_RELAYS_DOUBLESPENDS) == NODE_NETWORK)
1617+
&& (nOutbound - nDoubleSpendRelayingOutbound >= MAX_STD_OUTBOUND_CONNECTIONS))
1618+
continue;
1619+
15981620
addrConnect = addr;
15991621
break;
16001622
}

src/protocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ enum {
230230
// set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want
231231
// network services but don't provide them.
232232
NODE_NETWORK = (1 << 0),
233+
233234
// NODE_GETUTXO means the node is capable of responding to the getutxo protocol request.
234235
// Bitcoin Core does not support this but a patch set called Bitcoin XT does.
235236
// See BIP 64 for details on how this is implemented.
@@ -250,6 +251,8 @@ enum {
250251
NODE_REPLACE_BY_FEE = (1 << 26),
251252
};
252253

254+
const uint64_t NODE_RELAYS_DOUBLESPENDS = NODE_REPLACE_BY_FEE;
255+
253256
/** A CService with information about it as peer */
254257
class CAddress : public CService
255258
{

0 commit comments

Comments
 (0)