|
59 | 59 | using namespace std; |
60 | 60 |
|
61 | 61 | 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; |
63 | 66 |
|
64 | 67 | struct ListenSocket { |
65 | 68 | SOCKET socket; |
@@ -1555,13 +1558,17 @@ void ThreadOpenConnections() |
1555 | 1558 | // Only connect out to one peer per network group (/16 for IPv4). |
1556 | 1559 | // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. |
1557 | 1560 | int nOutbound = 0; |
| 1561 | + int nDoubleSpendRelayingOutbound = 0; |
1558 | 1562 | set<vector<unsigned char> > setConnected; |
1559 | 1563 | { |
1560 | 1564 | LOCK(cs_vNodes); |
1561 | 1565 | BOOST_FOREACH(CNode* pnode, vNodes) { |
1562 | 1566 | if (!pnode->fInbound) { |
1563 | 1567 | setConnected.insert(pnode->addr.GetGroup()); |
1564 | 1568 | nOutbound++; |
| 1569 | + |
| 1570 | + if (pnode->nServices & NODE_RELAYS_DOUBLESPENDS) |
| 1571 | + nDoubleSpendRelayingOutbound++; |
1565 | 1572 | } |
1566 | 1573 | } |
1567 | 1574 | } |
@@ -1595,6 +1602,21 @@ void ThreadOpenConnections() |
1595 | 1602 | if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50) |
1596 | 1603 | continue; |
1597 | 1604 |
|
| 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 | + |
1598 | 1620 | addrConnect = addr; |
1599 | 1621 | break; |
1600 | 1622 | } |
|
0 commit comments