Overwinter peer management and network handshaking.

Implements ZIP 201.
This commit is contained in:
Simon 2018-02-20 11:03:40 -08:00
parent 2423a40c08
commit 72b2192950
4 changed files with 61 additions and 1 deletions

View File

@ -4721,6 +4721,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return false;
}
// When Overwinter is active, reject incoming connections from non-Overwinter nodes
const Consensus::Params& params = Params().GetConsensus();
if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
&& pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
{
LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
strprintf("Version must be %d or greater",
params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
pfrom->fDisconnect = true;
return false;
}
if (pfrom->nVersion == 10300)
pfrom->nVersion = 300;
if (!vRecv.empty())
@ -4839,6 +4852,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
// Disconnect existing peer connection when:
// 1. The version message has been received
// 2. Overwinter is active
// 3. Peer version is pre-Overwinter
else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
&& (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
{
LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
strprintf("Version must be %d or greater",
chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
pfrom->fDisconnect = true;
return false;
}
else if (strCommand == "addr")
{
vector<CAddress> vAddr;

View File

@ -7,6 +7,7 @@
#include "config/bitcoin-config.h"
#endif
#include "main.h"
#include "net.h"
#include "addrman.h"
@ -812,6 +813,34 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Protect connections with certain characteristics
// Check version of eviction candidates and prioritize nodes which do not support network upgrade.
std::vector<CNodeRef> vTmpEvictionCandidates;
int height;
{
LOCK(cs_main);
height = chainActive.Height();
}
const Consensus::Params& params = Params().GetConsensus();
int nActivationHeight = params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight;
if (nActivationHeight > 0 &&
height < nActivationHeight &&
height >= nActivationHeight - NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD)
{
// Find any nodes which don't support Overwinter protocol version
BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
if (node->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion) {
vTmpEvictionCandidates.push_back(node);
}
}
// Prioritize these nodes by replacing eviction set with them
if (vTmpEvictionCandidates.size() > 0) {
vEvictionCandidates = vTmpEvictionCandidates;
}
}
// Deterministically select 4 peers to protect by netgroup.
// An attacker cannot predict which netgroups will be protected.
static CompareNetGroupKeyed comparerNetGroupKeyed;

View File

@ -57,6 +57,8 @@ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
/** The maximum number of peer connections to maintain. */
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;
unsigned int ReceiveFloodSize();
unsigned int SendBufferSize();

View File

@ -9,7 +9,7 @@
* network protocol versioning
*/
static const int PROTOCOL_VERSION = 170002;
static const int PROTOCOL_VERSION = 170003;
//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;