Merge f98872f127 into merged_master (Bitcoin PR #18244)

This commit is contained in:
Andrew Poelstra 2020-11-28 18:55:44 +00:00
commit 5f6eb8ee3f
5 changed files with 33 additions and 6 deletions

View file

@ -0,0 +1,7 @@
Updated RPCs
------------
- `fundrawtransaction` and `walletcreatefundedpsbt` when used with the `lockUnspents`
argument now lock manually selected coins, in addition to automatically selected
coins. Note that locked coins are never used in automatic coin selection, but
can still be manually selected.

View file

@ -2224,6 +2224,7 @@ static UniValue lockunspent(const JSONRPCRequest& request)
"Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
"If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
"A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
"Manually selected coins are automatically unlocked.\n"
"Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
"is always cleared (by virtue of process exit) when a node stops or fails.\n"
"Also see the listunspent call\n",

View file

@ -2950,10 +2950,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
if (!coinControl.IsSelected(txin.prevout)) {
tx.vin.push_back(txin);
if (lockUnspents) {
LockCoin(txin.prevout);
}
}
if (lockUnspents) {
LockCoin(txin.prevout);
}
}
return true;

View file

@ -113,6 +113,7 @@ class PSBTTest(BitcoinTestFramework):
return result
def run_basic_tests(self, confidential):
starting_n_unspent = len(self.nodes[0].listlockunspent()) # ELEMENTS
# Create and fund a raw tx for sending 10 BTC
psbtx1 = self.nodes[0].walletcreatefundedpsbt([], {self.get_address(confidential, 2):10})['psbt']
@ -139,7 +140,16 @@ class PSBTTest(BitcoinTestFramework):
assert(self.num_blinded_outputs(final_tx) > 0)
self.nodes[0].sendrawtransaction(final_tx)
# Get pubkeys
# Manually selected inputs can be locked:
assert_equal(len(self.nodes[0].listlockunspent()), starting_n_unspent)
utxo1 = self.nodes[0].listunspent()[0]
psbtx1 = self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.get_address(confidential, 2):1}, 0,{"lockUnspents": True})["psbt"]
assert_equal(len(self.nodes[0].listlockunspent()), starting_n_unspent + 1)
# Locks are ignored for manually selected inputs
self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.get_address(confidential, 2):1}, 0)
# Create p2sh, p2wpkh, and p2wsh addresses
pubkey0 = self.nodes[0].getaddressinfo(self.get_address(confidential, 0))['pubkey']
pubkey1 = self.nodes[1].getaddressinfo(self.get_address(confidential, 1))['pubkey']
pubkey2 = self.nodes[2].getaddressinfo(self.get_address(confidential, 2))['pubkey']

View file

@ -135,11 +135,19 @@ class WalletTest(BitcoinTestFramework):
self.nodes[2].lockunspent, False,
[{"txid": unspent_0["txid"], "vout": 999}])
# An output should be unlocked when spent
# The lock on a manually selected output is ignored
unspent_0 = self.nodes[1].listunspent()[0]
self.nodes[1].lockunspent(False, [unspent_0])
tx = self.nodes[1].createrawtransaction([unspent_0], { self.nodes[1].getnewaddress() : 1 })
tx = self.nodes[1].fundrawtransaction(tx)['hex']
self.nodes[1].fundrawtransaction(tx,{"lockUnspents": True})
# fundrawtransaction can lock an input
self.nodes[1].lockunspent(True, [unspent_0])
assert_equal(len(self.nodes[1].listlockunspent()), 0)
tx = self.nodes[1].fundrawtransaction(tx,{"lockUnspents": True})['hex']
assert_equal(len(self.nodes[1].listlockunspent()), 1)
# Send transaction
tx = self.nodes[1].signrawtransactionwithwallet(tx)["hex"]
self.nodes[1].sendrawtransaction(tx)
assert_equal(len(self.nodes[1].listlockunspent()), 0)