| 1261 | } |
| 1262 | |
| 1263 | void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool>& interruptMsgProc) |
| 1264 | { |
| 1265 | AssertLockNotHeld(cs_main); |
| 1266 | |
| 1267 | std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); |
| 1268 | std::vector<CInv> vNotFound; |
| 1269 | const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); |
| 1270 | { |
| 1271 | LOCK(cs_main); |
| 1272 | |
| 1273 | while (it != pfrom->vRecvGetData.end() && (it->type == MSG_TX || it->type == MSG_WITNESS_TX)) { |
| 1274 | if (interruptMsgProc) |
| 1275 | return; |
| 1276 | // Don't bother if send buffer is too full to respond anyway |
| 1277 | if (pfrom->fPauseSend) |
| 1278 | break; |
| 1279 | |
| 1280 | const CInv &inv = *it; |
| 1281 | it++; |
| 1282 | |
| 1283 | // Send stream from relay memory |
| 1284 | bool push = false; |
| 1285 | auto mi = mapRelay.find(inv.hash); |
| 1286 | int nSendFlags = (inv.type == MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0); |
| 1287 | if (mi != mapRelay.end()) { |
| 1288 | connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *mi->second)); |
| 1289 | push = true; |
| 1290 | } else if (pfrom->timeLastMempoolReq) { |
| 1291 | auto txinfo = mempool.info(inv.hash); |
| 1292 | // To protect privacy, do not answer getdata using the mempool when |
| 1293 | // that TX couldn't have been INVed in reply to a MEMPOOL request. |
| 1294 | if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) { |
| 1295 | connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *txinfo.tx)); |
| 1296 | push = true; |
| 1297 | } |
| 1298 | } |
| 1299 | if (!push) { |
| 1300 | vNotFound.push_back(inv); |
| 1301 | } |
| 1302 | } |
| 1303 | } // release cs_main |
| 1304 | |
| 1305 | if (it != pfrom->vRecvGetData.end() && !pfrom->fPauseSend) { |
| 1306 | const CInv &inv = *it; |
| 1307 | if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) { |
| 1308 | it++; |
| 1309 | ProcessGetBlockData(pfrom, chainparams, inv, connman); |
| 1310 | } |
| 1311 | } |
| 1312 | |
| 1313 | pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); |
| 1314 | |
| 1315 | if (!vNotFound.empty()) { |
| 1316 | // Let the peer know that we didn't find what it asked for, so it doesn't |
| 1317 | // have to wait around forever. Currently only SPV clients actually care |
| 1318 | // about this message: it's needed when they are recursively walking the |
| 1319 | // dependencies of relevant unconfirmed transactions. SPV clients want to |
| 1320 | // do that because they want to know about (and store and rebroadcast and |
no test coverage detected