v29.4-roots.4 · Commit 27: [PATCH 27/37] docs(wallet): document advanced privacy tools
test/functional/wallet_sweepprivkeys.py
Before: test/functional/wallet_sweepprivkeys.py · After: test/functional/wallet_sweepprivkeys.py
File metadata
index eab6638441788085b28aef9c917b8d580db24383..6c463b040a3726808909eda45de3658d841445d4 100644
Download original patch · Release notes
Diff rows 1–51 of 51. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
test/functional/wallet_sweepprivkeys.py
CHANGED
|
@@ -131,6 +131,28 @@ class SweepPrivKeysTest(BitcoinTestFramework):
|
|
| 131 |
wallet.settxfee(Decimal('0.10000000'))
|
| 132 |
assert_raises_rpc_error(-6, 'Fee exceeds swept value', wallet.sweepprivkeys, [small_wif], destination)
|
| 133 |
assert wif not in Path(self.options.tmpdir, 'node0', 'regtest', 'debug.log').read_text()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
wallet_name = wallet.getwalletinfo()['walletname']
|
| 135 |
self.restart_node(0)
|
| 136 |
wallet = self.nodes[0].get_wallet_rpc(wallet_name)
|
|
@@ -141,5 +163,23 @@ class SweepPrivKeysTest(BitcoinTestFramework):
|
|
| 141 |
self.nodes[0].loadwallet(wallet_name)
|
| 142 |
wallet = self.nodes[0].get_wallet_rpc(wallet_name)
|
| 143 |
assert_equal(wallet.getaddressinfo(key_to_p2pkh(pubkey))['ismine'], False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
if __name__ == '__main__': SweepPrivKeysTest(__file__).main()
|
|
|
|
| 131 |
wallet.settxfee(Decimal('0.10000000'))
|
| 132 |
assert_raises_rpc_error(-6, 'Fee exceeds swept value', wallet.sweepprivkeys, [small_wif], destination)
|
| 133 |
assert wif not in Path(self.options.tmpdir, 'node0', 'regtest', 'debug.log').read_text()
|
| 134 |
+
|
| 135 |
+
# A sweep output is an ordinary wallet UTXO after confirmation. Exercise
|
| 136 |
+
# it through explicit coin control only after the encrypted wallet has
|
| 137 |
+
# restarted and been unloaded/reloaded, so neither lifecycle handling
|
| 138 |
+
# nor a stale sweep state can silently substitute another input.
|
| 139 |
+
lifecycle_wif, lifecycle_pubkey = generate_keypair(wif=True)
|
| 140 |
+
miner.sendtoaddress(key_to_p2wpkh(lifecycle_pubkey), 1)
|
| 141 |
+
self.generate(miner, 1)
|
| 142 |
+
self.sync_blocks()
|
| 143 |
+
lifecycle_preview = wallet.sweepprivkeys([lifecycle_wif], destination)
|
| 144 |
+
lifecycle_sweep = wallet.sweepprivkeys([lifecycle_wif], destination, True)
|
| 145 |
+
assert_equal(lifecycle_sweep['txid'], lifecycle_preview['txid'])
|
| 146 |
+
self.sync_mempools()
|
| 147 |
+
self.generate(miner, 1)
|
| 148 |
+
self.sync_blocks()
|
| 149 |
+
self.wait_until(lambda: any(utxo['txid'] == lifecycle_sweep['txid'] for utxo in wallet.listunspent()))
|
| 150 |
+
lifecycle_utxo = next(utxo for utxo in wallet.listunspent() if utxo['txid'] == lifecycle_sweep['txid'])
|
| 151 |
+
lifecycle_input = {'txid': lifecycle_utxo['txid'], 'vout': lifecycle_utxo['vout']}
|
| 152 |
+
wallet.lockunspent(False, [lifecycle_input])
|
| 153 |
+
assert_equal(wallet.listlockunspent(), [lifecycle_input])
|
| 154 |
+
wallet.lockunspent(True, [lifecycle_input])
|
| 155 |
+
|
| 156 |
wallet_name = wallet.getwalletinfo()['walletname']
|
| 157 |
self.restart_node(0)
|
| 158 |
wallet = self.nodes[0].get_wallet_rpc(wallet_name)
|
|
|
|
| 163 |
self.nodes[0].loadwallet(wallet_name)
|
| 164 |
wallet = self.nodes[0].get_wallet_rpc(wallet_name)
|
| 165 |
assert_equal(wallet.getaddressinfo(key_to_p2pkh(pubkey))['ismine'], False)
|
| 166 |
+
wallet.walletpassphrase('pass', 60)
|
| 167 |
+
controlled_send = wallet.send(
|
| 168 |
+
outputs={miner.getnewaddress(): Decimal('0.5')},
|
| 169 |
+
options={
|
| 170 |
+
'inputs': [lifecycle_input],
|
| 171 |
+
'add_inputs': False,
|
| 172 |
+
'fee_rate': 1,
|
| 173 |
+
'replaceable': True,
|
| 174 |
+
},
|
| 175 |
+
)
|
| 176 |
+
assert_equal(controlled_send['complete'], True)
|
| 177 |
+
controlled_tx = self.nodes[0].decoderawtransaction(self.nodes[0].getrawtransaction(controlled_send['txid']))
|
| 178 |
+
assert_equal(len(controlled_tx['vin']), 1)
|
| 179 |
+
assert_equal(controlled_tx['vin'][0]['txid'], lifecycle_input['txid'])
|
| 180 |
+
assert_equal(controlled_tx['vin'][0]['vout'], lifecycle_input['vout'])
|
| 181 |
+
assert controlled_tx['vin'][0]['sequence'] < 0xfffffffe
|
| 182 |
+
assert controlled_send['txid'] in wallet.getrawmempool()
|
| 183 |
+
assert lifecycle_wif not in Path(self.options.tmpdir, 'node0', 'regtest', 'debug.log').read_text()
|
| 184 |
|
| 185 |
if __name__ == '__main__': SweepPrivKeysTest(__file__).main()
|