| 4558 | } |
| 4559 | |
| 4560 | void static ProcessGetData(CNode* pfrom) |
| 4561 | { |
| 4562 | std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); |
| 4563 | |
| 4564 | vector<CInv> vNotFound; |
| 4565 | |
| 4566 | LOCK(cs_main); |
| 4567 | |
| 4568 | while (it != pfrom->vRecvGetData.end()) { |
| 4569 | // Don't bother if send buffer is too full to respond anyway |
| 4570 | if (pfrom->nSendSize >= SendBufferSize()) |
| 4571 | break; |
| 4572 | |
| 4573 | const CInv &inv = *it; |
| 4574 | { |
| 4575 | boost::this_thread::interruption_point(); |
| 4576 | it++; |
| 4577 | |
| 4578 | BlockSender blockSender; |
| 4579 | if (blockSender.isBlockType(inv.type)) |
| 4580 | { |
| 4581 | BlockMap::iterator mi = mapBlockIndex.find(inv.hash); |
| 4582 | bool haveBlock = mi != mapBlockIndex.end(); |
| 4583 | bool canSend = haveBlock && blockSender.canSend( |
| 4584 | chainActive, *(mi->second), pindexBestHeader); |
| 4585 | |
| 4586 | if (canSend) |
| 4587 | blockSender.send(chainActive, *pfrom, *(mi->second), inv); |
| 4588 | } |
| 4589 | else if (inv.IsKnownType()) |
| 4590 | { |
| 4591 | // Send stream from relay memory |
| 4592 | bool pushed = false; |
| 4593 | { |
| 4594 | LOCK(cs_mapRelay); |
| 4595 | map<CInv, CDataStream>::iterator mi = mapRelay.find(inv); |
| 4596 | if (mi != mapRelay.end()) { |
| 4597 | pfrom->PushMessage(inv.GetCommand(), (*mi).second); |
| 4598 | pushed = true; |
| 4599 | } |
| 4600 | } |
| 4601 | if (!pushed && inv.type == MSG_TX) { |
| 4602 | CTransaction tx; |
| 4603 | if (mempool.lookup(inv.hash, tx)) { |
| 4604 | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); |
| 4605 | ss.reserve(1000); |
| 4606 | ss << tx; |
| 4607 | pfrom->PushMessage("tx", ss); |
| 4608 | pushed = true; |
| 4609 | } |
| 4610 | } |
| 4611 | if (!pushed) { |
| 4612 | vNotFound.push_back(inv); |
| 4613 | } |
| 4614 | } |
| 4615 | |
| 4616 | // Track requests for our stuff. |
| 4617 | GetMainSignals().Inventory(inv.hash); |
no test coverage detected