From e6a2d2b071fac7f8315ef99ab30db02a4bcb2611 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 9 Apr 2019 12:52:24 +0200 Subject: [PATCH 1/4] Merge #15757: List new RPCs in psbt.md and descriptors.md 9b085f4863eaefde4bec0638f1cbc8509d6ee59a Mention new descriptor RPCs in descriptors.md (Pieter Wuille) 28d78de00bf49c6efc19f0edeef2a03d039752a1 Mention new PSBT RPCs in psbt.md (Pieter Wuille) Pull request description: The documentation in `psbt.md` and `descriptors.md` does not list new and updated RPCs (`analyzepsbt`, `utxoupdatepsbt`, `joinpsbts`, `deriveaddresses`, `getdescriptorinfo`, `listunspent`). Fix this. It'd be good to have this in 0.18 (only documentation). ACKs for commit 9b085f: fanquake: utACK 9b085f4 Tree-SHA512: ee16907e8c15351a530f11fc0a585c50835a7bf5aec997ac0e897949d9b9e41a28ddebbeaba69753fee7d2de75e518091518185085fcd1f6ada94b7231097b2e --- doc/descriptors.md | 19 +++++++++++++------ doc/psbt.md | 6 ++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/descriptors.md b/doc/descriptors.md index 9659a1263b72..e1ab22179786 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. - -This document describes the language. For the specifics on usage for scanning -the UTXO set, see the `scantxoutset` RPC help. +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, see the RPC +documentation for the functions mentioned above. ## Features diff --git a/doc/psbt.md b/doc/psbt.md index 560b45ef3126..8ed0c04164be 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. From d5d3490a954f2ce0cf23c1be214995f34b223d6a Mon Sep 17 00:00:00 2001 From: MeshCollider Date: Sat, 27 Apr 2019 15:29:30 +1200 Subject: [PATCH 2/4] Merge #15784: rpc: Remove dependency on interfaces::Chain in SignTransaction 99e88a372 rpc: Remove dependency on interfaces::Chain in SignTransaction (Antoine Riard) Pull request description: Assuming wallet RPCs and node RPCs will go into different processes, signrawtransactionwithkey doesn't need to access Coins via interfaces::Chain, it may use directly utility in node/coins.cpp Obviously will need rebase after #15638 Tree-SHA512: 42ee8fcbcd38643bbd82210db6f68249bed5ee036a4c930a1db534d0469a133e287b8869c977bf0cc79a7296dde04f72adb74d24e1cd20f4a280f4c2b7fceb74 --- src/rpc/rawtransaction.cpp | 10 +++++++++- src/rpc/rawtransaction_util.cpp | 12 +----------- src/rpc/rawtransaction_util.h | 22 ++++++++++++++++------ src/wallet/rpcwallet.cpp | 9 ++++++++- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 551e60723c79..cd8edefddc34 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -759,7 +760,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 3f32edce0b20..ba6b06b70a0a 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 d2106eb2579e..fa0020ab1010 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 86913c8adff6..268691ff1632 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3473,7 +3473,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 From 5e00c3e704bc7ff88956259f7e270a10ac95783d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 17 Jun 2019 13:02:45 -0400 Subject: [PATCH 3/4] Merge #16210: rpc: add 2nd arg to signrawtransactionwithkey examples 71fd628ada Add example 2nd arg to signrawtransactionwithkey (Chris Moore) Pull request description: The RPC examples for signrawtransactionwithkey are missing the 2nd parameter. Before this change the help text showed: Examples: > bitcoin-cli signrawtransactionwithkey "myhex" > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithkey", "params": ["myhex"] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ With the change, it shows: Examples: > bitcoin-cli signrawtransactionwithkey "myhex" "[\"key1\",\"key2\"]" > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithkey", "params": ["myhex", "[\"key1\",\"key2\"]"] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ACKs for commit 71fd62: Tree-SHA512: dadf6bf0ba64ac356b7b8f9ed4d483384b70080ac4b1664b27a2e72b97f25d7266f3dae89fbeade73c1bae802b5bae7b84d596c93a9ae9c748851ae35758d9a6 --- src/rpc/rawtransaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index cd8edefddc34..64ff7f6aac48 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -737,8 +737,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()); From 036c9537ca7ee2831429488dd696c8854da93a62 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 3 Jul 2019 14:49:07 +0200 Subject: [PATCH 4/4] partial Merge #16325: rpc: Clarify that block count means height excl genesis fab0c820fa4c0c3227eec85c64310a3bf938a149 rpc: Clarify that block count means height excl genesis (MarcoFalke) Pull request description: There is a common misconception that the block count returned by the blockchain rpcs includes the genesis block. See for example the discussion in https://github.com/bitcoin/bitcoin/pull/16292#issuecomment-506303256. However, it really returns the height, which is `0` for the genesis block. So clarify that and also remove the misleading "longest blockchain" comment. Finally, fix the wallet test that incorrectly used this rpc. ACKs for top commit: instagibbs: utACK https://github.com/bitcoin/bitcoin/pull/16325/commits/fab0c820fa4c0c3227eec85c64310a3bf938a149 promag: ACK fab0c82, sorry for the misconception. Tree-SHA512: 0d087cbb628d3866352bca6420402f392e6a997e579941701a408a7fca355d84645045661f39b022e4479cc07f85a6cddaa9095b6fd9911b245692482420a5e4 --- src/rpc/blockchain.cpp | 7 ++++--- test/functional/wallet_resendwallettransactions.py | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 301f831928d9..4c72fa4f6960 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/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py index 5888cfe107d0..2a39c57bc5aa 100755 --- a/test/functional/wallet_resendwallettransactions.py +++ b/test/functional/wallet_resendwallettransactions.py @@ -62,8 +62,7 @@ def wait_p2p(): # 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))