wallet_sendall.py raw
1 #!/usr/bin/env python3
2 # Copyright (c) 2022-present The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test the sendall RPC command."""
6
7 from decimal import Decimal, getcontext
8
9 from test_framework.messages import SEQUENCE_FINAL
10 from test_framework.test_framework import BitcoinTestFramework
11 from test_framework.util import (
12 assert_equal,
13 assert_greater_than,
14 assert_greater_than_or_equal,
15 assert_raises_rpc_error,
16 )
17
18 # Decorator to reset activewallet to zero utxos
19 def cleanup(func):
20 def wrapper(self):
21 func(self)
22
23 if 0 < self.wallet.getbalances()["mine"]["trusted"]:
24 self.wallet.sendall([self.remainder_target])
25 assert_equal(0, self.wallet.getbalances()["mine"]["trusted"]) # wallet is empty
26 return wrapper
27
28 class SendallTest(BitcoinTestFramework):
29 def skip_test_if_missing_module(self):
30 self.skip_if_no_wallet()
31
32 def set_test_params(self):
33 getcontext().prec=10
34 self.num_nodes = 1
35 self.setup_clean_chain = True
36
37 def assert_balance_swept_completely(self, tx, balance):
38 output_sum = sum([o["value"] for o in tx["decoded"]["vout"]])
39 assert_equal(output_sum, balance + tx["fee"])
40 assert_equal(0, self.wallet.getbalances()["mine"]["trusted"]) # wallet is empty
41
42 def assert_tx_has_output(self, tx, addr, value=None):
43 for output in tx["decoded"]["vout"]:
44 if addr == output["scriptPubKey"]["address"] and value is None or value == output["value"]:
45 return
46 raise AssertionError("Output to {} not present or wrong amount".format(addr))
47
48 def assert_tx_has_outputs(self, tx, expected_outputs):
49 assert_equal(len(expected_outputs), len(tx["decoded"]["vout"]))
50 for eo in expected_outputs:
51 self.assert_tx_has_output(tx, eo["address"], eo["value"])
52
53 def add_utxos(self, amounts):
54 for a in amounts:
55 self.def_wallet.sendtoaddress(self.wallet.getnewaddress(), a)
56 self.generate(self.nodes[0], 1)
57 assert_greater_than(self.wallet.getbalances()["mine"]["trusted"], 0)
58 return self.wallet.getbalances()["mine"]["trusted"]
59
60 # Helper schema for success cases
61 def test_sendall_success(self, sendall_args, remaining_balance = 0, *, options=None):
62 sendall_tx_receipt = self.wallet.sendall(sendall_args, options=options)
63 self.generate(self.nodes[0], 1)
64 # wallet has remaining balance (usually empty)
65 assert_equal(remaining_balance, self.wallet.getbalances()["mine"]["trusted"])
66
67 assert_equal(sendall_tx_receipt["complete"], True)
68 return self.wallet.gettransaction(txid = sendall_tx_receipt["txid"], verbose = True)
69
70 @cleanup
71 def gen_and_clean(self):
72 self.add_utxos([15, 2, 4])
73
74 def test_cleanup(self):
75 self.log.info("Test that cleanup wrapper empties wallet")
76 self.gen_and_clean()
77 assert_equal(0, self.wallet.getbalances()["mine"]["trusted"]) # wallet is empty
78
79 # Actual tests
80 @cleanup
81 def sendall_two_utxos(self):
82 self.log.info("Testing basic sendall case without specific amounts")
83 pre_sendall_balance = self.add_utxos([10,11])
84 tx_from_wallet = self.test_sendall_success(sendall_args = [self.remainder_target])
85
86 self.assert_tx_has_outputs(tx = tx_from_wallet,
87 expected_outputs = [
88 { "address": self.remainder_target, "value": pre_sendall_balance + tx_from_wallet["fee"] } # fee is neg
89 ]
90 )
91 self.assert_balance_swept_completely(tx_from_wallet, pre_sendall_balance)
92
93 @cleanup
94 def sendall_split(self):
95 self.log.info("Testing sendall where two recipients have unspecified amount")
96 pre_sendall_balance = self.add_utxos([1, 2, 3, 15])
97 tx_from_wallet = self.test_sendall_success([self.remainder_target, self.split_target])
98
99 half = (pre_sendall_balance + tx_from_wallet["fee"]) / 2
100 self.assert_tx_has_outputs(tx_from_wallet,
101 expected_outputs = [
102 { "address": self.split_target, "value": half },
103 { "address": self.remainder_target, "value": half }
104 ]
105 )
106 self.assert_balance_swept_completely(tx_from_wallet, pre_sendall_balance)
107
108 @cleanup
109 def sendall_and_spend(self):
110 self.log.info("Testing sendall in combination with paying specified amount to recipient")
111 pre_sendall_balance = self.add_utxos([8, 13])
112 tx_from_wallet = self.test_sendall_success([{self.recipient: 5}, self.remainder_target])
113
114 self.assert_tx_has_outputs(tx_from_wallet,
115 expected_outputs = [
116 { "address": self.recipient, "value": 5 },
117 { "address": self.remainder_target, "value": pre_sendall_balance - 5 + tx_from_wallet["fee"] }
118 ]
119 )
120 self.assert_balance_swept_completely(tx_from_wallet, pre_sendall_balance)
121
122 @cleanup
123 def sendall_invalid_recipient_addresses(self):
124 self.log.info("Test having only recipient with specified amount, missing recipient with unspecified amount")
125 self.add_utxos([12, 9])
126
127 assert_raises_rpc_error(
128 -8,
129 "Must provide at least one address without a specified amount" ,
130 self.wallet.sendall,
131 [{self.recipient: 5}]
132 )
133
134 @cleanup
135 def sendall_duplicate_recipient(self):
136 self.log.info("Test duplicate destination")
137 self.add_utxos([1, 8, 3, 9])
138
139 assert_raises_rpc_error(
140 -8,
141 "Invalid parameter, duplicated address: {}".format(self.remainder_target),
142 self.wallet.sendall,
143 [self.remainder_target, self.remainder_target]
144 )
145
146 @cleanup
147 def sendall_invalid_amounts(self):
148 self.log.info("Test sending more than balance")
149 pre_sendall_balance = self.add_utxos([7, 14])
150
151 expected_tx = self.wallet.sendall(recipients=[{self.recipient: 5}, self.remainder_target], add_to_wallet=False)
152 tx = self.wallet.decoderawtransaction(expected_tx['hex'])
153 fee = 21 - sum([o["value"] for o in tx["vout"]])
154
155 assert_raises_rpc_error(-6, "Assigned more value to outputs than available funds.", self.wallet.sendall,
156 [{self.recipient: pre_sendall_balance + 1}, self.remainder_target])
157 assert_raises_rpc_error(-6, "Insufficient funds for fees after creating specified outputs.", self.wallet.sendall,
158 [{self.recipient: pre_sendall_balance}, self.remainder_target])
159 assert_raises_rpc_error(-8, "Specified output amount to {} is below dust threshold".format(self.recipient),
160 self.wallet.sendall, [{self.recipient: 0.00000001}, self.remainder_target])
161 assert_raises_rpc_error(-6, "Dynamically assigned remainder results in dust output.", self.wallet.sendall,
162 [{self.recipient: pre_sendall_balance - fee}, self.remainder_target])
163 assert_raises_rpc_error(-6, "Dynamically assigned remainder results in dust output.", self.wallet.sendall,
164 [{self.recipient: pre_sendall_balance - fee - Decimal(0.00000010)}, self.remainder_target])
165
166 # @cleanup not needed because different wallet used
167 def sendall_negative_effective_value(self):
168 self.log.info("Test that sendall fails if all UTXOs have negative effective value")
169 # Use dedicated wallet for dust amounts and unload wallet at end
170 self.nodes[0].createwallet("dustwallet")
171 dust_wallet = self.nodes[0].get_wallet_rpc("dustwallet")
172
173 self.def_wallet.sendtoaddress(dust_wallet.getnewaddress(), 0.00000400)
174 self.def_wallet.sendtoaddress(dust_wallet.getnewaddress(), 0.00000300)
175 self.generate(self.nodes[0], 1)
176 assert_greater_than(dust_wallet.getbalances()["mine"]["trusted"], 0)
177
178 assert_raises_rpc_error(-6, "Total value of UTXO pool too low to pay for transaction."
179 + " Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.",
180 dust_wallet.sendall, recipients=[self.remainder_target], fee_rate=300)
181
182 dust_wallet.unloadwallet()
183
184 @cleanup
185 def sendall_with_send_max(self):
186 self.log.info("Check that `send_max` option causes negative value UTXOs to be left behind")
187 self.add_utxos([0.00000400, 0.00000300, 1])
188
189 # sendall with send_max
190 sendall_tx_receipt = self.wallet.sendall(recipients=[self.remainder_target], fee_rate=300, send_max=True)
191 tx_from_wallet = self.wallet.gettransaction(txid = sendall_tx_receipt["txid"], verbose = True)
192
193 assert_equal(len(tx_from_wallet["decoded"]["vin"]), 1)
194 self.assert_tx_has_outputs(tx_from_wallet, [{"address": self.remainder_target, "value": 1 + tx_from_wallet["fee"]}])
195 assert_equal(self.wallet.getbalances()["mine"]["trusted"], Decimal("0.00000700"))
196
197 self.def_wallet.sendtoaddress(self.wallet.getnewaddress(), 1)
198 self.generate(self.nodes[0], 1)
199
200 @cleanup
201 def sendall_specific_inputs(self):
202 self.log.info("Test sendall with a subset of UTXO pool")
203 self.add_utxos([17, 4])
204 utxo = self.wallet.listunspent()[0]
205
206 sendall_tx_receipt = self.wallet.sendall(recipients=[self.remainder_target], inputs=[utxo])
207 tx_from_wallet = self.wallet.gettransaction(txid = sendall_tx_receipt["txid"], verbose = True)
208 assert_equal(len(tx_from_wallet["decoded"]["vin"]), 1)
209 assert_equal(len(tx_from_wallet["decoded"]["vout"]), 1)
210 assert_equal(tx_from_wallet["decoded"]["vin"][0]["txid"], utxo["txid"])
211 assert_equal(tx_from_wallet["decoded"]["vin"][0]["vout"], utxo["vout"])
212 self.assert_tx_has_output(tx_from_wallet, self.remainder_target)
213
214 self.generate(self.nodes[0], 1)
215 assert_greater_than(self.wallet.getbalances()["mine"]["trusted"], 0)
216
217 @cleanup
218 def sendall_fails_on_missing_input(self):
219 # fails because UTXO was previously spent, and wallet is empty
220 self.log.info("Test sendall fails because specified UTXO is not available")
221 self.add_utxos([16, 5])
222 spent_utxo = self.wallet.listunspent()[0]
223
224 # fails on out of bounds vout
225 assert_raises_rpc_error(-8,
226 "Input not found. UTXO ({}:{}) is not part of wallet.".format(spent_utxo["txid"], 1000),
227 self.wallet.sendall, recipients=[self.remainder_target], inputs=[{"txid": spent_utxo["txid"], "vout": 1000}])
228
229 # fails on unconfirmed spent UTXO
230 self.wallet.sendall(recipients=[self.remainder_target])
231 assert_raises_rpc_error(-8,
232 "Input not available. UTXO ({}:{}) was already spent.".format(spent_utxo["txid"], spent_utxo["vout"]),
233 self.wallet.sendall, recipients=[self.remainder_target], inputs=[spent_utxo])
234
235 # fails on specific previously spent UTXO, while other UTXOs exist
236 self.generate(self.nodes[0], 1)
237 self.add_utxos([19, 2])
238 assert_raises_rpc_error(-8,
239 "Input not available. UTXO ({}:{}) was already spent.".format(spent_utxo["txid"], spent_utxo["vout"]),
240 self.wallet.sendall, recipients=[self.remainder_target], inputs=[spent_utxo])
241
242 # fails because UTXO is unknown, while other UTXOs exist
243 foreign_utxo = self.def_wallet.listunspent()[0]
244 assert_raises_rpc_error(-8, "Input not found. UTXO ({}:{}) is not part of wallet.".format(foreign_utxo["txid"],
245 foreign_utxo["vout"]), self.wallet.sendall, recipients=[self.remainder_target],
246 inputs=[foreign_utxo])
247
248 @cleanup
249 def sendall_fails_on_no_address(self):
250 self.log.info("Test sendall fails because no address is provided")
251 self.add_utxos([19, 2])
252
253 assert_raises_rpc_error(
254 -8,
255 "Must provide at least one address without a specified amount" ,
256 self.wallet.sendall,
257 []
258 )
259
260 @cleanup
261 def sendall_fails_on_specific_inputs_with_send_max(self):
262 self.log.info("Test sendall fails because send_max is used while specific inputs are provided")
263 self.add_utxos([15, 6])
264 utxo = self.wallet.listunspent()[0]
265
266 assert_raises_rpc_error(-8,
267 "Cannot combine send_max with specific inputs.",
268 self.wallet.sendall,
269 recipients=[self.remainder_target],
270 inputs=[utxo], send_max=True)
271
272 @cleanup
273 def sendall_fails_on_high_fee(self):
274 self.log.info("Test sendall fails if the transaction fee exceeds the maxtxfee")
275 self.add_utxos([21])
276
277 assert_raises_rpc_error(
278 -4,
279 "Fee exceeds maximum configured by user",
280 self.wallet.sendall,
281 recipients=[self.remainder_target],
282 fee_rate=100000)
283
284 @cleanup
285 def sendall_fails_on_low_fee(self):
286 self.log.info("Test sendall fails if the transaction fee is lower than the minimum fee rate setting")
287 assert_raises_rpc_error(-8, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
288 self.wallet.sendall, recipients=[self.recipient], fee_rate=0.999)
289
290 @cleanup
291 def sendall_watchonly_specific_inputs(self):
292 self.log.info("Test sendall with a subset of UTXO pool in a watchonly wallet")
293 self.add_utxos([17, 4])
294 utxo = self.wallet.listunspent()[0]
295
296 self.nodes[0].createwallet(wallet_name="watching", disable_private_keys=True)
297 watchonly = self.nodes[0].get_wallet_rpc("watching")
298
299 import_req = [{
300 "desc": utxo["desc"],
301 "timestamp": 0,
302 }]
303 watchonly.importdescriptors(import_req)
304
305 sendall_tx_receipt = watchonly.sendall(recipients=[self.remainder_target], inputs=[utxo])
306 psbt = sendall_tx_receipt["psbt"]
307 decoded = self.nodes[0].decodepsbt(psbt)
308 assert_equal(len(decoded["inputs"]), 1)
309 assert_equal(len(decoded["outputs"]), 1)
310 assert_equal(decoded["inputs"][0]["previous_txid"], utxo["txid"])
311 assert_equal(decoded["inputs"][0]["previous_vout"], utxo["vout"])
312 assert_equal(decoded["outputs"][0]["script"]["address"], self.remainder_target)
313
314 @cleanup
315 def sendall_with_minconf(self):
316 # utxo of 17 bicoin has 6 confirmations, utxo of 4 has 3
317 self.add_utxos([17])
318 self.generate(self.nodes[0], 2)
319 self.add_utxos([4])
320 self.generate(self.nodes[0], 2)
321
322 self.log.info("Test sendall fails because minconf is negative")
323
324 assert_raises_rpc_error(-8,
325 "Invalid minconf (minconf cannot be negative): -2",
326 self.wallet.sendall,
327 recipients=[self.remainder_target],
328 options={"minconf": -2})
329 self.log.info("Test sendall fails because minconf is used while specific inputs are provided")
330
331 utxo = self.wallet.listunspent()[0]
332 assert_raises_rpc_error(-8,
333 "Cannot combine minconf or maxconf with specific inputs.",
334 self.wallet.sendall,
335 recipients=[self.remainder_target],
336 options={"inputs": [utxo], "minconf": 2})
337
338 self.log.info("Test sendall fails because there are no utxos with enough confirmations specified by minconf")
339
340 assert_raises_rpc_error(-6,
341 "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.",
342 self.wallet.sendall,
343 recipients=[self.remainder_target],
344 options={"minconf": 7})
345
346 self.log.info("Test sendall only spends utxos with a specified number of confirmations when minconf is used")
347 self.wallet.sendall(recipients=[self.remainder_target], fee_rate=300, options={"minconf": 6})
348
349 assert_equal(len(self.wallet.listunspent()), 1)
350 assert_equal(self.wallet.listunspent()[0]['confirmations'], 3)
351
352 # decrease minconf and show the remaining utxo is picked up
353 self.wallet.sendall(recipients=[self.remainder_target], fee_rate=300, options={"minconf": 3})
354 assert_equal(self.wallet.getbalance(), 0)
355
356 @cleanup
357 def sendall_with_maxconf(self):
358 # utxo of 17 bicoin has 6 confirmations, utxo of 4 has 3
359 self.add_utxos([17])
360 self.generate(self.nodes[0], 2)
361 self.add_utxos([4])
362 self.generate(self.nodes[0], 2)
363
364 self.log.info("Test sendall fails because there are no utxos with enough confirmations specified by maxconf")
365 assert_raises_rpc_error(-6,
366 "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.",
367 self.wallet.sendall,
368 recipients=[self.remainder_target],
369 options={"maxconf": 1})
370
371 self.log.info("Test sendall only spends utxos with a specified number of confirmations when maxconf is used")
372 self.wallet.sendall(recipients=[self.remainder_target], fee_rate=300, options={"maxconf":4})
373 assert_equal(len(self.wallet.listunspent()), 1)
374 assert_equal(self.wallet.listunspent()[0]['confirmations'], 6)
375
376 @cleanup
377 def sendall_spends_unconfirmed_change(self):
378 self.log.info("Test that sendall spends unconfirmed change")
379 self.add_utxos([17])
380 self.wallet.sendtoaddress(self.remainder_target, 10)
381 assert_greater_than(self.wallet.getbalances()["mine"]["trusted"], 6)
382 self.test_sendall_success(sendall_args = [self.remainder_target])
383
384 assert_equal(self.wallet.getbalance(), 0)
385
386 @cleanup
387 def sendall_spends_unconfirmed_inputs_if_specified(self):
388 self.log.info("Test that sendall spends specified unconfirmed inputs")
389 self.def_wallet.sendtoaddress(self.wallet.getnewaddress(), 17)
390 self.wallet.syncwithvalidationinterfacequeue()
391 assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17)
392 unspent = self.wallet.listunspent(minconf=0)[0]
393
394 self.wallet.sendall(recipients=[self.remainder_target], inputs=[unspent])
395 assert_equal(self.wallet.getbalance(), 0)
396
397 @cleanup
398 def sendall_does_ancestor_aware_funding(self):
399 self.log.info("Test that sendall does ancestor aware funding for unconfirmed inputs")
400
401 # higher parent feerate
402 self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=20)
403 self.wallet.syncwithvalidationinterfacequeue()
404
405 assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17)
406 unspent = self.wallet.listunspent(minconf=0)[0]
407
408 parent_txid = unspent["txid"]
409 assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0)
410
411 res_1 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True)
412 child_hex = res_1["hex"]
413
414 child_tx = self.wallet.decoderawtransaction(child_hex)
415 higher_parent_feerate_amount = child_tx["vout"][0]["value"]
416
417 # lower parent feerate
418 self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=10)
419 self.wallet.syncwithvalidationinterfacequeue()
420 assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 34)
421 unspent = self.wallet.listunspent(minconf=0)[0]
422
423 parent_txid = unspent["txid"]
424 assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0)
425
426 res_2 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True)
427 child_hex = res_2["hex"]
428
429 child_tx = self.wallet.decoderawtransaction(child_hex)
430 lower_parent_feerate_amount = child_tx["vout"][0]["value"]
431
432 assert_greater_than(higher_parent_feerate_amount, lower_parent_feerate_amount)
433
434 @cleanup
435 def sendall_anti_fee_sniping(self):
436 self.log.info("Testing sendall does anti-fee-sniping when locktime is not specified")
437 self.add_utxos([10,11])
438 tx_from_wallet = self.test_sendall_success(sendall_args = [self.remainder_target], options={"replaceable":False})
439
440 # the locktime should be within 100 blocks of the
441 # block height
442 assert_greater_than_or_equal(tx_from_wallet["decoded"]["locktime"], tx_from_wallet["blockheight"] - 100)
443
444 self.log.info("Testing sendall does not do anti-fee-sniping when locktime is specified")
445 self.add_utxos([10,11])
446 txid = self.wallet.sendall(recipients=[self.remainder_target], options={"locktime":0})["txid"]
447 assert_equal(self.wallet.gettransaction(txid=txid, verbose=True)["decoded"]["locktime"], 0)
448
449 self.log.info("Testing sendall does not do anti-fee-sniping when even one of the sequences is final")
450 self.add_utxos([10, 11])
451 utxos = self.wallet.listunspent()
452 utxos[0]["sequence"] = SEQUENCE_FINAL
453 txid = self.wallet.sendall(recipients=[self.remainder_target], inputs=utxos)["txid"]
454 assert_equal(self.wallet.gettransaction(txid=txid, verbose=True)["decoded"]["locktime"], 0)
455
456 # This tests needs to be the last one otherwise @cleanup will fail with "Transaction too large" error
457 def sendall_fails_with_transaction_too_large(self):
458 self.log.info("Test that sendall fails if resulting transaction is too large")
459
460 # Force the wallet to bulk-generate the addresses we'll need
461 self.wallet.keypoolrefill(1600)
462
463 # create many inputs
464 outputs = {self.wallet.getnewaddress(): 0.000025 for _ in range(1600)}
465 self.def_wallet.sendmany(amounts=outputs)
466 self.generate(self.nodes[0], 1)
467
468 assert_raises_rpc_error(
469 -4,
470 "Transaction too large.",
471 self.wallet.sendall,
472 recipients=[self.remainder_target])
473
474 def run_test(self):
475 self.nodes[0].createwallet("activewallet")
476 self.wallet = self.nodes[0].get_wallet_rpc("activewallet")
477 self.def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
478 self.generate(self.nodes[0], 101)
479 self.recipient = self.def_wallet.getnewaddress() # payee for a specific amount
480 self.remainder_target = self.def_wallet.getnewaddress() # address that receives everything left after payments and fees
481 self.split_target = self.def_wallet.getnewaddress() # 2nd target when splitting rest
482
483 # Test cleanup
484 self.test_cleanup()
485
486 # Basic sweep: everything to one address
487 self.sendall_two_utxos()
488
489 # Split remainder to two addresses with equal amounts
490 self.sendall_split()
491
492 # Pay recipient and sweep remainder
493 self.sendall_and_spend()
494
495 # sendall fails if no recipient has unspecified amount
496 self.sendall_invalid_recipient_addresses()
497
498 # Sendall fails if same destination is provided twice
499 self.sendall_duplicate_recipient()
500
501 # Sendall fails when trying to spend more than the balance
502 self.sendall_invalid_amounts()
503
504 # Sendall fails when wallet has no economically spendable UTXOs
505 self.sendall_negative_effective_value()
506
507 # Leave dust behind if using send_max
508 self.sendall_with_send_max()
509
510 # Sendall succeeds with specific inputs
511 self.sendall_specific_inputs()
512
513 # Fails for the right reasons on missing or previously spent UTXOs
514 self.sendall_fails_on_missing_input()
515
516 # Sendall fails when no address is provided
517 self.sendall_fails_on_no_address()
518
519 # Sendall fails when using send_max while specifying inputs
520 self.sendall_fails_on_specific_inputs_with_send_max()
521
522 # Sendall fails when providing a fee that is too high
523 self.sendall_fails_on_high_fee()
524
525 # Sendall fails when fee rate is lower than minimum
526 self.sendall_fails_on_low_fee()
527
528 # Sendall succeeds with watchonly wallets spending specific UTXOs
529 self.sendall_watchonly_specific_inputs()
530
531 # Sendall only uses outputs with at least a give number of confirmations when using minconf
532 self.sendall_with_minconf()
533
534 # Sendall only uses outputs with less than a given number of confirmation when using minconf
535 self.sendall_with_maxconf()
536
537 # Sendall discourages fee-sniping when a locktime is not specified
538 self.sendall_anti_fee_sniping()
539
540 # Sendall spends unconfirmed change
541 self.sendall_spends_unconfirmed_change()
542
543 # Sendall spends unconfirmed inputs if they are specified
544 self.sendall_spends_unconfirmed_inputs_if_specified()
545
546 # Sendall does ancestor aware funding when spending an unconfirmed UTXO
547 self.sendall_does_ancestor_aware_funding()
548
549 # Sendall fails when many inputs result to too large transaction
550 self.sendall_fails_with_transaction_too_large()
551
552 if __name__ == '__main__':
553 SendallTest(__file__).main()
554