From 93e447b631440aee505a7c884a59c0885f9d968c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 11 Apr 2012 12:38:03 -0400 Subject: [PATCH 1/3] BIP 0031: pong message Add a pong message that is sent in reply to a ping. It echoes back a nonce field that is now added to the ping message. Send a nonce of zero in ping messages. Original author: Mike Hearn @ Google Modified Mike's change to introduce a mild form of protocol documentation in version.h. --- src/main.cpp | 28 +++++++++++++++++++++++++--- src/version.h | 3 +++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b9c9db7a6..fbe9232ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2652,6 +2652,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) else if (strCommand == "ping") { + if (pfrom->nVersion > BIP0031_VERSION) + { + uint64 nonce = 0; + vRecv >> nonce; + // Echo the message back with the nonce. This allows for two useful features: + // + // 1) A remote node can quickly check if the connection is operational + // 2) Remote nodes can measure the latency of the network thread. If this node + // is overloaded it won't respond to pings quickly and the remote node can + // avoid sending us more work, like chain download requests. + // + // The nonce stops the remote getting confused between different pings: without + // it, if the remote node sends a ping once per second and this node takes 5 + // seconds to respond to each, the 5th ping the remote sends would appear to + // return very quickly. + pfrom->PushMessage("pong", nonce); + } } @@ -2814,9 +2831,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pto->nVersion == 0) return true; - // Keep-alive ping - if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) - pto->PushMessage("ping"); + // Keep-alive ping. We send a nonce of zero because we don't use it anywhere + // right now. + if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) { + if (pto->nVersion > BIP0031_VERSION) + pto->PushMessage("ping", 0); + else + pto->PushMessage("ping"); + } // Resend wallet transactions that haven't gotten in a block yet ResendWalletTransactions(); diff --git a/src/version.h b/src/version.h index c93b28fb7..e0e216aad 100644 --- a/src/version.h +++ b/src/version.h @@ -11,4 +11,7 @@ extern const std::string CLIENT_BUILD; extern const std::string CLIENT_DATE; extern const int CLIENT_VERSION; +// BIP 0031, pong message, is enabled for all versions AFTER this one +const int BIP0031_VERSION = 60000; + #endif From b87c0fc4403040185b625d1b21bbff0cb7c828d7 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 12 Apr 2012 12:23:58 -0400 Subject: [PATCH 2/3] version.h: separate client, net sections. Move more constants to this file. * move PROTOCOL_VERSION to version.h * move CLIENT_VERSION* to version.h, make available past cpp stage * clearly separate client, network version portions of version.h --- src/serialize.h | 3 +-- src/version.cpp | 10 ---------- src/version.h | 24 ++++++++++++++++++++++-- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index 2d4aaba6a..d34f3e557 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -20,6 +20,7 @@ #include #include "allocators.h" +#include "version.h" typedef long long int64; typedef unsigned long long uint64; @@ -29,8 +30,6 @@ class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int PROTOCOL_VERSION = 60000; - // Used to bypass the rule against non-const reference to temporary // where it makes sense with wrappers such as CFlatData or CTxDB template diff --git a/src/version.cpp b/src/version.cpp index e1be5f491..0c1e8bfa8 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -11,18 +11,8 @@ const std::string CLIENT_NAME("Satoshi"); // Client version number -#define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 6 -#define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 99 #define CLIENT_VERSION_SUFFIX "-beta" -const int CLIENT_VERSION = 1000000 * CLIENT_VERSION_MAJOR - + 10000 * CLIENT_VERSION_MINOR - + 100 * CLIENT_VERSION_REVISION - + 1 * CLIENT_VERSION_BUILD; - - // The following part of the code determines the CLIENT_BUILD variable. // Several mechanisms are used for this: diff --git a/src/version.h b/src/version.h index e0e216aad..1ea1a0dbb 100644 --- a/src/version.h +++ b/src/version.h @@ -6,12 +6,32 @@ #include +// +// client versioning +// + +static const int CLIENT_VERSION_MAJOR = 0; +static const int CLIENT_VERSION_MINOR = 6; +static const int CLIENT_VERSION_REVISION = 0; +static const int CLIENT_VERSION_BUILD = 99; + +static const int CLIENT_VERSION = + 1000000 * CLIENT_VERSION_MAJOR + + 10000 * CLIENT_VERSION_MINOR + + 100 * CLIENT_VERSION_REVISION + + 1 * CLIENT_VERSION_BUILD; + extern const std::string CLIENT_NAME; extern const std::string CLIENT_BUILD; extern const std::string CLIENT_DATE; -extern const int CLIENT_VERSION; + +// +// network protocol versioning +// + +static const int PROTOCOL_VERSION = 60000; // BIP 0031, pong message, is enabled for all versions AFTER this one -const int BIP0031_VERSION = 60000; +static const int BIP0031_VERSION = 60000; #endif From 8b09cd3a4db2d712e91826d44a0e777478b450c6 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 12 Apr 2012 20:07:49 -0400 Subject: [PATCH 3/3] Replace several network protocol version numbers with named constants stored in version.h. Also, a minor CAddress code reformat while we're in there, fixing some incorrect indentation. --- src/main.cpp | 11 ++++++----- src/net.h | 4 ++-- src/protocol.h | 7 ++++--- src/version.h | 11 +++++++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fbe9232ac..b270fd0cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2185,7 +2185,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CAddress addrFrom; uint64 nNonce = 1; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; - if (pfrom->nVersion < 209) + if (pfrom->nVersion < MIN_PROTO_VERSION) { // Since February 20, 2012, the protocol is initiated at version 209, // and earlier versions are no longer supported @@ -2235,7 +2235,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } // Get recent addresses - if (pfrom->nVersion >= 31402 || addrman.size() < 1000) + if (pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) { pfrom->PushMessage("getaddr"); pfrom->fGetAddr = true; @@ -2252,7 +2252,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Ask the first connected node for block updates static int nAskedForBlocks = 0; if (!pfrom->fClient && - (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) && + (pfrom->nVersion < NOBLKS_VERSION_START || + pfrom->nVersion >= NOBLKS_VERSION_END) && (nAskedForBlocks < 1 || vNodes.size() <= 1)) { nAskedForBlocks++; @@ -2294,7 +2295,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> vAddr; // Don't want addr from older versions unless seeding - if (pfrom->nVersion < 31402 && addrman.size() > 1000) + if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) return true; if (vAddr.size() > 1000) { @@ -2331,7 +2332,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) multimap mapMix; BOOST_FOREACH(CNode* pnode, vNodes) { - if (pnode->nVersion < 31402) + if (pnode->nVersion < CADDR_TIME_VERSION) continue; unsigned int nPointer; memcpy(&nPointer, &pnode, sizeof(nPointer)); diff --git a/src/net.h b/src/net.h index 3c84650c2..bb2d455d9 100644 --- a/src/net.h +++ b/src/net.h @@ -163,8 +163,8 @@ public: hSocket = hSocketIn; vSend.SetType(SER_NETWORK); vRecv.SetType(SER_NETWORK); - vSend.SetVersion(209); - vRecv.SetVersion(209); + vSend.SetVersion(MIN_PROTO_VERSION); + vRecv.SetVersion(MIN_PROTO_VERSION); nLastSend = 0; nLastRecv = 0; nLastSendEmpty = GetTime(); diff --git a/src/protocol.h b/src/protocol.h index e63912735..a820563d0 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -79,9 +79,10 @@ class CAddress : public CService if (fRead) pthis->Init(); if (nType & SER_DISK) - READWRITE(nVersion); - if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH))) - READWRITE(nTime); + READWRITE(nVersion); + if ((nType & SER_DISK) || + (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) + READWRITE(nTime); READWRITE(nServices); READWRITE(*pip); ) diff --git a/src/version.h b/src/version.h index 1ea1a0dbb..d71041574 100644 --- a/src/version.h +++ b/src/version.h @@ -31,6 +31,17 @@ extern const std::string CLIENT_DATE; static const int PROTOCOL_VERSION = 60000; +// earlier versions not supported as of Feb 2012, and are disconnected +static const int MIN_PROTO_VERSION = 209; + +// nTime field added to CAddress, starting with this version; +// if possible, avoid requesting addresses nodes older than this +static const int CADDR_TIME_VERSION = 31402; + +// only request blocks from nodes outside this range of versions +static const int NOBLKS_VERSION_START = 32000; +static const int NOBLKS_VERSION_END = 32400; + // BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000;