mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 22:50:59 +01:00
Implement utxoupdatepsbt RPC and tests
This commit is contained in:
@@ -1691,6 +1691,70 @@ UniValue converttopsbt(const JSONRPCRequest& request)
|
||||
return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size());
|
||||
}
|
||||
|
||||
UniValue utxoupdatepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"utxoupdatepsbt",
|
||||
"\nUpdates a PSBT with witness UTXOs retrieved from the UTXO set or the mempool.\n",
|
||||
{
|
||||
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
|
||||
},
|
||||
RPCResult {
|
||||
" \"psbt\" (string) The base64-encoded partially signed transaction with inputs updated\n"
|
||||
},
|
||||
RPCExamples {
|
||||
HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
|
||||
}}.ToString());
|
||||
}
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR}, true);
|
||||
|
||||
// Unserialize the transactions
|
||||
PartiallySignedTransaction psbtx;
|
||||
std::string error;
|
||||
if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
|
||||
}
|
||||
|
||||
// Fetch previous transactions (inputs):
|
||||
CCoinsView viewDummy;
|
||||
CCoinsViewCache view(&viewDummy);
|
||||
{
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
CCoinsViewCache &viewChain = *pcoinsTip;
|
||||
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
for (const CTxIn& txin : psbtx.tx->vin) {
|
||||
view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
|
||||
}
|
||||
|
||||
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
|
||||
}
|
||||
|
||||
// Fill the inputs
|
||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||
PSBTInput& input = psbtx.inputs.at(i);
|
||||
|
||||
if (input.non_witness_utxo || !input.witness_utxo.IsNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Coin& coin = view.AccessCoin(psbtx.tx->vin[i].prevout);
|
||||
|
||||
std::vector<std::vector<unsigned char>> solutions_data;
|
||||
txnouttype which_type = Solver(coin.out.scriptPubKey, solutions_data);
|
||||
if (which_type == TX_WITNESS_V0_SCRIPTHASH || which_type == TX_WITNESS_V0_KEYHASH || which_type == TX_WITNESS_UNKNOWN) {
|
||||
input.witness_utxo = coin.out;
|
||||
}
|
||||
}
|
||||
|
||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssTx << psbtx;
|
||||
return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size());
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) argNames
|
||||
@@ -1709,6 +1773,7 @@ static const CRPCCommand commands[] =
|
||||
{ "rawtransactions", "finalizepsbt", &finalizepsbt, {"psbt", "extract"} },
|
||||
{ "rawtransactions", "createpsbt", &createpsbt, {"inputs","outputs","locktime","replaceable"} },
|
||||
{ "rawtransactions", "converttopsbt", &converttopsbt, {"hexstring","permitsigdata","iswitness"} },
|
||||
{ "rawtransactions", "utxoupdatepsbt", &utxoupdatepsbt, {"psbt"} },
|
||||
|
||||
{ "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
|
||||
{ "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
|
||||
|
||||
Reference in New Issue
Block a user