| 1440 | } |
| 1441 | |
| 1442 | std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index) |
| 1443 | { |
| 1444 | if (fImporting) return "Importing..."; |
| 1445 | if (fReindex) return "Reindexing..."; |
| 1446 | |
| 1447 | LOCK(cs_main); |
| 1448 | // Ensure this peer exists and hasn't been disconnected |
| 1449 | CNodeState* state = State(peer_id); |
| 1450 | if (state == nullptr) return "Peer does not exist"; |
| 1451 | // Ignore pre-segwit peers |
| 1452 | if (!state->fHaveWitness) return "Pre-SegWit peer"; |
| 1453 | |
| 1454 | // Mark block as in-flight unless it already is (for this peer). |
| 1455 | // If a block was already in-flight for a different peer, its BLOCKTXN |
| 1456 | // response will be dropped. |
| 1457 | if (!BlockRequested(peer_id, block_index)) return "Already requested from this peer"; |
| 1458 | |
| 1459 | // Construct message to request the block |
| 1460 | const uint256& hash{block_index.GetBlockHash()}; |
| 1461 | std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)}; |
| 1462 | |
| 1463 | // Send block request message to the peer |
| 1464 | bool success = m_connman.ForNode(peer_id, [this, &invs](CNode* node) { |
| 1465 | const CNetMsgMaker msgMaker(node->GetCommonVersion()); |
| 1466 | this->m_connman.PushMessage(node, msgMaker.Make(NetMsgType::GETDATA, invs)); |
| 1467 | return true; |
| 1468 | }); |
| 1469 | |
| 1470 | if (!success) return "Peer not fully connected"; |
| 1471 | |
| 1472 | LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n", |
| 1473 | hash.ToString(), peer_id); |
| 1474 | return std::nullopt; |
| 1475 | } |
| 1476 | |
| 1477 | std::unique_ptr<PeerManager> PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, |
| 1478 | BanMan* banman, ChainstateManager& chainman, |
no test coverage detected