Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 27: [PATCH 27/68] 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 b9c940b7cb566da373f74439311bb611d042d918..bc87a94384e65d70f8b2a65022db9a17f0a88feb 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
@@ -130,6 +130,28 @@ class SweepPrivKeysTest(BitcoinTestFramework):
130
130
  wallet.settxfee(Decimal('0.10000000'))
131
131
  assert_raises_rpc_error(-6, 'Fee exceeds swept value', wallet.sweepprivkeys, [small_wif], destination)
132
132
  assert wif not in Path(self.options.tmpdir, 'node0', 'regtest', 'debug.log').read_text()
133
+
134
+ # A sweep output is an ordinary wallet UTXO after confirmation. Exercise
135
+ # it through explicit coin control only after the encrypted wallet has
136
+ # restarted and been unloaded/reloaded, so neither lifecycle handling
137
+ # nor a stale sweep state can silently substitute another input.
138
+ lifecycle_wif, lifecycle_pubkey = generate_keypair(wif=True)
139
+ miner.sendtoaddress(key_to_p2wpkh(lifecycle_pubkey), 1)
140
+ self.generate(miner, 1)
141
+ self.sync_blocks()
142
+ lifecycle_preview = wallet.sweepprivkeys([lifecycle_wif], destination)
143
+ lifecycle_sweep = wallet.sweepprivkeys([lifecycle_wif], destination, True)
144
+ assert_equal(lifecycle_sweep['txid'], lifecycle_preview['txid'])
145
+ self.sync_mempools()
146
+ self.generate(miner, 1)
147
+ self.sync_blocks()
148
+ self.wait_until(lambda: any(utxo['txid'] == lifecycle_sweep['txid'] for utxo in wallet.listunspent()))
149
+ lifecycle_utxo = next(utxo for utxo in wallet.listunspent() if utxo['txid'] == lifecycle_sweep['txid'])
150
+ lifecycle_input = {'txid': lifecycle_utxo['txid'], 'vout': lifecycle_utxo['vout']}
151
+ wallet.lockunspent(False, [lifecycle_input])
152
+ assert_equal(wallet.listlockunspent(), [lifecycle_input])
153
+ wallet.lockunspent(True, [lifecycle_input])
154
+
133
155
  wallet_name = wallet.getwalletinfo()['walletname']
134
156
  self.restart_node(0)
135
157
  wallet = self.nodes[0].get_wallet_rpc(wallet_name)
@@ -140,5 +162,23 @@ class SweepPrivKeysTest(BitcoinTestFramework):
140
162
  self.nodes[0].loadwallet(wallet_name)
141
163
  wallet = self.nodes[0].get_wallet_rpc(wallet_name)
142
164
  assert_equal(wallet.getaddressinfo(key_to_p2pkh(pubkey))['ismine'], False)
165
+ wallet.walletpassphrase('pass', 60)
166
+ controlled_send = wallet.send(
167
+ outputs={miner.getnewaddress(): Decimal('0.5')},
168
+ options={
169
+ 'inputs': [lifecycle_input],
170
+ 'add_inputs': False,
171
+ 'fee_rate': 1,
172
+ 'replaceable': True,
173
+ },
174
+ )
175
+ assert_equal(controlled_send['complete'], True)
176
+ controlled_tx = self.nodes[0].decoderawtransaction(self.nodes[0].getrawtransaction(controlled_send['txid']))
177
+ assert_equal(len(controlled_tx['vin']), 1)
178
+ assert_equal(controlled_tx['vin'][0]['txid'], lifecycle_input['txid'])
179
+ assert_equal(controlled_tx['vin'][0]['vout'], lifecycle_input['vout'])
180
+ assert controlled_tx['vin'][0]['sequence'] < 0xfffffffe
181
+ assert controlled_send['txid'] in wallet.getrawmempool()
182
+ assert lifecycle_wif not in Path(self.options.tmpdir, 'node0', 'regtest', 'debug.log').read_text()
143
183
 
144
184
  if __name__ == '__main__': SweepPrivKeysTest(__file__).main()