Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 3,016 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::INV) { | ||||
// mode if whitelistrelay is true | // mode if whitelistrelay is true | ||||
if (pfrom.HasPermission(PF_RELAY)) { | if (pfrom.HasPermission(PF_RELAY)) { | ||||
fBlocksOnly = false; | fBlocksOnly = false; | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const auto current_time = GetTime<std::chrono::microseconds>(); | const auto current_time = GetTime<std::chrono::microseconds>(); | ||||
std::optional<BlockHash> best_block; | |||||
for (CInv &inv : vInv) { | for (CInv &inv : vInv) { | ||||
if (interruptMsgProc) { | if (interruptMsgProc) { | ||||
return; | return; | ||||
} | } | ||||
bool fAlreadyHave = AlreadyHave(inv, m_mempool); | bool fAlreadyHave = AlreadyHave(inv, m_mempool); | ||||
LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), | LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), | ||||
fAlreadyHave ? "have" : "new", pfrom.GetId()); | fAlreadyHave ? "have" : "new", pfrom.GetId()); | ||||
if (inv.type == MSG_BLOCK) { | if (inv.type == MSG_BLOCK) { | ||||
const BlockHash hash(inv.hash); | const BlockHash hash{inv.hash}; | ||||
UpdateBlockAvailability(pfrom.GetId(), hash); | UpdateBlockAvailability(pfrom.GetId(), hash); | ||||
if (!fAlreadyHave && !fImporting && !fReindex && | if (!fAlreadyHave && !fImporting && !fReindex && | ||||
!mapBlocksInFlight.count(hash)) { | !mapBlocksInFlight.count(hash)) { | ||||
// We used to request the full block here, but since | // Headers-first is the primary method of announcement on | ||||
// headers-announcements are now the primary method of | // the network. If a node fell back to sending blocks by | ||||
// announcement on the network, and since, in the case that | // inv, it's probably for a re-org. The final block hash | ||||
// a node fell back to inv we probably have a reorg which we | // provided should be the highest, so send a getheaders and | ||||
// should get the headers for first, we now only provide a | // then fetch the blocks we need to catch up. | ||||
// getheaders response here. When we receive the headers, we | best_block = std::move(hash); | ||||
// will then ask for the blocks we need. | |||||
m_connman.PushMessage( | |||||
&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, | |||||
::ChainActive().GetLocator( | |||||
pindexBestHeader), | |||||
hash)); | |||||
LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", | |||||
pindexBestHeader->nHeight, hash.ToString(), | |||||
pfrom.GetId()); | |||||
} | } | ||||
} else { | } else { | ||||
const TxId txid(inv.hash); | const TxId txid(inv.hash); | ||||
pfrom.AddKnownTx(txid); | pfrom.AddKnownTx(txid); | ||||
if (fBlocksOnly) { | if (fBlocksOnly) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"transaction (%s) inv sent in violation of " | "transaction (%s) inv sent in violation of " | ||||
"protocol, disconnecting peer=%d\n", | "protocol, disconnecting peer=%d\n", | ||||
txid.ToString(), pfrom.GetId()); | txid.ToString(), pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} else if (!fAlreadyHave && !fImporting && !fReindex && | } else if (!fAlreadyHave && !fImporting && !fReindex && | ||||
!::ChainstateActive().IsInitialBlockDownload()) { | !::ChainstateActive().IsInitialBlockDownload()) { | ||||
RequestTx(State(pfrom.GetId()), txid, current_time); | RequestTx(State(pfrom.GetId()), txid, current_time); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (best_block) { | |||||
m_connman.PushMessage( | |||||
&pfrom, | |||||
msgMaker.Make(NetMsgType::GETHEADERS, | |||||
::ChainActive().GetLocator(pindexBestHeader), | |||||
*best_block)); | |||||
LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", | |||||
pindexBestHeader->nHeight, best_block->ToString(), | |||||
pfrom.GetId()); | |||||
} | |||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETDATA) { | if (msg_type == NetMsgType::GETDATA) { | ||||
std::vector<CInv> vInv; | std::vector<CInv> vInv; | ||||
vRecv >> vInv; | vRecv >> vInv; | ||||
if (vInv.size() > MAX_INV_SZ) { | if (vInv.size() > MAX_INV_SZ) { | ||||
Misbehaving(pfrom, 20, | Misbehaving(pfrom, 20, | ||||
▲ Show 20 Lines • Show All 2,430 Lines • Show Last 20 Lines |