wallet_sendall.py raw

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