| 1246 | } |
| 1247 | |
| 1248 | bool PeerManagerImpl::BlockRequested(NodeId nodeid, const CBlockIndex& block, std::list<QueuedBlock>::iterator** pit) |
| 1249 | { |
| 1250 | const uint256& hash{block.GetBlockHash()}; |
| 1251 | |
| 1252 | CNodeState *state = State(nodeid); |
| 1253 | assert(state != nullptr); |
| 1254 | |
| 1255 | Assume(mapBlocksInFlight.count(hash) <= MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK); |
| 1256 | |
| 1257 | // Short-circuit most stuff in case it is from the same node |
| 1258 | for (auto range = mapBlocksInFlight.equal_range(hash); range.first != range.second; range.first++) { |
| 1259 | if (range.first->second.first == nodeid) { |
| 1260 | if (pit) { |
| 1261 | *pit = &range.first->second.second; |
| 1262 | } |
| 1263 | return false; |
| 1264 | } |
| 1265 | } |
| 1266 | |
| 1267 | // Make sure it's not being fetched already from same peer. |
| 1268 | RemoveBlockRequest(hash, nodeid); |
| 1269 | |
| 1270 | std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), |
| 1271 | {&block, std::unique_ptr<PartiallyDownloadedBlock>(pit ? new PartiallyDownloadedBlock(&m_mempool) : nullptr)}); |
| 1272 | if (state->vBlocksInFlight.size() == 1) { |
| 1273 | // We're starting a block download (batch) from this peer. |
| 1274 | state->m_downloading_since = GetTime<std::chrono::microseconds>(); |
| 1275 | m_peers_downloading_from++; |
| 1276 | } |
| 1277 | auto itInFlight = mapBlocksInFlight.insert(std::make_pair(hash, std::make_pair(nodeid, it))); |
| 1278 | if (pit) { |
| 1279 | *pit = &itInFlight->second.second; |
| 1280 | } |
| 1281 | return true; |
| 1282 | } |
| 1283 | |
| 1284 | void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid) |
| 1285 | { |