fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

/Users/eugenesiegel/btc/bitcoin/src/rpc/rawtransaction.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6
#include <base58.h>
7
#include <chain.h>
8
#include <coins.h>
9
#include <consensus/amount.h>
10
#include <consensus/validation.h>
11
#include <core_io.h>
12
#include <index/txindex.h>
13
#include <key_io.h>
14
#include <node/blockstorage.h>
15
#include <node/coin.h>
16
#include <node/context.h>
17
#include <node/psbt.h>
18
#include <node/transaction.h>
19
#include <node/types.h>
20
#include <policy/packages.h>
21
#include <policy/policy.h>
22
#include <policy/rbf.h>
23
#include <primitives/transaction.h>
24
#include <psbt.h>
25
#include <random.h>
26
#include <rpc/blockchain.h>
27
#include <rpc/rawtransaction_util.h>
28
#include <rpc/server.h>
29
#include <rpc/server_util.h>
30
#include <rpc/util.h>
31
#include <script/script.h>
32
#include <script/sign.h>
33
#include <script/signingprovider.h>
34
#include <script/solver.h>
35
#include <uint256.h>
36
#include <undo.h>
37
#include <util/bip32.h>
38
#include <util/check.h>
39
#include <util/strencodings.h>
40
#include <util/string.h>
41
#include <util/vector.h>
42
#include <validation.h>
43
#include <validationinterface.h>
44
45
#include <numeric>
46
#include <stdint.h>
47
48
#include <univalue.h>
49
50
using node::AnalyzePSBT;
51
using node::FindCoins;
52
using node::GetTransaction;
53
using node::NodeContext;
54
using node::PSBTAnalysis;
55
56
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry,
57
                     Chainstate& active_chainstate, const CTxUndo* txundo = nullptr,
58
                     TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS)
59
0
{
60
0
    CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
Line
Count
Source
103
0
    inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
61
    // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
62
    //
63
    // Blockchain contextual information (confirmations and blocktime) is not
64
    // available to code in bitcoin-common, so we query them here and push the
65
    // data into the returned UniValue.
66
0
    TxToUniv(tx, /*block_hash=*/uint256(), entry, /*include_hex=*/true, txundo, verbosity);
67
68
0
    if (!hashBlock.IsNull()) {
69
0
        LOCK(cs_main);
Line
Count
Source
257
0
#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
Line
Count
Source
11
0
#define UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
Line
Count
Source
9
0
#define PASTE2(x, y) PASTE(x, y)
Line
Count
Source
8
0
#define PASTE(x, y) x ## y
70
71
0
        entry.pushKV("blockhash", hashBlock.GetHex());
72
0
        const CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
73
0
        if (pindex) {
74
0
            if (active_chainstate.m_chain.Contains(pindex)) {
75
0
                entry.pushKV("confirmations", 1 + active_chainstate.m_chain.Height() - pindex->nHeight);
76
0
                entry.pushKV("time", pindex->GetBlockTime());
77
0
                entry.pushKV("blocktime", pindex->GetBlockTime());
78
0
            }
79
0
            else
80
0
                entry.pushKV("confirmations", 0);
81
0
        }
82
0
    }
83
0
}
84
85
static std::vector<RPCResult> DecodeTxDoc(const std::string& txid_field_doc)
86
4
{
87
4
    return {
88
4
        {RPCResult::Type::STR_HEX, "txid", txid_field_doc},
89
4
        {RPCResult::Type::STR_HEX, "hash", "The transaction hash (differs from txid for witness transactions)"},
90
4
        {RPCResult::Type::NUM, "size", "The serialized transaction size"},
91
4
        {RPCResult::Type::NUM, "vsize", "The virtual transaction size (differs from size for witness transactions)"},
92
4
        {RPCResult::Type::NUM, "weight", "The transaction's weight (between vsize*4-3 and vsize*4)"},
93
4
        {RPCResult::Type::NUM, "version", "The version"},
94
4
        {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
95
4
        {RPCResult::Type::ARR, "vin", "",
96
4
        {
97
4
            {RPCResult::Type::OBJ, "", "",
98
4
            {
99
4
                {RPCResult::Type::STR_HEX, "coinbase", /*optional=*/true, "The coinbase value (only if coinbase transaction)"},
100
4
                {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id (if not coinbase transaction)"},
101
4
                {RPCResult::Type::NUM, "vout", /*optional=*/true, "The output number (if not coinbase transaction)"},
102
4
                {RPCResult::Type::OBJ, "scriptSig", /*optional=*/true, "The script (if not coinbase transaction)",
103
4
                {
104
4
                    {RPCResult::Type::STR, "asm", "Disassembly of the signature script"},
105
4
                    {RPCResult::Type::STR_HEX, "hex", "The raw signature script bytes, hex-encoded"},
106
4
                }},
107
4
                {RPCResult::Type::ARR, "txinwitness", /*optional=*/true, "",
108
4
                {
109
4
                    {RPCResult::Type::STR_HEX, "hex", "hex-encoded witness data (if any)"},
110
4
                }},
111
4
                {RPCResult::Type::NUM, "sequence", "The script sequence number"},
112
4
            }},
113
4
        }},
114
4
        {RPCResult::Type::ARR, "vout", "",
115
4
        {
116
4
            {RPCResult::Type::OBJ, "", "",
117
4
            {
118
4
                {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
119
4
                {RPCResult::Type::NUM, "n", "index"},
120
4
                {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
121
4
            }},
122
4
        }},
123
4
    };
124
4
}
125
126
static std::vector<RPCArg> CreateTxDoc()
127
4
{
128
4
    return {
129
4
        {"inputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The inputs",
130
4
            {
131
4
                {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
132
4
                    {
133
4
                        {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
134
4
                        {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
135
4
                        {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"},
136
4
                    },
137
4
                },
138
4
            },
139
4
        },
140
4
        {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n"
141
4
                "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
142
4
                "At least one output of either type must be specified.\n"
143
4
                "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
144
4
                "                             accepted as second parameter.",
145
4
            {
146
4
                {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
147
4
                    {
148
4
                        {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT},
149
4
                    },
150
4
                },
151
4
                {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
152
4
                    {
153
4
                        {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data that becomes a part of an OP_RETURN output"},
154
4
                    },
155
4
                },
156
4
            },
157
4
         RPCArgOptions{.skip_type_check = true}},
158
4
        {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
159
4
        {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
160
4
                "Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
161
4
    };
162
4
}
163
164
// Update PSBT with information from the mempool, the UTXO set, the txindex, and the provided descriptors.
165
// Optionally, sign the inputs that we can using information from the descriptors.
166
PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std::any& context, const HidingSigningProvider& provider, int sighash_type, bool finalize)
167
0
{
168
    // Unserialize the transactions
169
0
    PartiallySignedTransaction psbtx;
170
0
    std::string error;
171
0
    if (!DecodeBase64PSBT(psbtx, psbt_string, error)) {
172
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
173
0
    }
174
175
0
    if (g_txindex) g_txindex->BlockUntilSyncedToCurrentChain();
176
0
    const NodeContext& node = EnsureAnyNodeContext(context);
177
178
    // If we can't find the corresponding full transaction for all of our inputs,
179
    // this will be used to find just the utxos for the segwit inputs for which
180
    // the full transaction isn't found
181
0
    std::map<COutPoint, Coin> coins;
182
183
    // Fetch previous transactions:
184
    // First, look in the txindex and the mempool
185
0
    for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
186
0
        PSBTInput& psbt_input = psbtx.inputs.at(i);
187
0
        const CTxIn& tx_in = psbtx.tx->vin.at(i);
188
189
        // The `non_witness_utxo` is the whole previous transaction
190
0
        if (psbt_input.non_witness_utxo) continue;
191
192
0
        CTransactionRef tx;
193
194
        // Look in the txindex
195
0
        if (g_txindex) {
196
0
            uint256 block_hash;
197
0
            g_txindex->FindTx(tx_in.prevout.hash, block_hash, tx);
198
0
        }
199
        // If we still don't have it look in the mempool
200
0
        if (!tx) {
201
0
            tx = node.mempool->get(tx_in.prevout.hash);
202
0
        }
203
0
        if (tx) {
204
0
            psbt_input.non_witness_utxo = tx;
205
0
        } else {
206
0
            coins[tx_in.prevout]; // Create empty map entry keyed by prevout
207
0
        }
208
0
    }
209
210
    // If we still haven't found all of the inputs, look for the missing ones in the utxo set
211
0
    if (!coins.empty()) {
212
0
        FindCoins(node, coins);
213
0
        for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
214
0
            PSBTInput& input = psbtx.inputs.at(i);
215
216
            // If there are still missing utxos, add them if they were found in the utxo set
217
0
            if (!input.non_witness_utxo) {
218
0
                const CTxIn& tx_in = psbtx.tx->vin.at(i);
219
0
                const Coin& coin = coins.at(tx_in.prevout);
220
0
                if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
221
0
                    input.witness_utxo = coin.out;
222
0
                }
223
0
            }
224
0
        }
225
0
    }
226
227
0
    const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
228
229
0
    for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
230
0
        if (PSBTInputSigned(psbtx.inputs.at(i))) {
231
0
            continue;
232
0
        }
233
234
        // Update script/keypath information using descriptor data.
235
        // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures.
236
        // We only actually care about those if our signing provider doesn't hide private
237
        // information, as is the case with `descriptorprocesspsbt`
238
0
        SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, sighash_type, /*out_sigdata=*/nullptr, finalize);
239
0
    }
240
241
    // Update script/keypath information using descriptor data.
242
0
    for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
243
0
        UpdatePSBTOutput(provider, psbtx, i);
244
0
    }
245
246
0
    RemoveUnnecessaryTransactions(psbtx, /*sighash_type=*/1);
247
248
0
    return psbtx;
249
0
}
250
251
static RPCHelpMan getrawtransaction()
252
2
{
253
2
    return RPCHelpMan{
254
2
                "getrawtransaction",
255
256
2
                "By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled\n"
257
2
                "and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.\n"
258
2
                "If a blockhash argument is passed, it will return the transaction if\n"
259
2
                "the specified block is available and the transaction is in that block.\n\n"
260
2
                "Hint: Use gettransaction for wallet transactions.\n\n"
261
262
2
                "If verbosity is 0 or omitted, returns the serialized transaction as a hex-encoded string.\n"
263
2
                "If verbosity is 1, returns a JSON Object with information about the transaction.\n"
264
2
                "If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.",
265
2
                {
266
2
                    {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
267
2
                    {"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for hex-encoded data, 1 for a JSON object, and 2 for JSON object with fee and prevout",
268
2
                     RPCArgOptions{.skip_type_check = true}},
269
2
                    {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The block in which to look for the transaction"},
270
2
                },
271
2
                {
272
2
                    RPCResult{"if verbosity is not set or set to 0",
273
2
                         RPCResult::Type::STR, "data", "The serialized transaction as a hex-encoded string for 'txid'"
274
2
                     },
275
2
                     RPCResult{"if verbosity is set to 1",
276
2
                         RPCResult::Type::OBJ, "", "",
277
2
                         Cat<std::vector<RPCResult>>(
278
2
                         {
279
2
                             {RPCResult::Type::BOOL, "in_active_chain", /*optional=*/true, "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"},
280
2
                             {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "the block hash"},
281
2
                             {RPCResult::Type::NUM, "confirmations", /*optional=*/true, "The confirmations"},
282
2
                             {RPCResult::Type::NUM_TIME, "blocktime", /*optional=*/true, "The block time expressed in " + UNIX_EPOCH_TIME},
283
2
                             {RPCResult::Type::NUM, "time", /*optional=*/true, "Same as \"blocktime\""},
284
2
                             {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"},
285
2
                         },
286
2
                         DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same as provided)")),
287
2
                    },
288
2
                    RPCResult{"for verbosity = 2",
289
2
                        RPCResult::Type::OBJ, "", "",
290
2
                        {
291
2
                            {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
292
2
                            {RPCResult::Type::NUM, "fee", /*optional=*/true, "transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"},
293
2
                            {RPCResult::Type::ARR, "vin", "",
294
2
                            {
295
2
                                {RPCResult::Type::OBJ, "", "utxo being spent",
296
2
                                {
297
2
                                    {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
298
2
                                    {RPCResult::Type::OBJ, "prevout", /*optional=*/true, "The previous output, omitted if block undo data is not available",
299
2
                                    {
300
2
                                        {RPCResult::Type::BOOL, "generated", "Coinbase or not"},
301
2
                                        {RPCResult::Type::NUM, "height", "The height of the prevout"},
302
2
                                        {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
303
2
                                        {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
304
2
                                    }},
305
2
                                }},
306
2
                            }},
307
2
                        }},
308
2
                },
309
2
                RPCExamples{
310
2
                    HelpExampleCli("getrawtransaction", "\"mytxid\"")
311
2
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
312
2
            + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
313
2
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 0 \"myblockhash\"")
314
2
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 1 \"myblockhash\"")
315
2
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 2 \"myblockhash\"")
316
2
                },
317
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
318
2
{
319
0
    const NodeContext& node = EnsureAnyNodeContext(request.context);
320
0
    ChainstateManager& chainman = EnsureChainman(node);
321
322
0
    uint256 hash = ParseHashV(request.params[0], "parameter 1");
323
0
    const CBlockIndex* blockindex = nullptr;
324
325
0
    if (hash == chainman.GetParams().GenesisBlock().hashMerkleRoot) {
326
        // Special exception for the genesis block coinbase transaction
327
0
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "The genesis block coinbase is not considered an ordinary transaction and cannot be retrieved");
328
0
    }
329
330
0
    int verbosity{ParseVerbosity(request.params[1], /*default_verbosity=*/0, /*allow_bool=*/true)};
331
332
0
    if (!request.params[2].isNull()) {
333
0
        LOCK(cs_main);
Line
Count
Source
257
0
#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
Line
Count
Source
11
0
#define UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
Line
Count
Source
9
0
#define PASTE2(x, y) PASTE(x, y)
Line
Count
Source
8
0
#define PASTE(x, y) x ## y
334
335
0
        uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
336
0
        blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
337
0
        if (!blockindex) {
338
0
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found");
339
0
        }
340
0
    }
341
342
0
    bool f_txindex_ready = false;
343
0
    if (g_txindex && !blockindex) {
344
0
        f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
345
0
    }
346
347
0
    uint256 hash_block;
348
0
    const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman);
349
0
    if (!tx) {
350
0
        std::string errmsg;
351
0
        if (blockindex) {
352
0
            const bool block_has_data = WITH_LOCK(::cs_main, return blockindex->nStatus & BLOCK_HAVE_DATA);
Line
Count
Source
301
0
#define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
353
0
            if (!block_has_data) {
354
0
                throw JSONRPCError(RPC_MISC_ERROR, "Block not available");
355
0
            }
356
0
            errmsg = "No such transaction found in the provided block";
357
0
        } else if (!g_txindex) {
358
0
            errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries";
359
0
        } else if (!f_txindex_ready) {
360
0
            errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
361
0
        } else {
362
0
            errmsg = "No such mempool or blockchain transaction";
363
0
        }
364
0
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errmsg + ". Use gettransaction for wallet transactions.");
365
0
    }
366
367
0
    if (verbosity <= 0) {
368
0
        return EncodeHexTx(*tx);
369
0
    }
370
371
0
    UniValue result(UniValue::VOBJ);
372
0
    if (blockindex) {
373
0
        LOCK(cs_main);
Line
Count
Source
257
0
#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
Line
Count
Source
11
0
#define UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
Line
Count
Source
9
0
#define PASTE2(x, y) PASTE(x, y)
Line
Count
Source
8
0
#define PASTE(x, y) x ## y
374
0
        result.pushKV("in_active_chain", chainman.ActiveChain().Contains(blockindex));
375
0
    }
376
    // If request is verbosity >= 1 but no blockhash was given, then look up the blockindex
377
0
    if (request.params[2].isNull()) {
378
0
        LOCK(cs_main);
Line
Count
Source
257
0
#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
Line
Count
Source
11
0
#define UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
Line
Count
Source
9
0
#define PASTE2(x, y) PASTE(x, y)
Line
Count
Source
8
0
#define PASTE(x, y) x ## y
379
0
        blockindex = chainman.m_blockman.LookupBlockIndex(hash_block); // May be nullptr for mempool transactions
380
0
    }
381
0
    if (verbosity == 1) {
382
0
        TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
383
0
        return result;
384
0
    }
385
386
0
    CBlockUndo blockUndo;
387
0
    CBlock block;
388
389
0
    if (tx->IsCoinBase() || !blockindex || WITH_LOCK(::cs_main, return !(blockindex->nStatus & BLOCK_HAVE_MASK))) {
Line
Count
Source
301
0
#define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
390
0
        TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
391
0
        return result;
392
0
    }
393
0
    if (!chainman.m_blockman.ReadBlockUndo(blockUndo, *blockindex)) {
394
0
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Undo data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");
395
0
    }
396
0
    if (!chainman.m_blockman.ReadBlock(block, *blockindex)) {
397
0
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Block data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");
398
0
    }
399
400
0
    CTxUndo* undoTX {nullptr};
401
0
    auto it = std::find_if(block.vtx.begin(), block.vtx.end(), [tx](CTransactionRef t){ return *t == *tx; });
402
0
    if (it != block.vtx.end()) {
403
        // -1 as blockundo does not have coinbase tx
404
0
        undoTX = &blockUndo.vtxundo.at(it - block.vtx.begin() - 1);
405
0
    }
406
0
    TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate(), undoTX, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
407
0
    return result;
408
0
},
409
2
    };
410
2
}
411
412
static RPCHelpMan createrawtransaction()
413
2
{
414
2
    return RPCHelpMan{"createrawtransaction",
415
2
                "\nCreate a transaction spending the given inputs and creating new outputs.\n"
416
2
                "Outputs can be addresses or data.\n"
417
2
                "Returns hex-encoded raw transaction.\n"
418
2
                "Note that the transaction's inputs are not signed, and\n"
419
2
                "it is not stored in the wallet or transmitted to the network.\n",
420
2
                CreateTxDoc(),
421
2
                RPCResult{
422
2
                    RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction"
423
2
                },
424
2
                RPCExamples{
425
2
                    HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
426
2
            + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
427
2
            + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"")
428
2
            + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
429
2
                },
430
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
431
2
{
432
0
    std::optional<bool> rbf;
433
0
    if (!request.params[3].isNull()) {
434
0
        rbf = request.params[3].get_bool();
435
0
    }
436
0
    CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
437
438
0
    return EncodeHexTx(CTransaction(rawTx));
439
0
},
440
2
    };
441
2
}
442
443
static RPCHelpMan decoderawtransaction()
444
2
{
445
2
    return RPCHelpMan{"decoderawtransaction",
446
2
                "Return a JSON object representing the serialized, hex-encoded transaction.",
447
2
                {
448
2
                    {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
449
2
                    {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
450
2
                        "If iswitness is not present, heuristic tests will be used in decoding.\n"
451
2
                        "If true, only witness deserialization will be tried.\n"
452
2
                        "If false, only non-witness deserialization will be tried.\n"
453
2
                        "This boolean should reflect whether the transaction has inputs\n"
454
2
                        "(e.g. fully valid, or on-chain transactions), if known by the caller."
455
2
                    },
456
2
                },
457
2
                RPCResult{
458
2
                    RPCResult::Type::OBJ, "", "",
459
2
                    DecodeTxDoc(/*txid_field_doc=*/"The transaction id"),
460
2
                },
461
2
                RPCExamples{
462
2
                    HelpExampleCli("decoderawtransaction", "\"hexstring\"")
463
2
            + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
464
2
                },
465
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
466
2
{
467
0
    CMutableTransaction mtx;
468
469
0
    bool try_witness = request.params[1].isNull() ? true : request.params[1].get_bool();
470
0
    bool try_no_witness = request.params[1].isNull() ? true : !request.params[1].get_bool();
471
472
0
    if (!DecodeHexTx(mtx, request.params[0].get_str(), try_no_witness, try_witness)) {
473
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
474
0
    }
475
476
0
    UniValue result(UniValue::VOBJ);
477
0
    TxToUniv(CTransaction(std::move(mtx)), /*block_hash=*/uint256(), /*entry=*/result, /*include_hex=*/false);
478
479
0
    return result;
480
0
},
481
2
    };
482
2
}
483
484
static RPCHelpMan decodescript()
485
2
{
486
2
    return RPCHelpMan{
487
2
        "decodescript",
488
2
        "\nDecode a hex-encoded script.\n",
489
2
        {
490
2
            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
491
2
        },
492
2
        RPCResult{
493
2
            RPCResult::Type::OBJ, "", "",
494
2
            {
495
2
                {RPCResult::Type::STR, "asm", "Disassembly of the script"},
496
2
                {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
497
2
                {RPCResult::Type::STR, "type", "The output type (e.g. " + GetAllOutputTypes() + ")"},
498
2
                {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
499
2
                {RPCResult::Type::STR, "p2sh", /*optional=*/true,
500
2
                 "address of P2SH script wrapping this redeem script (not returned for types that should not be wrapped)"},
501
2
                {RPCResult::Type::OBJ, "segwit", /*optional=*/true,
502
2
                 "Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped)",
503
2
                 {
504
2
                     {RPCResult::Type::STR, "asm", "Disassembly of the output script"},
505
2
                     {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"},
506
2
                     {RPCResult::Type::STR, "type", "The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash)"},
507
2
                     {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
508
2
                     {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
509
2
                     {RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"},
510
2
                 }},
511
2
            },
512
2
        },
513
2
        RPCExamples{
514
2
            HelpExampleCli("decodescript", "\"hexstring\"")
515
2
          + HelpExampleRpc("decodescript", "\"hexstring\"")
516
2
        },
517
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
518
2
{
519
0
    UniValue r(UniValue::VOBJ);
520
0
    CScript script;
521
0
    if (request.params[0].get_str().size() > 0){
522
0
        std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
523
0
        script = CScript(scriptData.begin(), scriptData.end());
524
0
    } else {
525
        // Empty scripts are valid
526
0
    }
527
0
    ScriptToUniv(script, /*out=*/r, /*include_hex=*/false, /*include_address=*/true);
528
529
0
    std::vector<std::vector<unsigned char>> solutions_data;
530
0
    const TxoutType which_type{Solver(script, solutions_data)};
531
532
0
    const bool can_wrap{[&] {
533
0
        switch (which_type) {
534
0
        case TxoutType::MULTISIG:
535
0
        case TxoutType::NONSTANDARD:
536
0
        case TxoutType::PUBKEY:
537
0
        case TxoutType::PUBKEYHASH:
538
0
        case TxoutType::WITNESS_V0_KEYHASH:
539
0
        case TxoutType::WITNESS_V0_SCRIPTHASH:
540
            // Can be wrapped if the checks below pass
541
0
            break;
542
0
        case TxoutType::NULL_DATA:
543
0
        case TxoutType::SCRIPTHASH:
544
0
        case TxoutType::WITNESS_UNKNOWN:
545
0
        case TxoutType::WITNESS_V1_TAPROOT:
546
0
        case TxoutType::ANCHOR:
547
            // Should not be wrapped
548
0
            return false;
549
0
        } // no default case, so the compiler can warn about missing cases
550
0
        if (!script.HasValidOps() || script.IsUnspendable()) {
551
0
            return false;
552
0
        }
553
0
        for (CScript::const_iterator it{script.begin()}; it != script.end();) {
554
0
            opcodetype op;
555
0
            CHECK_NONFATAL(script.GetOp(it, op));
Line
Count
Source
103
0
    inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
556
0
            if (op == OP_CHECKSIGADD || IsOpSuccess(op)) {
557
0
                return false;
558
0
            }
559
0
        }
560
0
        return true;
561
0
    }()};
562
563
0
    if (can_wrap) {
564
0
        r.pushKV("p2sh", EncodeDestination(ScriptHash(script)));
565
        // P2SH and witness programs cannot be wrapped in P2WSH, if this script
566
        // is a witness program, don't return addresses for a segwit programs.
567
0
        const bool can_wrap_P2WSH{[&] {
568
0
            switch (which_type) {
569
0
            case TxoutType::MULTISIG:
570
0
            case TxoutType::PUBKEY:
571
            // Uncompressed pubkeys cannot be used with segwit checksigs.
572
            // If the script contains an uncompressed pubkey, skip encoding of a segwit program.
573
0
                for (const auto& solution : solutions_data) {
574
0
                    if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
575
0
                        return false;
576
0
                    }
577
0
                }
578
0
                return true;
579
0
            case TxoutType::NONSTANDARD:
580
0
            case TxoutType::PUBKEYHASH:
581
                // Can be P2WSH wrapped
582
0
                return true;
583
0
            case TxoutType::NULL_DATA:
584
0
            case TxoutType::SCRIPTHASH:
585
0
            case TxoutType::WITNESS_UNKNOWN:
586
0
            case TxoutType::WITNESS_V0_KEYHASH:
587
0
            case TxoutType::WITNESS_V0_SCRIPTHASH:
588
0
            case TxoutType::WITNESS_V1_TAPROOT:
589
0
            case TxoutType::ANCHOR:
590
                // Should not be wrapped
591
0
                return false;
592
0
            } // no default case, so the compiler can warn about missing cases
593
0
            NONFATAL_UNREACHABLE();
Line
Count
Source
124
0
    throw NonFatalCheckError(                                         \
125
0
        "Unreachable code reached (non-fatal)", __FILE__, __LINE__, __func__)
594
0
        }()};
595
0
        if (can_wrap_P2WSH) {
596
0
            UniValue sr(UniValue::VOBJ);
597
0
            CScript segwitScr;
598
0
            FlatSigningProvider provider;
599
0
            if (which_type == TxoutType::PUBKEY) {
600
0
                segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0])));
601
0
            } else if (which_type == TxoutType::PUBKEYHASH) {
602
0
                segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));
603
0
            } else {
604
                // Scripts that are not fit for P2WPKH are encoded as P2WSH.
605
0
                provider.scripts[CScriptID(script)] = script;
606
0
                segwitScr = GetScriptForDestination(WitnessV0ScriptHash(script));
607
0
            }
608
0
            ScriptToUniv(segwitScr, /*out=*/sr, /*include_hex=*/true, /*include_address=*/true, /*provider=*/&provider);
609
0
            sr.pushKV("p2sh-segwit", EncodeDestination(ScriptHash(segwitScr)));
610
0
            r.pushKV("segwit", std::move(sr));
611
0
        }
612
0
    }
613
614
0
    return r;
615
0
},
616
2
    };
617
2
}
618
619
static RPCHelpMan combinerawtransaction()
620
2
{
621
2
    return RPCHelpMan{"combinerawtransaction",
622
2
                "\nCombine multiple partially signed transactions into one transaction.\n"
623
2
                "The combined transaction may be another partially signed transaction or a \n"
624
2
                "fully signed transaction.",
625
2
                {
626
2
                    {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex strings of partially signed transactions",
627
2
                        {
628
2
                            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"},
629
2
                        },
630
2
                        },
631
2
                },
632
2
                RPCResult{
633
2
                    RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)"
634
2
                },
635
2
                RPCExamples{
636
2
                    HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
637
2
                },
638
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
639
2
{
640
641
0
    UniValue txs = request.params[0].get_array();
642
0
    std::vector<CMutableTransaction> txVariants(txs.size());
643
644
0
    for (unsigned int idx = 0; idx < txs.size(); idx++) {
645
0
        if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
646
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx));
Line
Count
Source
1172
0
#define strprintf tfm::format
647
0
        }
648
0
    }
649
650
0
    if (txVariants.empty()) {
651
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions");
652
0
    }
653
654
    // mergedTx will end up with all the signatures; it
655
    // starts as a clone of the rawtx:
656
0
    CMutableTransaction mergedTx(txVariants[0]);
657
658
    // Fetch previous transactions (inputs):
659
0
    CCoinsView viewDummy;
660
0
    CCoinsViewCache view(&viewDummy);
661
0
    {
662
0
        NodeContext& node = EnsureAnyNodeContext(request.context);
663
0
        const CTxMemPool& mempool = EnsureMemPool(node);
664
0
        ChainstateManager& chainman = EnsureChainman(node);
665
0
        LOCK2(cs_main, mempool.cs);
Line
Count
Source
259
0
    UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \
260
0
    UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__)
666
0
        CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();
667
0
        CCoinsViewMemPool viewMempool(&viewChain, mempool);
668
0
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
669
670
0
        for (const CTxIn& txin : mergedTx.vin) {
671
0
            view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
672
0
        }
673
674
0
        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
675
0
    }
676
677
    // Use CTransaction for the constant parts of the
678
    // transaction to avoid rehashing.
679
0
    const CTransaction txConst(mergedTx);
680
    // Sign what we can:
681
0
    for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
682
0
        CTxIn& txin = mergedTx.vin[i];
683
0
        const Coin& coin = view.AccessCoin(txin.prevout);
684
0
        if (coin.IsSpent()) {
685
0
            throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");
686
0
        }
687
0
        SignatureData sigdata;
688
689
        // ... and merge in other signatures:
690
0
        for (const CMutableTransaction& txv : txVariants) {
691
0
            if (txv.vin.size() > i) {
692
0
                sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));
693
0
            }
694
0
        }
695
0
        ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);
696
697
0
        UpdateInput(txin, sigdata);
698
0
    }
699
700
0
    return EncodeHexTx(CTransaction(mergedTx));
701
0
},
702
2
    };
703
2
}
704
705
static RPCHelpMan signrawtransactionwithkey()
706
2
{
707
2
    return RPCHelpMan{"signrawtransactionwithkey",
708
2
                "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
709
2
                "The second argument is an array of base58-encoded private\n"
710
2
                "keys that will be the only keys used to sign the transaction.\n"
711
2
                "The third optional argument (may be null) is an array of previous transaction outputs that\n"
712
2
                "this transaction depends on but may not yet be in the block chain.\n",
713
2
                {
714
2
                    {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},
715
2
                    {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing",
716
2
                        {
717
2
                            {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"},
718
2
                        },
719
2
                        },
720
2
                    {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs",
721
2
                        {
722
2
                            {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
723
2
                                {
724
2
                                    {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
725
2
                                    {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
726
2
                                    {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "output script"},
727
2
                                    {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
728
2
                                    {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
729
2
                                    {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},
730
2
                                },
731
2
                                },
732
2
                        },
733
2
                        },
734
2
                    {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of:\n"
735
2
            "       \"DEFAULT\"\n"
736
2
            "       \"ALL\"\n"
737
2
            "       \"NONE\"\n"
738
2
            "       \"SINGLE\"\n"
739
2
            "       \"ALL|ANYONECANPAY\"\n"
740
2
            "       \"NONE|ANYONECANPAY\"\n"
741
2
            "       \"SINGLE|ANYONECANPAY\"\n"
742
2
                    },
743
2
                },
744
2
                RPCResult{
745
2
                    RPCResult::Type::OBJ, "", "",
746
2
                    {
747
2
                        {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
748
2
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
749
2
                        {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)",
750
2
                        {
751
2
                            {RPCResult::Type::OBJ, "", "",
752
2
                            {
753
2
                                {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
754
2
                                {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
755
2
                                {RPCResult::Type::ARR, "witness", "",
756
2
                                {
757
2
                                    {RPCResult::Type::STR_HEX, "witness", ""},
758
2
                                }},
759
2
                                {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
760
2
                                {RPCResult::Type::NUM, "sequence", "Script sequence number"},
761
2
                                {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
762
2
                            }},
763
2
                        }},
764
2
                    }
765
2
                },
766
2
                RPCExamples{
767
2
                    HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
768
2
            + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
769
2
                },
770
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
771
2
{
772
0
    CMutableTransaction mtx;
773
0
    if (!DecodeHexTx(mtx, request.params[0].get_str())) {
774
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
775
0
    }
776
777
0
    FlatSigningProvider keystore;
778
0
    const UniValue& keys = request.params[1].get_array();
779
0
    for (unsigned int idx = 0; idx < keys.size(); ++idx) {
780
0
        UniValue k = keys[idx];
781
0
        CKey key = DecodeSecret(k.get_str());
782
0
        if (!key.IsValid()) {
783
0
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
784
0
        }
785
786
0
        CPubKey pubkey = key.GetPubKey();
787
0
        CKeyID key_id = pubkey.GetID();
788
0
        keystore.pubkeys.emplace(key_id, pubkey);
789
0
        keystore.keys.emplace(key_id, key);
790
0
    }
791
792
    // Fetch previous transactions (inputs):
793
0
    std::map<COutPoint, Coin> coins;
794
0
    for (const CTxIn& txin : mtx.vin) {
795
0
        coins[txin.prevout]; // Create empty map entry keyed by prevout.
796
0
    }
797
0
    NodeContext& node = EnsureAnyNodeContext(request.context);
798
0
    FindCoins(node, coins);
799
800
    // Parse the prevtxs array
801
0
    ParsePrevouts(request.params[2], &keystore, coins);
802
803
0
    UniValue result(UniValue::VOBJ);
804
0
    SignTransaction(mtx, &keystore, coins, request.params[3], result);
805
0
    return result;
806
0
},
807
2
    };
808
2
}
809
810
const RPCResult decodepsbt_inputs{
811
    RPCResult::Type::ARR, "inputs", "",
812
    {
813
        {RPCResult::Type::OBJ, "", "",
814
        {
815
            {RPCResult::Type::OBJ, "non_witness_utxo", /*optional=*/true, "Decoded network transaction for non-witness UTXOs",
816
            {
817
                {RPCResult::Type::ELISION, "",""},
818
            }},
819
            {RPCResult::Type::OBJ, "witness_utxo", /*optional=*/true, "Transaction output for witness UTXOs",
820
            {
821
                {RPCResult::Type::NUM, "amount", "The value in " + CURRENCY_UNIT},
822
                {RPCResult::Type::OBJ, "scriptPubKey", "",
823
                {
824
                    {RPCResult::Type::STR, "asm", "Disassembly of the output script"},
825
                    {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"},
826
                    {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"},
827
                    {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
828
                    {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
829
                }},
830
            }},
831
            {RPCResult::Type::OBJ_DYN, "partial_signatures", /*optional=*/true, "",
832
            {
833
                {RPCResult::Type::STR, "pubkey", "The public key and signature that corresponds to it."},
834
            }},
835
            {RPCResult::Type::STR, "sighash", /*optional=*/true, "The sighash type to be used"},
836
            {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
837
            {
838
                {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
839
                {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
840
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
841
            }},
842
            {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
843
            {
844
                {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
845
                {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
846
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
847
            }},
848
            {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
849
            {
850
                {RPCResult::Type::OBJ, "", "",
851
                {
852
                    {RPCResult::Type::STR, "pubkey", "The public key with the derivation path as the value."},
853
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
854
                    {RPCResult::Type::STR, "path", "The path"},
855
                }},
856
            }},
857
            {RPCResult::Type::OBJ, "final_scriptSig", /*optional=*/true, "",
858
            {
859
                {RPCResult::Type::STR, "asm", "Disassembly of the final signature script"},
860
                {RPCResult::Type::STR_HEX, "hex", "The raw final signature script bytes, hex-encoded"},
861
            }},
862
            {RPCResult::Type::ARR, "final_scriptwitness", /*optional=*/true, "",
863
            {
864
                {RPCResult::Type::STR_HEX, "", "hex-encoded witness data (if any)"},
865
            }},
866
            {RPCResult::Type::OBJ_DYN, "ripemd160_preimages", /*optional=*/ true, "",
867
            {
868
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
869
            }},
870
            {RPCResult::Type::OBJ_DYN, "sha256_preimages", /*optional=*/ true, "",
871
            {
872
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
873
            }},
874
            {RPCResult::Type::OBJ_DYN, "hash160_preimages", /*optional=*/ true, "",
875
            {
876
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
877
            }},
878
            {RPCResult::Type::OBJ_DYN, "hash256_preimages", /*optional=*/ true, "",
879
            {
880
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
881
            }},
882
            {RPCResult::Type::STR_HEX, "taproot_key_path_sig", /*optional=*/ true, "hex-encoded signature for the Taproot key path spend"},
883
            {RPCResult::Type::ARR, "taproot_script_path_sigs", /*optional=*/ true, "",
884
            {
885
                {RPCResult::Type::OBJ, "signature", /*optional=*/ true, "The signature for the pubkey and leaf hash combination",
886
                {
887
                    {RPCResult::Type::STR, "pubkey", "The x-only pubkey for this signature"},
888
                    {RPCResult::Type::STR, "leaf_hash", "The leaf hash for this signature"},
889
                    {RPCResult::Type::STR, "sig", "The signature itself"},
890
                }},
891
            }},
892
            {RPCResult::Type::ARR, "taproot_scripts", /*optional=*/ true, "",
893
            {
894
                {RPCResult::Type::OBJ, "", "",
895
                {
896
                    {RPCResult::Type::STR_HEX, "script", "A leaf script"},
897
                    {RPCResult::Type::NUM, "leaf_ver", "The version number for the leaf script"},
898
                    {RPCResult::Type::ARR, "control_blocks", "The control blocks for this script",
899
                    {
900
                        {RPCResult::Type::STR_HEX, "control_block", "A hex-encoded control block for this script"},
901
                    }},
902
                }},
903
            }},
904
            {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
905
            {
906
                {RPCResult::Type::OBJ, "", "",
907
                {
908
                    {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
909
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
910
                    {RPCResult::Type::STR, "path", "The path"},
911
                    {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
912
                    {
913
                        {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
914
                    }},
915
                }},
916
            }},
917
            {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
918
            {RPCResult::Type::STR_HEX, "taproot_merkle_root", /*optional=*/ true, "The hex-encoded Taproot merkle root"},
919
            {RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
920
            {
921
                {RPCResult::Type::OBJ, "", "",
922
                {
923
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
924
                    {RPCResult::Type::ARR, "participant_pubkeys", "",
925
                    {
926
                        {RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
927
                    }},
928
                }},
929
            }},
930
            {RPCResult::Type::ARR, "musig2_pubnonces", /*optional=*/true, "",
931
            {
932
                {RPCResult::Type::OBJ, "", "",
933
                {
934
                    {RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this pubnonce."},
935
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this pubnonce is for."},
936
                    {RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
937
                    {RPCResult::Type::STR_HEX, "pubnonce", "The public nonce itself."},
938
                }},
939
            }},
940
            {RPCResult::Type::ARR, "musig2_partial_sigs", /*optional=*/true, "",
941
            {
942
                {RPCResult::Type::OBJ, "", "",
943
                {
944
                    {RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this partial signature."},
945
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this partial signature is for."},
946
                    {RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
947
                    {RPCResult::Type::STR_HEX, "partial_sig", "The partial signature itself."},
948
                }},
949
            }},
950
            {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
951
            {
952
                {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
953
            }},
954
            {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The input proprietary map",
955
            {
956
                {RPCResult::Type::OBJ, "", "",
957
                {
958
                    {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
959
                    {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
960
                    {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
961
                    {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
962
                }},
963
            }},
964
        }},
965
    }
966
};
967
968
const RPCResult decodepsbt_outputs{
969
    RPCResult::Type::ARR, "outputs", "",
970
    {
971
        {RPCResult::Type::OBJ, "", "",
972
        {
973
            {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
974
            {
975
                {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
976
                {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
977
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
978
            }},
979
            {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
980
            {
981
                {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
982
                {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
983
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
984
            }},
985
            {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
986
            {
987
                {RPCResult::Type::OBJ, "", "",
988
                {
989
                    {RPCResult::Type::STR, "pubkey", "The public key this path corresponds to"},
990
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
991
                    {RPCResult::Type::STR, "path", "The path"},
992
                }},
993
            }},
994
            {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
995
            {RPCResult::Type::ARR, "taproot_tree", /*optional=*/ true, "The tuples that make up the Taproot tree, in depth first search order",
996
            {
997
                {RPCResult::Type::OBJ, "tuple", /*optional=*/ true, "A single leaf script in the taproot tree",
998
                {
999
                    {RPCResult::Type::NUM, "depth", "The depth of this element in the tree"},
1000
                    {RPCResult::Type::NUM, "leaf_ver", "The version of this leaf"},
1001
                    {RPCResult::Type::STR, "script", "The hex-encoded script itself"},
1002
                }},
1003
            }},
1004
            {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
1005
            {
1006
                {RPCResult::Type::OBJ, "", "",
1007
                {
1008
                    {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
1009
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
1010
                    {RPCResult::Type::STR, "path", "The path"},
1011
                    {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
1012
                    {
1013
                        {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
1014
                    }},
1015
                }},
1016
            }},
1017
            {RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
1018
            {
1019
                {RPCResult::Type::OBJ, "", "",
1020
                {
1021
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
1022
                    {RPCResult::Type::ARR, "participant_pubkeys", "",
1023
                    {
1024
                        {RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
1025
                    }},
1026
                }},
1027
            }},
1028
            {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/true, "The unknown output fields",
1029
            {
1030
                {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
1031
            }},
1032
            {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The output proprietary map",
1033
            {
1034
                {RPCResult::Type::OBJ, "", "",
1035
                {
1036
                    {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1037
                    {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1038
                    {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1039
                    {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1040
                }},
1041
            }},
1042
        }},
1043
    }
1044
};
1045
1046
static RPCHelpMan decodepsbt()
1047
2
{
1048
2
    return RPCHelpMan{
1049
2
        "decodepsbt",
1050
2
        "Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.",
1051
2
                {
1052
2
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
1053
2
                },
1054
2
                RPCResult{
1055
2
                    RPCResult::Type::OBJ, "", "",
1056
2
                    {
1057
2
                        {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.",
1058
2
                        {
1059
2
                            {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."},
1060
2
                        }},
1061
2
                        {RPCResult::Type::ARR, "global_xpubs", "",
1062
2
                        {
1063
2
                            {RPCResult::Type::OBJ, "", "",
1064
2
                            {
1065
2
                                {RPCResult::Type::STR, "xpub", "The extended public key this path corresponds to"},
1066
2
                                {RPCResult::Type::STR_HEX, "master_fingerprint", "The fingerprint of the master key"},
1067
2
                                {RPCResult::Type::STR, "path", "The path"},
1068
2
                            }},
1069
2
                        }},
1070
2
                        {RPCResult::Type::NUM, "psbt_version", "The PSBT version number. Not to be confused with the unsigned transaction version"},
1071
2
                        {RPCResult::Type::ARR, "proprietary", "The global proprietary map",
1072
2
                        {
1073
2
                            {RPCResult::Type::OBJ, "", "",
1074
2
                            {
1075
2
                                {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1076
2
                                {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1077
2
                                {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1078
2
                                {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1079
2
                            }},
1080
2
                        }},
1081
2
                        {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
1082
2
                        {
1083
2
                             {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
1084
2
                        }},
1085
2
                        decodepsbt_inputs,
1086
2
                        decodepsbt_outputs,
1087
2
                        {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."},
1088
2
                    }
1089
2
                },
1090
2
                RPCExamples{
1091
2
                    HelpExampleCli("decodepsbt", "\"psbt\"")
1092
2
                },
1093
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1094
2
{
1095
    // Unserialize the transactions
1096
0
    PartiallySignedTransaction psbtx;
1097
0
    std::string error;
1098
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1099
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
1100
0
    }
1101
1102
0
    UniValue result(UniValue::VOBJ);
1103
1104
    // Add the decoded tx
1105
0
    UniValue tx_univ(UniValue::VOBJ);
1106
0
    TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
1107
0
    result.pushKV("tx", std::move(tx_univ));
1108
1109
    // Add the global xpubs
1110
0
    UniValue global_xpubs(UniValue::VARR);
1111
0
    for (std::pair<KeyOriginInfo, std::set<CExtPubKey>> xpub_pair : psbtx.m_xpubs) {
1112
0
        for (auto& xpub : xpub_pair.second) {
1113
0
            std::vector<unsigned char> ser_xpub;
1114
0
            ser_xpub.assign(BIP32_EXTKEY_WITH_VERSION_SIZE, 0);
1115
0
            xpub.EncodeWithVersion(ser_xpub.data());
1116
1117
0
            UniValue keypath(UniValue::VOBJ);
1118
0
            keypath.pushKV("xpub", EncodeBase58Check(ser_xpub));
1119
0
            keypath.pushKV("master_fingerprint", HexStr(std::span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4)));
1120
0
            keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path));
1121
0
            global_xpubs.push_back(std::move(keypath));
1122
0
        }
1123
0
    }
1124
0
    result.pushKV("global_xpubs", std::move(global_xpubs));
1125
1126
    // PSBT version
1127
0
    result.pushKV("psbt_version", static_cast<uint64_t>(psbtx.GetVersion()));
1128
1129
    // Proprietary
1130
0
    UniValue proprietary(UniValue::VARR);
1131
0
    for (const auto& entry : psbtx.m_proprietary) {
1132
0
        UniValue this_prop(UniValue::VOBJ);
1133
0
        this_prop.pushKV("identifier", HexStr(entry.identifier));
1134
0
        this_prop.pushKV("subtype", entry.subtype);
1135
0
        this_prop.pushKV("key", HexStr(entry.key));
1136
0
        this_prop.pushKV("value", HexStr(entry.value));
1137
0
        proprietary.push_back(std::move(this_prop));
1138
0
    }
1139
0
    result.pushKV("proprietary", std::move(proprietary));
1140
1141
    // Unknown data
1142
0
    UniValue unknowns(UniValue::VOBJ);
1143
0
    for (auto entry : psbtx.unknown) {
1144
0
        unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1145
0
    }
1146
0
    result.pushKV("unknown", std::move(unknowns));
1147
1148
    // inputs
1149
0
    CAmount total_in = 0;
1150
0
    bool have_all_utxos = true;
1151
0
    UniValue inputs(UniValue::VARR);
1152
0
    for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
1153
0
        const PSBTInput& input = psbtx.inputs[i];
1154
0
        UniValue in(UniValue::VOBJ);
1155
        // UTXOs
1156
0
        bool have_a_utxo = false;
1157
0
        CTxOut txout;
1158
0
        if (!input.witness_utxo.IsNull()) {
1159
0
            txout = input.witness_utxo;
1160
1161
0
            UniValue o(UniValue::VOBJ);
1162
0
            ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
1163
1164
0
            UniValue out(UniValue::VOBJ);
1165
0
            out.pushKV("amount", ValueFromAmount(txout.nValue));
1166
0
            out.pushKV("scriptPubKey", std::move(o));
1167
1168
0
            in.pushKV("witness_utxo", std::move(out));
1169
1170
0
            have_a_utxo = true;
1171
0
        }
1172
0
        if (input.non_witness_utxo) {
1173
0
            txout = input.non_witness_utxo->vout[psbtx.tx->vin[i].prevout.n];
1174
1175
0
            UniValue non_wit(UniValue::VOBJ);
1176
0
            TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false);
1177
0
            in.pushKV("non_witness_utxo", std::move(non_wit));
1178
1179
0
            have_a_utxo = true;
1180
0
        }
1181
0
        if (have_a_utxo) {
1182
0
            if (MoneyRange(txout.nValue) && MoneyRange(total_in + txout.nValue)) {
1183
0
                total_in += txout.nValue;
1184
0
            } else {
1185
                // Hack to just not show fee later
1186
0
                have_all_utxos = false;
1187
0
            }
1188
0
        } else {
1189
0
            have_all_utxos = false;
1190
0
        }
1191
1192
        // Partial sigs
1193
0
        if (!input.partial_sigs.empty()) {
1194
0
            UniValue partial_sigs(UniValue::VOBJ);
1195
0
            for (const auto& sig : input.partial_sigs) {
1196
0
                partial_sigs.pushKV(HexStr(sig.second.first), HexStr(sig.second.second));
1197
0
            }
1198
0
            in.pushKV("partial_signatures", std::move(partial_sigs));
1199
0
        }
1200
1201
        // Sighash
1202
0
        if (input.sighash_type != std::nullopt) {
1203
0
            in.pushKV("sighash", SighashToStr((unsigned char)*input.sighash_type));
1204
0
        }
1205
1206
        // Redeem script and witness script
1207
0
        if (!input.redeem_script.empty()) {
1208
0
            UniValue r(UniValue::VOBJ);
1209
0
            ScriptToUniv(input.redeem_script, /*out=*/r);
1210
0
            in.pushKV("redeem_script", std::move(r));
1211
0
        }
1212
0
        if (!input.witness_script.empty()) {
1213
0
            UniValue r(UniValue::VOBJ);
1214
0
            ScriptToUniv(input.witness_script, /*out=*/r);
1215
0
            in.pushKV("witness_script", std::move(r));
1216
0
        }
1217
1218
        // keypaths
1219
0
        if (!input.hd_keypaths.empty()) {
1220
0
            UniValue keypaths(UniValue::VARR);
1221
0
            for (auto entry : input.hd_keypaths) {
1222
0
                UniValue keypath(UniValue::VOBJ);
1223
0
                keypath.pushKV("pubkey", HexStr(entry.first));
1224
1225
0
                keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
Line
Count
Source
1172
0
#define strprintf tfm::format
1226
0
                keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1227
0
                keypaths.push_back(std::move(keypath));
1228
0
            }
1229
0
            in.pushKV("bip32_derivs", std::move(keypaths));
1230
0
        }
1231
1232
        // Final scriptSig and scriptwitness
1233
0
        if (!input.final_script_sig.empty()) {
1234
0
            UniValue scriptsig(UniValue::VOBJ);
1235
0
            scriptsig.pushKV("asm", ScriptToAsmStr(input.final_script_sig, true));
1236
0
            scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1237
0
            in.pushKV("final_scriptSig", std::move(scriptsig));
1238
0
        }
1239
0
        if (!input.final_script_witness.IsNull()) {
1240
0
            UniValue txinwitness(UniValue::VARR);
1241
0
            for (const auto& item : input.final_script_witness.stack) {
1242
0
                txinwitness.push_back(HexStr(item));
1243
0
            }
1244
0
            in.pushKV("final_scriptwitness", std::move(txinwitness));
1245
0
        }
1246
1247
        // Ripemd160 hash preimages
1248
0
        if (!input.ripemd160_preimages.empty()) {
1249
0
            UniValue ripemd160_preimages(UniValue::VOBJ);
1250
0
            for (const auto& [hash, preimage] : input.ripemd160_preimages) {
1251
0
                ripemd160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1252
0
            }
1253
0
            in.pushKV("ripemd160_preimages", std::move(ripemd160_preimages));
1254
0
        }
1255
1256
        // Sha256 hash preimages
1257
0
        if (!input.sha256_preimages.empty()) {
1258
0
            UniValue sha256_preimages(UniValue::VOBJ);
1259
0
            for (const auto& [hash, preimage] : input.sha256_preimages) {
1260
0
                sha256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1261
0
            }
1262
0
            in.pushKV("sha256_preimages", std::move(sha256_preimages));
1263
0
        }
1264
1265
        // Hash160 hash preimages
1266
0
        if (!input.hash160_preimages.empty()) {
1267
0
            UniValue hash160_preimages(UniValue::VOBJ);
1268
0
            for (const auto& [hash, preimage] : input.hash160_preimages) {
1269
0
                hash160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1270
0
            }
1271
0
            in.pushKV("hash160_preimages", std::move(hash160_preimages));
1272
0
        }
1273
1274
        // Hash256 hash preimages
1275
0
        if (!input.hash256_preimages.empty()) {
1276
0
            UniValue hash256_preimages(UniValue::VOBJ);
1277
0
            for (const auto& [hash, preimage] : input.hash256_preimages) {
1278
0
                hash256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1279
0
            }
1280
0
            in.pushKV("hash256_preimages", std::move(hash256_preimages));
1281
0
        }
1282
1283
        // Taproot key path signature
1284
0
        if (!input.m_tap_key_sig.empty()) {
1285
0
            in.pushKV("taproot_key_path_sig", HexStr(input.m_tap_key_sig));
1286
0
        }
1287
1288
        // Taproot script path signatures
1289
0
        if (!input.m_tap_script_sigs.empty()) {
1290
0
            UniValue script_sigs(UniValue::VARR);
1291
0
            for (const auto& [pubkey_leaf, sig] : input.m_tap_script_sigs) {
1292
0
                const auto& [xonly, leaf_hash] = pubkey_leaf;
1293
0
                UniValue sigobj(UniValue::VOBJ);
1294
0
                sigobj.pushKV("pubkey", HexStr(xonly));
1295
0
                sigobj.pushKV("leaf_hash", HexStr(leaf_hash));
1296
0
                sigobj.pushKV("sig", HexStr(sig));
1297
0
                script_sigs.push_back(std::move(sigobj));
1298
0
            }
1299
0
            in.pushKV("taproot_script_path_sigs", std::move(script_sigs));
1300
0
        }
1301
1302
        // Taproot leaf scripts
1303
0
        if (!input.m_tap_scripts.empty()) {
1304
0
            UniValue tap_scripts(UniValue::VARR);
1305
0
            for (const auto& [leaf, control_blocks] : input.m_tap_scripts) {
1306
0
                const auto& [script, leaf_ver] = leaf;
1307
0
                UniValue script_info(UniValue::VOBJ);
1308
0
                script_info.pushKV("script", HexStr(script));
1309
0
                script_info.pushKV("leaf_ver", leaf_ver);
1310
0
                UniValue control_blocks_univ(UniValue::VARR);
1311
0
                for (const auto& control_block : control_blocks) {
1312
0
                    control_blocks_univ.push_back(HexStr(control_block));
1313
0
                }
1314
0
                script_info.pushKV("control_blocks", std::move(control_blocks_univ));
1315
0
                tap_scripts.push_back(std::move(script_info));
1316
0
            }
1317
0
            in.pushKV("taproot_scripts", std::move(tap_scripts));
1318
0
        }
1319
1320
        // Taproot bip32 keypaths
1321
0
        if (!input.m_tap_bip32_paths.empty()) {
1322
0
            UniValue keypaths(UniValue::VARR);
1323
0
            for (const auto& [xonly, leaf_origin] : input.m_tap_bip32_paths) {
1324
0
                const auto& [leaf_hashes, origin] = leaf_origin;
1325
0
                UniValue path_obj(UniValue::VOBJ);
1326
0
                path_obj.pushKV("pubkey", HexStr(xonly));
1327
0
                path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
Line
Count
Source
1172
0
#define strprintf tfm::format
1328
0
                path_obj.pushKV("path", WriteHDKeypath(origin.path));
1329
0
                UniValue leaf_hashes_arr(UniValue::VARR);
1330
0
                for (const auto& leaf_hash : leaf_hashes) {
1331
0
                    leaf_hashes_arr.push_back(HexStr(leaf_hash));
1332
0
                }
1333
0
                path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr));
1334
0
                keypaths.push_back(std::move(path_obj));
1335
0
            }
1336
0
            in.pushKV("taproot_bip32_derivs", std::move(keypaths));
1337
0
        }
1338
1339
        // Taproot internal key
1340
0
        if (!input.m_tap_internal_key.IsNull()) {
1341
0
            in.pushKV("taproot_internal_key", HexStr(input.m_tap_internal_key));
1342
0
        }
1343
1344
        // Write taproot merkle root
1345
0
        if (!input.m_tap_merkle_root.IsNull()) {
1346
0
            in.pushKV("taproot_merkle_root", HexStr(input.m_tap_merkle_root));
1347
0
        }
1348
1349
        // Write MuSig2 fields
1350
0
        if (!input.m_musig2_participants.empty()) {
1351
0
            UniValue musig_pubkeys(UniValue::VARR);
1352
0
            for (const auto& [agg, parts] : input.m_musig2_participants) {
1353
0
                UniValue musig_part(UniValue::VOBJ);
1354
0
                musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1355
0
                UniValue part_pubkeys(UniValue::VARR);
1356
0
                for (const auto& pub : parts) {
1357
0
                    part_pubkeys.push_back(HexStr(pub));
1358
0
                }
1359
0
                musig_part.pushKV("participant_pubkeys", part_pubkeys);
1360
0
                musig_pubkeys.push_back(musig_part);
1361
0
            }
1362
0
            in.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1363
0
        }
1364
0
        if (!input.m_musig2_pubnonces.empty()) {
1365
0
            UniValue musig_pubnonces(UniValue::VARR);
1366
0
            for (const auto& [agg_lh, part_pubnonce] : input.m_musig2_pubnonces) {
1367
0
                const auto& [agg, lh] = agg_lh;
1368
0
                for (const auto& [part, pubnonce] : part_pubnonce) {
1369
0
                    UniValue info(UniValue::VOBJ);
1370
0
                    info.pushKV("participant_pubkey", HexStr(part));
1371
0
                    info.pushKV("aggregate_pubkey", HexStr(agg));
1372
0
                    if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
1373
0
                    info.pushKV("pubnonce", HexStr(pubnonce));
1374
0
                    musig_pubnonces.push_back(info);
1375
0
                }
1376
0
            }
1377
0
            in.pushKV("musig2_pubnonces", musig_pubnonces);
1378
0
        }
1379
0
        if (!input.m_musig2_partial_sigs.empty()) {
1380
0
            UniValue musig_partial_sigs(UniValue::VARR);
1381
0
            for (const auto& [agg_lh, part_psig] : input.m_musig2_partial_sigs) {
1382
0
                const auto& [agg, lh] = agg_lh;
1383
0
                for (const auto& [part, psig] : part_psig) {
1384
0
                    UniValue info(UniValue::VOBJ);
1385
0
                    info.pushKV("participant_pubkey", HexStr(part));
1386
0
                    info.pushKV("aggregate_pubkey", HexStr(agg));
1387
0
                    if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
1388
0
                    info.pushKV("partial_sig", HexStr(psig));
1389
0
                    musig_partial_sigs.push_back(info);
1390
0
                }
1391
0
            }
1392
0
            in.pushKV("musig2_partial_sigs", musig_partial_sigs);
1393
0
        }
1394
1395
        // Proprietary
1396
0
        if (!input.m_proprietary.empty()) {
1397
0
            UniValue proprietary(UniValue::VARR);
1398
0
            for (const auto& entry : input.m_proprietary) {
1399
0
                UniValue this_prop(UniValue::VOBJ);
1400
0
                this_prop.pushKV("identifier", HexStr(entry.identifier));
1401
0
                this_prop.pushKV("subtype", entry.subtype);
1402
0
                this_prop.pushKV("key", HexStr(entry.key));
1403
0
                this_prop.pushKV("value", HexStr(entry.value));
1404
0
                proprietary.push_back(std::move(this_prop));
1405
0
            }
1406
0
            in.pushKV("proprietary", std::move(proprietary));
1407
0
        }
1408
1409
        // Unknown data
1410
0
        if (input.unknown.size() > 0) {
1411
0
            UniValue unknowns(UniValue::VOBJ);
1412
0
            for (auto entry : input.unknown) {
1413
0
                unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1414
0
            }
1415
0
            in.pushKV("unknown", std::move(unknowns));
1416
0
        }
1417
1418
0
        inputs.push_back(std::move(in));
1419
0
    }
1420
0
    result.pushKV("inputs", std::move(inputs));
1421
1422
    // outputs
1423
0
    CAmount output_value = 0;
1424
0
    UniValue outputs(UniValue::VARR);
1425
0
    for (unsigned int i = 0; i < psbtx.outputs.size(); ++i) {
1426
0
        const PSBTOutput& output = psbtx.outputs[i];
1427
0
        UniValue out(UniValue::VOBJ);
1428
        // Redeem script and witness script
1429
0
        if (!output.redeem_script.empty()) {
1430
0
            UniValue r(UniValue::VOBJ);
1431
0
            ScriptToUniv(output.redeem_script, /*out=*/r);
1432
0
            out.pushKV("redeem_script", std::move(r));
1433
0
        }
1434
0
        if (!output.witness_script.empty()) {
1435
0
            UniValue r(UniValue::VOBJ);
1436
0
            ScriptToUniv(output.witness_script, /*out=*/r);
1437
0
            out.pushKV("witness_script", std::move(r));
1438
0
        }
1439
1440
        // keypaths
1441
0
        if (!output.hd_keypaths.empty()) {
1442
0
            UniValue keypaths(UniValue::VARR);
1443
0
            for (auto entry : output.hd_keypaths) {
1444
0
                UniValue keypath(UniValue::VOBJ);
1445
0
                keypath.pushKV("pubkey", HexStr(entry.first));
1446
0
                keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
Line
Count
Source
1172
0
#define strprintf tfm::format
1447
0
                keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1448
0
                keypaths.push_back(std::move(keypath));
1449
0
            }
1450
0
            out.pushKV("bip32_derivs", std::move(keypaths));
1451
0
        }
1452
1453
        // Taproot internal key
1454
0
        if (!output.m_tap_internal_key.IsNull()) {
1455
0
            out.pushKV("taproot_internal_key", HexStr(output.m_tap_internal_key));
1456
0
        }
1457
1458
        // Taproot tree
1459
0
        if (!output.m_tap_tree.empty()) {
1460
0
            UniValue tree(UniValue::VARR);
1461
0
            for (const auto& [depth, leaf_ver, script] : output.m_tap_tree) {
1462
0
                UniValue elem(UniValue::VOBJ);
1463
0
                elem.pushKV("depth", (int)depth);
1464
0
                elem.pushKV("leaf_ver", (int)leaf_ver);
1465
0
                elem.pushKV("script", HexStr(script));
1466
0
                tree.push_back(std::move(elem));
1467
0
            }
1468
0
            out.pushKV("taproot_tree", std::move(tree));
1469
0
        }
1470
1471
        // Taproot bip32 keypaths
1472
0
        if (!output.m_tap_bip32_paths.empty()) {
1473
0
            UniValue keypaths(UniValue::VARR);
1474
0
            for (const auto& [xonly, leaf_origin] : output.m_tap_bip32_paths) {
1475
0
                const auto& [leaf_hashes, origin] = leaf_origin;
1476
0
                UniValue path_obj(UniValue::VOBJ);
1477
0
                path_obj.pushKV("pubkey", HexStr(xonly));
1478
0
                path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
Line
Count
Source
1172
0
#define strprintf tfm::format
1479
0
                path_obj.pushKV("path", WriteHDKeypath(origin.path));
1480
0
                UniValue leaf_hashes_arr(UniValue::VARR);
1481
0
                for (const auto& leaf_hash : leaf_hashes) {
1482
0
                    leaf_hashes_arr.push_back(HexStr(leaf_hash));
1483
0
                }
1484
0
                path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr));
1485
0
                keypaths.push_back(std::move(path_obj));
1486
0
            }
1487
0
            out.pushKV("taproot_bip32_derivs", std::move(keypaths));
1488
0
        }
1489
1490
        // Write MuSig2 fields
1491
0
        if (!output.m_musig2_participants.empty()) {
1492
0
            UniValue musig_pubkeys(UniValue::VARR);
1493
0
            for (const auto& [agg, parts] : output.m_musig2_participants) {
1494
0
                UniValue musig_part(UniValue::VOBJ);
1495
0
                musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1496
0
                UniValue part_pubkeys(UniValue::VARR);
1497
0
                for (const auto& pub : parts) {
1498
0
                    part_pubkeys.push_back(HexStr(pub));
1499
0
                }
1500
0
                musig_part.pushKV("participant_pubkeys", part_pubkeys);
1501
0
                musig_pubkeys.push_back(musig_part);
1502
0
            }
1503
0
            out.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1504
0
        }
1505
1506
        // Proprietary
1507
0
        if (!output.m_proprietary.empty()) {
1508
0
            UniValue proprietary(UniValue::VARR);
1509
0
            for (const auto& entry : output.m_proprietary) {
1510
0
                UniValue this_prop(UniValue::VOBJ);
1511
0
                this_prop.pushKV("identifier", HexStr(entry.identifier));
1512
0
                this_prop.pushKV("subtype", entry.subtype);
1513
0
                this_prop.pushKV("key", HexStr(entry.key));
1514
0
                this_prop.pushKV("value", HexStr(entry.value));
1515
0
                proprietary.push_back(std::move(this_prop));
1516
0
            }
1517
0
            out.pushKV("proprietary", std::move(proprietary));
1518
0
        }
1519
1520
        // Unknown data
1521
0
        if (output.unknown.size() > 0) {
1522
0
            UniValue unknowns(UniValue::VOBJ);
1523
0
            for (auto entry : output.unknown) {
1524
0
                unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1525
0
            }
1526
0
            out.pushKV("unknown", std::move(unknowns));
1527
0
        }
1528
1529
0
        outputs.push_back(std::move(out));
1530
1531
        // Fee calculation
1532
0
        if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
1533
0
            output_value += psbtx.tx->vout[i].nValue;
1534
0
        } else {
1535
            // Hack to just not show fee later
1536
0
            have_all_utxos = false;
1537
0
        }
1538
0
    }
1539
0
    result.pushKV("outputs", std::move(outputs));
1540
0
    if (have_all_utxos) {
1541
0
        result.pushKV("fee", ValueFromAmount(total_in - output_value));
1542
0
    }
1543
1544
0
    return result;
1545
0
},
1546
2
    };
1547
2
}
1548
1549
static RPCHelpMan combinepsbt()
1550
2
{
1551
2
    return RPCHelpMan{"combinepsbt",
1552
2
                "\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
1553
2
                "Implements the Combiner role.\n",
1554
2
                {
1555
2
                    {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1556
2
                        {
1557
2
                            {"psbt", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A base64 string of a PSBT"},
1558
2
                        },
1559
2
                        },
1560
2
                },
1561
2
                RPCResult{
1562
2
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1563
2
                },
1564
2
                RPCExamples{
1565
2
                    HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
1566
2
                },
1567
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1568
2
{
1569
    // Unserialize the transactions
1570
0
    std::vector<PartiallySignedTransaction> psbtxs;
1571
0
    UniValue txs = request.params[0].get_array();
1572
0
    if (txs.empty()) {
1573
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txs' cannot be empty");
1574
0
    }
1575
0
    for (unsigned int i = 0; i < txs.size(); ++i) {
1576
0
        PartiallySignedTransaction psbtx;
1577
0
        std::string error;
1578
0
        if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1579
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
1580
0
        }
1581
0
        psbtxs.push_back(psbtx);
1582
0
    }
1583
1584
0
    PartiallySignedTransaction merged_psbt;
1585
0
    if (!CombinePSBTs(merged_psbt, psbtxs)) {
1586
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "PSBTs not compatible (different transactions)");
1587
0
    }
1588
1589
0
    DataStream ssTx{};
1590
0
    ssTx << merged_psbt;
1591
0
    return EncodeBase64(ssTx);
1592
0
},
1593
2
    };
1594
2
}
1595
1596
static RPCHelpMan finalizepsbt()
1597
2
{
1598
2
    return RPCHelpMan{"finalizepsbt",
1599
2
                "Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
1600
2
                "network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
1601
2
                "created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n"
1602
2
                "Implements the Finalizer and Extractor roles.\n",
1603
2
                {
1604
2
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1605
2
                    {"extract", RPCArg::Type::BOOL, RPCArg::Default{true}, "If true and the transaction is complete,\n"
1606
2
            "                             extract and return the complete transaction in normal network serialization instead of the PSBT."},
1607
2
                },
1608
2
                RPCResult{
1609
2
                    RPCResult::Type::OBJ, "", "",
1610
2
                    {
1611
2
                        {RPCResult::Type::STR, "psbt", /*optional=*/true, "The base64-encoded partially signed transaction if not extracted"},
1612
2
                        {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if extracted"},
1613
2
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1614
2
                    }
1615
2
                },
1616
2
                RPCExamples{
1617
2
                    HelpExampleCli("finalizepsbt", "\"psbt\"")
1618
2
                },
1619
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1620
2
{
1621
    // Unserialize the transactions
1622
0
    PartiallySignedTransaction psbtx;
1623
0
    std::string error;
1624
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1625
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
1626
0
    }
1627
1628
0
    bool extract = request.params[1].isNull() || (!request.params[1].isNull() && request.params[1].get_bool());
1629
1630
0
    CMutableTransaction mtx;
1631
0
    bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1632
1633
0
    UniValue result(UniValue::VOBJ);
1634
0
    DataStream ssTx{};
1635
0
    std::string result_str;
1636
1637
0
    if (complete && extract) {
1638
0
        ssTx << TX_WITH_WITNESS(mtx);
1639
0
        result_str = HexStr(ssTx);
1640
0
        result.pushKV("hex", result_str);
1641
0
    } else {
1642
0
        ssTx << psbtx;
1643
0
        result_str = EncodeBase64(ssTx.str());
1644
0
        result.pushKV("psbt", result_str);
1645
0
    }
1646
0
    result.pushKV("complete", complete);
1647
1648
0
    return result;
1649
0
},
1650
2
    };
1651
2
}
1652
1653
static RPCHelpMan createpsbt()
1654
2
{
1655
2
    return RPCHelpMan{"createpsbt",
1656
2
                "\nCreates a transaction in the Partially Signed Transaction format.\n"
1657
2
                "Implements the Creator role.\n"
1658
2
                "Note that the transaction's inputs are not signed, and\n"
1659
2
                "it is not stored in the wallet or transmitted to the network.\n",
1660
2
                CreateTxDoc(),
1661
2
                RPCResult{
1662
2
                    RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1663
2
                },
1664
2
                RPCExamples{
1665
2
                    HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
1666
2
                },
1667
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1668
2
{
1669
1670
0
    std::optional<bool> rbf;
1671
0
    if (!request.params[3].isNull()) {
1672
0
        rbf = request.params[3].get_bool();
1673
0
    }
1674
0
    CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
1675
1676
    // Make a blank psbt
1677
0
    PartiallySignedTransaction psbtx;
1678
0
    psbtx.tx = rawTx;
1679
0
    for (unsigned int i = 0; i < rawTx.vin.size(); ++i) {
1680
0
        psbtx.inputs.emplace_back();
1681
0
    }
1682
0
    for (unsigned int i = 0; i < rawTx.vout.size(); ++i) {
1683
0
        psbtx.outputs.emplace_back();
1684
0
    }
1685
1686
    // Serialize the PSBT
1687
0
    DataStream ssTx{};
1688
0
    ssTx << psbtx;
1689
1690
0
    return EncodeBase64(ssTx);
1691
0
},
1692
2
    };
1693
2
}
1694
1695
static RPCHelpMan converttopsbt()
1696
2
{
1697
2
    return RPCHelpMan{"converttopsbt",
1698
2
                "\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
1699
2
                "createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
1700
2
                {
1701
2
                    {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of a raw transaction"},
1702
2
                    {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, any signatures in the input will be discarded and conversion\n"
1703
2
                            "                              will continue. If false, RPC will fail if any signatures are present."},
1704
2
                    {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
1705
2
                        "If iswitness is not present, heuristic tests will be used in decoding.\n"
1706
2
                        "If true, only witness deserialization will be tried.\n"
1707
2
                        "If false, only non-witness deserialization will be tried.\n"
1708
2
                        "This boolean should reflect whether the transaction has inputs\n"
1709
2
                        "(e.g. fully valid, or on-chain transactions), if known by the caller."
1710
2
                    },
1711
2
                },
1712
2
                RPCResult{
1713
2
                    RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1714
2
                },
1715
2
                RPCExamples{
1716
2
                            "\nCreate a transaction\n"
1717
2
                            + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1718
2
                            "\nConvert the transaction to a PSBT\n"
1719
2
                            + HelpExampleCli("converttopsbt", "\"rawtransaction\"")
1720
2
                },
1721
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1722
2
{
1723
    // parse hex string from parameter
1724
0
    CMutableTransaction tx;
1725
0
    bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
1726
0
    bool witness_specified = !request.params[2].isNull();
1727
0
    bool iswitness = witness_specified ? request.params[2].get_bool() : false;
1728
0
    const bool try_witness = witness_specified ? iswitness : true;
1729
0
    const bool try_no_witness = witness_specified ? !iswitness : true;
1730
0
    if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
1731
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1732
0
    }
1733
1734
    // Remove all scriptSigs and scriptWitnesses from inputs
1735
0
    for (CTxIn& input : tx.vin) {
1736
0
        if ((!input.scriptSig.empty() || !input.scriptWitness.IsNull()) && !permitsigdata) {
1737
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Inputs must not have scriptSigs and scriptWitnesses");
1738
0
        }
1739
0
        input.scriptSig.clear();
1740
0
        input.scriptWitness.SetNull();
1741
0
    }
1742
1743
    // Make a blank psbt
1744
0
    PartiallySignedTransaction psbtx;
1745
0
    psbtx.tx = tx;
1746
0
    for (unsigned int i = 0; i < tx.vin.size(); ++i) {
1747
0
        psbtx.inputs.emplace_back();
1748
0
    }
1749
0
    for (unsigned int i = 0; i < tx.vout.size(); ++i) {
1750
0
        psbtx.outputs.emplace_back();
1751
0
    }
1752
1753
    // Serialize the PSBT
1754
0
    DataStream ssTx{};
1755
0
    ssTx << psbtx;
1756
1757
0
    return EncodeBase64(ssTx);
1758
0
},
1759
2
    };
1760
2
}
1761
1762
static RPCHelpMan utxoupdatepsbt()
1763
2
{
1764
2
    return RPCHelpMan{"utxoupdatepsbt",
1765
2
            "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set, txindex, or the mempool.\n",
1766
2
            {
1767
2
                {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1768
2
                {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "An array of either strings or objects", {
1769
2
                    {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
1770
2
                    {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
1771
2
                         {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
1772
2
                         {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
1773
2
                    }},
1774
2
                }},
1775
2
            },
1776
2
            RPCResult {
1777
2
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated"
1778
2
            },
1779
2
            RPCExamples {
1780
2
                HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
1781
2
            },
1782
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1783
2
{
1784
    // Parse descriptors, if any.
1785
0
    FlatSigningProvider provider;
1786
0
    if (!request.params[1].isNull()) {
1787
0
        auto descs = request.params[1].get_array();
1788
0
        for (size_t i = 0; i < descs.size(); ++i) {
1789
0
            EvalDescriptorStringOrObject(descs[i], provider);
1790
0
        }
1791
0
    }
1792
1793
    // We don't actually need private keys further on; hide them as a precaution.
1794
0
    const PartiallySignedTransaction& psbtx = ProcessPSBT(
1795
0
        request.params[0].get_str(),
1796
0
        request.context,
1797
0
        HidingSigningProvider(&provider, /*hide_secret=*/true, /*hide_origin=*/false),
1798
0
        /*sighash_type=*/SIGHASH_ALL,
1799
0
        /*finalize=*/false);
1800
1801
0
    DataStream ssTx{};
1802
0
    ssTx << psbtx;
1803
0
    return EncodeBase64(ssTx);
1804
0
},
1805
2
    };
1806
2
}
1807
1808
static RPCHelpMan joinpsbts()
1809
2
{
1810
2
    return RPCHelpMan{"joinpsbts",
1811
2
            "\nJoins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n"
1812
2
            "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1813
2
            {
1814
2
                {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1815
2
                    {
1816
2
                        {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1817
2
                    }}
1818
2
            },
1819
2
            RPCResult {
1820
2
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1821
2
            },
1822
2
            RPCExamples {
1823
2
                HelpExampleCli("joinpsbts", "\"psbt\"")
1824
2
            },
1825
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1826
2
{
1827
    // Unserialize the transactions
1828
0
    std::vector<PartiallySignedTransaction> psbtxs;
1829
0
    UniValue txs = request.params[0].get_array();
1830
1831
0
    if (txs.size() <= 1) {
1832
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "At least two PSBTs are required to join PSBTs.");
1833
0
    }
1834
1835
0
    uint32_t best_version = 1;
1836
0
    uint32_t best_locktime = 0xffffffff;
1837
0
    for (unsigned int i = 0; i < txs.size(); ++i) {
1838
0
        PartiallySignedTransaction psbtx;
1839
0
        std::string error;
1840
0
        if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
1841
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
1842
0
        }
1843
0
        psbtxs.push_back(psbtx);
1844
        // Choose the highest version number
1845
0
        if (psbtx.tx->version > best_version) {
1846
0
            best_version = psbtx.tx->version;
1847
0
        }
1848
        // Choose the lowest lock time
1849
0
        if (psbtx.tx->nLockTime < best_locktime) {
1850
0
            best_locktime = psbtx.tx->nLockTime;
1851
0
        }
1852
0
    }
1853
1854
    // Create a blank psbt where everything will be added
1855
0
    PartiallySignedTransaction merged_psbt;
1856
0
    merged_psbt.tx = CMutableTransaction();
1857
0
    merged_psbt.tx->version = best_version;
1858
0
    merged_psbt.tx->nLockTime = best_locktime;
1859
1860
    // Merge
1861
0
    for (auto& psbt : psbtxs) {
1862
0
        for (unsigned int i = 0; i < psbt.tx->vin.size(); ++i) {
1863
0
            if (!merged_psbt.AddInput(psbt.tx->vin[i], psbt.inputs[i])) {
1864
0
                throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input %s:%d exists in multiple PSBTs", psbt.tx->vin[i].prevout.hash.ToString(), psbt.tx->vin[i].prevout.n));
Line
Count
Source
1172
0
#define strprintf tfm::format
1865
0
            }
1866
0
        }
1867
0
        for (unsigned int i = 0; i < psbt.tx->vout.size(); ++i) {
1868
0
            merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1869
0
        }
1870
0
        for (auto& xpub_pair : psbt.m_xpubs) {
1871
0
            if (merged_psbt.m_xpubs.count(xpub_pair.first) == 0) {
1872
0
                merged_psbt.m_xpubs[xpub_pair.first] = xpub_pair.second;
1873
0
            } else {
1874
0
                merged_psbt.m_xpubs[xpub_pair.first].insert(xpub_pair.second.begin(), xpub_pair.second.end());
1875
0
            }
1876
0
        }
1877
0
        merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
1878
0
    }
1879
1880
    // Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT
1881
0
    std::vector<int> input_indices(merged_psbt.inputs.size());
1882
0
    std::iota(input_indices.begin(), input_indices.end(), 0);
1883
0
    std::vector<int> output_indices(merged_psbt.outputs.size());
1884
0
    std::iota(output_indices.begin(), output_indices.end(), 0);
1885
1886
    // Shuffle input and output indices lists
1887
0
    std::shuffle(input_indices.begin(), input_indices.end(), FastRandomContext());
1888
0
    std::shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
1889
1890
0
    PartiallySignedTransaction shuffled_psbt;
1891
0
    shuffled_psbt.tx = CMutableTransaction();
1892
0
    shuffled_psbt.tx->version = merged_psbt.tx->version;
1893
0
    shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1894
0
    for (int i : input_indices) {
1895
0
        shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]);
1896
0
    }
1897
0
    for (int i : output_indices) {
1898
0
        shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]);
1899
0
    }
1900
0
    shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end());
1901
1902
0
    DataStream ssTx{};
1903
0
    ssTx << shuffled_psbt;
1904
0
    return EncodeBase64(ssTx);
1905
0
},
1906
2
    };
1907
2
}
1908
1909
static RPCHelpMan analyzepsbt()
1910
2
{
1911
2
    return RPCHelpMan{"analyzepsbt",
1912
2
            "\nAnalyzes and provides information about the current status of a PSBT and its inputs\n",
1913
2
            {
1914
2
                {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1915
2
            },
1916
2
            RPCResult {
1917
2
                RPCResult::Type::OBJ, "", "",
1918
2
                {
1919
2
                    {RPCResult::Type::ARR, "inputs", /*optional=*/true, "",
1920
2
                    {
1921
2
                        {RPCResult::Type::OBJ, "", "",
1922
2
                        {
1923
2
                            {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"},
1924
2
                            {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"},
1925
2
                            {RPCResult::Type::OBJ, "missing", /*optional=*/true, "Things that are missing that are required to complete this input",
1926
2
                            {
1927
2
                                {RPCResult::Type::ARR, "pubkeys", /*optional=*/true, "",
1928
2
                                {
1929
2
                                    {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"},
1930
2
                                }},
1931
2
                                {RPCResult::Type::ARR, "signatures", /*optional=*/true, "",
1932
2
                                {
1933
2
                                    {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"},
1934
2
                                }},
1935
2
                                {RPCResult::Type::STR_HEX, "redeemscript", /*optional=*/true, "Hash160 of the redeem script that is missing"},
1936
2
                                {RPCResult::Type::STR_HEX, "witnessscript", /*optional=*/true, "SHA256 of the witness script that is missing"},
1937
2
                            }},
1938
2
                            {RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"},
1939
2
                        }},
1940
2
                    }},
1941
2
                    {RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"},
1942
2
                    {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /*optional=*/true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kvB. Shown only if all UTXO slots in the PSBT have been filled"},
1943
2
                    {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},
1944
2
                    {RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},
1945
2
                    {RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"},
1946
2
                }
1947
2
            },
1948
2
            RPCExamples {
1949
2
                HelpExampleCli("analyzepsbt", "\"psbt\"")
1950
2
            },
1951
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1952
2
{
1953
    // Unserialize the transaction
1954
0
    PartiallySignedTransaction psbtx;
1955
0
    std::string error;
1956
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1957
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
Line
Count
Source
1172
0
#define strprintf tfm::format
1958
0
    }
1959
1960
0
    PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1961
1962
0
    UniValue result(UniValue::VOBJ);
1963
0
    UniValue inputs_result(UniValue::VARR);
1964
0
    for (const auto& input : psbta.inputs) {
1965
0
        UniValue input_univ(UniValue::VOBJ);
1966
0
        UniValue missing(UniValue::VOBJ);
1967
1968
0
        input_univ.pushKV("has_utxo", input.has_utxo);
1969
0
        input_univ.pushKV("is_final", input.is_final);
1970
0
        input_univ.pushKV("next", PSBTRoleName(input.next));
1971
1972
0
        if (!input.missing_pubkeys.empty()) {
1973
0
            UniValue missing_pubkeys_univ(UniValue::VARR);
1974
0
            for (const CKeyID& pubkey : input.missing_pubkeys) {
1975
0
                missing_pubkeys_univ.push_back(HexStr(pubkey));
1976
0
            }
1977
0
            missing.pushKV("pubkeys", std::move(missing_pubkeys_univ));
1978
0
        }
1979
0
        if (!input.missing_redeem_script.IsNull()) {
1980
0
            missing.pushKV("redeemscript", HexStr(input.missing_redeem_script));
1981
0
        }
1982
0
        if (!input.missing_witness_script.IsNull()) {
1983
0
            missing.pushKV("witnessscript", HexStr(input.missing_witness_script));
1984
0
        }
1985
0
        if (!input.missing_sigs.empty()) {
1986
0
            UniValue missing_sigs_univ(UniValue::VARR);
1987
0
            for (const CKeyID& pubkey : input.missing_sigs) {
1988
0
                missing_sigs_univ.push_back(HexStr(pubkey));
1989
0
            }
1990
0
            missing.pushKV("signatures", std::move(missing_sigs_univ));
1991
0
        }
1992
0
        if (!missing.getKeys().empty()) {
1993
0
            input_univ.pushKV("missing", std::move(missing));
1994
0
        }
1995
0
        inputs_result.push_back(std::move(input_univ));
1996
0
    }
1997
0
    if (!inputs_result.empty()) result.pushKV("inputs", std::move(inputs_result));
1998
1999
0
    if (psbta.estimated_vsize != std::nullopt) {
2000
0
        result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
2001
0
    }
2002
0
    if (psbta.estimated_feerate != std::nullopt) {
2003
0
        result.pushKV("estimated_feerate", ValueFromAmount(psbta.estimated_feerate->GetFeePerK()));
2004
0
    }
2005
0
    if (psbta.fee != std::nullopt) {
2006
0
        result.pushKV("fee", ValueFromAmount(*psbta.fee));
2007
0
    }
2008
0
    result.pushKV("next", PSBTRoleName(psbta.next));
2009
0
    if (!psbta.error.empty()) {
2010
0
        result.pushKV("error", psbta.error);
2011
0
    }
2012
2013
0
    return result;
2014
0
},
2015
2
    };
2016
2
}
2017
2018
RPCHelpMan descriptorprocesspsbt()
2019
2
{
2020
2
    return RPCHelpMan{"descriptorprocesspsbt",
2021
2
                "\nUpdate all segwit inputs in a PSBT with information from output descriptors, the UTXO set or the mempool. \n"
2022
2
                "Then, sign the inputs we are able to with information from the output descriptors. ",
2023
2
                {
2024
2
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
2025
2
                    {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of either strings or objects", {
2026
2
                        {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
2027
2
                        {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
2028
2
                             {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
2029
2
                             {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
2030
2
                        }},
2031
2
                    }},
2032
2
                    {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
2033
2
            "       \"DEFAULT\"\n"
2034
2
            "       \"ALL\"\n"
2035
2
            "       \"NONE\"\n"
2036
2
            "       \"SINGLE\"\n"
2037
2
            "       \"ALL|ANYONECANPAY\"\n"
2038
2
            "       \"NONE|ANYONECANPAY\"\n"
2039
2
            "       \"SINGLE|ANYONECANPAY\""},
2040
2
                    {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
2041
2
                    {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
2042
2
                },
2043
2
                RPCResult{
2044
2
                    RPCResult::Type::OBJ, "", "",
2045
2
                    {
2046
2
                        {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
2047
2
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
2048
2
                        {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"},
2049
2
                    }
2050
2
                },
2051
2
                RPCExamples{
2052
2
                    HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[\\\"descriptor1\\\", \\\"descriptor2\\\"]\"") +
2053
2
                    HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[{\\\"desc\\\":\\\"mydescriptor\\\", \\\"range\\\":21}]\"")
2054
2
                },
2055
2
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2056
2
{
2057
    // Add descriptor information to a signing provider
2058
0
    FlatSigningProvider provider;
2059
2060
0
    auto descs = request.params[1].get_array();
2061
0
    for (size_t i = 0; i < descs.size(); ++i) {
2062
0
        EvalDescriptorStringOrObject(descs[i], provider, /*expand_priv=*/true);
2063
0
    }
2064
2065
0
    int sighash_type = ParseSighashString(request.params[2]);
2066
0
    bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
2067
0
    bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
2068
2069
0
    const PartiallySignedTransaction& psbtx = ProcessPSBT(
2070
0
        request.params[0].get_str(),
2071
0
        request.context,
2072
0
        HidingSigningProvider(&provider, /*hide_secret=*/false, !bip32derivs),
2073
0
        sighash_type,
2074
0
        finalize);
2075
2076
    // Check whether or not all of the inputs are now signed
2077
0
    bool complete = true;
2078
0
    for (const auto& input : psbtx.inputs) {
2079
0
        complete &= PSBTInputSigned(input);
2080
0
    }
2081
2082
0
    DataStream ssTx{};
2083
0
    ssTx << psbtx;
2084
2085
0
    UniValue result(UniValue::VOBJ);
2086
2087
0
    result.pushKV("psbt", EncodeBase64(ssTx));
2088
0
    result.pushKV("complete", complete);
2089
0
    if (complete) {
2090
0
        CMutableTransaction mtx;
2091
0
        PartiallySignedTransaction psbtx_copy = psbtx;
2092
0
        CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx_copy, mtx));
Line
Count
Source
103
0
    inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
2093
0
        DataStream ssTx_final;
2094
0
        ssTx_final << TX_WITH_WITNESS(mtx);
2095
0
        result.pushKV("hex", HexStr(ssTx_final));
2096
0
    }
2097
0
    return result;
2098
0
},
2099
2
    };
2100
2
}
2101
2102
void RegisterRawTransactionRPCCommands(CRPCTable& t)
2103
49.9k
{
2104
49.9k
    static const CRPCCommand commands[]{
2105
49.9k
        {"rawtransactions", &getrawtransaction},
2106
49.9k
        {"rawtransactions", &createrawtransaction},
2107
49.9k
        {"rawtransactions", &decoderawtransaction},
2108
49.9k
        {"rawtransactions", &decodescript},
2109
49.9k
        {"rawtransactions", &combinerawtransaction},
2110
49.9k
        {"rawtransactions", &signrawtransactionwithkey},
2111
49.9k
        {"rawtransactions", &decodepsbt},
2112
49.9k
        {"rawtransactions", &combinepsbt},
2113
49.9k
        {"rawtransactions", &finalizepsbt},
2114
49.9k
        {"rawtransactions", &createpsbt},
2115
49.9k
        {"rawtransactions", &converttopsbt},
2116
49.9k
        {"rawtransactions", &utxoupdatepsbt},
2117
49.9k
        {"rawtransactions", &descriptorprocesspsbt},
2118
49.9k
        {"rawtransactions", &joinpsbts},
2119
49.9k
        {"rawtransactions", &analyzepsbt},
2120
49.9k
    };
2121
749k
    for (const auto& c : commands) {
2122
749k
        t.appendCommand(c.name, &c);
2123
749k
    }
2124
49.9k
}