diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/functional/feature_config_args.py | 10 | ||||
-rwxr-xr-x | test/functional/rpc_createmultisig.py | 30 | ||||
-rwxr-xr-x | test/functional/rpc_fundrawtransaction.py | 1 | ||||
-rwxr-xr-x | test/functional/rpc_psbt.py | 40 | ||||
-rwxr-xr-x | test/functional/wallet_avoidreuse.py | 24 | ||||
-rwxr-xr-x | test/functional/wallet_balance.py | 2 | ||||
-rwxr-xr-x | test/functional/wallet_bumpfee.py | 4 | ||||
-rwxr-xr-x | test/lint/lint-circular-dependencies.sh | 1 |
8 files changed, 102 insertions, 10 deletions
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 074a832594..f0d6bc21e6 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -21,6 +21,16 @@ class ConfArgsTest(BitcoinTestFramework): with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf: conf.write('includeconf={}\n'.format(inc_conf_file_path)) + self.nodes[0].assert_start_raises_init_error( + expected_msg='Error parsing command line arguments: Invalid parameter -dash_cli', + extra_args=['-dash_cli=1'], + ) + with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: + conf.write('dash_conf=1\n') + with self.nodes[0].assert_debug_log(expected_msgs=['Ignoring unknown configuration value dash_conf']): + self.start_node(0) + self.stop_node(0) + with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('-dash=1\n') self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -') diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py index 18709f3f01..62f3843756 100755 --- a/test/functional/rpc_createmultisig.py +++ b/test/functional/rpc_createmultisig.py @@ -7,9 +7,13 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_raises_rpc_error, + assert_equal, ) -import decimal +from test_framework.key import ECPubKey +import binascii +import decimal +import itertools class RpcCreateMultiSigTest(BitcoinTestFramework): def set_test_params(self): @@ -44,6 +48,30 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): self.checkbalances() + # Test mixed compressed and uncompressed pubkeys + self.log.info('Mixed compressed and uncompressed multisigs are not allowed') + pk0 = node0.getaddressinfo(node0.getnewaddress())['pubkey'] + pk1 = node1.getaddressinfo(node1.getnewaddress())['pubkey'] + pk2 = node2.getaddressinfo(node2.getnewaddress())['pubkey'] + + # decompress pk2 + pk_obj = ECPubKey() + pk_obj.set(binascii.unhexlify(pk2)) + pk_obj.compressed = False + pk2 = binascii.hexlify(pk_obj.get_bytes()).decode() + + # Check all permutations of keys because order matters apparently + for keys in itertools.permutations([pk0, pk1, pk2]): + # Results should be the same as this legacy one + legacy_addr = node0.createmultisig(2, keys, 'legacy')['address'] + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'legacy')['address']) + + # Generate addresses with the segwit types. These should all make legacy addresses + assert_equal(legacy_addr, node0.createmultisig(2, keys, 'bech32')['address']) + assert_equal(legacy_addr, node0.createmultisig(2, keys, 'p2sh-segwit')['address']) + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'bech32')['address']) + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'p2sh-segwit')['address']) + def check_addmultisigaddress_errors(self): self.log.info('Check that addmultisigaddress fails when the private keys are missing') addresses = [self.nodes[1].getnewaddress(address_type='legacy') for _ in range(2)] diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index d89fd6461f..cdf636e200 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -662,6 +662,7 @@ class RawTransactionsTest(BitcoinTestFramework): result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee) result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}) result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee}) + assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[3].fundrawtransaction, rawtx, {"feeRate": 1}) result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex']) assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 430be6dd37..2fffe96ebe 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -9,6 +9,7 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, assert_raises_rpc_error, connect_nodes_bi, disconnect_nodes, @@ -129,6 +130,15 @@ class PSBTTest(BitcoinTestFramework): assert_equal(walletprocesspsbt_out['complete'], True) self.nodes[1].sendrawtransaction(self.nodes[1].finalizepsbt(walletprocesspsbt_out['psbt'])['hex']) + # feeRate of 0.1 BTC / KB produces a total fee slightly below -maxtxfee (~0.05280000): + res = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 0.1}) + assert_greater_than(res["fee"], 0.05) + assert_greater_than(0.06, res["fee"]) + + # feeRate of 10 BTC / KB produces a total fee well above -maxtxfee + # previously this was silenty capped at -maxtxfee + assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 10}) + # partially sign multisig things with node 1 psbtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], {self.nodes[1].getnewaddress():29.99})['psbt'] walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx) @@ -315,18 +325,32 @@ class PSBTTest(BitcoinTestFramework): vout3 = find_output(self.nodes[0], txid3, 11) self.sync_all() - # Update a PSBT with UTXOs from the node - # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness + def test_psbt_input_keys(psbt_input, keys): + """Check that the psbt input has only the expected keys.""" + assert_equal(set(keys), set(psbt_input.keys())) + + # Create a PSBT. None of the inputs are filled initially psbt = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1},{"txid":txid2, "vout":vout2},{"txid":txid3, "vout":vout3}], {self.nodes[0].getnewaddress():32.999}) decoded = self.nodes[1].decodepsbt(psbt) - assert "witness_utxo" not in decoded['inputs'][0] and "non_witness_utxo" not in decoded['inputs'][0] - assert "witness_utxo" not in decoded['inputs'][1] and "non_witness_utxo" not in decoded['inputs'][1] - assert "witness_utxo" not in decoded['inputs'][2] and "non_witness_utxo" not in decoded['inputs'][2] + test_psbt_input_keys(decoded['inputs'][0], []) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], []) + + # Update a PSBT with UTXOs from the node + # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness updated = self.nodes[1].utxoupdatepsbt(psbt) decoded = self.nodes[1].decodepsbt(updated) - assert "witness_utxo" in decoded['inputs'][0] and "non_witness_utxo" not in decoded['inputs'][0] - assert "witness_utxo" not in decoded['inputs'][1] and "non_witness_utxo" not in decoded['inputs'][1] - assert "witness_utxo" not in decoded['inputs'][2] and "non_witness_utxo" not in decoded['inputs'][2] + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo']) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], []) + + # Try again, now while providing descriptors, making P2SH-segwit work, and causing bip32_derivs and redeem_script to be filled in + descs = [self.nodes[1].getaddressinfo(addr)['desc'] for addr in [addr1,addr2,addr3]] + updated = self.nodes[1].utxoupdatepsbt(psbt, descs) + decoded = self.nodes[1].decodepsbt(updated) + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'bip32_derivs']) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], ['witness_utxo', 'bip32_derivs', 'redeem_script']) # Two PSBTs with a common input should not be joinable psbt1 = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1}], {self.nodes[0].getnewaddress():Decimal('10.999')}) diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py index 1dec040f68..58ad835d39 100755 --- a/test/functional/wallet_avoidreuse.py +++ b/test/functional/wallet_avoidreuse.py @@ -63,6 +63,12 @@ def assert_unspent(node, total_count=None, total_sum=None, reused_supported=None if reused_sum is not None: assert_approx(stats["reused"]["sum"], reused_sum, 0.001) +def assert_balances(node, mine): + '''Make assertions about a node's getbalances output''' + got = node.getbalances()["mine"] + for k,v in mine.items(): + assert_approx(got[k], v, 0.001) + class AvoidReuseTest(BitcoinTestFramework): def set_test_params(self): @@ -140,6 +146,10 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 1 single, unused 10 btc output assert_unspent(self.nodes[1], total_count=1, total_sum=10, reused_supported=True, reused_count=0) + # getbalances should show no used, 10 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10}) + # node 0 should not show a used entry, as it does not enable avoid_reuse + assert("used" not in self.nodes[0].getbalances()["mine"]) self.nodes[1].sendtoaddress(retaddr, 5) self.nodes[0].generate(1) @@ -147,6 +157,8 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 1 single, unused 5 btc output assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_supported=True, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) self.nodes[0].sendtoaddress(fundaddr, 10) self.nodes[0].generate(1) @@ -154,11 +166,15 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 2 total outputs (5, 10 btc), one unused (5), one reused (10) assert_unspent(self.nodes[1], total_count=2, total_sum=15, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5}) self.nodes[1].sendtoaddress(address=retaddr, amount=10, avoid_reuse=False) # listunspent should show 1 total outputs (5 btc), unused assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) # node 1 should now have about 5 btc left (for both cases) assert_approx(self.nodes[1].getbalance(), 5, 0.001) @@ -183,6 +199,8 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 1 single, unused 10 btc output assert_unspent(self.nodes[1], total_count=1, total_sum=10, reused_supported=True, reused_count=0) + # getbalances should show no used, 10 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10}) self.nodes[1].sendtoaddress(retaddr, 5) self.nodes[0].generate(1) @@ -190,6 +208,8 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 1 single, unused 5 btc output assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_supported=True, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) self.nodes[0].sendtoaddress(fundaddr, 10) self.nodes[0].generate(1) @@ -197,6 +217,8 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 2 total outputs (5, 10 btc), one unused (5), one reused (10) assert_unspent(self.nodes[1], total_count=2, total_sum=15, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5}) # node 1 should now have a balance of 5 (no dirty) or 15 (including dirty) assert_approx(self.nodes[1].getbalance(), 5, 0.001) @@ -208,6 +230,8 @@ class AvoidReuseTest(BitcoinTestFramework): # listunspent should show 2 total outputs (1, 10 btc), one unused (1), one reused (10) assert_unspent(self.nodes[1], total_count=2, total_sum=11, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 1 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 1}) # node 1 should now have about 1 btc left (no dirty) and 11 (including dirty) assert_approx(self.nodes[1].getbalance(), 1, 0.001) diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py index 15f2195e21..137c77a51e 100755 --- a/test/functional/wallet_balance.py +++ b/test/functional/wallet_balance.py @@ -203,6 +203,8 @@ class WalletTest(BitcoinTestFramework): self.log.info('Put txs back into mempool of node 1 (not node 0)') self.nodes[0].invalidateblock(block_reorg) self.nodes[1].invalidateblock(block_reorg) + self.sync_blocks() + self.nodes[0].syncwithvalidationinterfacequeue() assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted self.nodes[0].generatetoaddress(1, ADDRESS_WATCHONLY) assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 4d9bacf299..1fe029a6fb 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -304,7 +304,9 @@ def test_unconfirmed_not_spendable(rbf_node, rbf_node_address): def test_bumpfee_metadata(rbf_node, dest_address): - rbfid = rbf_node.sendtoaddress(dest_address, Decimal("0.00100000"), "comment value", "to value") + assert(rbf_node.getbalance() < 49) + rbf_node.generatetoaddress(101, rbf_node.getnewaddress()) + rbfid = rbf_node.sendtoaddress(dest_address, 49, "comment value", "to value") bumped_tx = rbf_node.bumpfee(rbfid) bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"]) assert_equal(bumped_wtx["comment"], "comment value") diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index 2701015c79..70cc16337e 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -30,6 +30,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "policy/fees -> txmempool -> validation -> policy/fees" "qt/guiutil -> qt/walletmodel -> qt/optionsmodel -> qt/guiutil" "txmempool -> validation -> validationinterface -> txmempool" + "wallet/ismine -> wallet/wallet -> wallet/ismine" ) EXIT_CODE=0 |