Skip to content
Bitcoin Roots

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. The two line-number columns refer to before and after.

test/functional/wallet_sweepprivkeys.py CHANGED
@@ -131,6 +131,28 @@ class SweepPrivKeysTest(BitcoinTestFramework):
131
131
  wallet.settxfee(Decimal('0.10000000'))
132
132
  assert_raises_rpc_error(-6, 'Fee exceeds swept value', wallet.sweepprivkeys, [small_wif], destination)
133
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
+
134
156
  wallet_name = wallet.getwalletinfo()['walletname']
135
157
  self.restart_node(0)
136
158
  wallet = self.nodes[0].get_wallet_rpc(wallet_name)
@@ -141,5 +163,23 @@ class SweepPrivKeysTest(BitcoinTestFramework):
141
163
  self.nodes[0].loadwallet(wallet_name)
142
164
  wallet = self.nodes[0].get_wallet_rpc(wallet_name)
143
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()
144
184
 
145
185
  if __name__ == '__main__': SweepPrivKeysTest(__file__).main()