Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 1,702 Lines • ▼ Show 20 Lines | static UniValue converttopsbt(const Config &config, | ||||
// Serialize the PSBT | // Serialize the PSBT | ||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); | CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); | ||||
ssTx << psbtx; | ssTx << psbtx; | ||||
return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | ||||
} | } | ||||
UniValue utxoupdatepsbt(const Config &config, 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, | |||||
/* opt */ false, /* default_val */ "", | |||||
"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, g_mempool.cs); | |||||
CCoinsViewCache &viewChain = *pcoinsTip; | |||||
CCoinsViewMemPool viewMempool(&viewChain, g_mempool); | |||||
// temporarily switch cache backend to db+mempool view | |||||
view.SetBackend(viewMempool); | |||||
for (const CTxIn &txin : psbtx.tx->vin) { | |||||
// Load entries from viewChain into view; can fail. | |||||
view.AccessCoin(txin.prevout); | |||||
} | |||||
// switch back to avoid locking mempool for too long | |||||
view.SetBackend(viewDummy); | |||||
} | |||||
// Fill the inputs | |||||
for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) { | |||||
PSBTInput &input = psbtx.inputs.at(i); | |||||
if (!input.utxo.IsNull()) { | |||||
continue; | |||||
} | |||||
input.utxo = view.AccessCoin(psbtx.tx->vin[i].prevout).GetTxOut(); | |||||
} | |||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); | |||||
ssTx << psbtx; | |||||
return EncodeBase64((uint8_t *)ssTx.data(), ssTx.size()); | |||||
} | |||||
// clang-format off | // clang-format off | ||||
static const CRPCCommand commands[] = { | static const CRPCCommand commands[] = { | ||||
// category name actor (function) argNames | // category name actor (function) argNames | ||||
// ------------------- ------------------------ ---------------------- ---------- | // ------------------- ------------------------ ---------------------- ---------- | ||||
{ "rawtransactions", "getrawtransaction", getrawtransaction, {"txid","verbose","blockhash"} }, | { "rawtransactions", "getrawtransaction", getrawtransaction, {"txid","verbose","blockhash"} }, | ||||
{ "rawtransactions", "createrawtransaction", createrawtransaction, {"inputs","outputs","locktime"} }, | { "rawtransactions", "createrawtransaction", createrawtransaction, {"inputs","outputs","locktime"} }, | ||||
{ "rawtransactions", "decoderawtransaction", decoderawtransaction, {"hexstring"} }, | { "rawtransactions", "decoderawtransaction", decoderawtransaction, {"hexstring"} }, | ||||
{ "rawtransactions", "decodescript", decodescript, {"hexstring"} }, | { "rawtransactions", "decodescript", decodescript, {"hexstring"} }, | ||||
{ "rawtransactions", "sendrawtransaction", sendrawtransaction, {"hexstring","allowhighfees"} }, | { "rawtransactions", "sendrawtransaction", sendrawtransaction, {"hexstring","allowhighfees"} }, | ||||
{ "rawtransactions", "combinerawtransaction", combinerawtransaction, {"txs"} }, | { "rawtransactions", "combinerawtransaction", combinerawtransaction, {"txs"} }, | ||||
{ "rawtransactions", "signrawtransactionwithkey", signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, | { "rawtransactions", "signrawtransactionwithkey", signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, | ||||
{ "rawtransactions", "testmempoolaccept", testmempoolaccept, {"rawtxs","allowhighfees"} }, | { "rawtransactions", "testmempoolaccept", testmempoolaccept, {"rawtxs","allowhighfees"} }, | ||||
{ "rawtransactions", "decodepsbt", decodepsbt, {"psbt"} }, | { "rawtransactions", "decodepsbt", decodepsbt, {"psbt"} }, | ||||
{ "rawtransactions", "combinepsbt", combinepsbt, {"txs"} }, | { "rawtransactions", "combinepsbt", combinepsbt, {"txs"} }, | ||||
{ "rawtransactions", "finalizepsbt", finalizepsbt, {"psbt", "extract"} }, | { "rawtransactions", "finalizepsbt", finalizepsbt, {"psbt", "extract"} }, | ||||
{ "rawtransactions", "createpsbt", createpsbt, {"inputs","outputs","locktime"} }, | { "rawtransactions", "createpsbt", createpsbt, {"inputs","outputs","locktime"} }, | ||||
{ "rawtransactions", "converttopsbt", converttopsbt, {"hexstring","permitsigdata"} }, | { "rawtransactions", "converttopsbt", converttopsbt, {"hexstring","permitsigdata"} }, | ||||
{ "rawtransactions", "utxoupdatepsbt", utxoupdatepsbt, {"psbt"} }, | |||||
{ "blockchain", "gettxoutproof", gettxoutproof, {"txids", "blockhash"} }, | { "blockchain", "gettxoutproof", gettxoutproof, {"txids", "blockhash"} }, | ||||
{ "blockchain", "verifytxoutproof", verifytxoutproof, {"proof"} }, | { "blockchain", "verifytxoutproof", verifytxoutproof, {"proof"} }, | ||||
}; | }; | ||||
// clang-format on | // clang-format on | ||||
void RegisterRawTransactionRPCCommands(CRPCTable &t) { | void RegisterRawTransactionRPCCommands(CRPCTable &t) { | ||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | ||||
t.appendCommand(commands[vcidx].name, &commands[vcidx]); | t.appendCommand(commands[vcidx].name, &commands[vcidx]); | ||||
} | } | ||||
} | } |