| 127 | } |
| 128 | |
| 129 | static RPCMethod verifytxoutproof() |
| 130 | { |
| 131 | return RPCMethod{ |
| 132 | "verifytxoutproof", |
| 133 | "Verifies that a proof points to a transaction in a block, returning the transaction it commits to\n" |
| 134 | "and throwing an RPC error if the block is not in our best chain\n", |
| 135 | { |
| 136 | {"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded proof generated by gettxoutproof"}, |
| 137 | }, |
| 138 | RPCResult{ |
| 139 | RPCResult::Type::ARR, "", "", |
| 140 | { |
| 141 | {RPCResult::Type::STR_HEX, "txid", "The txid(s) which the proof commits to, or empty array if the proof cannot be validated."}, |
| 142 | } |
| 143 | }, |
| 144 | RPCExamples{""}, |
| 145 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 146 | { |
| 147 | CMerkleBlock merkleBlock; |
| 148 | SpanReader{ParseHexV(request.params[0], "proof")} >> merkleBlock; |
| 149 | |
| 150 | UniValue res(UniValue::VARR); |
| 151 | |
| 152 | std::vector<Txid> vMatch; |
| 153 | std::vector<unsigned int> vIndex; |
| 154 | if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) |
| 155 | return res; |
| 156 | |
| 157 | ChainstateManager& chainman = EnsureAnyChainman(request.context); |
| 158 | LOCK(cs_main); |
| 159 | |
| 160 | const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(merkleBlock.header.GetHash()); |
| 161 | if (!pindex || !chainman.ActiveChain().Contains(*pindex) || pindex->nTx == 0) { |
| 162 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); |
| 163 | } |
| 164 | |
| 165 | // Check if proof is valid, only add results if so |
| 166 | if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { |
| 167 | for (const auto& txid : vMatch) { |
| 168 | res.push_back(txid.GetHex()); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | return res; |
| 173 | }, |
| 174 | }; |
| 175 | } |
| 176 | |
| 177 | void RegisterTxoutProofRPCCommands(CRPCTable& t) |
| 178 | { |
nothing calls this directly
no test coverage detected