| 873 | } |
| 874 | |
| 875 | static RPCHelpMan getblockfrompeer() |
| 876 | { |
| 877 | return RPCHelpMan{ |
| 878 | "getblockfrompeer", |
| 879 | "Attempt to fetch block from a given peer.\n\n" |
| 880 | "We must have the header for this block, e.g. using submitheader.\n" |
| 881 | "Subsequent calls for the same block and a new peer will cause the response from the previous peer to be ignored.\n\n" |
| 882 | "Returns an empty JSON object if the request was successfully scheduled.", |
| 883 | { |
| 884 | {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash to try to fetch"}, |
| 885 | {"peer_id", RPCArg::Type::NUM, RPCArg::Optional::NO, "The peer to fetch it from (see getpeerinfo for peer IDs)"}, |
| 886 | }, |
| 887 | RPCResult{RPCResult::Type::OBJ, "", /*optional=*/false, "", {}}, |
| 888 | RPCExamples{ |
| 889 | HelpExampleCli("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0") |
| 890 | + HelpExampleRpc("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0") |
| 891 | }, |
| 892 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 893 | { |
| 894 | const NodeContext& node = EnsureAnyNodeContext(request.context); |
| 895 | ChainstateManager& chainman = EnsureChainman(node); |
| 896 | PeerManager& peerman = EnsurePeerman(node); |
| 897 | |
| 898 | const uint256& block_hash{ParseHashV(request.params[0], "blockhash")}; |
| 899 | const NodeId peer_id{request.params[1].get_int64()}; |
| 900 | |
| 901 | const CBlockIndex* const index = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(block_hash);); |
| 902 | |
| 903 | if (!index) { |
| 904 | throw JSONRPCError(RPC_MISC_ERROR, "Block header missing"); |
| 905 | } |
| 906 | |
| 907 | const bool block_has_data = WITH_LOCK(::cs_main, return index->nStatus & BLOCK_HAVE_DATA); |
| 908 | if (block_has_data) { |
| 909 | throw JSONRPCError(RPC_MISC_ERROR, "Block already downloaded"); |
| 910 | } |
| 911 | |
| 912 | if (const auto err{peerman.FetchBlock(peer_id, *index)}) { |
| 913 | throw JSONRPCError(RPC_MISC_ERROR, err.value()); |
| 914 | } |
| 915 | return UniValue::VOBJ; |
| 916 | }, |
| 917 | }; |
| 918 | } |
| 919 | |
| 920 | static RPCHelpMan getblockhash() |
| 921 | { |
nothing calls this directly
no test coverage detected