| 2299 | } |
| 2300 | |
| 2301 | static RPCHelpMan utxoupdatepsbt() |
| 2302 | { |
| 2303 | return RPCHelpMan{"utxoupdatepsbt", |
| 2304 | "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n", |
| 2305 | { |
| 2306 | {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}, |
| 2307 | {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "An array of either strings or objects", { |
| 2308 | {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, |
| 2309 | {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", { |
| 2310 | {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, |
| 2311 | {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"}, |
| 2312 | }}, |
| 2313 | }}, |
| 2314 | }, |
| 2315 | RPCResult { |
| 2316 | RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated" |
| 2317 | }, |
| 2318 | RPCExamples { |
| 2319 | HelpExampleCli("utxoupdatepsbt", "\"psbt\"") |
| 2320 | }, |
| 2321 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 2322 | { |
| 2323 | RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true); |
| 2324 | |
| 2325 | // Unserialize the transactions |
| 2326 | PartiallySignedTransaction psbtx; |
| 2327 | std::string error; |
| 2328 | if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { |
| 2329 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error)); |
| 2330 | } |
| 2331 | |
| 2332 | // Parse descriptors, if any. |
| 2333 | FlatSigningProvider provider; |
| 2334 | if (!request.params[1].isNull()) { |
| 2335 | auto descs = request.params[1].get_array(); |
| 2336 | for (size_t i = 0; i < descs.size(); ++i) { |
| 2337 | EvalDescriptorStringOrObject(descs[i], provider); |
| 2338 | } |
| 2339 | } |
| 2340 | // We don't actually need private keys further on; hide them as a precaution. |
| 2341 | HidingSigningProvider public_provider(&provider, /*hide_secret=*/true, /*hide_origin=*/false); |
| 2342 | |
| 2343 | // Fetch previous transactions (inputs): |
| 2344 | CCoinsView viewDummy; |
| 2345 | CCoinsViewCache view(&viewDummy); |
| 2346 | { |
| 2347 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 2348 | const CTxMemPool& mempool = EnsureMemPool(node); |
| 2349 | ChainstateManager& chainman = EnsureChainman(node); |
| 2350 | LOCK2(cs_main, mempool.cs); |
| 2351 | CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip(); |
| 2352 | CCoinsViewMemPool viewMempool(&viewChain, mempool); |
| 2353 | view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view |
| 2354 | |
| 2355 | for (const PSBTInput& txin : psbtx.inputs) { |
| 2356 | view.AccessCoin(txin.GetOutPoint()); // Load entries from viewChain into view; can fail. |
| 2357 | } |
| 2358 |
nothing calls this directly
no test coverage detected