| 2965 | } |
| 2966 | |
| 2967 | static RPCMethod getblockfilter() |
| 2968 | { |
| 2969 | return RPCMethod{ |
| 2970 | "getblockfilter", |
| 2971 | "Retrieve a BIP 157 content filter for a particular block.\n", |
| 2972 | { |
| 2973 | {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hash of the block"}, |
| 2974 | {"filtertype", RPCArg::Type::STR, RPCArg::Default{BlockFilterTypeName(BlockFilterType::BASIC)}, "The type name of the filter"}, |
| 2975 | }, |
| 2976 | RPCResult{ |
| 2977 | RPCResult::Type::OBJ, "", "", |
| 2978 | { |
| 2979 | {RPCResult::Type::STR_HEX, "filter", "the hex-encoded filter data"}, |
| 2980 | {RPCResult::Type::STR_HEX, "header", "the hex-encoded filter header"}, |
| 2981 | }}, |
| 2982 | RPCExamples{ |
| 2983 | HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") + |
| 2984 | HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"") |
| 2985 | }, |
| 2986 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 2987 | { |
| 2988 | uint256 block_hash = ParseHashV(request.params[0], "blockhash"); |
| 2989 | auto filtertype_name{self.Arg<std::string_view>("filtertype")}; |
| 2990 | |
| 2991 | BlockFilterType filtertype; |
| 2992 | if (!BlockFilterTypeByName(filtertype_name, filtertype)) { |
| 2993 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown filtertype"); |
| 2994 | } |
| 2995 | |
| 2996 | BlockFilterIndex* index = GetBlockFilterIndex(filtertype); |
| 2997 | if (!index) { |
| 2998 | throw JSONRPCError(RPC_MISC_ERROR, tfm::format("Index is not enabled for filtertype %s", filtertype_name)); |
| 2999 | } |
| 3000 | |
| 3001 | const CBlockIndex* block_index; |
| 3002 | bool block_was_connected; |
| 3003 | { |
| 3004 | ChainstateManager& chainman = EnsureAnyChainman(request.context); |
| 3005 | LOCK(cs_main); |
| 3006 | block_index = chainman.m_blockman.LookupBlockIndex(block_hash); |
| 3007 | if (!block_index) { |
| 3008 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); |
| 3009 | } |
| 3010 | block_was_connected = block_index->IsValid(BLOCK_VALID_SCRIPTS); |
| 3011 | } |
| 3012 | |
| 3013 | bool index_ready = index->BlockUntilSyncedToCurrentChain(); |
| 3014 | |
| 3015 | BlockFilter filter; |
| 3016 | uint256 filter_header; |
| 3017 | if (!index->LookupFilter(block_index, filter) || |
| 3018 | !index->LookupFilterHeader(block_index, filter_header)) { |
| 3019 | int err_code; |
| 3020 | std::string errmsg = "Filter not found."; |
| 3021 | |
| 3022 | if (!block_was_connected) { |
| 3023 | err_code = RPC_INVALID_ADDRESS_OR_KEY; |
| 3024 | errmsg += " Block was not connected to active chain."; |
nothing calls this directly
no test coverage detected