diff --git a/doc/descriptors.md b/doc/descriptors.md index 9659a1263b..e1ab221797 100644 --- a/doc/descriptors.md +++ b/doc/descriptors.md @@ -1,11 +1,18 @@ # Support for Output Descriptors in Dash Core -Since Dash Core v0.17, there is support for Output Descriptors in the -`scantxoutset` RPC call. This is a simple language which can be used to -describe collections of output scripts. +Since Dash Core v0.17, there is support for Output Descriptors. This is a +simple language which can be used to describe collections of output scripts. +Supporting RPCs are: +- `scantxoutset` takes as input descriptors to scan for, and also reports + specialized descriptors for the matching UTXOs. +- `getdescriptorinfo` analyzes a descriptor, and reports a canonicalized version + with checksum added. +- `deriveaddresses` takes as input a descriptor and computes the corresponding + addresses. +- `listunspent` outputs a specialized descriptor for the reported unspent outputs. -This document describes the language. For the specifics on usage for scanning -the UTXO set, see the `scantxoutset` RPC help. +This document describes the language. For the specifics on usage, see the RPC +documentation for the functions mentioned above. ## Features diff --git a/doc/psbt.md b/doc/psbt.md index 560b45ef31..8ed0c04164 100644 --- a/doc/psbt.md +++ b/doc/psbt.md @@ -67,6 +67,9 @@ hardware implementations will typically implement multiple roles simultaneously. input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss it, and optionally signs inputs. Where possible it also finalizes the partial signatures. +- **`utxoupdatepsbt` (Updater)** is a node RPC that takes a PSBT and updates it + to include information available from the UTXO set (works only for SegWit + inputs). - **`finalizepsbt` (Finalizer, Extractor)** is a utility RPC that finalizes any partial signatures, and if all inputs are finalized, converts the result to a fully signed transaction which can be broadcast with `sendrawtransaction`. @@ -74,6 +77,9 @@ hardware implementations will typically implement multiple roles simultaneously. can be used at any point in the workflow to merge information added to different versions of the same PSBT. In particular it is useful to combine the output of multiple Updaters or Signers. +- **`joinpsbts`** (Creator) is a utility RPC that joins multiple PSBTs together, + concatenating the inputs and outputs. This can be used to construct CoinJoin + transactions. - **`decodepsbt`** is a diagnostic utility RPC which will show all information in a PSBT in human-readable form, as well as compute its eventual fee if known. diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 301f831928..4c72fa4f69 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -186,7 +186,8 @@ static UniValue getblockcount(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw std::runtime_error( RPCHelpMan{"getblockcount", - "\nReturns the number of blocks in the longest blockchain.\n", + "\nReturns the height of the most-work fully-validated chain.\n" + "The genesis block has height 0.\n", {}, RPCResult{ "n (numeric) The current block count\n" @@ -206,7 +207,7 @@ static UniValue getbestblockhash(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw std::runtime_error( RPCHelpMan{"getbestblockhash", - "\nReturns the hash of the best (tip) block in the longest blockchain.\n", + "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", {}, RPCResult{ "\"hex\" (string) the block hash, hex-encoded\n" @@ -1476,7 +1477,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest) and\n" " devnet or devnet- for \"-devnet\" and \"-devnet=\" respectively\n" - " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" + " \"blocks\": xxxxxx, (numeric) the height of the most-work fully-validated chain. The genesis block has height 0\n" " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index f5f1cd0a92..e76cd11500 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -735,8 +736,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) "}\n" }, RPCExamples{ - HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") - + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"") + HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") + + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") }, }.ToString()); @@ -758,7 +759,14 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) keystore.AddKey(key); } - return SignTransaction(*g_rpc_interfaces->chain, mtx, request.params[2], &keystore, true, request.params[3]); + // Fetch previous transactions (inputs): + std::map coins; + for (const CTxIn& txin : mtx.vin) { + coins[txin.prevout]; // Create empty map entry keyed by prevout. + } + FindCoins(coins); + + return SignTransaction(mtx, request.params[2], &keystore, coins, true, request.params[3]); } UniValue sendrawtransaction(const JSONRPCRequest& request) diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index 3f32edce0b..ba6b06b70a 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -121,18 +121,8 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: vErrorsRet.push_back(entry); } -// TODO(https://github.com/bitcoin/bitcoin/pull/10973#discussion_r267084237): -// The dependency on interfaces::Chain should be removed, so -// signrawtransactionwithkey doesn't need access to a Chain instance. -UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType) +UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore* keystore, std::map& coins, bool is_temp_keystore, const UniValue& hashType) { - // Fetch previous transactions (inputs): - std::map coins; - for (const CTxIn& txin : mtx.vin) { - coins[txin.prevout]; // Create empty map entry keyed by prevout. - } - chain.findCoins(coins); - // Add previous txouts given in the RPC call: if (!prevTxsUnival.isNull()) { UniValue prevTxs = prevTxsUnival.get_array(); diff --git a/src/rpc/rawtransaction_util.h b/src/rpc/rawtransaction_util.h index d2106eb257..fa0020ab10 100644 --- a/src/rpc/rawtransaction_util.h +++ b/src/rpc/rawtransaction_util.h @@ -5,16 +5,26 @@ #ifndef BITCOIN_RPC_RAWTRANSACTION_UTIL_H #define BITCOIN_RPC_RAWTRANSACTION_UTIL_H +#include + class CBasicKeyStore; class UniValue; struct CMutableTransaction; +class Coin; +class COutPoint; -namespace interfaces { -class Chain; -} // namespace interfaces - -/** Sign a transaction with the given keystore and previous transactions */ -UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, const UniValue& prevTxs, CBasicKeyStore *keystore, bool tempKeystore, const UniValue& hashType); +/** + * Sign a transaction with the given keystore and previous transactions + * + * @param mtx The transaction to-be-signed + * @param prevTxs Array of previous txns outputs that tx depends on but may not yet be in the block chain + * @param keystore Temporary keystore containing signing keys + * @param coins Map of unspent outputs - coins in mempool and current chain UTXO set, may be extended by previous txns outputs after call + * @param tempKeystore Whether to use temporary keystore + * @param hashType The signature hash type + * @returns JSON object with details of signed transaction + */ +UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxs, CBasicKeyStore* keystore, std::map& coins, bool tempKeystore, const UniValue& hashType); /** Create a transaction from univalue parameters */ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c092c1f01c..eee62c301d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3472,7 +3472,14 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); EnsureWalletIsUnlocked(pwallet); - return SignTransaction(pwallet->chain(), mtx, request.params[1], pwallet, false, request.params[2]); + // Fetch previous transactions (inputs): + std::map coins; + for (const CTxIn& txin : mtx.vin) { + coins[txin.prevout]; // Create empty map entry keyed by prevout. + } + pwallet->chain().findCoins(coins); + + return SignTransaction(mtx, request.params[1], pwallet, coins, false, request.params[2]); } #if ENABLE_MINER diff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py index 5888cfe107..2a39c57bc5 100755 --- a/test/functional/wallet_resendwallettransactions.py +++ b/test/functional/wallet_resendwallettransactions.py @@ -62,8 +62,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework): # after the last time we tried to broadcast. Use mocktime and give an extra minute to be sure. block_time = self.mocktime + 6 * 60 node.setmocktime(block_time) - block = create_block(int(node.getbestblockhash(), 16), create_coinbase(node.getblockchaininfo()['blocks']), block_time) - block.nVersion = 3 + block = create_block(int(node.getbestblockhash(), 16), create_coinbase(node.getblockcount() + 1), block_time) block.rehash() block.solve() node.submitblock(ToHex(block))