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