From 7afbd9c3674d5d9e0268b49aa2aa5f5edb50b982 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 31 Dec 2024 12:40:54 +0000 Subject: [PATCH] qa: Ensure consistent use of decimals instead of floats This change fixes tests for Python 3.12.8 and 3.13.1 on NetBSD. --- test/functional/feature_assumeutxo.py | 3 +- test/functional/rpc_psbt.py | 44 ++++----- .../wallet_avoid_mixing_output_types.py | 3 +- test/functional/wallet_balance.py | 2 +- test/functional/wallet_basic.py | 2 +- test/functional/wallet_bumpfee.py | 22 ++--- test/functional/wallet_change_address.py | 11 ++- test/functional/wallet_conflicts.py | 28 +++--- test/functional/wallet_create_tx.py | 6 +- test/functional/wallet_fundrawtransaction.py | 98 +++++++++---------- test/functional/wallet_groups.py | 18 ++-- test/functional/wallet_importdescriptors.py | 11 ++- test/functional/wallet_importprunedfunds.py | 6 +- test/functional/wallet_keypool.py | 14 +-- test/functional/wallet_listreceivedby.py | 8 +- test/functional/wallet_listtransactions.py | 16 +-- test/functional/wallet_miniscript.py | 4 +- .../wallet_multisig_descriptor_psbt.py | 4 +- 18 files changed, 156 insertions(+), 144 deletions(-) diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index 8addb7e2385f7..ee2c28a1d4909 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -9,6 +9,7 @@ The assumeutxo value generated and used here is committed to in `CRegTestParams::m_assumeutxo_data` in `src/kernel/chainparams.cpp`. """ +from decimal import Decimal from shutil import rmtree from dataclasses import dataclass @@ -560,7 +561,7 @@ def check_tx_counts(final: bool) -> None: prev_tx = n0.getblock(spend_coin_blockhash, 3)['tx'][0] prevout = {"txid": prev_tx['txid'], "vout": 0, "scriptPubKey": prev_tx['vout'][0]['scriptPubKey']['hex']} privkey = n0.get_deterministic_priv_key().key - raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: 24.99}) + raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: Decimal("24.99")}) signed_tx = n1.signrawtransactionwithkey(raw_tx, [privkey], [prevout])['hex'] signed_txid = tx_from_hex(signed_tx).rehash() diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 8042bdf0715ac..6e47f9e20f51a 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -78,17 +78,17 @@ def test_psbt_incomplete_after_invalid_modification(self): node = self.nodes[2] wallet = node.get_wallet_rpc(self.default_wallet_name) address = wallet.getnewaddress() - wallet.sendtoaddress(address=address, amount=1.0) + wallet.sendtoaddress(address=address, amount=Decimal("1.0")) self.generate(node, nblocks=1, sync_fun=lambda: self.sync_all(self.nodes[:2])) utxos = wallet.listunspent(addresses=[address]) - psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): 0.9999}]) + psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): Decimal("0.9999")}]) signed_psbt = wallet.walletprocesspsbt(psbt)["psbt"] # Modify the raw transaction by changing the output address, so the signature is no longer valid signed_psbt_obj = PSBT.from_base64(signed_psbt) substitute_addr = wallet.getnewaddress() - raw = wallet.createrawtransaction([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{substitute_addr: 0.9999}]) + raw = wallet.createrawtransaction([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{substitute_addr: Decimal("0.9999")}]) signed_psbt_obj.g.map[PSBT_GLOBAL_UNSIGNED_TX] = bytes.fromhex(raw) # Check that the walletprocesspsbt call succeeds but also recognizes that the transaction is not complete @@ -120,7 +120,7 @@ def test_utxo_conversion(self): # Construct an unsigned PSBT on the online node utxos = wonline.listunspent(addresses=[offline_addr]) - raw = wonline.createrawtransaction([{"txid":utxos[0]["txid"], "vout":utxos[0]["vout"]}],[{online_addr:0.9999}]) + raw = wonline.createrawtransaction([{"txid":utxos[0]["txid"], "vout":utxos[0]["vout"]}],[{online_addr:Decimal("0.9999")}]) psbt = wonline.walletprocesspsbt(online_node.converttopsbt(raw))["psbt"] assert not "not_witness_utxo" in mining_node.decodepsbt(psbt)["inputs"][0] @@ -154,11 +154,11 @@ def test_input_confs_control(self): self.nodes[1].sendmany("", {wallet.getnewaddress():1, wallet.getnewaddress():1}) self.generate(self.nodes[1], 1) - unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), 0.5) + unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), Decimal("0.5")) self.log.info("Crafting PSBT using an unconfirmed input") target_address = self.nodes[1].getnewaddress() - psbtx1 = wallet.walletcreatefundedpsbt([], {target_address: 0.1}, 0, {'fee_rate': 1, 'maxconf': 0})['psbt'] + psbtx1 = wallet.walletcreatefundedpsbt([], {target_address: Decimal("0.1")}, 0, {'fee_rate': 1, 'maxconf': 0})['psbt'] # Make sure we only had the one input tx1_inputs = self.nodes[0].decodepsbt(psbtx1)['tx']['vin'] @@ -355,7 +355,7 @@ def run_test(self): p2pkh_pos = out['n'] inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}] - outputs = [{self.nodes[1].getnewaddress(): 29.99}] + outputs = [{self.nodes[1].getnewaddress(): Decimal("29.99")}] # spend single key from node 1 created_psbt = self.nodes[1].walletcreatefundedpsbt(inputs, outputs) @@ -370,15 +370,15 @@ def run_test(self): self.nodes[1].sendrawtransaction(walletprocesspsbt_out['hex']) self.log.info("Test walletcreatefundedpsbt fee rate of 10000 sat/vB and 0.1 BTC/kvB produces a total fee at or slightly below -maxtxfee (~0.05290000)") - res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 10000, "add_inputs": True}) + res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": Decimal("10000"), "add_inputs": True}) assert_approx(res1["fee"], 0.055, 0.005) - res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": "0.1", "add_inputs": True}) + res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": Decimal("0.1"), "add_inputs": True}) assert_approx(res2["fee"], 0.055, 0.005) self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed") - res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": "0.999", "add_inputs": True}) + res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": Decimal("0.999"), "add_inputs": True}) assert_approx(res3["fee"], 0.00000381, 0.0000001) - res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True}) + res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": Decimal("0.00000999"), "add_inputs": True}) assert_approx(res4["fee"], 0.00000381, 0.0000001) self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed and that funding non-standard 'zero-fee' transactions is valid") @@ -394,21 +394,21 @@ def run_test(self): assert_raises_rpc_error(-3, "Amount is not a number or string", self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: {"foo": "bar"}, "add_inputs": True}) # Test fee rate values that don't pass fixed-point parsing checks. - for invalid_value in ["", 0.000000001, 1e-09, 1.111111111, 1111111111111111, "31.999999999999999999999"]: + for invalid_value in [""] + list(map(Decimal, "0.000000001 1e-09 1.111111111 1111111111111111 31.999999999999999999999".split())): assert_raises_rpc_error(-3, "Invalid amount", self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: invalid_value, "add_inputs": True}) # Test fee_rate values that cannot be represented in sat/vB. - for invalid_value in [0.0001, 0.00000001, 0.00099999, 31.99999999]: + for invalid_value in list(map(Decimal, "0.0001 0.00000001 0.00099999 31.99999999".split())): assert_raises_rpc_error(-3, "Invalid amount", self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": invalid_value, "add_inputs": True}) self.log.info("- raises RPC error if both feeRate and fee_rate are passed") assert_raises_rpc_error(-8, "Cannot specify both fee_rate (sat/vB) and feeRate (BTC/kvB)", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0.1, "feeRate": 0.1, "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": Decimal("0.1"), "feeRate": Decimal("0.1"), "add_inputs": True}) self.log.info("- raises RPC error if both feeRate and estimate_mode passed") assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and feeRate", - self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": "economical", "feeRate": 0.1, "add_inputs": True}) + self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": "economical", "feeRate": Decimal("0.1"), "add_inputs": True}) for param in ["feeRate", "fee_rate"]: self.log.info("- raises RPC error if both {} and conf_target are passed".format(param)) @@ -447,7 +447,7 @@ def run_test(self): self.log.info("Test various PSBT operations") # partially sign multisig things with node 1 - psbtx = wmulti.walletcreatefundedpsbt(inputs=[{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], outputs={self.nodes[1].getnewaddress():29.99}, changeAddress=self.nodes[1].getrawchangeaddress())['psbt'] + psbtx = wmulti.walletcreatefundedpsbt(inputs=[{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], outputs={self.nodes[1].getnewaddress():Decimal("29.99")}, changeAddress=self.nodes[1].getrawchangeaddress())['psbt'] walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx) psbtx = walletprocesspsbt_out['psbt'] assert_equal(walletprocesspsbt_out['complete'], False) @@ -461,7 +461,7 @@ def run_test(self): self.nodes[2].sendrawtransaction(walletprocesspsbt_out['hex']) # check that walletprocesspsbt fails to decode a non-psbt - rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():9.99}) + rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():Decimal("9.99")}) assert_raises_rpc_error(-22, "TX decode failed", self.nodes[1].walletprocesspsbt, rawtx) # Convert a non-psbt to psbt and make sure we can decode it @@ -492,7 +492,7 @@ def run_test(self): self.generate(self.nodes[0], 6)[0] # Create a psbt spending outputs from nodes 1 and 2 - psbt_orig = self.nodes[0].createpsbt([utxo1, utxo2], {self.nodes[0].getnewaddress():25.999}) + psbt_orig = self.nodes[0].createpsbt([utxo1, utxo2], {self.nodes[0].getnewaddress():Decimal("25.999")}) # Update psbts, should only have data for one input and not the other psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig, False, "ALL")['psbt'] @@ -558,7 +558,7 @@ def run_test(self): self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"changeAddress":self.nodes[1].getnewaddress()}, False) # Make sure the wallet's change type is respected by default - small_output = {self.nodes[0].getnewaddress():0.1} + small_output = {self.nodes[0].getnewaddress():Decimal("0.1")} psbtx_native = self.nodes[0].walletcreatefundedpsbt([], [small_output]) self.assert_change_type(psbtx_native, "witness_v0_keyhash") psbtx_legacy = self.nodes[1].walletcreatefundedpsbt([], [small_output]) @@ -680,7 +680,7 @@ def test_psbt_input_keys(psbt_input, keys): assert_equal(set(keys), set(psbt_input.keys())) # Create a PSBT. None of the inputs are filled initially - psbt = self.nodes[1].createpsbt([utxo1, utxo2, utxo3], {self.nodes[0].getnewaddress():32.999}) + psbt = self.nodes[1].createpsbt([utxo1, utxo2, utxo3], {self.nodes[0].getnewaddress():Decimal("32.999")}) decoded = self.nodes[1].decodepsbt(psbt) test_psbt_input_keys(decoded['inputs'][0], []) test_psbt_input_keys(decoded['inputs'][1], []) @@ -928,7 +928,7 @@ def test_psbt_input_keys(psbt_input, keys): self.log.info("Test that walletprocesspsbt both updates and signs a non-updated psbt containing Taproot inputs") addr = self.nodes[0].getnewaddress("", "bech32m") utxo = self.create_outpoints(self.nodes[0], outputs=[{addr: 1}])[0] - psbt = self.nodes[0].createpsbt([utxo], [{self.nodes[0].getnewaddress(): 0.9999}]) + psbt = self.nodes[0].createpsbt([utxo], [{self.nodes[0].getnewaddress(): Decimal("0.9999")}]) signed = self.nodes[0].walletprocesspsbt(psbt) rawtx = signed["hex"] self.nodes[0].sendrawtransaction(rawtx) @@ -1019,7 +1019,7 @@ def test_psbt_input_keys(psbt_input, keys): utxo = self.create_outpoints(self.nodes[0], outputs=[{address: 1}])[0] self.sync_all() - psbt = self.nodes[2].createpsbt([utxo], {self.nodes[0].getnewaddress(): 0.99999}) + psbt = self.nodes[2].createpsbt([utxo], {self.nodes[0].getnewaddress(): Decimal("0.99999")}) decoded = self.nodes[2].decodepsbt(psbt) test_psbt_input_keys(decoded['inputs'][0], []) diff --git a/test/functional/wallet_avoid_mixing_output_types.py b/test/functional/wallet_avoid_mixing_output_types.py index 146b3df3f4df7..a19f0938dd010 100755 --- a/test/functional/wallet_avoid_mixing_output_types.py +++ b/test/functional/wallet_avoid_mixing_output_types.py @@ -26,6 +26,7 @@ but still know when to expect mixing due to the wallet being close to empty. """ +from decimal import Decimal import random from test_framework.test_framework import BitcoinTestFramework @@ -172,7 +173,7 @@ def run_test(self): self.generate(A, 1) assert is_same_type(B, tx) - tx = self.make_payment(A, B, 30.99, random.choice(ADDRESS_TYPES)) + tx = self.make_payment(A, B, Decimal("30.99"), random.choice(ADDRESS_TYPES)) assert not is_same_type(B, tx) diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py index 9da53402a45df..ed6c18a533d39 100755 --- a/test/functional/wallet_balance.py +++ b/test/functional/wallet_balance.py @@ -244,7 +244,7 @@ def test_balances(*, fee_node_1=0): before = self.nodes[1].getbalances()['mine']['untrusted_pending'] dst = self.nodes[1].getnewaddress() self.nodes[1].unloadwallet(self.default_wallet_name) - self.nodes[0].sendtoaddress(dst, 0.1) + self.nodes[0].sendtoaddress(dst, Decimal('0.1')) self.sync_all() self.nodes[1].loadwallet(self.default_wallet_name) after = self.nodes[1].getbalances()['mine']['untrusted_pending'] diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index c968e4333a0ea..3938519f4402b 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -355,7 +355,7 @@ def run_test(self): # 4. check if recipient (node0) can list the zero value tx usp = self.nodes[1].listunspent(query_options={'minimumAmount': '49.998'})[0] inputs = [{"txid": usp['txid'], "vout": usp['vout']}] - outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11} + outputs = {self.nodes[1].getnewaddress(): Decimal("49.998"), self.nodes[0].getnewaddress(): Decimal("11.11")} raw_tx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") # replace 11.11 with 0.0 (int32) signed_raw_tx = self.nodes[1].signrawtransactionwithwallet(raw_tx) diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 061e9f2caa1fc..8c344e839ee34 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -82,7 +82,7 @@ def run_test(self): self.log.info("Mining blocks...") self.generate(peer_node, 110) for _ in range(25): - peer_node.sendtoaddress(rbf_node_address, 0.001) + peer_node.sendtoaddress(rbf_node_address, Decimal("0.001")) self.sync_all() self.generate(peer_node, 1) assert_equal(rbf_node.getbalance(), Decimal("0.025")) @@ -176,7 +176,7 @@ def test_invalid_parameters(self, rbf_node, peer_node, dest_address): assert_raises_rpc_error(-8, "Invalid parameter, output argument cannot be an empty array", rbf_node.bumpfee, rbfid, {"outputs": []}) assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: " + dest_address, - rbf_node.bumpfee, rbfid, {"outputs": [{dest_address: 0.1}, {dest_address: 0.2}]}) + rbf_node.bumpfee, rbfid, {"outputs": [{dest_address: Decimal("0.1")}, {dest_address: Decimal("0.2")}]}) assert_raises_rpc_error(-8, "Invalid parameter, duplicate key: data", rbf_node.bumpfee, rbfid, {"outputs": [{"data": "deadbeef"}, {"data": "deadbeef"}]}) @@ -185,7 +185,7 @@ def test_invalid_parameters(self, rbf_node, peer_node, dest_address): assert_raises_rpc_error(-8, "Change position is out of range", rbf_node.bumpfee, rbfid, {"original_change_index": 2}) self.log.info("Test outputs and original_change_index cannot both be provided") - assert_raises_rpc_error(-8, "The options 'outputs' and 'original_change_index' are incompatible. You can only either specify a new set of outputs, or designate a change output to be recycled.", rbf_node.bumpfee, rbfid, {"original_change_index": 2, "outputs": [{dest_address: 0.1}]}) + assert_raises_rpc_error(-8, "The options 'outputs' and 'original_change_index' are incompatible. You can only either specify a new set of outputs, or designate a change output to be recycled.", rbf_node.bumpfee, rbfid, {"original_change_index": 2, "outputs": [{dest_address: Decimal("0.1")}]}) self.clear_mempool() @@ -315,8 +315,8 @@ def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address): bumped_tx = rbf_node.bumpfee(rbfid, fee_rate=NORMAL) elif mode == "new_outputs": new_address = peer_node.getnewaddress() - bumped_psbt = rbf_node.psbtbumpfee(rbfid, outputs={new_address: 0.0003}) - bumped_tx = rbf_node.bumpfee(rbfid, outputs={new_address: 0.0003}) + bumped_psbt = rbf_node.psbtbumpfee(rbfid, outputs={new_address: Decimal("0.0003")}) + bumped_tx = rbf_node.bumpfee(rbfid, outputs={new_address: Decimal("0.0003")}) else: bumped_psbt = rbf_node.psbtbumpfee(rbfid) bumped_tx = rbf_node.bumpfee(rbfid) @@ -353,7 +353,7 @@ def test_segwit_bumpfee_succeeds(self, rbf_node, dest_address): # which spends it, and make sure bumpfee can be called on it. segwit_out = rbf_node.getnewaddress(address_type='bech32') - segwitid = rbf_node.send({segwit_out: "0.0009"}, options={"change_position": 1})["txid"] + segwitid = rbf_node.send({segwit_out: Decimal("0.0009")}, options={"change_position": 1})["txid"] rbfraw = rbf_node.createrawtransaction([{ 'txid': segwitid, @@ -423,7 +423,7 @@ def test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_ad self.log.info('Test that fee cannot be bumped when it has descendant') # parent is send-to-self, so we don't have to check which output is change when creating the child tx parent_id = spend_one_input(rbf_node, rbf_node_address) - tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: 0.00020000}) + tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: Decimal("0.00020000")}) tx = rbf_node.signrawtransactionwithwallet(tx) rbf_node.sendrawtransaction(tx["hex"]) assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id) @@ -443,7 +443,7 @@ def test_bumpfee_with_abandoned_descendant_succeeds(self, rbf_node, rbf_node_add # parent is send-to-self, so we don't have to check which output is change when creating the child tx parent_id = spend_one_input(rbf_node, rbf_node_address) # Submit child transaction with low fee - child_id = rbf_node.send(outputs={dest_address: 0.00020000}, + child_id = rbf_node.send(outputs={dest_address: Decimal("0.00020000")}, options={"inputs": [{"txid": parent_id, "vout": 0}], "fee_rate": 2})["txid"] assert child_id in rbf_node.getrawmempool() @@ -631,12 +631,12 @@ def test_watchonly_psbt(self, peer_node, rbf_node, dest_address): funding_address1 = watcher.getnewaddress(address_type='bech32') funding_address2 = watcher.getnewaddress(address_type='bech32') - peer_node.sendmany("", {funding_address1: 0.001, funding_address2: 0.001}) + peer_node.sendmany("", {funding_address1: Decimal("0.001"), funding_address2: Decimal("0.001")}) self.generate(peer_node, 1) # Create single-input PSBT for transaction to be bumped # Ensure the payment amount + change can be fully funded using one of the 0.001BTC inputs. - psbt = watcher.walletcreatefundedpsbt([watcher.listunspent()[0]], {dest_address: 0.0005}, 0, + psbt = watcher.walletcreatefundedpsbt([watcher.listunspent()[0]], {dest_address: Decimal("0.0005")}, 0, {"fee_rate": 1, "add_inputs": False}, True)['psbt'] psbt_signed = signer.walletprocesspsbt(psbt=psbt, sign=True, sighashtype="ALL", bip32derivs=True) original_txid = watcher.sendrawtransaction(psbt_signed["hex"]) @@ -846,7 +846,7 @@ def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, # Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is # less than (original fee + incrementalrelayfee) - assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.8}) + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": Decimal("2.8")}) # You can fee bump as long as the new fee set from fee_rate is at least (original fee + incrementalrelayfee) rbf_node.bumpfee(tx["txid"], {"fee_rate": 3}) diff --git a/test/functional/wallet_change_address.py b/test/functional/wallet_change_address.py index 07bab82697ecb..9c4e3d827a221 100755 --- a/test/functional/wallet_change_address.py +++ b/test/functional/wallet_change_address.py @@ -4,6 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test wallet change address selection""" +from decimal import Decimal import re from test_framework.blocktools import COINBASE_MATURITY @@ -66,7 +67,7 @@ def run_test(self): for i in range(20): for n in [1, 2]: self.log.debug(f"Send transaction from node {n}: expected change index {i}") - txid = self.nodes[n].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + txid = self.nodes[n].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("0.2")) tx = self.nodes[n].getrawtransaction(txid, True) # find the change output and ensure that expected change index was used self.assert_change_index(self.nodes[n], tx, i) @@ -78,10 +79,10 @@ def run_test(self): w2 = self.nodes[2].get_wallet_rpc("w2") addr1 = w1.getnewaddress() addr2 = w2.getnewaddress() - self.nodes[0].sendtoaddress(addr1, 3.0) - self.nodes[0].sendtoaddress(addr1, 0.1) - self.nodes[0].sendtoaddress(addr2, 3.0) - self.nodes[0].sendtoaddress(addr2, 0.1) + self.nodes[0].sendtoaddress(addr1, Decimal("3.0")) + self.nodes[0].sendtoaddress(addr1, Decimal("0.1")) + self.nodes[0].sendtoaddress(addr2, Decimal("3.0")) + self.nodes[0].sendtoaddress(addr2, Decimal("0.1")) self.generate(self.nodes[0], 1) sendTo1 = self.nodes[0].getnewaddress() diff --git a/test/functional/wallet_conflicts.py b/test/functional/wallet_conflicts.py index 7a950ffae6f10..0e0e73390c439 100755 --- a/test/functional/wallet_conflicts.py +++ b/test/functional/wallet_conflicts.py @@ -80,7 +80,7 @@ def test_block_conflicts(self): self.generate(self.nodes[0], 1, sync_fun=self.no_op) # Now that 'AB_parent_tx' was broadcast, build 'Child_Tx' - output_c = self.get_utxo_of_value(from_tx_id=txid_AB_parent, search_value=19.99998) + output_c = self.get_utxo_of_value(from_tx_id=txid_AB_parent, search_value=Decimal("19.99998")) inputs_tx_C_child = [({"txid": txid_AB_parent, "vout": output_c})] tx_C_child = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs_tx_C_child, {self.nodes[0].getnewaddress() : Decimal("19.99996")})) @@ -152,15 +152,15 @@ def test_mempool_conflict(self): assert all([tx["amount"] == 25 for tx in unspents]) # tx1 spends unspent[0] and unspent[1] - raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[1]], outputs=[{bob.getnewaddress() : 49.9999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[1]], outputs=[{bob.getnewaddress() : Decimal("49.9999")}]) tx1 = alice.signrawtransactionwithwallet(raw_tx)['hex'] # tx2 spends unspent[1] and unspent[2], conflicts with tx1 - raw_tx = alice.createrawtransaction(inputs=[unspents[1], unspents[2]], outputs=[{bob.getnewaddress() : 49.99}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[1], unspents[2]], outputs=[{bob.getnewaddress() : Decimal("49.99")}]) tx2 = alice.signrawtransactionwithwallet(raw_tx)['hex'] # tx3 spends unspent[2], conflicts with tx2 - raw_tx = alice.createrawtransaction(inputs=[unspents[2]], outputs=[{bob.getnewaddress() : 24.9899}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[2]], outputs=[{bob.getnewaddress() : Decimal("24.9899")}]) tx3 = alice.signrawtransactionwithwallet(raw_tx)['hex'] # broadcast tx1 @@ -222,21 +222,21 @@ def test_mempool_and_block_conflicts(self): self.disconnect_nodes(0, 1) # Sends funds to bob - raw_tx = alice.createrawtransaction(inputs=[unspents[0]], outputs=[{bob.getnewaddress() : 24.99999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[0]], outputs=[{bob.getnewaddress() : Decimal("24.99999")}]) raw_tx1 = alice.signrawtransactionwithwallet(raw_tx)['hex'] tx1_txid = bob.sendrawtransaction(raw_tx1) # broadcast original tx spending unspents[0] only to bob # create a conflict to previous tx (also spends unspents[0]), but don't broadcast, sends funds back to alice - raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[2]], outputs=[{alice.getnewaddress() : 49.999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[2]], outputs=[{alice.getnewaddress() : Decimal("49.999")}]) tx1_conflict = alice.signrawtransactionwithwallet(raw_tx)['hex'] # Sends funds to bob - raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{bob.getnewaddress() : 24.9999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{bob.getnewaddress() : Decimal("24.9999")}]) raw_tx2 = alice.signrawtransactionwithwallet(raw_tx)['hex'] tx2_txid = bob.sendrawtransaction(raw_tx2) # broadcast another original tx spending unspents[1] only to bob # create a conflict to previous tx (also spends unspents[1]), but don't broadcast, sends funds to alice - raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{alice.getnewaddress() : 24.9999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{alice.getnewaddress() : Decimal("24.9999")}]) tx2_conflict = alice.signrawtransactionwithwallet(raw_tx)['hex'] bob_unspents = [{"txid" : element, "vout" : 0} for element in [tx1_txid, tx2_txid]] @@ -245,7 +245,7 @@ def test_mempool_and_block_conflicts(self): assert_equal(bob.getbalances()["mine"]["untrusted_pending"], Decimal("49.99989000")) # spend both of bob's unspents, child tx of tx1 and tx2 - raw_tx = bob.createrawtransaction(inputs=[bob_unspents[0], bob_unspents[1]], outputs=[{bob.getnewaddress() : 49.999}]) + raw_tx = bob.createrawtransaction(inputs=[bob_unspents[0], bob_unspents[1]], outputs=[{bob.getnewaddress() : Decimal("49.999")}]) raw_tx3 = bob.signrawtransactionwithwallet(raw_tx)['hex'] tx3_txid = bob.sendrawtransaction(raw_tx3) # broadcast tx only to bob @@ -301,7 +301,7 @@ def test_mempool_and_block_conflicts(self): assert_equal(bob.getbalances()["mine"]["untrusted_pending"], Decimal("24.99990000")) # create a conflict to previous tx (also spends unspents[2]), but don't broadcast, sends funds back to alice - raw_tx = alice.createrawtransaction(inputs=[unspents[2]], outputs=[{alice.getnewaddress() : 24.99}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[2]], outputs=[{alice.getnewaddress() : Decimal("24.99")}]) tx1_conflict_conflict = alice.signrawtransactionwithwallet(raw_tx)['hex'] bob.sendrawtransaction(tx1_conflict_conflict) # kick tx1_conflict out of the mempool @@ -344,7 +344,7 @@ def test_descendants_with_mempool_conflicts(self): assert_equal(alice.getrawmempool(), []) # Alice spends first utxo to bob in tx1 - raw_tx = alice.createrawtransaction(inputs=[unspents[0]], outputs=[{bob.getnewaddress() : 24.9999}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[0]], outputs=[{bob.getnewaddress() : Decimal("24.9999")}]) tx1 = alice.signrawtransactionwithwallet(raw_tx)['hex'] tx1_txid = alice.sendrawtransaction(tx1) @@ -355,7 +355,7 @@ def test_descendants_with_mempool_conflicts(self): assert_equal(bob.gettransaction(tx1_txid)["mempoolconflicts"], []) - raw_tx = bob.createrawtransaction(inputs=[bob.listunspent(minconf=0)[0]], outputs=[{carol.getnewaddress() : 24.999}]) + raw_tx = bob.createrawtransaction(inputs=[bob.listunspent(minconf=0)[0]], outputs=[{carol.getnewaddress() : Decimal("24.999")}]) # Bob creates a child to tx1 tx1_child = bob.signrawtransactionwithwallet(raw_tx)['hex'] tx1_child_txid = bob.sendrawtransaction(tx1_child) @@ -373,7 +373,7 @@ def test_descendants_with_mempool_conflicts(self): assert_equal(carol.getbalances()["mine"]["untrusted_pending"], Decimal("24.99900000")) # Alice spends first unspent again, conflicting with tx1 - raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[1]], outputs=[{carol.getnewaddress() : 49.99}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[0], unspents[1]], outputs=[{carol.getnewaddress() : Decimal("49.99")}]) tx1_conflict = alice.signrawtransactionwithwallet(raw_tx)['hex'] tx1_conflict_txid = alice.sendrawtransaction(tx1_conflict) @@ -392,7 +392,7 @@ def test_descendants_with_mempool_conflicts(self): assert_equal(bob.gettransaction(tx1_child_txid)["mempoolconflicts"], [tx1_conflict_txid]) # Now create a conflict to tx1_conflict, so that it gets kicked out of the mempool - raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{carol.getnewaddress() : 24.9895}]) + raw_tx = alice.createrawtransaction(inputs=[unspents[1]], outputs=[{carol.getnewaddress() : Decimal("24.9895")}]) tx1_conflict_conflict = alice.signrawtransactionwithwallet(raw_tx)['hex'] tx1_conflict_conflict_txid = alice.sendrawtransaction(tx1_conflict_conflict) diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py index 6deb262c9aab8..f0b5d9498e64e 100755 --- a/test/functional/wallet_create_tx.py +++ b/test/functional/wallet_create_tx.py @@ -3,6 +3,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +from decimal import Decimal + from test_framework.messages import ( tx_from_hex, ) @@ -53,7 +55,7 @@ def test_anti_fee_sniping(self): def test_tx_size_too_large(self): # More than 10kB of outputs, so that we hit -maxtxfee with a high feerate - outputs = {self.nodes[0].getnewaddress(address_type='bech32'): 0.000025 for _ in range(400)} + outputs = {self.nodes[0].getnewaddress(address_type='bech32'): Decimal("0.000025") for _ in range(400)} raw_tx = self.nodes[0].createrawtransaction(inputs=[], outputs=outputs) for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01', '-paytxfee=0.01']: @@ -106,7 +108,7 @@ def test_create_too_long_mempool_chain(self): # Sending one more chained transaction will fail options = {"minconf": 0, "include_unsafe": True, 'add_inputs': True} assert_raises_rpc_error(-4, "Unconfirmed UTXOs are available, but spending them creates a chain of transactions that will be rejected by the mempool", - test_wallet.send, outputs=[{test_wallet.getnewaddress(): 0.3}], options=options) + test_wallet.send, outputs=[{test_wallet.getnewaddress(): Decimal("0.3")}], options=options) test_wallet.unloadwallet() diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py index 827f27b431c7d..1e0e6bd9b418d 100755 --- a/test/functional/wallet_fundrawtransaction.py +++ b/test/functional/wallet_fundrawtransaction.py @@ -199,9 +199,9 @@ def test_change_position(self): self.nodes[0].sendtoaddress(self.nodes[3].get_wallet_rpc(self.default_wallet_name).getnewaddress(), self.watchonly_amount / 10) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("1.5")) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("1.0")) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("5.0")) self.generate(self.nodes[0], 1) @@ -210,7 +210,7 @@ def test_change_position(self): def test_simple(self): self.log.info("Test fundrawtxn") inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 1.0 } + outputs = { self.nodes[0].getnewaddress() : Decimal("1.0") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) @@ -219,7 +219,7 @@ def test_simple(self): def test_simple_two_coins(self): self.log.info("Test fundrawtxn with 2 coins") inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 2.2 } + outputs = { self.nodes[0].getnewaddress() : Decimal("2.2") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) @@ -230,7 +230,7 @@ def test_simple_two_outputs(self): self.log.info("Test fundrawtxn with 2 outputs") inputs = [ ] - outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 } + outputs = { self.nodes[0].getnewaddress() : Decimal("2.6"), self.nodes[1].getnewaddress() : Decimal("2.5") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtxfund = self.nodes[2].fundrawtransaction(rawtx) @@ -244,7 +244,7 @@ def test_change(self): utx = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] - outputs = { self.nodes[0].getnewaddress() : 1.0 } + outputs = { self.nodes[0].getnewaddress() : Decimal("1.0") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) @@ -341,7 +341,7 @@ def test_coin_selection(self): utx = get_unspent(self.nodes[2].listunspent(), 1) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] - outputs = { self.nodes[0].getnewaddress() : 1.0 } + outputs = { self.nodes[0].getnewaddress() : Decimal("1.0") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) # 4-byte version + 1-byte vin count + 36-byte prevout then script_len @@ -376,7 +376,7 @@ def test_two_vin(self): utx2 = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] - outputs = { self.nodes[0].getnewaddress() : 6.0 } + outputs = { self.nodes[0].getnewaddress() : Decimal("6.0") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) @@ -407,7 +407,7 @@ def test_two_vin_two_vout(self): utx2 = get_unspent(self.nodes[2].listunspent(), 5) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] - outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 } + outputs = { self.nodes[0].getnewaddress() : Decimal("6.0"), self.nodes[0].getnewaddress() : Decimal("1.0") } rawtx = self.nodes[2].createrawtransaction(inputs, outputs) dec_tx = self.nodes[2].decoderawtransaction(rawtx) assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) @@ -430,7 +430,7 @@ def test_invalid_input(self): txid = "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1" vout = 0 inputs = [ {'txid' : txid, 'vout' : vout} ] #invalid vin! - outputs = { self.nodes[0].getnewaddress() : 1.0} + outputs = { self.nodes[0].getnewaddress() : Decimal("1.0")} rawtx = self.nodes[2].createrawtransaction(inputs, outputs) assert_raises_rpc_error(-4, "Unable to find UTXO for external input", self.nodes[2].fundrawtransaction, rawtx) @@ -439,12 +439,12 @@ def test_fee_p2pkh(self): self.log.info("Test fundrawtxn p2pkh fee") self.lock_outputs_type(self.nodes[0], "p2pkh") inputs = [] - outputs = {self.nodes[1].getnewaddress():1.1} + outputs = {self.nodes[1].getnewaddress():Decimal("1.1")} rawtx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawtx) # Create same transaction over sendtoaddress. - txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1) + txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), Decimal("1.1")) signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base'] # Compare fee. @@ -459,12 +459,12 @@ def test_fee_p2pkh_multi_out(self): self.lock_outputs_type(self.nodes[0], "p2pkh") inputs = [] outputs = { - self.nodes[1].getnewaddress():1.1, - self.nodes[1].getnewaddress():1.2, - self.nodes[1].getnewaddress():0.1, - self.nodes[1].getnewaddress():1.3, - self.nodes[1].getnewaddress():0.2, - self.nodes[1].getnewaddress():0.3, + self.nodes[1].getnewaddress():Decimal("1.1"), + self.nodes[1].getnewaddress():Decimal("1.2"), + self.nodes[1].getnewaddress():Decimal("0.1"), + self.nodes[1].getnewaddress():Decimal("1.3"), + self.nodes[1].getnewaddress():Decimal("0.2"), + self.nodes[1].getnewaddress():Decimal("0.3"), } rawtx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawtx) @@ -492,12 +492,12 @@ def test_fee_p2sh(self): mSigObj = self.nodes[3].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] inputs = [] - outputs = {mSigObj:1.1} + outputs = {mSigObj:Decimal("1.1")} rawtx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawtx) # Create same transaction over sendtoaddress. - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) + txId = self.nodes[0].sendtoaddress(mSigObj, Decimal("1.1")) signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base'] # Compare fee. @@ -536,12 +536,12 @@ def test_fee_4of5(self): )['address'] inputs = [] - outputs = {mSigObj:1.1} + outputs = {mSigObj:Decimal("1.1")} rawtx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawtx) # Create same transaction over sendtoaddress. - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) + txId = self.nodes[0].sendtoaddress(mSigObj, Decimal("1.1")) signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base'] # Compare fee. @@ -575,12 +575,12 @@ def test_spend_2of2(self): wmulti.importaddress(mSigObj) # Send 1.2 BTC to msig addr. - self.nodes[0].sendtoaddress(mSigObj, 1.2) + self.nodes[0].sendtoaddress(mSigObj, Decimal("1.2")) self.generate(self.nodes[0], 1) oldBalance = self.nodes[1].getbalance() inputs = [] - outputs = {self.nodes[1].getnewaddress():1.1} + outputs = {self.nodes[1].getnewaddress():Decimal("1.1")} funded_psbt = wmulti.walletcreatefundedpsbt(inputs=inputs, outputs=outputs, changeAddress=w2.getrawchangeaddress())['psbt'] signed_psbt = w2.walletprocesspsbt(funded_psbt) @@ -649,12 +649,12 @@ def test_locked_wallet(self): with WalletUnlock(wallet, "test"): wallet.keypoolrefill(8) #need to refill the keypool to get an internal change address - assert_raises_rpc_error(-13, "walletpassphrase", wallet.sendtoaddress, self.nodes[0].getnewaddress(), 1.2) + assert_raises_rpc_error(-13, "walletpassphrase", wallet.sendtoaddress, self.nodes[0].getnewaddress(), Decimal("1.2")) oldBalance = self.nodes[0].getbalance() inputs = [] - outputs = {self.nodes[0].getnewaddress():1.1} + outputs = {self.nodes[0].getnewaddress():Decimal("1.1")} rawtx = wallet.createrawtransaction(inputs, outputs) fundedTx = wallet.fundrawtransaction(rawtx) assert fundedTx["changepos"] != -1 @@ -682,12 +682,12 @@ def test_many_inputs_fee(self): self.generate(self.nodes[1], 1) for _ in range(20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), Decimal("0.01")) self.generate(self.nodes[0], 1) # Fund a tx with ~20 small inputs. inputs = [] - outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + outputs = {self.nodes[0].getnewaddress():Decimal("0.15"),self.nodes[0].getnewaddress():Decimal("0.04")} rawtx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawtx) @@ -708,14 +708,14 @@ def test_many_inputs_send(self): self.generate(self.nodes[1], 1) for _ in range(20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), Decimal("0.01")) self.generate(self.nodes[0], 1) # Fund a tx with ~20 small inputs. oldBalance = self.nodes[0].getbalance() inputs = [] - outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + outputs = {self.nodes[0].getnewaddress():Decimal("0.15"),self.nodes[0].getnewaddress():Decimal("0.04")} rawtx = self.nodes[1].createrawtransaction(inputs, outputs) fundedTx = self.nodes[1].fundrawtransaction(rawtx) fundedAndSignedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex']) @@ -860,20 +860,20 @@ def test_option_feerate(self): assert_raises_rpc_error(-3, "Amount is not a number or string", node.fundrawtransaction, rawtx, add_inputs=True, **{param: {"foo": "bar"}}) # Test fee rate values that don't pass fixed-point parsing checks. - for invalid_value in ["", 0.000000001, 1e-09, 1.111111111, 1111111111111111, "31.999999999999999999999"]: + for invalid_value in [""] + list(map(Decimal, "0.000000001 1e-09 1.111111111 1111111111111111 31.999999999999999999999".split())): assert_raises_rpc_error(-3, "Invalid amount", node.fundrawtransaction, rawtx, add_inputs=True, **{param: invalid_value}) # Test fee_rate values that cannot be represented in sat/vB. - for invalid_value in [0.0001, 0.00000001, 0.00099999, 31.99999999]: + for invalid_value in list(map(Decimal, "0.0001 0.00000001 0.00099999 31.99999999".split())): assert_raises_rpc_error(-3, "Invalid amount", node.fundrawtransaction, rawtx, fee_rate=invalid_value, add_inputs=True) self.log.info("Test min fee rate checks are bypassed with fundrawtxn, e.g. a fee_rate under 1 sat/vB is allowed") - node.fundrawtransaction(rawtx, fee_rate=0.999, add_inputs=True) - node.fundrawtransaction(rawtx, feeRate=0.00000999, add_inputs=True) + node.fundrawtransaction(rawtx, fee_rate=Decimal("0.999"), add_inputs=True) + node.fundrawtransaction(rawtx, feeRate=Decimal("0.00000999"), add_inputs=True) self.log.info("- raises RPC error if both feeRate and fee_rate are passed") assert_raises_rpc_error(-8, "Cannot specify both fee_rate (sat/vB) and feeRate (BTC/kvB)", - node.fundrawtransaction, rawtx, fee_rate=0.1, feeRate=0.1, add_inputs=True) + node.fundrawtransaction, rawtx, fee_rate=Decimal("0.1"), feeRate=Decimal("0.1"), add_inputs=True) self.log.info("- raises RPC error if both feeRate and estimate_mode passed") assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and feeRate", @@ -955,7 +955,7 @@ def test_option_subtract_fee_from_outputs(self): assert_equal(change[3] + result[3]['fee'], change[4]) inputs = [] - outputs = {self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)} + outputs = {self.nodes[2].getnewaddress(): value for value in list(map(Decimal, "1.0 1.1 1.2 1.3".split()))} rawtx = self.nodes[3].createrawtransaction(inputs, outputs) result = [self.nodes[3].fundrawtransaction(rawtx), @@ -1011,7 +1011,7 @@ def test_transaction_too_large(self): wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name) recipient = self.nodes[0].get_wallet_rpc("large") outputs = {} - rawtx = recipient.createrawtransaction([], {wallet.getnewaddress(): 147.99899260}) + rawtx = recipient.createrawtransaction([], {wallet.getnewaddress(): Decimal("147.99899260")}) # Make 1500 0.1 BTC outputs. The amount that we target for funding is in # the BnB range when these outputs are used. However if these outputs @@ -1021,7 +1021,7 @@ def test_transaction_too_large(self): # First, force the wallet to bulk-generate the addresses we'll need. recipient.keypoolrefill(1500) for _ in range(1500): - outputs[recipient.getnewaddress()] = 0.1 + outputs[recipient.getnewaddress()] = Decimal("0.1") wallet.sendmany("", outputs) self.generate(self.nodes[0], 10) assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight. " @@ -1321,12 +1321,12 @@ def test_weight_limits(self): outputs = [] for _ in range(1472): - outputs.append({wallet.getnewaddress(address_type="legacy"): 0.1}) + outputs.append({wallet.getnewaddress(address_type="legacy"): Decimal("0.1")}) txid = self.nodes[0].send(outputs=outputs, change_position=0)["txid"] self.generate(self.nodes[0], 1) # 272 WU per input (273 when high-s); picking 1471 inputs will exceed the max standard tx weight. - rawtx = wallet.createrawtransaction([], [{wallet.getnewaddress(): 0.1 * 1471}]) + rawtx = wallet.createrawtransaction([], [{wallet.getnewaddress(): Decimal("0.1") * 1471}]) # 1) Try to fund transaction only using the preset inputs (pick all 1472 inputs to cover the fee) input_weights = [] @@ -1360,7 +1360,7 @@ def test_include_unsafe(self): self.sync_mempools() # Unsafe inputs are ignored by default. - rawtx = wallet.createrawtransaction([], [{self.nodes[2].getnewaddress(): 7.5}]) + rawtx = wallet.createrawtransaction([], [{self.nodes[2].getnewaddress(): Decimal("7.5")}]) assert_raises_rpc_error(-4, "Insufficient funds", wallet.fundrawtransaction, rawtx) # But we can opt-in to use them for funding. @@ -1405,8 +1405,8 @@ def test_22670(self): self.generate(self.nodes[0], 1, sync_fun=self.no_op) # Create transactions in order to calculate fees for the target bounds that can trigger this bug - change_tx = tester.fundrawtransaction(tester.createrawtransaction([], [{funds.getnewaddress(): 1.5}])) - tx = tester.createrawtransaction([], [{funds.getnewaddress(): 2}]) + change_tx = tester.fundrawtransaction(tester.createrawtransaction([], [{funds.getnewaddress(): Decimal("1.5")}])) + tx = tester.createrawtransaction([], [{funds.getnewaddress(): Decimal("2")}]) no_change_tx = tester.fundrawtransaction(tx, subtractFeeFromOutputs=[0]) overhead_fees = feerate * len(tx) / 2 / 1000 @@ -1458,8 +1458,8 @@ def test_feerate_rounding(self): # In the former case, the calculated needed fee is higher than the actual fee being paid, so an assertion is reached # To test this does not happen, we subtract 202 sats from the input value. If working correctly, this should # fail with insufficient funds rather than bitcoind asserting. - rawtx = w.createrawtransaction(inputs=[], outputs=[{self.nodes[0].getnewaddress(address_type="bech32"): 1 - 0.00000202}]) - assert_raises_rpc_error(-4, "Insufficient funds", w.fundrawtransaction, rawtx, fee_rate=1.85) + rawtx = w.createrawtransaction(inputs=[], outputs=[{self.nodes[0].getnewaddress(address_type="bech32"): Decimal("1") - Decimal("0.00000202")}]) + assert_raises_rpc_error(-4, "Insufficient funds", w.fundrawtransaction, rawtx, fee_rate=Decimal("1.85")) def test_input_confs_control(self): self.nodes[0].createwallet("minconf") @@ -1470,12 +1470,12 @@ def test_input_confs_control(self): self.nodes[2].sendmany("", {wallet.getnewaddress():1, wallet.getnewaddress():1}) self.generate(self.nodes[2], 1) - unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), 0.5) + unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), Decimal("0.5")) self.log.info("Crafting TX using an unconfirmed input") target_address = self.nodes[2].getnewaddress() - raw_tx1 = wallet.createrawtransaction([], {target_address: 0.1}, 0, True) - funded_tx1 = wallet.fundrawtransaction(raw_tx1, {'fee_rate': 1, 'maxconf': 0})['hex'] + raw_tx1 = wallet.createrawtransaction([], {target_address: Decimal("0.1")}, 0, True) + funded_tx1 = wallet.fundrawtransaction(raw_tx1, {'fee_rate': Decimal("1"), 'maxconf': 0})['hex'] # Make sure we only had the one input tx1_inputs = self.nodes[0].decoderawtransaction(funded_tx1)['vin'] diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py index 8d6c96c0e004c..ad9dc41d11197 100755 --- a/test/functional/wallet_groups.py +++ b/test/functional/wallet_groups.py @@ -4,6 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test wallet group functionality.""" +from decimal import Decimal + from test_framework.blocktools import COINBASE_MATURITY from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import ( @@ -33,7 +35,7 @@ def set_test_params(self): ] for args in self.extra_args: - args.append(f"-paytxfee={20 * 1e3 / 1e8}") # apply feerate of 20 sats/vB across all nodes + args.append(f"-paytxfee={20 * Decimal("1e3") / Decimal("1e8")}") # apply feerate of 20 sats/vB across all nodes self.rpc_timeout = 480 @@ -61,7 +63,7 @@ def run_test(self): # - node[2] should pick one (1.0 + 0.5) UTXO group corresponding to a # given address, and leave the rest self.log.info("Test sending transactions picks one UTXO group and leaves the rest") - txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("0.2")) tx1 = self.nodes[1].getrawtransaction(txid1, True) # txid1 should have 1 input and 2 outputs assert_equal(1, len(tx1["vin"])) @@ -72,7 +74,7 @@ def run_test(self): assert_approx(v[0], vexp=0.2, vspan=0.0001) assert_approx(v[1], vexp=0.3, vspan=0.0001) - txid2 = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + txid2 = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("0.2")) tx2 = self.nodes[2].getrawtransaction(txid2, True) # txid2 should have 2 inputs and 2 outputs assert_equal(2, len(tx2["vin"])) @@ -100,7 +102,7 @@ def run_test(self): # this could be (A / B0 / C0) + (B1 / C1 / D). We ensure that it is # B0 + B1 or C0 + C1, because this avoids partial spends while not being # detrimental to transaction cost - txid3 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.4) + txid3 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("1.4")) tx3 = self.nodes[1].getrawtransaction(txid3, True) # tx3 should have 2 inputs and 2 outputs assert_equal(2, len(tx3["vin"])) @@ -128,7 +130,7 @@ def run_test(self): self.nodes[0].sendtoaddress(addr_aps, 1.0) self.generate(self.nodes[0], 1) with self.nodes[3].assert_debug_log([f'Fee non-grouped = {tx4_ungrouped_fee}, grouped = {tx4_grouped_fee}, using grouped']): - txid4 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 0.1) + txid4 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("0.1")) tx4 = self.nodes[3].getrawtransaction(txid4, True) # tx4 should have 2 inputs and 2 outputs although one output would # have been enough and the transaction caused higher fees @@ -139,7 +141,7 @@ def run_test(self): [self.nodes[0].sendtoaddress(addr_aps2, 1.0) for _ in range(5)] self.generate(self.nodes[0], 1) with self.nodes[3].assert_debug_log([f'Fee non-grouped = {tx5_6_ungrouped_fee}, grouped = {tx5_6_grouped_fee}, using non-grouped']): - txid5 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 2.95) + txid5 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("2.95")) tx5 = self.nodes[3].getrawtransaction(txid5, True) # tx5 should have 3 inputs (1.0, 1.0, 1.0) and 2 outputs assert_equal(3, len(tx5["vin"])) @@ -152,7 +154,7 @@ def run_test(self): [self.nodes[0].sendtoaddress(addr_aps3, 1.0) for _ in range(5)] self.generate(self.nodes[0], 1) with self.nodes[4].assert_debug_log([f'Fee non-grouped = {tx5_6_ungrouped_fee}, grouped = {tx5_6_grouped_fee}, using grouped']): - txid6 = self.nodes[4].sendtoaddress(self.nodes[0].getnewaddress(), 2.95) + txid6 = self.nodes[4].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("2.95")) tx6 = self.nodes[4].getrawtransaction(txid6, True) # tx6 should have 5 inputs and 2 outputs assert_equal(5, len(tx6["vin"])) @@ -165,7 +167,7 @@ def run_test(self): self.log.info("Fill a wallet with 10,000 outputs corresponding to the same scriptPubKey") for _ in range(5): - raw_tx = self.nodes[0].createrawtransaction([{"txid":"0"*64, "vout":0}], [{addr2[0]: 0.05}]) + raw_tx = self.nodes[0].createrawtransaction([{"txid":"0"*64, "vout":0}], [{addr2[0]: Decimal("0.05")}]) tx = tx_from_hex(raw_tx) tx.vin = [] tx.vout = [tx.vout[0]] * 2000 diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py index 84c07b6a282aa..bf0b9ad376677 100755 --- a/test/functional/wallet_importdescriptors.py +++ b/test/functional/wallet_importdescriptors.py @@ -15,6 +15,7 @@ - `test_address()` is called to call getaddressinfo for an address on node1 and test the values returned.""" +from decimal import Decimal import concurrent.futures import time @@ -410,9 +411,9 @@ def run_test(self): address, solvable=True, ismine=True) - txid = w0.sendtoaddress(address, 49.99995540) + txid = w0.sendtoaddress(address, Decimal("49.99995540")) self.generatetoaddress(self.nodes[0], 6, w0.getnewaddress()) - tx = wpriv.createrawtransaction([{"txid": txid, "vout": 0}], {w0.getnewaddress(): 49.999}) + tx = wpriv.createrawtransaction([{"txid": txid, "vout": 0}], {w0.getnewaddress(): Decimal("49.999")}) signed_tx = wpriv.signrawtransactionwithwallet(tx) w1.sendrawtransaction(signed_tx['hex']) @@ -551,7 +552,7 @@ def run_test(self): assert_equal(res[1]['success'], True) assert_equal(res[1]['warnings'][0], 'Not all private keys provided. Some wallet functionality may return unexpected errors') - rawtx = self.nodes[1].createrawtransaction([utxo], {w0.getnewaddress(): 9.999}) + rawtx = self.nodes[1].createrawtransaction([utxo], {w0.getnewaddress(): Decimal("9.999")}) tx_signed_1 = wmulti_priv1.signrawtransactionwithwallet(rawtx) assert_equal(tx_signed_1['complete'], False) tx_signed_2 = wmulti_priv2.signrawtransactionwithwallet(tx_signed_1['hex']) @@ -586,7 +587,7 @@ def run_test(self): w0.sendtoaddress(addr, 10) self.generate(self.nodes[0], 1) # It is standard and would relay. - txid = wmulti_priv_big.sendtoaddress(w0.getnewaddress(), 9.999) + txid = wmulti_priv_big.sendtoaddress(w0.getnewaddress(), Decimal("9.999")) decoded = wmulti_priv_big.gettransaction(txid=txid, verbose=True)['decoded'] # 20 sigs + dummy + witness script assert_equal(len(decoded['vin'][0]['txinwitness']), 22) @@ -645,7 +646,7 @@ def run_test(self): }]) assert_equal(res[0]['success'], True) - rawtx = self.nodes[1].createrawtransaction([utxo2], {w0.getnewaddress(): 9.999}) + rawtx = self.nodes[1].createrawtransaction([utxo2], {w0.getnewaddress(): Decimal("9.999")}) tx = wmulti_priv3.signrawtransactionwithwallet(rawtx) assert_equal(tx['complete'], True) self.nodes[1].sendrawtransaction(tx['hex']) diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py index 467fddeb59087..406bb687bc69a 100755 --- a/test/functional/wallet_importprunedfunds.py +++ b/test/functional/wallet_importprunedfunds.py @@ -66,17 +66,17 @@ def run_test(self): assert_equal(address_info['ismine'], False) # Send funds to self - txnid1 = self.nodes[0].sendtoaddress(address1, 0.1) + txnid1 = self.nodes[0].sendtoaddress(address1, Decimal("0.1")) self.generate(self.nodes[0], 1) rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex'] proof1 = self.nodes[0].gettxoutproof([txnid1]) - txnid2 = self.nodes[0].sendtoaddress(address2, 0.05) + txnid2 = self.nodes[0].sendtoaddress(address2, Decimal("0.05")) self.generate(self.nodes[0], 1) rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex'] proof2 = self.nodes[0].gettxoutproof([txnid2]) - txnid3 = self.nodes[0].sendtoaddress(address3, 0.025) + txnid3 = self.nodes[0].sendtoaddress(address3, Decimal("0.025")) self.generate(self.nodes[0], 1) rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex'] proof3 = self.nodes[0].gettxoutproof([txnid3]) diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py index d3b6ca1ed1112..d6c63ca75e23e 100755 --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -192,30 +192,30 @@ def run_test(self): # Using a fee rate (10 sat / byte) well above the minimum relay rate # creating a 5,000 sat transaction with change should not be possible - assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], subtractFeeFromOutputs=[0], feeRate=0.00010) + assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): Decimal("0.00005000")}], subtractFeeFromOutputs=[0], feeRate=Decimal("0.00010")) # creating a 10,000 sat transaction without change, with a manual input, should still be possible - res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: 0.00010000}], subtractFeeFromOutputs=[0], feeRate=0.00010) + res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: Decimal("0.00010000")}], subtractFeeFromOutputs=[0], feeRate=Decimal("0.00010")) assert_equal("psbt" in res, True) # creating a 10,000 sat transaction without change should still be possible - res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], subtractFeeFromOutputs=[0], feeRate=0.00010) + res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: Decimal("0.00010000")}], subtractFeeFromOutputs=[0], feeRate=Decimal("0.00010")) assert_equal("psbt" in res, True) # should work without subtractFeeFromOutputs if the exact fee is subtracted from the amount - res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00008900}], feeRate=0.00010) + res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: Decimal("0.00008900")}], feeRate=Decimal("0.00010")) assert_equal("psbt" in res, True) # dust change should be removed - res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00008800}], feeRate=0.00010) + res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: Decimal("0.00008800")}], feeRate=Decimal("0.00010")) assert_equal("psbt" in res, True) # create a transaction without change at the maximum fee rate, such that the output is still spendable: - res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], subtractFeeFromOutputs=[0], feeRate=0.0008823) + res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: Decimal("0.00010000")}], subtractFeeFromOutputs=[0], feeRate=Decimal("0.0008823")) assert_equal("psbt" in res, True) assert_equal(res["fee"], Decimal("0.00009706")) # creating a 10,000 sat transaction with a manual change address should be possible - res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], subtractFeeFromOutputs=[0], feeRate=0.00010, changeAddress=addr.pop()) + res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: Decimal("0.00010000")}], subtractFeeFromOutputs=[0], feeRate=Decimal("0.00010"), changeAddress=addr.pop()) assert_equal("psbt" in res, True) if not self.options.descriptors: diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py index 522c7732fef40..3dfff1b055ed8 100755 --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -36,7 +36,7 @@ def run_test(self): # Send from node 0 to 1 addr = self.nodes[1].getnewaddress() - txid = self.nodes[0].sendtoaddress(addr, 0.1) + txid = self.nodes[0].sendtoaddress(addr, Decimal("0.1")) self.sync_all() # Check not listed in listreceivedbyaddress because has 0 confirmations @@ -83,7 +83,7 @@ def run_test(self): res = self.nodes[1].listreceivedbyaddress(0, True, True) assert_equal(len(res), 2 + num_cb_reward_addresses) # Right now 2 entries other_addr = self.nodes[1].getnewaddress() - txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1) + txid2 = self.nodes[0].sendtoaddress(other_addr, Decimal("0.1")) self.generate(self.nodes[0], 1) # Same test as above should still pass expected = {"address": addr, "label": "", "amount": Decimal("0.1"), "confirmations": 11, "txids": [txid, ]} @@ -108,7 +108,7 @@ def run_test(self): # Send from node 0 to 1 addr = self.nodes[1].getnewaddress() - txid = self.nodes[0].sendtoaddress(addr, 0.1) + txid = self.nodes[0].sendtoaddress(addr, Decimal("0.1")) self.sync_all() # Check balance is 0 because of 0 confirmations @@ -136,7 +136,7 @@ def run_test(self): received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel() if r["label"] == label][0] balance_by_label = self.nodes[1].getreceivedbylabel(label) - txid = self.nodes[0].sendtoaddress(addr, 0.1) + txid = self.nodes[0].sendtoaddress(addr, Decimal("0.1")) self.sync_all() # getreceivedbylabel returns an error if the wallet doesn't own the label diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py index a9f2066dd19b6..e242c621c0def 100755 --- a/test/functional/wallet_listtransactions.py +++ b/test/functional/wallet_listtransactions.py @@ -35,7 +35,7 @@ def skip_test_if_missing_module(self): def run_test(self): self.log.info("Test simple send from node0 to node1") - txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), Decimal("0.1")) self.sync_all() assert_array_result(self.nodes[0].listtransactions(), {"txid": txid}, @@ -54,7 +54,7 @@ def run_test(self): {"category": "receive", "amount": Decimal("0.1"), "confirmations": 1, "blockhash": blockhash, "blockheight": blockheight}) self.log.info("Test send-to-self on node0") - txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("0.2")) assert_array_result(self.nodes[0].listtransactions(), {"txid": txid, "category": "send"}, {"amount": Decimal("-0.2")}) @@ -63,10 +63,10 @@ def run_test(self): {"amount": Decimal("0.2")}) self.log.info("Test sendmany from node1: twice to self, twice to node0") - send_to = {self.nodes[0].getnewaddress(): 0.11, - self.nodes[1].getnewaddress(): 0.22, - self.nodes[0].getnewaddress(): 0.33, - self.nodes[1].getnewaddress(): 0.44} + send_to = {self.nodes[0].getnewaddress(): Decimal("0.11"), + self.nodes[1].getnewaddress(): Decimal("0.22"), + self.nodes[0].getnewaddress(): Decimal("0.33"), + self.nodes[1].getnewaddress(): Decimal("0.44")} txid = self.nodes[1].sendmany("", send_to) self.sync_all() assert_array_result(self.nodes[1].listtransactions(), @@ -284,8 +284,8 @@ def normalize_list(txs): def run_coinjoin_test(self): self.log.info('Check "coin-join" transaction') - input_0 = next(i for i in self.nodes[0].listunspent(query_options={"minimumAmount": 0.2}, include_unsafe=False)) - input_1 = next(i for i in self.nodes[1].listunspent(query_options={"minimumAmount": 0.2}, include_unsafe=False)) + input_0 = next(i for i in self.nodes[0].listunspent(query_options={"minimumAmount": Decimal("0.2")}, include_unsafe=False)) + input_1 = next(i for i in self.nodes[1].listunspent(query_options={"minimumAmount": Decimal("0.2")}, include_unsafe=False)) raw_hex = self.nodes[0].createrawtransaction( inputs=[ { diff --git a/test/functional/wallet_miniscript.py b/test/functional/wallet_miniscript.py index 064eac499b2fe..6ff82b1abcb2b 100755 --- a/test/functional/wallet_miniscript.py +++ b/test/functional/wallet_miniscript.py @@ -4,6 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test Miniscript descriptors integration in the wallet.""" +from decimal import Decimal + from test_framework.descriptors import descsum_create from test_framework.psbt import PSBT, PSBT_IN_SHA256 from test_framework.test_framework import BitcoinTestFramework @@ -289,7 +291,7 @@ def signing_test( "sequence": seq, } ], - [{dest_addr: 0.009}], + [{dest_addr: Decimal("0.009")}], lt, ) diff --git a/test/functional/wallet_multisig_descriptor_psbt.py b/test/functional/wallet_multisig_descriptor_psbt.py index a69185b3a5f69..0cc8acf6cfce4 100755 --- a/test/functional/wallet_multisig_descriptor_psbt.py +++ b/test/functional/wallet_multisig_descriptor_psbt.py @@ -7,6 +7,8 @@ This is meant to be documentation as much as functional tests, so it is kept as simple and readable as possible. """ +from decimal import Decimal + from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_approx, @@ -104,7 +106,7 @@ def run_test(self): coordinator_wallet = participants["signers"][0] self.generatetoaddress(self.nodes[0], 101, coordinator_wallet.getnewaddress()) - deposit_amount = 6.15 + deposit_amount = Decimal("6.15") multisig_receiving_address = participants["multisigs"][0].getnewaddress() self.log.info("Send funds to the resulting multisig receiving address...") coordinator_wallet.sendtoaddress(multisig_receiving_address, deposit_amount)