Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; | static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; | ||||
/// Age after which a stale block will no longer be served if requested as | /// Age after which a stale block will no longer be served if requested as | ||||
/// protection against fingerprinting. Set to one month, denominated in seconds. | /// protection against fingerprinting. Set to one month, denominated in seconds. | ||||
static constexpr int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60; | static constexpr int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60; | ||||
/// Age after which a block is considered historical for purposes of rate | /// Age after which a block is considered historical for purposes of rate | ||||
/// limiting block relay. Set to one week, denominated in seconds. | /// limiting block relay. Set to one week, denominated in seconds. | ||||
static constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60; | static constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60; | ||||
/** | /** | ||||
* Time between pings automatically sent out for latency probing and keepalive | * Time between pings automatically sent out for latency probing and keepalive. | ||||
* (in seconds). | |||||
*/ | */ | ||||
static const int PING_INTERVAL = 2 * 60; | static constexpr std::chrono::minutes PING_INTERVAL{2}; | ||||
/** The maximum number of entries in a locator */ | /** The maximum number of entries in a locator */ | ||||
static const unsigned int MAX_LOCATOR_SZ = 101; | static const unsigned int MAX_LOCATOR_SZ = 101; | ||||
/** The maximum number of entries in an 'inv' protocol message */ | /** The maximum number of entries in an 'inv' protocol message */ | ||||
static const unsigned int MAX_INV_SZ = 50000; | static const unsigned int MAX_INV_SZ = 50000; | ||||
static_assert(MAX_PROTOCOL_MESSAGE_LENGTH > MAX_INV_SZ * sizeof(CInv), | static_assert(MAX_PROTOCOL_MESSAGE_LENGTH > MAX_INV_SZ * sizeof(CInv), | ||||
"Max protocol message length must be greater than largest " | "Max protocol message length must be greater than largest " | ||||
"possible INV message"); | "possible INV message"); | ||||
/** Maximum number of in-flight transactions from a peer */ | /** Maximum number of in-flight transactions from a peer */ | ||||
▲ Show 20 Lines • Show All 2,539 Lines • ▼ Show 20 Lines | static void ProcessGetCFCheckPt(CNode &peer, CDataStream &vRecv, | ||||
CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | ||||
.Make(NetMsgType::CFCHECKPT, filter_type_ser, | .Make(NetMsgType::CFCHECKPT, filter_type_ser, | ||||
stop_index->GetBlockHash(), headers); | stop_index->GetBlockHash(), headers); | ||||
connman.PushMessage(&peer, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
void PeerManager::ProcessMessage(const Config &config, CNode &pfrom, | void PeerManager::ProcessMessage(const Config &config, CNode &pfrom, | ||||
const std::string &msg_type, | const std::string &msg_type, | ||||
CDataStream &vRecv, int64_t nTimeReceived, | CDataStream &vRecv, | ||||
const std::chrono::microseconds time_received, | |||||
const std::atomic<bool> &interruptMsgProc) { | const std::atomic<bool> &interruptMsgProc) { | ||||
LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", | LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", | ||||
SanitizeString(msg_type), vRecv.size(), pfrom.GetId()); | SanitizeString(msg_type), vRecv.size(), pfrom.GetId()); | ||||
if (gArgs.IsArgSet("-dropmessagestest") && | if (gArgs.IsArgSet("-dropmessagestest") && | ||||
GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) { | GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) { | ||||
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); | LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,027 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::CMPCTBLOCK) { | ||||
// treatment as a header message. | // treatment as a header message. | ||||
fRevertToHeaderProcessing = true; | fRevertToHeaderProcessing = true; | ||||
} | } | ||||
} | } | ||||
} // cs_main | } // cs_main | ||||
if (fProcessBLOCKTXN) { | if (fProcessBLOCKTXN) { | ||||
return ProcessMessage(config, pfrom, NetMsgType::BLOCKTXN, | return ProcessMessage(config, pfrom, NetMsgType::BLOCKTXN, | ||||
blockTxnMsg, nTimeReceived, interruptMsgProc); | blockTxnMsg, time_received, interruptMsgProc); | ||||
} | } | ||||
if (fRevertToHeaderProcessing) { | if (fRevertToHeaderProcessing) { | ||||
// Headers received from HB compact block peers are permitted to be | // Headers received from HB compact block peers are permitted to be | ||||
// relayed before full validation (see BIP 152), so we don't want to | // relayed before full validation (see BIP 152), so we don't want to | ||||
// disconnect the peer if the header turns out to be for an invalid | // disconnect the peer if the header turns out to be for an invalid | ||||
// block. Note that if a peer tries to build on an invalid chain, | // block. Note that if a peer tries to build on an invalid chain, | ||||
// that will be detected and the peer will be banned. | // that will be detected and the peer will be banned. | ||||
▲ Show 20 Lines • Show All 504 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::PING) { | ||||
// ping the remote sends would appear to return very quickly. | // ping the remote sends would appear to return very quickly. | ||||
m_connman.PushMessage(&pfrom, | m_connman.PushMessage(&pfrom, | ||||
msgMaker.Make(NetMsgType::PONG, nonce)); | msgMaker.Make(NetMsgType::PONG, nonce)); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::PONG) { | if (msg_type == NetMsgType::PONG) { | ||||
int64_t pingUsecEnd = nTimeReceived; | const auto ping_end = time_received; | ||||
uint64_t nonce = 0; | uint64_t nonce = 0; | ||||
size_t nAvail = vRecv.in_avail(); | size_t nAvail = vRecv.in_avail(); | ||||
bool bPingFinished = false; | bool bPingFinished = false; | ||||
std::string sProblem; | std::string sProblem; | ||||
if (nAvail >= sizeof(nonce)) { | if (nAvail >= sizeof(nonce)) { | ||||
vRecv >> nonce; | vRecv >> nonce; | ||||
// Only process pong message if there is an outstanding ping (old | // Only process pong message if there is an outstanding ping (old | ||||
// ping without nonce should never pong) | // ping without nonce should never pong) | ||||
if (pfrom.nPingNonceSent != 0) { | if (pfrom.nPingNonceSent != 0) { | ||||
if (nonce == pfrom.nPingNonceSent) { | if (nonce == pfrom.nPingNonceSent) { | ||||
// Matching pong received, this ping is no longer | // Matching pong received, this ping is no longer | ||||
// outstanding | // outstanding | ||||
bPingFinished = true; | bPingFinished = true; | ||||
int64_t pingUsecTime = pingUsecEnd - pfrom.nPingUsecStart; | const auto ping_time = ping_end - pfrom.m_ping_start.load(); | ||||
if (pingUsecTime > 0) { | if (ping_time.count() > 0) { | ||||
// Successful ping time measurement, replace previous | // Successful ping time measurement, replace previous | ||||
pfrom.nPingUsecTime = pingUsecTime; | pfrom.nPingUsecTime = count_microseconds(ping_time); | ||||
pfrom.nMinPingUsecTime = std::min( | pfrom.nMinPingUsecTime = | ||||
pfrom.nMinPingUsecTime.load(), pingUsecTime); | std::min(pfrom.nMinPingUsecTime.load(), | ||||
count_microseconds(ping_time)); | |||||
} else { | } else { | ||||
// This should never happen | // This should never happen | ||||
sProblem = "Timing mishap"; | sProblem = "Timing mishap"; | ||||
} | } | ||||
} else { | } else { | ||||
// Nonce mismatches are normal when pings are overlapping | // Nonce mismatches are normal when pings are overlapping | ||||
sProblem = "Nonce mismatch"; | sProblem = "Nonce mismatch"; | ||||
if (nonce == 0) { | if (nonce == 0) { | ||||
▲ Show 20 Lines • Show All 546 Lines • ▼ Show 20 Lines | bool PeerManager::SendMessages(const Config &config, CNode *pto, | ||||
// | // | ||||
// Message: ping | // Message: ping | ||||
// | // | ||||
bool pingSend = false; | bool pingSend = false; | ||||
if (pto->fPingQueued) { | if (pto->fPingQueued) { | ||||
// RPC ping request by user | // RPC ping request by user | ||||
pingSend = true; | pingSend = true; | ||||
} | } | ||||
if (pto->nPingNonceSent == 0 && | if (pto->nPingNonceSent == 0 && pto->m_ping_start.load() + PING_INTERVAL < | ||||
pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) { | GetTime<std::chrono::microseconds>()) { | ||||
// Ping automatically sent as a latency probe & keepalive. | // Ping automatically sent as a latency probe & keepalive. | ||||
pingSend = true; | pingSend = true; | ||||
} | } | ||||
if (pingSend) { | if (pingSend) { | ||||
uint64_t nonce = 0; | uint64_t nonce = 0; | ||||
while (nonce == 0) { | while (nonce == 0) { | ||||
GetRandBytes((uint8_t *)&nonce, sizeof(nonce)); | GetRandBytes((uint8_t *)&nonce, sizeof(nonce)); | ||||
} | } | ||||
pto->fPingQueued = false; | pto->fPingQueued = false; | ||||
pto->nPingUsecStart = GetTimeMicros(); | pto->m_ping_start = GetTime<std::chrono::microseconds>(); | ||||
if (pto->nVersion > BIP0031_VERSION) { | if (pto->nVersion > BIP0031_VERSION) { | ||||
pto->nPingNonceSent = nonce; | pto->nPingNonceSent = nonce; | ||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce)); | m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce)); | ||||
} else { | } else { | ||||
// Peer is too old to support ping command with nonce, pong will | // Peer is too old to support ping command with nonce, pong will | ||||
// never arrive. | // never arrive. | ||||
pto->nPingNonceSent = 0; | pto->nPingNonceSent = 0; | ||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING)); | m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING)); | ||||
▲ Show 20 Lines • Show All 697 Lines • Show Last 20 Lines |