MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / getblockfrompeer

Function getblockfrompeer

src/rpc/blockchain.cpp:524–577  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

522}
523
524static RPCMethod getblockfrompeer()
525{
526 return RPCMethod{
527 "getblockfrompeer",
528 "Attempt to fetch block from a given peer.\n\n"
529 "We must have the header for this block, e.g. using submitheader.\n"
530 "The block will not have any undo data which can limit the usage of the block data in a context where the undo data is needed.\n"
531 "Subsequent calls for the same block may cause the response from the previous peer to be ignored.\n"
532 "Peers generally ignore requests for a stale block that they never fully verified, or one that is more than a month old.\n"
533 "When a peer does not respond with a block, we will disconnect.\n"
534 "Note: The block could be re-pruned as soon as it is received.\n\n"
535 "Returns an empty JSON object if the request was successfully scheduled.",
536 {
537 {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash to try to fetch"},
538 {"peer_id", RPCArg::Type::NUM, RPCArg::Optional::NO, "The peer to fetch it from (see getpeerinfo for peer IDs)"},
539 },
540 RPCResult{RPCResult::Type::OBJ, "", /*optional=*/false, "", {}},
541 RPCExamples{
542 HelpExampleCli("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
543 + HelpExampleRpc("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
544 },
545 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
546{
547 const NodeContext& node = EnsureAnyNodeContext(request.context);
548 ChainstateManager& chainman = EnsureChainman(node);
549 PeerManager& peerman = EnsurePeerman(node);
550
551 const uint256& block_hash{ParseHashV(request.params[0], "blockhash")};
552 const NodeId peer_id{request.params[1].getInt<int64_t>()};
553
554 const CBlockIndex* const index = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(block_hash););
555
556 if (!index) {
557 throw JSONRPCError(RPC_MISC_ERROR, "Block header missing");
558 }
559
560 // Fetching blocks before the node has syncing past their height can prevent block files from
561 // being pruned, so we avoid it if the node is in prune mode.
562 if (chainman.m_blockman.IsPruneMode() && index->nHeight > WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip()->nHeight)) {
563 throw JSONRPCError(RPC_MISC_ERROR, "In prune mode, only blocks that the node has already synced previously can be fetched from a peer");
564 }
565
566 const bool block_has_data = WITH_LOCK(::cs_main, return index->nStatus & BLOCK_HAVE_DATA);
567 if (block_has_data) {
568 throw JSONRPCError(RPC_MISC_ERROR, "Block already downloaded");
569 }
570
571 if (const auto res{peerman.FetchBlock(peer_id, *index)}; !res) {
572 throw JSONRPCError(RPC_MISC_ERROR, res.error());
573 }
574 return UniValue::VOBJ;
575},
576 };
577}
578
579static RPCMethod getblockhash()
580{

Callers

nothing calls this directly

Calls 8

HelpExampleCliFunction · 0.85
HelpExampleRpcFunction · 0.85
ParseHashVFunction · 0.85
JSONRPCErrorFunction · 0.85
LookupBlockIndexMethod · 0.80
IsPruneModeMethod · 0.80
FetchBlockMethod · 0.80
errorMethod · 0.45

Tested by

no test coverage detected