diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/README.md | 2 | ||||
-rw-r--r-- | test/functional/README.md | 20 | ||||
-rwxr-xr-x | test/functional/create_cache.py | 3 | ||||
-rwxr-xr-x | test/functional/feature_assumevalid.py (renamed from test/functional/assumevalid.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_bip68_sequence.py (renamed from test/functional/bip68-sequence.py) | 5 | ||||
-rwxr-xr-x | test/functional/feature_bip9_softforks.py (renamed from test/functional/bip9-softforks.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_block.py (renamed from test/functional/p2p-fullblocktest.py) | 9 | ||||
-rwxr-xr-x | test/functional/feature_cltv.py (renamed from test/functional/bip65-cltv-p2p.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_config_args.py (renamed from test/functional/conf_args.py) | 0 | ||||
-rwxr-xr-x | test/functional/feature_csv_activation.py (renamed from test/functional/bip68-112-113-p2p.py) | 4 | ||||
-rwxr-xr-x | test/functional/feature_dbcrash.py (renamed from test/functional/dbcrash.py) | 0 | ||||
-rwxr-xr-x | test/functional/feature_dersig.py (renamed from test/functional/bipdersig-p2p.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_fee_estimation.py (renamed from test/functional/smartfees.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_maxuploadtarget.py (renamed from test/functional/maxuploadtarget.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_minchainwork.py (renamed from test/functional/minchainwork.py) | 0 | ||||
-rwxr-xr-x | test/functional/feature_notifications.py (renamed from test/functional/notifications.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_nulldummy.py (renamed from test/functional/nulldummy.py) | 8 | ||||
-rwxr-xr-x | test/functional/feature_proxy.py (renamed from test/functional/proxy_test.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_pruning.py (renamed from test/functional/pruning.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_rbf.py (renamed from test/functional/replace-by-fee.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_reindex.py (renamed from test/functional/reindex.py) | 2 | ||||
-rwxr-xr-x | test/functional/feature_segwit.py (renamed from test/functional/segwit.py) | 131 | ||||
-rwxr-xr-x | test/functional/feature_uacomment.py (renamed from test/functional/uacomment.py) | 0 | ||||
-rwxr-xr-x | test/functional/feature_versionbits_warning.py | 112 | ||||
-rwxr-xr-x | test/functional/interface_bitcoin_cli.py (renamed from test/functional/bitcoin_cli.py) | 2 | ||||
-rwxr-xr-x | test/functional/interface_http.py (renamed from test/functional/httpbasics.py) | 2 | ||||
-rwxr-xr-x | test/functional/interface_rest.py (renamed from test/functional/rest.py) | 2 | ||||
-rwxr-xr-x | test/functional/interface_zmq.py (renamed from test/functional/zmq_test.py) | 2 | ||||
-rwxr-xr-x | test/functional/mempool_limit.py | 14 | ||||
-rwxr-xr-x | test/functional/mempool_packages.py | 2 | ||||
-rwxr-xr-x | test/functional/mempool_persist.py | 9 | ||||
-rwxr-xr-x | test/functional/mempool_reorg.py | 2 | ||||
-rwxr-xr-x | test/functional/mempool_resurrect.py (renamed from test/functional/mempool_resurrect_test.py) | 2 | ||||
-rwxr-xr-x | test/functional/mempool_spend_coinbase.py (renamed from test/functional/mempool_spendcoinbase.py) | 2 | ||||
-rwxr-xr-x | test/functional/mining_basic.py (renamed from test/functional/mining.py) | 2 | ||||
-rwxr-xr-x | test/functional/mining_getblocktemplate_longpoll.py (renamed from test/functional/getblocktemplate_longpoll.py) | 2 | ||||
-rwxr-xr-x | test/functional/mining_prioritisetransaction.py (renamed from test/functional/prioritise_transaction.py) | 21 | ||||
-rwxr-xr-x | test/functional/p2p-versionbits-warning.py | 121 | ||||
-rwxr-xr-x | test/functional/p2p_compactblocks.py (renamed from test/functional/p2p-compactblocks.py) | 4 | ||||
-rwxr-xr-x | test/functional/p2p_disconnect_ban.py (renamed from test/functional/disconnect_ban.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_feefilter.py (renamed from test/functional/p2p-feefilter.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_fingerprint.py (renamed from test/functional/p2p-fingerprint.py) | 0 | ||||
-rwxr-xr-x | test/functional/p2p_invalid_block.py (renamed from test/functional/invalidblockrequest.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_invalid_tx.py (renamed from test/functional/invalidtxrequest.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_leak.py (renamed from test/functional/p2p-leaktests.py) | 0 | ||||
-rwxr-xr-x | test/functional/p2p_mempool.py (renamed from test/functional/p2p-mempool.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_node_network_limited.py (renamed from test/functional/node_network_limited.py) | 0 | ||||
-rwxr-xr-x | test/functional/p2p_segwit.py (renamed from test/functional/p2p-segwit.py) | 18 | ||||
-rwxr-xr-x | test/functional/p2p_sendheaders.py (renamed from test/functional/sendheaders.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_timeouts.py (renamed from test/functional/p2p-timeouts.py) | 2 | ||||
-rwxr-xr-x | test/functional/p2p_unrequested_blocks.py (renamed from test/functional/p2p-acceptblock.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_bind.py (renamed from test/functional/rpcbind_test.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_blockchain.py (renamed from test/functional/blockchain.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_decodescript.py (renamed from test/functional/decodescript.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_deprecated.py (renamed from test/functional/deprecated_rpc.py) | 6 | ||||
-rwxr-xr-x | test/functional/rpc_fundrawtransaction.py (renamed from test/functional/fundrawtransaction.py) | 21 | ||||
-rwxr-xr-x | test/functional/rpc_getchaintips.py (renamed from test/functional/getchaintips.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_invalidateblock.py (renamed from test/functional/invalidateblock.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_listtransactions.py (renamed from test/functional/listtransactions.py) | 5 | ||||
-rwxr-xr-x | test/functional/rpc_named_arguments.py (renamed from test/functional/rpcnamedargs.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_net.py (renamed from test/functional/net.py) | 0 | ||||
-rwxr-xr-x | test/functional/rpc_preciousblock.py (renamed from test/functional/preciousblock.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_rawtransaction.py (renamed from test/functional/rawtransactions.py) | 20 | ||||
-rwxr-xr-x | test/functional/rpc_signmessage.py (renamed from test/functional/signmessages.py) | 3 | ||||
-rwxr-xr-x | test/functional/rpc_signrawtransaction.py (renamed from test/functional/signrawtransactions.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_txoutproof.py (renamed from test/functional/merkle_blocks.py) | 2 | ||||
-rwxr-xr-x | test/functional/rpc_uptime.py (renamed from test/functional/uptime.py) | 0 | ||||
-rwxr-xr-x | test/functional/rpc_users.py (renamed from test/functional/multi_rpc.py) | 2 | ||||
-rw-r--r-- | test/functional/test_framework/address.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/blockstore.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/blocktools.py | 66 | ||||
-rwxr-xr-x | test/functional/test_framework/comptool.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/coverage.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/messages.py | 25 | ||||
-rwxr-xr-x | test/functional/test_framework/mininode.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/netutil.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/script.py | 4 | ||||
-rw-r--r-- | test/functional/test_framework/siphash.py | 2 | ||||
-rw-r--r-- | test/functional/test_framework/socks5.py | 2 | ||||
-rwxr-xr-x | test/functional/test_framework/test_framework.py | 21 | ||||
-rwxr-xr-x | test/functional/test_framework/test_node.py | 88 | ||||
-rw-r--r-- | test/functional/test_framework/util.py | 7 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 198 | ||||
-rwxr-xr-x | test/functional/wallet_abandonconflict.py (renamed from test/functional/abandonconflict.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_accounts.py (renamed from test/functional/wallet-accounts.py) | 4 | ||||
-rwxr-xr-x | test/functional/wallet_address_types.py | 294 | ||||
-rwxr-xr-x | test/functional/wallet_backup.py (renamed from test/functional/walletbackup.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_basic.py (renamed from test/functional/wallet.py) | 13 | ||||
-rwxr-xr-x | test/functional/wallet_bumpfee.py (renamed from test/functional/bumpfee.py) | 9 | ||||
-rwxr-xr-x | test/functional/wallet_disable.py (renamed from test/functional/disablewallet.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_dump.py (renamed from test/functional/wallet-dump.py) | 6 | ||||
-rwxr-xr-x | test/functional/wallet_encryption.py (renamed from test/functional/wallet-encryption.py) | 21 | ||||
-rwxr-xr-x | test/functional/wallet_hd.py (renamed from test/functional/wallet-hd.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_import_rescan.py (renamed from test/functional/import-rescan.py) | 4 | ||||
-rwxr-xr-x | test/functional/wallet_importmulti.py (renamed from test/functional/importmulti.py) | 11 | ||||
-rwxr-xr-x | test/functional/wallet_importprunedfunds.py (renamed from test/functional/importprunedfunds.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_keypool.py (renamed from test/functional/keypool.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_keypool_topup.py (renamed from test/functional/keypool-topup.py) | 0 | ||||
-rwxr-xr-x | test/functional/wallet_listreceivedby.py (renamed from test/functional/receivedby.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_listsinceblock.py (renamed from test/functional/listsinceblock.py) | 0 | ||||
-rwxr-xr-x | test/functional/wallet_multiwallet.py (renamed from test/functional/multiwallet.py) | 66 | ||||
-rwxr-xr-x | test/functional/wallet_resendwallettransactions.py (renamed from test/functional/resendwallettransactions.py) | 0 | ||||
-rwxr-xr-x | test/functional/wallet_txn_clone.py (renamed from test/functional/txn_clone.py) | 17 | ||||
-rwxr-xr-x | test/functional/wallet_txn_doublespend.py (renamed from test/functional/txn_doublespend.py) | 2 | ||||
-rwxr-xr-x | test/functional/wallet_zapwallettxes.py (renamed from test/functional/zapwallettxes.py) | 5 | ||||
-rwxr-xr-x | test/util/bitcoin-util-test.py | 12 |
106 files changed, 1015 insertions, 502 deletions
diff --git a/test/README.md b/test/README.md index 868eb667ae..b59c8db4e5 100644 --- a/test/README.md +++ b/test/README.md @@ -8,7 +8,7 @@ There are currently two sets of tests in this directory: - [functional](/test/functional) which test the functionality of bitcoind and bitcoin-qt by interacting with them through the RPC and P2P interfaces. -- [util](test/util) which tests the bitcoin utilities, currently only +- [util](/test/util) which tests the bitcoin utilities, currently only bitcoin-tx. The util tests are run as part of `make check` target. The functional diff --git a/test/functional/README.md b/test/functional/README.md index 6be4d9cfab..662b4b44d5 100644 --- a/test/functional/README.md +++ b/test/functional/README.md @@ -17,7 +17,7 @@ don't have test cases for. #### Style guidelines -- Where possible, try to adhere to [PEP-8 guidelines]([https://www.python.org/dev/peps/pep-0008/) +- Where possible, try to adhere to [PEP-8 guidelines](https://www.python.org/dev/peps/pep-0008/) - Use a python linter like flake8 before submitting PRs to catch common style nits (eg trailing whitespace, unused imports, etc) - Avoid wildcard imports where possible @@ -27,6 +27,20 @@ don't have test cases for. `set_test_params()`, `add_options()` and `setup_xxxx()` methods at the top of the subclass, then locally-defined helper methods, then the `run_test()` method. +#### Naming guidelines + +- Name the test `<area>_test.py`, where area can be one of the following: + - `feature` for tests for full features that aren't wallet/mining/mempool, eg `feature_rbf.py` + - `interface` for tests for other interfaces (REST, ZMQ, etc), eg `interface_rest.py` + - `mempool` for tests for mempool behaviour, eg `mempool_reorg.py` + - `mining` for tests for mining features, eg `mining_prioritisetransaction.py` + - `p2p` for tests that explicitly test the p2p interface, eg `p2p_disconnect_ban.py` + - `rpc` for tests for individual RPC methods or features, eg `rpc_listtransactions.py` + - `wallet` for tests for wallet features, eg `wallet_keypool.py` +- use an underscore to separate words + - exception: for tests for specific RPCs or command line options which don't include underscores, name the test after the exact RPC or argument name, eg `rpc_decodescript.py`, not `rpc_decode_script.py` +- Don't use the redundant word `test` in the name, eg `interface_zmq.py`, not `interface_zmq_test.py` + #### General test-writing advice - Set `self.num_nodes` to the minimum number of nodes necessary for the test. @@ -73,7 +87,7 @@ start the networking thread. (Continue with the test logic in your existing thread.) - Can be used to write tests where specific P2P protocol behavior is tested. -Examples tests are `p2p-accept-block.py`, `p2p-compactblocks.py`. +Examples tests are `p2p_unrequested_blocks.py`, `p2p_compactblocks.py`. #### Comptool @@ -119,7 +133,7 @@ Each `TestInstance` consists of: acceptance is tested against the given outcome. - For examples of tests written in this framework, see - `invalidblockrequest.py` and `p2p-fullblocktest.py`. + `p2p_invalid_block.py` and `feature_block.py`. ### test-framework modules diff --git a/test/functional/create_cache.py b/test/functional/create_cache.py index 7d4d1a529b..9665c50a92 100755 --- a/test/functional/create_cache.py +++ b/test/functional/create_cache.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Create a blockchain cache. @@ -16,6 +16,7 @@ class CreateCache(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 0 + self.supports_cli = True def setup_network(self): pass diff --git a/test/functional/assumevalid.py b/test/functional/feature_assumevalid.py index 362b94e0d3..5a09142412 100755 --- a/test/functional/assumevalid.py +++ b/test/functional/feature_assumevalid.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test logic for skipping signature validation on old blocks. diff --git a/test/functional/bip68-sequence.py b/test/functional/feature_bip68_sequence.py index 5f8f21701f..94b13653b9 100755 --- a/test/functional/bip68-sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP68 implementation.""" @@ -362,9 +362,10 @@ class BIP68Test(BitcoinTestFramework): block.vtx.extend([tx1, tx2, tx3]) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() + add_witness_commitment(block) block.solve() - self.nodes[0].submitblock(ToHex(block)) + self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True))) assert_equal(self.nodes[0].getbestblockhash(), block.hash) def activateCSV(self): diff --git a/test/functional/bip9-softforks.py b/test/functional/feature_bip9_softforks.py index 4cd6a177aa..ae92e9f07c 100755 --- a/test/functional/bip9-softforks.py +++ b/test/functional/feature_bip9_softforks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP 9 soft forks. diff --git a/test/functional/p2p-fullblocktest.py b/test/functional/feature_block.py index 010dbdccad..fe9bbda14b 100755 --- a/test/functional/p2p-fullblocktest.py +++ b/test/functional/feature_block.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test block processing. @@ -36,12 +36,15 @@ class CBrokenBlock(CBlock): self.vtx = copy.deepcopy(base_block.vtx) self.hashMerkleRoot = self.calc_merkle_root() - def serialize(self): + def serialize(self, with_witness=False): r = b"" r += super(CBlock, self).serialize() r += struct.pack("<BQ", 255, len(self.vtx)) for tx in self.vtx: - r += tx.serialize() + if with_witness: + r += tx.serialize_with_witness() + else: + r += tx.serialize_without_witness() return r def normal_serialize(self): diff --git a/test/functional/bip65-cltv-p2p.py b/test/functional/feature_cltv.py index f4df879723..f62ae31654 100755 --- a/test/functional/bip65-cltv-p2p.py +++ b/test/functional/feature_cltv.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP65 (CHECKLOCKTIMEVERIFY). diff --git a/test/functional/conf_args.py b/test/functional/feature_config_args.py index 61abba8082..61abba8082 100755 --- a/test/functional/conf_args.py +++ b/test/functional/feature_config_args.py diff --git a/test/functional/bip68-112-113-p2p.py b/test/functional/feature_csv_activation.py index d3c7d8fc11..82aa0ff891 100755 --- a/test/functional/bip68-112-113-p2p.py +++ b/test/functional/feature_csv_activation.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test activation of the first version bits soft fork. @@ -95,7 +95,7 @@ class BIP68_112_113Test(ComparisonTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True - self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4']] + self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4', '-addresstype=legacy']] def run_test(self): test = TestManager(self, self.options.tmpdir) diff --git a/test/functional/dbcrash.py b/test/functional/feature_dbcrash.py index 24b9765b4e..24b9765b4e 100755 --- a/test/functional/dbcrash.py +++ b/test/functional/feature_dbcrash.py diff --git a/test/functional/bipdersig-p2p.py b/test/functional/feature_dersig.py index 5d7b889e83..3414571678 100755 --- a/test/functional/bipdersig-p2p.py +++ b/test/functional/feature_dersig.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP66 (DER SIG). diff --git a/test/functional/smartfees.py b/test/functional/feature_fee_estimation.py index 986f4546a8..68453e50f4 100755 --- a/test/functional/smartfees.py +++ b/test/functional/feature_fee_estimation.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test fee estimation code.""" diff --git a/test/functional/maxuploadtarget.py b/test/functional/feature_maxuploadtarget.py index cf2e484d9f..45336ee801 100755 --- a/test/functional/maxuploadtarget.py +++ b/test/functional/feature_maxuploadtarget.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test behavior of -maxuploadtarget. diff --git a/test/functional/minchainwork.py b/test/functional/feature_minchainwork.py index 90a3de0e0d..90a3de0e0d 100755 --- a/test/functional/minchainwork.py +++ b/test/functional/feature_minchainwork.py diff --git a/test/functional/notifications.py b/test/functional/feature_notifications.py index c88972ab91..980bef5fc8 100755 --- a/test/functional/notifications.py +++ b/test/functional/feature_notifications.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the -alertnotify, -blocknotify and -walletnotify options.""" diff --git a/test/functional/nulldummy.py b/test/functional/feature_nulldummy.py index 9f9f2f90c0..e4f413cc2a 100755 --- a/test/functional/nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test NULLDUMMY softfork. @@ -42,13 +42,13 @@ class NULLDUMMYTest(BitcoinTestFramework): self.setup_clean_chain = True # This script tests NULLDUMMY activation, which is part of the 'segwit' deployment, so we go through # normal segwit activation here (and don't use the default always-on behaviour). - self.extra_args = [['-whitelist=127.0.0.1', '-walletprematurewitness', '-vbparams=segwit:0:999999999999']] + self.extra_args = [['-whitelist=127.0.0.1', '-walletprematurewitness', '-vbparams=segwit:0:999999999999', '-addresstype=legacy', "-deprecatedrpc=addwitnessaddress"]] def run_test(self): self.address = self.nodes[0].getnewaddress() - self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address]) + self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address])['address'] self.wit_address = self.nodes[0].addwitnessaddress(self.address) - self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address) + self.wit_ms_address = self.nodes[0].addmultisigaddress(1, [self.address], '', 'p2sh-segwit')['address'] network_thread_start() self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 diff --git a/test/functional/proxy_test.py b/test/functional/feature_proxy.py index 81b99d1bf4..2eb1be47a5 100755 --- a/test/functional/proxy_test.py +++ b/test/functional/feature_proxy.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test bitcoind with different proxy configuration. diff --git a/test/functional/pruning.py b/test/functional/feature_pruning.py index 0101f61185..49ad7f838c 100755 --- a/test/functional/pruning.py +++ b/test/functional/feature_pruning.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the pruning code. diff --git a/test/functional/replace-by-fee.py b/test/functional/feature_rbf.py index 815e964848..6b7ab0f43e 100755 --- a/test/functional/replace-by-fee.py +++ b/test/functional/feature_rbf.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the RBF code.""" diff --git a/test/functional/reindex.py b/test/functional/feature_reindex.py index 1f684a1afe..ac67e6e9ba 100755 --- a/test/functional/reindex.py +++ b/test/functional/feature_reindex.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test running bitcoind with -reindex and -reindex-chainstate options. diff --git a/test/functional/segwit.py b/test/functional/feature_segwit.py index 338fa1bc52..ba6373fa33 100755 --- a/test/functional/segwit.py +++ b/test/functional/feature_segwit.py @@ -1,13 +1,21 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the SegWit changeover logic.""" +from test_framework.address import ( + key_to_p2sh_p2wpkh, + key_to_p2wpkh, + program_to_witness, + script_to_p2sh_p2wsh, + script_to_p2wsh, +) +from test_framework.blocktools import witness_script, send_to_witness from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import sha256, CTransaction, CTxIn, COutPoint, CTxOut, COIN, ToHex, FromHex -from test_framework.address import script_to_p2sh, key_to_p2pkh, key_to_p2sh_p2wpkh, key_to_p2wpkh, script_to_p2sh_p2wsh, script_to_p2wsh, program_to_witness +from test_framework.address import script_to_p2sh, key_to_p2pkh from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, OP_TRUE from io import BytesIO @@ -16,52 +24,6 @@ NODE_2 = 2 WIT_V0 = 0 WIT_V1 = 1 -# Create a scriptPubKey corresponding to either a P2WPKH output for the -# given pubkey, or a P2WSH output of a 1-of-1 multisig for the given -# pubkey. Returns the hex encoding of the scriptPubKey. -def witness_script(use_p2wsh, pubkey): - if (use_p2wsh == False): - # P2WPKH instead - pubkeyhash = hash160(hex_str_to_bytes(pubkey)) - pkscript = CScript([OP_0, pubkeyhash]) - else: - # 1-of-1 multisig - witness_program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG]) - scripthash = sha256(witness_program) - pkscript = CScript([OP_0, scripthash]) - return bytes_to_hex_str(pkscript) - -# Return a transaction (in hex) that spends the given utxo to a segwit output, -# optionally wrapping the segwit output using P2SH. -def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount): - if use_p2wsh: - program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG]) - addr = script_to_p2sh_p2wsh(program) if encode_p2sh else script_to_p2wsh(program) - else: - addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey) - if not encode_p2sh: - assert_equal(node.validateaddress(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey)) - return node.createrawtransaction([utxo], {addr: amount}) - -# Create a transaction spending a given utxo to a segwit output corresponding -# to the given pubkey: use_p2wsh determines whether to use P2WPKH or P2WSH; -# encode_p2sh determines whether to wrap in P2SH. -# sign=True will have the given node sign the transaction. -# insert_redeem_script will be added to the scriptSig, if given. -def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""): - tx_to_witness = create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount) - if (sign): - signed = node.signrawtransaction(tx_to_witness) - assert("errors" not in signed or len(["errors"]) == 0) - return node.sendrawtransaction(signed["hex"]) - else: - if (insert_redeem_script): - tx = FromHex(CTransaction(), tx_to_witness) - tx.vin[0].scriptSig += CScript([hex_str_to_bytes(insert_redeem_script)]) - tx_to_witness = ToHex(tx) - - return node.sendrawtransaction(tx_to_witness) - def getutxo(txid): utxo = {} utxo["vout"] = 0 @@ -78,9 +40,9 @@ class SegWitTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 # This test tests SegWit both pre and post-activation, so use the normal BIP9 activation. - self.extra_args = [["-walletprematurewitness", "-rpcserialversion=0", "-vbparams=segwit:0:999999999999"], - ["-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999"], - ["-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-vbparams=segwit:0:999999999999"]] + self.extra_args = [["-walletprematurewitness", "-rpcserialversion=0", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"], + ["-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"], + ["-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-vbparams=segwit:0:999999999999", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]] def setup_network(self): super().setup_network() @@ -133,12 +95,11 @@ class SegWitTest(BitcoinTestFramework): for i in range(3): newaddress = self.nodes[i].getnewaddress() self.pubkey.append(self.nodes[i].validateaddress(newaddress)["pubkey"]) - multiaddress = self.nodes[i].addmultisigaddress(1, [self.pubkey[-1]]) multiscript = CScript([OP_1, hex_str_to_bytes(self.pubkey[-1]), OP_1, OP_CHECKMULTISIG]) - p2sh_addr = self.nodes[i].addwitnessaddress(newaddress, True) + p2sh_addr = self.nodes[i].addwitnessaddress(newaddress) bip173_addr = self.nodes[i].addwitnessaddress(newaddress, False) - p2sh_ms_addr = self.nodes[i].addwitnessaddress(multiaddress, True) - bip173_ms_addr = self.nodes[i].addwitnessaddress(multiaddress, False) + p2sh_ms_addr = self.nodes[i].addmultisigaddress(1, [self.pubkey[-1]], '', 'p2sh-segwit')['address'] + bip173_ms_addr = self.nodes[i].addmultisigaddress(1, [self.pubkey[-1]], '', 'bech32')['address'] assert_equal(p2sh_addr, key_to_p2sh_p2wpkh(self.pubkey[-1])) assert_equal(bip173_addr, key_to_p2wpkh(self.pubkey[-1])) assert_equal(p2sh_ms_addr, script_to_p2sh_p2wsh(multiscript)) @@ -328,19 +289,19 @@ class SegWitTest(BitcoinTestFramework): solvable_anytime = [] # These outputs should be solvable after importpubkey unseen_anytime = [] # These outputs should never be seen - uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) - uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) - compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) - uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], uncompressed_solvable_address[0]])) - compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) - compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], compressed_solvable_address[1]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])['address']) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])['address']) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])['address']) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], uncompressed_solvable_address[0]])['address']) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])['address']) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], compressed_solvable_address[1]])['address']) unknown_address = ["mtKKyoHabkk6e4ppT7NaM7THqPUt7AzPrT", "2NDP3jLWAFT8NDAiUa9qiE6oBt2awmMq7Dx"] # Test multisig_without_privkey # We have 2 public keys without private keys, use addmultisigaddress to add to wallet. # Money sent to P2SH of multisig of this should only be seen after importaddress with the BASE58 P2SH address. - multisig_without_privkey_address = self.nodes[0].addmultisigaddress(2, [pubkeys[3], pubkeys[4]]) + multisig_without_privkey_address = self.nodes[0].addmultisigaddress(2, [pubkeys[3], pubkeys[4]])['address'] script = CScript([OP_2, hex_str_to_bytes(pubkeys[3]), hex_str_to_bytes(pubkeys[4]), OP_2, OP_CHECKMULTISIG]) solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL])) @@ -356,8 +317,10 @@ class SegWitTest(BitcoinTestFramework): [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) # normal P2PKH and P2PK with compressed keys should always be spendable spendable_anytime.extend([p2pkh, p2pk]) - # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are spendable after direct importaddress - spendable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + # P2SH_P2PK, P2SH_P2PKH with compressed keys are spendable after direct importaddress + spendable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + # P2WPKH and P2SH_P2WPKH with compressed keys should always be spendable + spendable_anytime.extend([p2wpkh, p2sh_p2wpkh]) for i in uncompressed_spendable_address: v = self.nodes[0].validateaddress(i) @@ -373,7 +336,7 @@ class SegWitTest(BitcoinTestFramework): spendable_anytime.extend([p2pkh, p2pk]) # P2SH_P2PK and P2SH_P2PKH are spendable after direct importaddress spendable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) - # witness with uncompressed keys are never seen + # Witness output types with uncompressed keys are never seen unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) for i in compressed_solvable_address: @@ -384,10 +347,10 @@ class SegWitTest(BitcoinTestFramework): solvable_after_importaddress.extend([bare, p2sh, p2wsh, p2sh_p2wsh]) else: [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) - # normal P2PKH and P2PK with compressed keys should always be seen - solvable_anytime.extend([p2pkh, p2pk]) - # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are seen after direct importaddress - solvable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + # normal P2PKH, P2PK, P2WPKH and P2SH_P2WPKH with compressed keys should always be seen + solvable_anytime.extend([p2pkh, p2pk, p2wpkh, p2sh_p2wpkh]) + # P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after direct importaddress + solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) for i in uncompressed_solvable_address: v = self.nodes[0].validateaddress(i) @@ -403,7 +366,7 @@ class SegWitTest(BitcoinTestFramework): solvable_anytime.extend([p2pkh, p2pk]) # P2SH_P2PK, P2SH_P2PKH with uncompressed keys are seen after direct importaddress solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) - # witness with uncompressed keys are never seen + # Witness output types with uncompressed keys are never seen unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) op1 = CScript([OP_1]) @@ -496,12 +459,14 @@ class SegWitTest(BitcoinTestFramework): spendable_after_addwitnessaddress = [] # These outputs should be seen after importaddress solvable_after_addwitnessaddress=[] # These outputs should be seen after importaddress but not spendable unseen_anytime = [] # These outputs should never be seen + solvable_anytime = [] # These outputs should be solvable after importpubkey + unseen_anytime = [] # These outputs should never be seen - uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) - uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) - compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) - uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], uncompressed_solvable_address[0]])) - compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])['address']) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])['address']) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])['address']) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], uncompressed_solvable_address[0]])['address']) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])['address']) premature_witaddress = [] @@ -514,9 +479,8 @@ class SegWitTest(BitcoinTestFramework): premature_witaddress.append(script_to_p2sh(p2wsh)) else: [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) - # P2WPKH, P2SH_P2WPKH are spendable after addwitnessaddress - spendable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) - premature_witaddress.append(script_to_p2sh(p2wpkh)) + # P2WPKH, P2SH_P2WPKH are always spendable + spendable_anytime.extend([p2wpkh, p2sh_p2wpkh]) for i in uncompressed_spendable_address + uncompressed_solvable_address: v = self.nodes[0].validateaddress(i) @@ -538,10 +502,11 @@ class SegWitTest(BitcoinTestFramework): premature_witaddress.append(script_to_p2sh(p2wsh)) else: [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) - # P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after addwitnessaddress - solvable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) - premature_witaddress.append(script_to_p2sh(p2wpkh)) + # P2SH_P2PK, P2SH_P2PKH with compressed keys are always solvable + solvable_anytime.extend([p2wpkh, p2sh_p2wpkh]) + self.mine_and_test_listunspent(spendable_anytime, 2) + self.mine_and_test_listunspent(solvable_anytime, 1) self.mine_and_test_listunspent(spendable_after_addwitnessaddress + solvable_after_addwitnessaddress + unseen_anytime, 0) # addwitnessaddress should refuse to return a witness address if an uncompressed key is used @@ -558,8 +523,8 @@ class SegWitTest(BitcoinTestFramework): witaddress = self.nodes[0].addwitnessaddress(i) assert_equal(witaddress, self.nodes[0].addwitnessaddress(witaddress)) - spendable_txid.append(self.mine_and_test_listunspent(spendable_after_addwitnessaddress, 2)) - solvable_txid.append(self.mine_and_test_listunspent(solvable_after_addwitnessaddress, 1)) + spendable_txid.append(self.mine_and_test_listunspent(spendable_after_addwitnessaddress + spendable_anytime, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_after_addwitnessaddress + solvable_anytime, 1)) self.mine_and_test_listunspent(unseen_anytime, 0) # Check that createrawtransaction/decoderawtransaction with non-v0 Bech32 works diff --git a/test/functional/uacomment.py b/test/functional/feature_uacomment.py index 0b2c64ab69..0b2c64ab69 100755 --- a/test/functional/uacomment.py +++ b/test/functional/feature_uacomment.py diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py new file mode 100755 index 0000000000..2985569a8f --- /dev/null +++ b/test/functional/feature_versionbits_warning.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test version bits warning system. + +Generate chains with block versions that appear to be signalling unknown +soft-forks, and test that warning alerts are generated. +""" +import os +import re + +from test_framework.blocktools import create_block, create_coinbase +from test_framework.messages import msg_block +from test_framework.mininode import P2PInterface, network_thread_start, mininode_lock +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import wait_until + +VB_PERIOD = 144 # versionbits period length for regtest +VB_THRESHOLD = 108 # versionbits activation threshold for regtest +VB_TOP_BITS = 0x20000000 +VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment +VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT) + +WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect" +WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT) +VB_PATTERN = re.compile("Warning: unknown new rules activated.*versionbit") + +class VersionBitsWarningTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self): + self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") + # Open and close to create zero-length file + with open(self.alert_filename, 'w', encoding='utf8'): + pass + self.extra_args = [["-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + self.setup_nodes() + + def send_blocks_with_version(self, peer, numblocks, version): + """Send numblocks blocks to peer with version set""" + tip = self.nodes[0].getbestblockhash() + height = self.nodes[0].getblockcount() + block_time = self.nodes[0].getblockheader(tip)["time"] + 1 + tip = int(tip, 16) + + for _ in range(numblocks): + block = create_block(tip, create_coinbase(height + 1), block_time) + block.nVersion = version + block.solve() + peer.send_message(msg_block(block)) + block_time += 1 + height += 1 + tip = block.sha256 + peer.sync_with_ping() + + def versionbits_in_alert_file(self): + """Test that the versionbits warning has been written to the alert file.""" + alert_text = open(self.alert_filename, 'r', encoding='utf8').read() + return VB_PATTERN.search(alert_text) is not None + + def run_test(self): + # Handy alias + node = self.nodes[0] + node.add_p2p_connection(P2PInterface()) + network_thread_start() + node.p2p.wait_for_verack() + + # Mine one period worth of blocks + node.generate(VB_PERIOD) + + self.log.info("Check that there is no warning if previous VB_BLOCKS have <VB_THRESHOLD blocks with unknown versionbits version.") + # Build one period of blocks with < VB_THRESHOLD blocks signaling some unknown bit + self.send_blocks_with_version(node.p2p, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION) + node.generate(VB_PERIOD - VB_THRESHOLD + 1) + + # Check that we're not getting any versionbit-related errors in get*info() + assert(not VB_PATTERN.match(node.getmininginfo()["warnings"])) + assert(not VB_PATTERN.match(node.getnetworkinfo()["warnings"])) + + self.log.info("Check that there is a warning if >50 blocks in the last 100 were an unknown version") + # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit + self.send_blocks_with_version(node.p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION) + node.generate(VB_PERIOD - VB_THRESHOLD) + + # Check that get*info() shows the 51/100 unknown block version error. + assert(WARN_UNKNOWN_RULES_MINED in node.getmininginfo()["warnings"]) + assert(WARN_UNKNOWN_RULES_MINED in node.getnetworkinfo()["warnings"]) + + self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") + # Mine a period worth of expected blocks so the generic block-version warning + # is cleared. This will move the versionbit state to ACTIVE. + node.generate(VB_PERIOD) + + # Stop-start the node. This is required because bitcoind will only warn once about unknown versions or unknown rules activating. + self.restart_node(0) + + # Generating one block guarantees that we'll get out of IBD + node.generate(1) + wait_until(lambda: not node.getblockchaininfo()['initialblockdownload'], timeout=10, lock=mininode_lock) + # Generating one more block will be enough to generate an error. + node.generate(1) + # Check that get*info() shows the versionbits unknown rules warning + assert(WARN_UNKNOWN_RULES_ACTIVE in node.getmininginfo()["warnings"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in node.getnetworkinfo()["warnings"]) + # Check that the alert file shows the versionbits unknown rules warning + wait_until(lambda: self.versionbits_in_alert_file(), timeout=60) + +if __name__ == '__main__': + VersionBitsWarningTest().main() diff --git a/test/functional/bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py index d1cd3b3620..d8c80ab34f 100755 --- a/test/functional/bitcoin_cli.py +++ b/test/functional/interface_bitcoin_cli.py @@ -39,7 +39,7 @@ class TestBitcoinCli(BitcoinTestFramework): assert_raises_process_error(1, "-getinfo takes no arguments", self.nodes[0].cli('-getinfo').help) self.log.info("Compare responses from `bitcoin-cli -getinfo` and the RPCs data is retrieved from.") - cli_get_info = self.nodes[0].cli().send_cli('-getinfo') + cli_get_info = self.nodes[0].cli('-getinfo').send_cli() wallet_info = self.nodes[0].getwalletinfo() network_info = self.nodes[0].getnetworkinfo() blockchain_info = self.nodes[0].getblockchaininfo() diff --git a/test/functional/httpbasics.py b/test/functional/interface_http.py index c7682cb49d..cd6d744545 100755 --- a/test/functional/httpbasics.py +++ b/test/functional/interface_http.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the RPC HTTP basics.""" diff --git a/test/functional/rest.py b/test/functional/interface_rest.py index 437111a4d7..9006e27cbe 100755 --- a/test/functional/rest.py +++ b/test/functional/interface_rest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the REST API.""" diff --git a/test/functional/zmq_test.py b/test/functional/interface_zmq.py index fa30318416..86ccea4394 100755 --- a/test/functional/zmq_test.py +++ b/test/functional/interface_zmq.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the ZMQ notification interface.""" diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py index e24dc5a464..e7ce3820d2 100755 --- a/test/functional/mempool_limit.py +++ b/test/functional/mempool_limit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test mempool limiting together/eviction with the wallet.""" @@ -17,10 +17,14 @@ class MempoolLimitTest(BitcoinTestFramework): txouts = gen_return_txouts() relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + self.log.info('Check that mempoolminfee is minrelytxfee') + assert_equal(self.nodes[0].getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) + assert_equal(self.nodes[0].getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + txids = [] utxos = create_confirmed_utxos(relayfee, self.nodes[0], 91) - #create a mempool tx that will be evicted + self.log.info('Create a mempool tx that will be evicted') us0 = utxos.pop() inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] outputs = {self.nodes[0].getnewaddress() : 0.0001} @@ -37,10 +41,14 @@ class MempoolLimitTest(BitcoinTestFramework): txids.append([]) txids[i] = create_lots_of_big_transactions(self.nodes[0], txouts, utxos[30*i:30*i+30], 30, (i+1)*base_fee) - # by now, the tx should be evicted, check confirmation state + self.log.info('The tx should be evicted by now') assert(txid not in self.nodes[0].getrawmempool()) txdata = self.nodes[0].gettransaction(txid) assert(txdata['confirmations'] == 0) #confirmation should still be 0 + self.log.info('Check that mempoolminfee is larger than minrelytxfee') + assert_equal(self.nodes[0].getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) + assert_greater_than(self.nodes[0].getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) + if __name__ == '__main__': MempoolLimitTest().main() diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py index b845c75681..a3e872a8c6 100755 --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test descendant package tracking code.""" diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py index 31a96ec60e..17f0967219 100755 --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -66,16 +66,17 @@ class MempoolPersistTest(BitcoinTestFramework): self.log.debug("Stop-start the nodes. Verify that node0 has the transactions in its mempool and node1 does not. Verify that node2 calculates its balance correctly after loading wallet transactions.") self.stop_nodes() + self.start_node(1) # Give this one a head-start, so we can be "extra-sure" that it didn't load anything later self.start_node(0) - self.start_node(1) self.start_node(2) # Give bitcoind a second to reload the mempool - time.sleep(1) - wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5) - wait_until(lambda: len(self.nodes[2].getrawmempool()) == 5) + wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5, timeout=1) + wait_until(lambda: len(self.nodes[2].getrawmempool()) == 5, timeout=1) + # The others have loaded their mempool. If node_1 loaded anything, we'd probably notice by now: assert_equal(len(self.nodes[1].getrawmempool()), 0) # Verify accounting of mempool transactions after restart is correct + self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet assert_equal(node2_balance, self.nodes[2].getbalance()) self.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.") diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py index 2803371f5b..d6bb292a58 100755 --- a/test/functional/mempool_reorg.py +++ b/test/functional/mempool_reorg.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test mempool re-org scenarios. diff --git a/test/functional/mempool_resurrect_test.py b/test/functional/mempool_resurrect.py index 1263c9306b..83e84da4bc 100755 --- a/test/functional/mempool_resurrect_test.py +++ b/test/functional/mempool_resurrect.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test resurrection of mined transactions when the blockchain is re-organized.""" diff --git a/test/functional/mempool_spendcoinbase.py b/test/functional/mempool_spend_coinbase.py index 6e8a635a76..db0738c08a 100755 --- a/test/functional/mempool_spendcoinbase.py +++ b/test/functional/mempool_spend_coinbase.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test spending coinbase transactions. diff --git a/test/functional/mining.py b/test/functional/mining_basic.py index 9aee06864e..569bf71933 100755 --- a/test/functional/mining.py +++ b/test/functional/mining_basic.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test mining RPCs diff --git a/test/functional/getblocktemplate_longpoll.py b/test/functional/mining_getblocktemplate_longpoll.py index 89768bd2fb..252ff4dbff 100755 --- a/test/functional/getblocktemplate_longpoll.py +++ b/test/functional/mining_getblocktemplate_longpoll.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test longpolling with getblocktemplate.""" diff --git a/test/functional/prioritise_transaction.py b/test/functional/mining_prioritisetransaction.py index bb56db9b40..57954ce321 100755 --- a/test/functional/prioritise_transaction.py +++ b/test/functional/mining_prioritisetransaction.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the prioritisetransaction mining RPC.""" @@ -15,6 +15,25 @@ class PrioritiseTransactionTest(BitcoinTestFramework): self.extra_args = [["-printpriority=1"], ["-printpriority=1"]] def run_test(self): + # Test `prioritisetransaction` required parameters + assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction) + assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '') + assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '', 0) + + # Test `prioritisetransaction` invalid extra parameters + assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '', 0, 0, 0) + + # Test `prioritisetransaction` invalid `txid` + assert_raises_rpc_error(-1, "txid must be hexadecimal string", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0) + + # Test `prioritisetransaction` invalid `dummy` + txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000' + assert_raises_rpc_error(-1, "JSON value is not a number as expected", self.nodes[0].prioritisetransaction, txid, 'foo', 0) + assert_raises_rpc_error(-8, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.", self.nodes[0].prioritisetransaction, txid, 1, 0) + + # Test `prioritisetransaction` invalid `fee_delta` + assert_raises_rpc_error(-1, "JSON value is not an integer as expected", self.nodes[0].prioritisetransaction, txid=txid, fee_delta='foo') + self.txouts = gen_return_txouts() self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] diff --git a/test/functional/p2p-versionbits-warning.py b/test/functional/p2p-versionbits-warning.py deleted file mode 100755 index d29d43ebed..0000000000 --- a/test/functional/p2p-versionbits-warning.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test version bits warning system. - -Generate chains with block versions that appear to be signalling unknown -soft-forks, and test that warning alerts are generated. -""" - -from test_framework.mininode import * -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import re -from test_framework.blocktools import create_block, create_coinbase - -VB_PERIOD = 144 # versionbits period length for regtest -VB_THRESHOLD = 108 # versionbits activation threshold for regtest -VB_TOP_BITS = 0x20000000 -VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment - -WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect" -WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT) -VB_PATTERN = re.compile("^Warning.*versionbit") - -class TestNode(P2PInterface): - def on_inv(self, message): - pass - -class VersionBitsWarningTest(BitcoinTestFramework): - def set_test_params(self): - self.setup_clean_chain = True - self.num_nodes = 1 - - def setup_network(self): - self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - # Open and close to create zero-length file - with open(self.alert_filename, 'w', encoding='utf8') as _: - pass - self.extra_args = [["-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] - self.setup_nodes() - - # Send numblocks blocks via peer with nVersionToUse set. - def send_blocks_with_version(self, peer, numblocks, nVersionToUse): - tip = self.nodes[0].getbestblockhash() - height = self.nodes[0].getblockcount() - block_time = self.nodes[0].getblockheader(tip)["time"]+1 - tip = int(tip, 16) - - for _ in range(numblocks): - block = create_block(tip, create_coinbase(height+1), block_time) - block.nVersion = nVersionToUse - block.solve() - peer.send_message(msg_block(block)) - block_time += 1 - height += 1 - tip = block.sha256 - peer.sync_with_ping() - - def test_versionbits_in_alert_file(self): - with open(self.alert_filename, 'r', encoding='utf8') as f: - alert_text = f.read() - assert(VB_PATTERN.match(alert_text)) - - def run_test(self): - # Setup the p2p connection and start up the network thread. - self.nodes[0].add_p2p_connection(TestNode()) - - network_thread_start() - - # Test logic begins here - self.nodes[0].p2p.wait_for_verack() - - # 1. Have the node mine one period worth of blocks - self.nodes[0].generate(VB_PERIOD) - - # 2. Now build one period of blocks on the tip, with < VB_THRESHOLD - # blocks signaling some unknown bit. - nVersion = VB_TOP_BITS | (1<<VB_UNKNOWN_BIT) - self.send_blocks_with_version(self.nodes[0].p2p, VB_THRESHOLD-1, nVersion) - - # Fill rest of period with regular version blocks - self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) - # Check that we're not getting any versionbit-related errors in - # get*info() - assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["warnings"])) - assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"])) - - # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling - # some unknown bit - self.send_blocks_with_version(self.nodes[0].p2p, VB_THRESHOLD, nVersion) - self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD) - # Might not get a versionbits-related alert yet, as we should - # have gotten a different alert due to more than 51/100 blocks - # being of unexpected version. - # Check that get*info() shows some kind of error. - assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["warnings"]) - assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"]) - - # Mine a period worth of expected blocks so the generic block-version warning - # is cleared, and restart the node. This should move the versionbit state - # to ACTIVE. - self.nodes[0].generate(VB_PERIOD) - self.stop_nodes() - # Empty out the alert file - with open(self.alert_filename, 'w', encoding='utf8') as _: - pass - self.start_nodes() - - # Connecting one block should be enough to generate an error. - self.nodes[0].generate(1) - assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["warnings"]) - assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) - self.stop_nodes() - self.test_versionbits_in_alert_file() - - # Test framework expects the node to still be running... - self.start_nodes() - -if __name__ == '__main__': - VersionBitsWarningTest().main() diff --git a/test/functional/p2p-compactblocks.py b/test/functional/p2p_compactblocks.py index 1e763df2a4..d9f461a049 100755 --- a/test/functional/p2p-compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test compact blocks (BIP 152). @@ -95,7 +95,7 @@ class CompactBlocksTest(BitcoinTestFramework): self.num_nodes = 2 # This test was written assuming SegWit is activated using BIP9 at height 432 (3x confirmation window). # TODO: Rewrite this test to support SegWit being always active. - self.extra_args = [["-vbparams=segwit:0:0"], ["-vbparams=segwit:0:999999999999", "-txindex"]] + self.extra_args = [["-vbparams=segwit:0:0"], ["-vbparams=segwit:0:999999999999", "-txindex", "-deprecatedrpc=addwitnessaddress"]] self.utxos = [] def build_block_on_tip(self, node, segwit=False): diff --git a/test/functional/disconnect_ban.py b/test/functional/p2p_disconnect_ban.py index 59655d37fb..c6067befb2 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/p2p_disconnect_ban.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node disconnect and ban behavior""" diff --git a/test/functional/p2p-feefilter.py b/test/functional/p2p_feefilter.py index ff4bed0efd..47d9c55160 100755 --- a/test/functional/p2p-feefilter.py +++ b/test/functional/p2p_feefilter.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test processing of feefilter messages.""" diff --git a/test/functional/p2p-fingerprint.py b/test/functional/p2p_fingerprint.py index 93ef73e25e..93ef73e25e 100755 --- a/test/functional/p2p-fingerprint.py +++ b/test/functional/p2p_fingerprint.py diff --git a/test/functional/invalidblockrequest.py b/test/functional/p2p_invalid_block.py index a89d1d8ef2..edcade63c1 100755 --- a/test/functional/invalidblockrequest.py +++ b/test/functional/p2p_invalid_block.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node responses to invalid blocks. diff --git a/test/functional/invalidtxrequest.py b/test/functional/p2p_invalid_tx.py index c60b0fce16..9c1100e070 100755 --- a/test/functional/invalidtxrequest.py +++ b/test/functional/p2p_invalid_tx.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node responses to invalid transactions. diff --git a/test/functional/p2p-leaktests.py b/test/functional/p2p_leak.py index ce4e6e9144..ce4e6e9144 100755 --- a/test/functional/p2p-leaktests.py +++ b/test/functional/p2p_leak.py diff --git a/test/functional/p2p-mempool.py b/test/functional/p2p_mempool.py index 168f9f685a..485a8af3d0 100755 --- a/test/functional/p2p-mempool.py +++ b/test/functional/p2p_mempool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test p2p mempool message. diff --git a/test/functional/node_network_limited.py b/test/functional/p2p_node_network_limited.py index 70415e0168..70415e0168 100755 --- a/test/functional/node_network_limited.py +++ b/test/functional/p2p_node_network_limited.py diff --git a/test/functional/p2p-segwit.py b/test/functional/p2p_segwit.py index a06601c38e..20e4805df0 100755 --- a/test/functional/p2p-segwit.py +++ b/test/functional/p2p_segwit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test segwit transactions and blocks on P2P network.""" @@ -25,7 +25,7 @@ MAX_SIGOP_COST = 80000 # Calculate the virtual size of a witness block: # (base + witness/4) def get_virtual_size(witness_block): - base_size = len(witness_block.serialize()) + base_size = len(witness_block.serialize(with_witness=False)) total_size = len(witness_block.serialize(with_witness=True)) # the "+3" is so we round up vsize = int((3*base_size + total_size + 3)/4) @@ -1396,18 +1396,20 @@ class SegWitTest(BitcoinTestFramework): temp_utxos.pop(0) - # Update self.utxos for later tests. Just spend everything in - # temp_utxos to a corresponding entry in self.utxos + # Update self.utxos for later tests by creating two outputs + # that consolidate all the coins in temp_utxos. + output_value = sum(i.nValue for i in temp_utxos) // 2 + tx = CTransaction() index = 0 + # Just spend to our usual anyone-can-spend output + tx.vout = [CTxOut(output_value, CScript([OP_TRUE]))] * 2 for i in temp_utxos: - # Just spend to our usual anyone-can-spend output - # Use SIGHASH_SINGLE|SIGHASH_ANYONECANPAY so we can build up + # Use SIGHASH_ALL|SIGHASH_ANYONECANPAY so we can build up # the signatures as we go. tx.vin.append(CTxIn(COutPoint(i.sha256, i.n), b"")) - tx.vout.append(CTxOut(i.nValue, CScript([OP_TRUE]))) tx.wit.vtxinwit.append(CTxInWitness()) - sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, i.nValue, key) + sign_P2PK_witness_input(witness_program, tx, index, SIGHASH_ALL|SIGHASH_ANYONECANPAY, i.nValue, key) index += 1 block = self.build_next_block() self.update_witness_block_with_transactions(block, [tx]) diff --git a/test/functional/sendheaders.py b/test/functional/p2p_sendheaders.py index 256227f721..8869aeaaea 100755 --- a/test/functional/sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test behavior of headers messages to announce blocks. diff --git a/test/functional/p2p-timeouts.py b/test/functional/p2p_timeouts.py index 984a3c8b90..6d21095cc6 100755 --- a/test/functional/p2p-timeouts.py +++ b/test/functional/p2p_timeouts.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test various net timeouts. diff --git a/test/functional/p2p-acceptblock.py b/test/functional/p2p_unrequested_blocks.py index bb204322ed..672626f15b 100755 --- a/test/functional/p2p-acceptblock.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test processing of unrequested blocks. diff --git a/test/functional/rpcbind_test.py b/test/functional/rpc_bind.py index 0e8c3fa209..05433c7e24 100755 --- a/test/functional/rpcbind_test.py +++ b/test/functional/rpc_bind.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test running bitcoind with the -rpcbind and -rpcallowip options.""" diff --git a/test/functional/blockchain.py b/test/functional/rpc_blockchain.py index 49fafbc9aa..11acff4be1 100755 --- a/test/functional/blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test RPCs related to blockchainstate. diff --git a/test/functional/decodescript.py b/test/functional/rpc_decodescript.py index 6611da8831..1ffc570437 100755 --- a/test/functional/decodescript.py +++ b/test/functional/rpc_decodescript.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test decoding scripts via decodescript RPC command.""" diff --git a/test/functional/deprecated_rpc.py b/test/functional/rpc_deprecated.py index 19fd24edb9..d6f25158ef 100755 --- a/test/functional/deprecated_rpc.py +++ b/test/functional/rpc_deprecated.py @@ -10,7 +10,7 @@ class DeprecatedRpcTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [[], ["-deprecatedrpc=estimatefee"]] + self.extra_args = [[], ["-deprecatedrpc=estimatefee", "-deprecatedrpc=createmultisig"]] def run_test(self): self.log.info("estimatefee: Shows deprecated message") @@ -19,5 +19,9 @@ class DeprecatedRpcTest(BitcoinTestFramework): self.log.info("Using -deprecatedrpc=estimatefee bypasses the error") self.nodes[1].estimatefee(1) + self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") + assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) + self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + if __name__ == '__main__': DeprecatedRpcTest().main() diff --git a/test/functional/fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index d446f56d0e..5f7a0586e0 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the fundrawtransaction RPC.""" @@ -212,6 +212,19 @@ class RawTransactionsTest(BitcoinTestFramework): out = dec_tx['vout'][0] assert_equal(change, out['scriptPubKey']['addresses'][0]) + ######################################################### + # test a fundrawtransaction with a provided change type # + ######################################################### + utx = get_unspent(self.nodes[2].listunspent(), 5) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] + outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[2].fundrawtransaction, rawtx, {'change_type': None}) + assert_raises_rpc_error(-5, "Unknown change type", self.nodes[2].fundrawtransaction, rawtx, {'change_type': ''}) + rawtx = self.nodes[2].fundrawtransaction(rawtx, {'change_type': 'bech32'}) + tx = self.nodes[2].decoderawtransaction(rawtx['hex']) + assert_equal('witness_v0_keyhash', tx['vout'][rawtx['changepos']]['scriptPubKey']['type']) ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # @@ -358,7 +371,7 @@ class RawTransactionsTest(BitcoinTestFramework): addr1Obj = self.nodes[1].validateaddress(addr1) addr2Obj = self.nodes[1].validateaddress(addr2) - mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] inputs = [] outputs = {mSigObj:1.1} @@ -391,7 +404,7 @@ class RawTransactionsTest(BitcoinTestFramework): addr4Obj = self.nodes[1].validateaddress(addr4) addr5Obj = self.nodes[1].validateaddress(addr5) - mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']]) + mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])['address'] inputs = [] outputs = {mSigObj:1.1} @@ -418,7 +431,7 @@ class RawTransactionsTest(BitcoinTestFramework): addr1Obj = self.nodes[2].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] # send 1.2 BTC to msig addr diff --git a/test/functional/getchaintips.py b/test/functional/rpc_getchaintips.py index 21b67bfc64..277930bb1a 100755 --- a/test/functional/getchaintips.py +++ b/test/functional/rpc_getchaintips.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the getchaintips RPC. diff --git a/test/functional/invalidateblock.py b/test/functional/rpc_invalidateblock.py index dd3daf1e07..b037c2431d 100755 --- a/test/functional/invalidateblock.py +++ b/test/functional/rpc_invalidateblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the invalidateblock RPC.""" diff --git a/test/functional/listtransactions.py b/test/functional/rpc_listtransactions.py index e4522cc3b5..ba71ac0967 100755 --- a/test/functional/listtransactions.py +++ b/test/functional/rpc_listtransactions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the listtransactions API.""" @@ -81,7 +81,8 @@ class ListTransactionsTest(BitcoinTestFramework): {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : "toself"} ) - multisig = self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + pubkey = self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['pubkey'] + multisig = self.nodes[1].createmultisig(1, [pubkey]) self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True) txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1) self.nodes[1].generate(1) diff --git a/test/functional/rpcnamedargs.py b/test/functional/rpc_named_arguments.py index c47212bddb..97bee39614 100755 --- a/test/functional/rpcnamedargs.py +++ b/test/functional/rpc_named_arguments.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test using named arguments for RPCs.""" diff --git a/test/functional/net.py b/test/functional/rpc_net.py index 16e4f6adb4..16e4f6adb4 100755 --- a/test/functional/net.py +++ b/test/functional/rpc_net.py diff --git a/test/functional/preciousblock.py b/test/functional/rpc_preciousblock.py index 1466f901c0..960cd0ad12 100755 --- a/test/functional/preciousblock.py +++ b/test/functional/rpc_preciousblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the preciousblock RPC.""" diff --git a/test/functional/rawtransactions.py b/test/functional/rpc_rawtransaction.py index aa519eb8e8..d39d86b310 100755 --- a/test/functional/rawtransactions.py +++ b/test/functional/rpc_rawtransaction.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the rawtransaction RPCs. @@ -39,6 +39,7 @@ class RawTransactionsTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 3 + self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"], ["-addresstype=legacy"]] def setup_network(self, split=False): super().setup_network() @@ -144,7 +145,12 @@ class RawTransactionsTest(BitcoinTestFramework): addr1Obj = self.nodes[2].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + # Tests for createmultisig and addmultisigaddress + assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"]) + self.nodes[0].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # createmultisig can only take public keys + assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here. + + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr1])['address'] #use balance deltas instead of absolute values bal = self.nodes[2].getbalance() @@ -167,7 +173,7 @@ class RawTransactionsTest(BitcoinTestFramework): addr2Obj = self.nodes[2].validateaddress(addr2) addr3Obj = self.nodes[2].validateaddress(addr3) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address'] txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) decTx = self.nodes[0].gettransaction(txId) @@ -189,7 +195,7 @@ class RawTransactionsTest(BitcoinTestFramework): break bal = self.nodes[0].getbalance() - inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}] + inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}] outputs = { self.nodes[0].getnewaddress() : 2.19 } rawTx = self.nodes[2].createrawtransaction(inputs, outputs) rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs) @@ -212,8 +218,8 @@ class RawTransactionsTest(BitcoinTestFramework): addr1Obj = self.nodes[1].validateaddress(addr1) addr2Obj = self.nodes[2].validateaddress(addr2) - self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) - mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address'] mSigObjValid = self.nodes[2].validateaddress(mSigObj) txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) @@ -234,7 +240,7 @@ class RawTransactionsTest(BitcoinTestFramework): break bal = self.nodes[0].getbalance() - inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex']}] + inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}] outputs = { self.nodes[0].getnewaddress() : 2.19 } rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs) rawTxPartialSigned1 = self.nodes[1].signrawtransaction(rawTx2, inputs) diff --git a/test/functional/signmessages.py b/test/functional/rpc_signmessage.py index 52ba6a5ad7..5b6935ceea 100755 --- a/test/functional/signmessages.py +++ b/test/functional/rpc_signmessage.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test RPC commands for signing and verifying messages.""" @@ -11,6 +11,7 @@ class SignMessagesTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 1 + self.extra_args = [["-addresstype=legacy"]] def run_test(self): message = 'This is just a test message' diff --git a/test/functional/signrawtransactions.py b/test/functional/rpc_signrawtransaction.py index 9a45d53cb8..dd0fa6c02c 100755 --- a/test/functional/signrawtransactions.py +++ b/test/functional/rpc_signrawtransaction.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test transaction signing using the signrawtransaction RPC.""" diff --git a/test/functional/merkle_blocks.py b/test/functional/rpc_txoutproof.py index b3989a4c54..50e0371fdf 100755 --- a/test/functional/merkle_blocks.py +++ b/test/functional/rpc_txoutproof.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test gettxoutproof and verifytxoutproof RPCs.""" diff --git a/test/functional/uptime.py b/test/functional/rpc_uptime.py index 78236b2393..78236b2393 100755 --- a/test/functional/uptime.py +++ b/test/functional/rpc_uptime.py diff --git a/test/functional/multi_rpc.py b/test/functional/rpc_users.py index a2b346f274..01f68344ae 100755 --- a/test/functional/multi_rpc.py +++ b/test/functional/rpc_users.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test multiple RPC users.""" diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py index 2e2db5ffb2..b076c9dd43 100644 --- a/test/functional/test_framework/address.py +++ b/test/functional/test_framework/address.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Encode and decode BASE58, P2PKH and P2SH addresses.""" diff --git a/test/functional/test_framework/blockstore.py b/test/functional/test_framework/blockstore.py index 051c57a6c7..6067a407cc 100644 --- a/test/functional/test_framework/blockstore.py +++ b/test/functional/test_framework/blockstore.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """BlockStore and TxStore helper classes.""" diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index 5dcf516dc6..642ef98a27 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -1,11 +1,27 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Utilities for manipulating blocks and transactions.""" +from .address import ( + key_to_p2sh_p2wpkh, + key_to_p2wpkh, + script_to_p2sh_p2wsh, + script_to_p2wsh, +) from .mininode import * -from .script import CScript, OP_TRUE, OP_CHECKSIG, OP_RETURN +from .script import ( + CScript, + OP_0, + OP_1, + OP_CHECKMULTISIG, + OP_CHECKSIG, + OP_RETURN, + OP_TRUE, + hash160, +) +from .util import assert_equal # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): @@ -108,3 +124,49 @@ def get_legacy_sigopcount_tx(tx, fAccurate=True): # scriptSig might be of type bytes, so convert to CScript for the moment count += CScript(j.scriptSig).GetSigOpCount(fAccurate) return count + +# Create a scriptPubKey corresponding to either a P2WPKH output for the +# given pubkey, or a P2WSH output of a 1-of-1 multisig for the given +# pubkey. Returns the hex encoding of the scriptPubKey. +def witness_script(use_p2wsh, pubkey): + if (use_p2wsh == False): + # P2WPKH instead + pubkeyhash = hash160(hex_str_to_bytes(pubkey)) + pkscript = CScript([OP_0, pubkeyhash]) + else: + # 1-of-1 multisig + witness_program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG]) + scripthash = sha256(witness_program) + pkscript = CScript([OP_0, scripthash]) + return bytes_to_hex_str(pkscript) + +# Return a transaction (in hex) that spends the given utxo to a segwit output, +# optionally wrapping the segwit output using P2SH. +def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount): + if use_p2wsh: + program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG]) + addr = script_to_p2sh_p2wsh(program) if encode_p2sh else script_to_p2wsh(program) + else: + addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey) + if not encode_p2sh: + assert_equal(node.validateaddress(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey)) + return node.createrawtransaction([utxo], {addr: amount}) + +# Create a transaction spending a given utxo to a segwit output corresponding +# to the given pubkey: use_p2wsh determines whether to use P2WPKH or P2WSH; +# encode_p2sh determines whether to wrap in P2SH. +# sign=True will have the given node sign the transaction. +# insert_redeem_script will be added to the scriptSig, if given. +def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""): + tx_to_witness = create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount) + if (sign): + signed = node.signrawtransaction(tx_to_witness) + assert("errors" not in signed or len(["errors"]) == 0) + return node.sendrawtransaction(signed["hex"]) + else: + if (insert_redeem_script): + tx = FromHex(CTransaction(), tx_to_witness) + tx.vin[0].scriptSig += CScript([hex_str_to_bytes(insert_redeem_script)]) + tx_to_witness = ToHex(tx) + + return node.sendrawtransaction(tx_to_witness) diff --git a/test/functional/test_framework/comptool.py b/test/functional/test_framework/comptool.py index f0f5c847ca..61ea2280e2 100755 --- a/test/functional/test_framework/comptool.py +++ b/test/functional/test_framework/comptool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Compare two or more bitcoinds to each other. diff --git a/test/functional/test_framework/coverage.py b/test/functional/test_framework/coverage.py index ddc3c515b2..f8761f2bb3 100644 --- a/test/functional/test_framework/coverage.py +++ b/test/functional/test_framework/coverage.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Utilities for doing coverage analysis on the RPC interface. diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index d8032e4430..a54a0299c7 100644 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -453,10 +453,10 @@ class CTransaction(): r += struct.pack("<I", self.nLockTime) return r - # Regular serialization is without witness -- must explicitly - # call serialize_with_witness to include witness data. + # Regular serialization is with witness -- must explicitly + # call serialize_without_witness to exclude witness data. def serialize(self): - return self.serialize_without_witness() + return self.serialize_with_witness() # Recalculate the txid (transaction hash without witness) def rehash(self): @@ -472,7 +472,7 @@ class CTransaction(): if self.sha256 is None: self.sha256 = uint256_from_str(hash256(self.serialize_without_witness())) - self.hash = encode(hash256(self.serialize())[::-1], 'hex_codec').decode('ascii') + self.hash = encode(hash256(self.serialize_without_witness())[::-1], 'hex_codec').decode('ascii') def is_valid(self): self.calc_sha256() @@ -569,7 +569,7 @@ class CBlock(CBlockHeader): if with_witness: r += ser_vector(self.vtx, "serialize_with_witness") else: - r += ser_vector(self.vtx) + r += ser_vector(self.vtx, "serialize_without_witness") return r # Calculate the merkle root given a vector of transaction hashes @@ -636,7 +636,7 @@ class PrefilledTransaction(): self.tx = CTransaction() self.tx.deserialize(f) - def serialize(self, with_witness=False): + def serialize(self, with_witness=True): r = b"" r += ser_compact_size(self.index) if with_witness: @@ -645,6 +645,9 @@ class PrefilledTransaction(): r += self.tx.serialize_without_witness() return r + def serialize_without_witness(self): + return self.serialize(with_witness=False) + def serialize_with_witness(self): return self.serialize(with_witness=True) @@ -684,7 +687,7 @@ class P2PHeaderAndShortIDs(): if with_witness: r += ser_vector(self.prefilled_txn, "serialize_with_witness") else: - r += ser_vector(self.prefilled_txn) + r += ser_vector(self.prefilled_txn, "serialize_without_witness") return r def __repr__(self): @@ -815,13 +818,13 @@ class BlockTransactions(): self.blockhash = deser_uint256(f) self.transactions = deser_vector(f, CTransaction) - def serialize(self, with_witness=False): + def serialize(self, with_witness=True): r = b"" r += ser_uint256(self.blockhash) if with_witness: r += ser_vector(self.transactions, "serialize_with_witness") else: - r += ser_vector(self.transactions) + r += ser_vector(self.transactions, "serialize_without_witness") return r def __repr__(self): @@ -1021,7 +1024,7 @@ class msg_block(): self.block.deserialize(f) def serialize(self): - return self.block.serialize() + return self.block.serialize(with_witness=False) def __repr__(self): return "msg_block(block=%s)" % (repr(self.block)) @@ -1292,7 +1295,7 @@ class msg_blocktxn(): def serialize(self): r = b"" - r += self.block_transactions.serialize() + r += self.block_transactions.serialize(with_witness=False) return r def __repr__(self): diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py index 724d418099..fe14591139 100755 --- a/test/functional/test_framework/mininode.py +++ b/test/functional/test_framework/mininode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # Copyright (c) 2010 ArtForz -- public domain half-a-node # Copyright (c) 2012 Jeff Garzik -# Copyright (c) 2010-2016 The Bitcoin Core developers +# Copyright (c) 2010-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Bitcoin P2P network half-a-node. diff --git a/test/functional/test_framework/netutil.py b/test/functional/test_framework/netutil.py index e5d415788f..96fe283347 100644 --- a/test/functional/test_framework/netutil.py +++ b/test/functional/test_framework/netutil.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Linux network utilities. diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py index a4c046bd3d..dae8a4e569 100644 --- a/test/functional/test_framework/script.py +++ b/test/functional/test_framework/script.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Functionality to build scripts, as well as SignatureHash(). @@ -641,7 +641,7 @@ def SignatureHash(script, txTo, inIdx, hashtype): txtmp.vin = [] txtmp.vin.append(tmp) - s = txtmp.serialize() + s = txtmp.serialize_without_witness() s += struct.pack(b"<I", hashtype) hash = hash256(s) diff --git a/test/functional/test_framework/siphash.py b/test/functional/test_framework/siphash.py index f68ecad36b..6ffc982cea 100644 --- a/test/functional/test_framework/siphash.py +++ b/test/functional/test_framework/siphash.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Specialized SipHash-2-4 implementations. diff --git a/test/functional/test_framework/socks5.py b/test/functional/test_framework/socks5.py index 7b40c47fbf..4721809a3b 100644 --- a/test/functional/test_framework/socks5.py +++ b/test/functional/test_framework/socks5.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Dummy Socks5 server for testing.""" diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index a46312d62c..f8d66def64 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Base class for RPC testing.""" @@ -62,6 +62,7 @@ class BitcoinTestFramework(): self.setup_clean_chain = False self.nodes = [] self.mocktime = 0 + self.supports_cli = False self.set_test_params() assert hasattr(self, "num_nodes"), "Test must set self.num_nodes in set_test_params()" @@ -91,6 +92,8 @@ class BitcoinTestFramework(): help="Location of the test framework config file") parser.add_option("--pdbonfailure", dest="pdbonfailure", default=False, action="store_true", help="Attach a python debugger if test fails") + parser.add_option("--usecli", dest="usecli", default=False, action="store_true", + help="use bitcoin-cli instead of RPC for all commands") self.add_options(parser) (self.options, self.args) = parser.parse_args() @@ -113,6 +116,8 @@ class BitcoinTestFramework(): success = TestStatus.FAILED try: + if self.options.usecli and not self.supports_cli: + raise SkipTest("--usecli specified but test does not support using CLI") self.setup_chain() self.setup_network() self.run_test() @@ -213,20 +218,20 @@ class BitcoinTestFramework(): assert_equal(len(extra_args), num_nodes) assert_equal(len(binary), num_nodes) for i in range(num_nodes): - self.nodes.append(TestNode(i, self.options.tmpdir, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir)) + self.nodes.append(TestNode(i, self.options.tmpdir, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, use_cli=self.options.usecli)) - def start_node(self, i, extra_args=None, stderr=None): + def start_node(self, i, *args, **kwargs): """Start a bitcoind""" node = self.nodes[i] - node.start(extra_args, stderr) + node.start(*args, **kwargs) node.wait_for_rpc_connection() if self.options.coveragedir is not None: coverage.write_all_rpc_commands(self.options.coveragedir, node.rpc) - def start_nodes(self, extra_args=None): + def start_nodes(self, extra_args=None, *args, **kwargs): """Start multiple bitcoinds""" if extra_args is None: @@ -234,7 +239,7 @@ class BitcoinTestFramework(): assert_equal(len(extra_args), self.num_nodes) try: for i, node in enumerate(self.nodes): - node.start(extra_args[i]) + node.start(extra_args[i], *args, **kwargs) for node in self.nodes: node.wait_for_rpc_connection() except: @@ -266,10 +271,10 @@ class BitcoinTestFramework(): self.stop_node(i) self.start_node(i, extra_args) - def assert_start_raises_init_error(self, i, extra_args=None, expected_msg=None): + def assert_start_raises_init_error(self, i, extra_args=None, expected_msg=None, *args, **kwargs): with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: try: - self.start_node(i, extra_args, stderr=log_stderr) + self.start_node(i, extra_args, stderr=log_stderr, *args, **kwargs) self.stop_node(i) except Exception as e: assert 'bitcoind exited' in str(e) # node must have shutdown diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index a9248c764e..1054e6d028 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -10,6 +10,7 @@ import http.client import json import logging import os +import re import subprocess import time @@ -22,6 +23,9 @@ from .util import ( p2p_port, ) +# For Python 3.4 compatibility +JSONDecodeError = getattr(json, "JSONDecodeError", ValueError) + BITCOIND_PROC_WAIT_TIMEOUT = 60 class TestNode(): @@ -38,7 +42,7 @@ class TestNode(): To make things easier for the test writer, any unrecognised messages will be dispatched to the RPC connection.""" - def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir): + def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir, use_cli=False): self.index = i self.datadir = os.path.join(dirname, "node" + str(i)) self.rpchost = rpchost @@ -58,6 +62,7 @@ class TestNode(): self.args = [self.binary, "-datadir=" + self.datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i] self.cli = TestNodeCLI(os.getenv("BITCOINCLI", "bitcoin-cli"), self.datadir) + self.use_cli = use_cli self.running = False self.process = None @@ -69,17 +74,20 @@ class TestNode(): self.p2ps = [] def __getattr__(self, name): - """Dispatches any unrecognised messages to the RPC connection.""" - assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection" - return getattr(self.rpc, name) + """Dispatches any unrecognised messages to the RPC connection or a CLI instance.""" + if self.use_cli: + return getattr(self.cli, name) + else: + assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection" + return getattr(self.rpc, name) - def start(self, extra_args=None, stderr=None): + def start(self, extra_args=None, stderr=None, *args, **kwargs): """Start the node.""" if extra_args is None: extra_args = self.extra_args if stderr is None: stderr = self.stderr - self.process = subprocess.Popen(self.args + extra_args, stderr=stderr) + self.process = subprocess.Popen(self.args + extra_args, stderr=stderr, *args, **kwargs) self.running = True self.log.debug("bitcoind started, waiting for RPC to come up") @@ -110,10 +118,13 @@ class TestNode(): raise AssertionError("Unable to connect to bitcoind") def get_wallet_rpc(self, wallet_name): - assert self.rpc_connected - assert self.rpc - wallet_path = "wallet/%s" % wallet_name - return self.rpc / wallet_path + if self.use_cli: + return self.cli("-rpcwallet={}".format(wallet_name)) + else: + assert self.rpc_connected + assert self.rpc + wallet_path = "wallet/%s" % wallet_name + return self.rpc / wallet_path def stop_node(self): """Stop the node.""" @@ -187,41 +198,70 @@ class TestNode(): p.peer_disconnect() del self.p2ps[:] +class TestNodeCLIAttr: + def __init__(self, cli, command): + self.cli = cli + self.command = command + + def __call__(self, *args, **kwargs): + return self.cli.send_cli(self.command, *args, **kwargs) + + def get_request(self, *args, **kwargs): + return lambda: self(*args, **kwargs) class TestNodeCLI(): """Interface to bitcoin-cli for an individual node""" def __init__(self, binary, datadir): - self.args = [] + self.options = [] self.binary = binary self.datadir = datadir self.input = None + self.log = logging.getLogger('TestFramework.bitcoincli') - def __call__(self, *args, input=None): - # TestNodeCLI is callable with bitcoin-cli command-line args - self.args = [str(arg) for arg in args] - self.input = input - return self + def __call__(self, *options, input=None): + # TestNodeCLI is callable with bitcoin-cli command-line options + cli = TestNodeCLI(self.binary, self.datadir) + cli.options = [str(o) for o in options] + cli.input = input + return cli def __getattr__(self, command): - def dispatcher(*args, **kwargs): - return self.send_cli(command, *args, **kwargs) - return dispatcher - - def send_cli(self, command, *args, **kwargs): + return TestNodeCLIAttr(self, command) + + def batch(self, requests): + results = [] + for request in requests: + try: + results.append(dict(result=request())) + except JSONRPCException as e: + results.append(dict(error=e)) + return results + + def send_cli(self, command=None, *args, **kwargs): """Run bitcoin-cli command. Deserializes returned string as python object.""" pos_args = [str(arg) for arg in args] named_args = [str(key) + "=" + str(value) for (key, value) in kwargs.items()] assert not (pos_args and named_args), "Cannot use positional arguments and named arguments in the same bitcoin-cli call" - p_args = [self.binary, "-datadir=" + self.datadir] + self.args + p_args = [self.binary, "-datadir=" + self.datadir] + self.options if named_args: p_args += ["-named"] - p_args += [command] + pos_args + named_args + if command is not None: + p_args += [command] + p_args += pos_args + named_args + self.log.debug("Running bitcoin-cli command: %s" % command) process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) cli_stdout, cli_stderr = process.communicate(input=self.input) returncode = process.poll() if returncode: + match = re.match(r'error code: ([-0-9]+)\nerror message:\n(.*)', cli_stderr) + if match: + code, message = match.groups() + raise JSONRPCException(dict(code=int(code), message=message)) # Ignore cli_stdout, raise with cli_stderr raise subprocess.CalledProcessError(returncode, self.binary, output=cli_stderr) - return json.loads(cli_stdout, parse_float=decimal.Decimal) + try: + return json.loads(cli_stdout, parse_float=decimal.Decimal) + except JSONDecodeError: + return cli_stdout.rstrip("\n") diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 102c903018..7fdc171332 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Helpful routines for regression testing.""" @@ -390,7 +390,7 @@ def sync_chain(rpc_connections, *, wait=1, timeout=60): timeout -= wait raise AssertionError("Chain sync failed: Best block hashes don't match") -def sync_mempools(rpc_connections, *, wait=1, timeout=60): +def sync_mempools(rpc_connections, *, wait=1, timeout=60, flush_scheduler=True): """ Wait until everybody has the same transactions in their memory pools @@ -402,6 +402,9 @@ def sync_mempools(rpc_connections, *, wait=1, timeout=60): if set(rpc_connections[i].getrawmempool()) == pool: num_match = num_match + 1 if num_match == len(rpc_connections): + if flush_scheduler: + for r in rpc_connections: + r.syncwithvalidationinterfacequeue() return time.sleep(wait) timeout -= wait diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index bfd1192d3a..98944685e1 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Run regression test suite. @@ -55,109 +55,114 @@ TEST_EXIT_SKIPPED = 77 BASE_SCRIPTS= [ # Scripts that are run by the travis build process. # Longest test should go first, to favor running tests in parallel - 'wallet-hd.py', - 'walletbackup.py', + 'wallet_hd.py', + 'wallet_backup.py', # vv Tests less than 5m vv - 'p2p-fullblocktest.py', - 'fundrawtransaction.py', - 'p2p-compactblocks.py', - 'segwit.py', + 'feature_block.py', + 'rpc_fundrawtransaction.py', + 'p2p_compactblocks.py', + 'feature_segwit.py', # vv Tests less than 2m vv - 'wallet.py', - 'wallet-accounts.py', - 'p2p-segwit.py', - 'wallet-dump.py', - 'listtransactions.py', + 'wallet_basic.py', + 'wallet_accounts.py', + 'p2p_segwit.py', + 'wallet_dump.py', + 'rpc_listtransactions.py', # vv Tests less than 60s vv - 'sendheaders.py', - 'zapwallettxes.py', - 'importmulti.py', + 'p2p_sendheaders.py', + 'wallet_zapwallettxes.py', + 'wallet_importmulti.py', 'mempool_limit.py', - 'merkle_blocks.py', - 'receivedby.py', - 'abandonconflict.py', - 'bip68-112-113-p2p.py', - 'rawtransactions.py', - 'reindex.py', + 'rpc_txoutproof.py', + 'wallet_listreceivedby.py', + 'wallet_abandonconflict.py', + 'feature_csv_activation.py', + 'rpc_rawtransaction.py', + 'wallet_address_types.py', + 'feature_reindex.py', # vv Tests less than 30s vv - 'keypool-topup.py', - 'zmq_test.py', - 'bitcoin_cli.py', - 'mempool_resurrect_test.py', - 'txn_doublespend.py --mineblock', - 'txn_clone.py', - 'getchaintips.py', - 'rest.py', - 'mempool_spendcoinbase.py', + 'wallet_keypool_topup.py', + 'interface_zmq.py', + 'interface_bitcoin_cli.py', + 'mempool_resurrect.py', + 'wallet_txn_doublespend.py --mineblock', + 'wallet_txn_clone.py', + 'wallet_txn_clone.py --segwit', + 'rpc_getchaintips.py', + 'interface_rest.py', + 'mempool_spend_coinbase.py', 'mempool_reorg.py', 'mempool_persist.py', - 'multiwallet.py', - 'httpbasics.py', - 'multi_rpc.py', - 'proxy_test.py', - 'signrawtransactions.py', - 'disconnect_ban.py', - 'decodescript.py', - 'blockchain.py', - 'deprecated_rpc.py', - 'disablewallet.py', - 'net.py', - 'keypool.py', - 'p2p-mempool.py', - 'prioritise_transaction.py', - 'invalidblockrequest.py', - 'invalidtxrequest.py', - 'p2p-versionbits-warning.py', - 'preciousblock.py', - 'importprunedfunds.py', - 'signmessages.py', - 'nulldummy.py', - 'import-rescan.py', - 'mining.py', - 'bumpfee.py', - 'rpcnamedargs.py', - 'listsinceblock.py', - 'p2p-leaktests.py', - 'wallet-encryption.py', - 'bipdersig-p2p.py', - 'bip65-cltv-p2p.py', - 'uptime.py', - 'resendwallettransactions.py', - 'minchainwork.py', - 'p2p-fingerprint.py', - 'uacomment.py', - 'p2p-acceptblock.py', + 'wallet_multiwallet.py', + 'wallet_multiwallet.py --usecli', + 'interface_http.py', + 'rpc_users.py', + 'feature_proxy.py', + 'rpc_signrawtransaction.py', + 'p2p_disconnect_ban.py', + 'rpc_decodescript.py', + 'rpc_blockchain.py', + 'rpc_deprecated.py', + 'wallet_disable.py', + 'rpc_net.py', + 'wallet_keypool.py', + 'p2p_mempool.py', + 'mining_prioritisetransaction.py', + 'p2p_invalid_block.py', + 'p2p_invalid_tx.py', + 'feature_versionbits_warning.py', + 'rpc_preciousblock.py', + 'wallet_importprunedfunds.py', + 'rpc_signmessage.py', + 'feature_nulldummy.py', + 'wallet_import_rescan.py', + 'mining_basic.py', + 'wallet_bumpfee.py', + 'rpc_named_arguments.py', + 'wallet_listsinceblock.py', + 'p2p_leak.py', + 'wallet_encryption.py', + 'feature_dersig.py', + 'feature_cltv.py', + 'rpc_uptime.py', + 'wallet_resendwallettransactions.py', + 'feature_minchainwork.py', + 'p2p_fingerprint.py', + 'feature_uacomment.py', + 'p2p_unrequested_blocks.py', 'feature_logging.py', - 'node_network_limited.py', - 'conf_args.py', + 'p2p_node_network_limited.py', + 'feature_config_args.py', + # Don't append tests at the end to avoid merge conflicts + # Put them in a random line within the section that fits their approximate run-time ] EXTENDED_SCRIPTS = [ # These tests are not run by the travis build process. # Longest test should go first, to favor running tests in parallel - 'pruning.py', + 'feature_pruning.py', # vv Tests less than 20m vv - 'smartfees.py', + 'feature_fee_estimation.py', # vv Tests less than 5m vv - 'maxuploadtarget.py', + 'feature_maxuploadtarget.py', 'mempool_packages.py', - 'dbcrash.py', + 'feature_dbcrash.py', # vv Tests less than 2m vv - 'bip68-sequence.py', - 'getblocktemplate_longpoll.py', - 'p2p-timeouts.py', + 'feature_bip68_sequence.py', + 'mining_getblocktemplate_longpoll.py', + 'p2p_timeouts.py', # vv Tests less than 60s vv - 'bip9-softforks.py', - 'p2p-feefilter.py', - 'rpcbind_test.py', + 'feature_bip9_softforks.py', + 'p2p_feefilter.py', + 'rpc_bind.py', # vv Tests less than 30s vv - 'assumevalid.py', + 'feature_assumevalid.py', 'example_test.py', - 'txn_doublespend.py', - 'txn_clone.py --mineblock', - 'notifications.py', - 'invalidateblock.py', - 'replace-by-fee.py', + 'wallet_txn_doublespend.py', + 'wallet_txn_clone.py --mineblock', + 'feature_notifications.py', + 'rpc_invalidateblock.py', + 'feature_rbf.py', ] # Place EXTENDED_SCRIPTS first since it has the 3 longest running tests @@ -267,6 +272,7 @@ def main(): sys.exit(0) check_script_list(config["environment"]["SRCDIR"]) + check_script_prefixes() if not args.keepcache: shutil.rmtree("%s/test/cache" % config["environment"]["BUILDDIR"], ignore_errors=True) @@ -307,9 +313,9 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove # Populate cache try: subprocess.check_output([tests_dir + 'create_cache.py'] + flags + ["--tmpdir=%s/cache" % tmpdir]) - except Exception as e: - print(e.output) - raise e + except subprocess.CalledProcessError as e: + sys.stdout.buffer.write(e.output) + raise #Run Tests job_queue = TestHandler(jobs, tests_dir, tmpdir, test_list, flags) @@ -465,6 +471,24 @@ class TestResult(): return self.status != "Failed" +def check_script_prefixes(): + """Check that at most a handful of the + test scripts don't start with one of the allowed name prefixes.""" + + # LEEWAY is provided as a transition measure, so that pull-requests + # that introduce new tests that don't conform with the naming + # convention don't immediately cause the tests to fail. + LEEWAY = 10 + + good_prefixes_re = re.compile("(example|feature|interface|mempool|mining|p2p|rpc|wallet)_") + bad_script_names = [script for script in ALL_SCRIPTS if good_prefixes_re.match(script) is None] + + if len(bad_script_names) > 0: + print("INFO: %d tests not meeting naming conventions:" % (len(bad_script_names))) + print(" %s" % ("\n ".join(sorted(bad_script_names)))) + assert len(bad_script_names) <= LEEWAY, "Too many tests not following naming convention! (%d found, maximum: %d)" % (len(bad_script_names), LEEWAY) + + def check_script_list(src_dir): """Check scripts directory. diff --git a/test/functional/abandonconflict.py b/test/functional/wallet_abandonconflict.py index e8dbc86469..14964438af 100755 --- a/test/functional/abandonconflict.py +++ b/test/functional/wallet_abandonconflict.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the abandontransaction RPC. diff --git a/test/functional/wallet-accounts.py b/test/functional/wallet_accounts.py index bc1efaee15..ecd1cfc82b 100755 --- a/test/functional/wallet-accounts.py +++ b/test/functional/wallet_accounts.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test account RPCs. @@ -126,7 +126,7 @@ class WalletAccountsTest(BitcoinTestFramework): addresses = [] for x in range(10): addresses.append(node.getnewaddress()) - multisig_address = node.addmultisigaddress(5, addresses, account.name) + multisig_address = node.addmultisigaddress(5, addresses, account.name)['address'] account.add_address(multisig_address) account.verify(node) node.sendfrom("", multisig_address, 50) diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py new file mode 100755 index 0000000000..38a3425214 --- /dev/null +++ b/test/functional/wallet_address_types.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test that the wallet can send and receive using all combinations of address types. + +There are 5 nodes-under-test: + - node0 uses legacy addresses + - node1 uses p2sh/segwit addresses + - node2 uses p2sh/segwit addresses and bech32 addresses for change + - node3 uses bech32 addresses + - node4 uses a p2sh/segwit addresses for change + +node5 exists to generate new blocks. + +## Multisig address test + +Test that adding a multisig address with: + - an uncompressed pubkey always gives a legacy address + - only compressed pubkeys gives the an `-addresstype` address + +## Sending to address types test + +A series of tests, iterating over node0-node4. In each iteration of the test, one node sends: + - 10/101th of its balance to itself (using getrawchangeaddress for single key addresses) + - 20/101th to the next node + - 30/101th to the node after that + - 40/101th to the remaining node + - 1/101th remains as fee+change + +Iterate over each node for single key addresses, and then over each node for +multisig addresses. + +Repeat test, but with explicit address_type parameters passed to getnewaddress +and getrawchangeaddress: + - node0 and node3 send to p2sh. + - node1 sends to bech32. + - node2 sends to legacy. + +As every node sends coins after receiving, this also +verifies that spending coins sent to all these address types works. + +## Change type test + +Test that the nodes generate the correct change address type: + - node0 always uses a legacy change address. + - node1 uses a bech32 addresses for change if any destination address is bech32. + - node2 always uses a bech32 address for change + - node3 always uses a bech32 address for change + - node4 always uses p2sh/segwit output for change. +""" + +from decimal import Decimal +import itertools + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_greater_than, + assert_raises_rpc_error, + connect_nodes_bi, + sync_blocks, + sync_mempools, +) + +class AddressTypeTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 6 + self.extra_args = [ + ["-addresstype=legacy"], + ["-addresstype=p2sh-segwit"], + ["-addresstype=p2sh-segwit", "-changetype=bech32"], + ["-addresstype=bech32"], + ["-changetype=p2sh-segwit"], + [] + ] + + def setup_network(self): + self.setup_nodes() + + # Fully mesh-connect nodes for faster mempool sync + for i, j in itertools.product(range(self.num_nodes), repeat=2): + if i > j: + connect_nodes_bi(self.nodes, i, j) + self.sync_all() + + def get_balances(self, confirmed=True): + """Return a list of confirmed or unconfirmed balances.""" + if confirmed: + return [self.nodes[i].getbalance() for i in range(4)] + else: + return [self.nodes[i].getunconfirmedbalance() for i in range(4)] + + def test_address(self, node, address, multisig, typ): + """Run sanity checks on an address.""" + info = self.nodes[node].validateaddress(address) + assert(info['isvalid']) + if not multisig and typ == 'legacy': + # P2PKH + assert(not info['isscript']) + assert(not info['iswitness']) + assert('pubkey' in info) + elif not multisig and typ == 'p2sh-segwit': + # P2SH-P2WPKH + assert(info['isscript']) + assert(not info['iswitness']) + assert_equal(info['script'], 'witness_v0_keyhash') + assert('pubkey' in info) + elif not multisig and typ == 'bech32': + # P2WPKH + assert(not info['isscript']) + assert(info['iswitness']) + assert_equal(info['witness_version'], 0) + assert_equal(len(info['witness_program']), 40) + assert('pubkey' in info) + elif typ == 'legacy': + # P2SH-multisig + assert(info['isscript']) + assert_equal(info['script'], 'multisig') + assert(not info['iswitness']) + assert('pubkeys' in info) + elif typ == 'p2sh-segwit': + # P2SH-P2WSH-multisig + assert(info['isscript']) + assert_equal(info['script'], 'witness_v0_scripthash') + assert(not info['iswitness']) + assert(info['embedded']['isscript']) + assert_equal(info['embedded']['script'], 'multisig') + assert(info['embedded']['iswitness']) + assert_equal(info['embedded']['witness_version'], 0) + assert_equal(len(info['embedded']['witness_program']), 64) + assert('pubkeys' in info['embedded']) + elif typ == 'bech32': + # P2WSH-multisig + assert(info['isscript']) + assert_equal(info['script'], 'multisig') + assert(info['iswitness']) + assert_equal(info['witness_version'], 0) + assert_equal(len(info['witness_program']), 64) + assert('pubkeys' in info) + else: + # Unknown type + assert(False) + + def test_change_output_type(self, node_sender, destinations, expected_type): + txid = self.nodes[node_sender].sendmany(fromaccount="", amounts=dict.fromkeys(destinations, 0.001)) + raw_tx = self.nodes[node_sender].getrawtransaction(txid) + tx = self.nodes[node_sender].decoderawtransaction(raw_tx) + + # Make sure the transaction has change: + assert_equal(len(tx["vout"]), len(destinations) + 1) + + # Make sure the destinations are included, and remove them: + output_addresses = [vout['scriptPubKey']['addresses'][0] for vout in tx["vout"]] + change_addresses = [d for d in output_addresses if d not in destinations] + assert_equal(len(change_addresses), 1) + + self.log.debug("Check if change address " + change_addresses[0] + " is " + expected_type) + self.test_address(node_sender, change_addresses[0], multisig=False, typ=expected_type) + + def run_test(self): + # Mine 101 blocks on node5 to bring nodes out of IBD and make sure that + # no coinbases are maturing for the nodes-under-test during the test + self.nodes[5].generate(101) + sync_blocks(self.nodes) + + uncompressed_1 = "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee" + uncompressed_2 = "047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77" + compressed_1 = "0296b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52" + compressed_2 = "037211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073" + + # addmultisigaddress with at least 1 uncompressed key should return a legacy address. + for node in range(4): + self.test_address(node, self.nodes[node].addmultisigaddress(2, [uncompressed_1, uncompressed_2])['address'], True, 'legacy') + self.test_address(node, self.nodes[node].addmultisigaddress(2, [compressed_1, uncompressed_2])['address'], True, 'legacy') + self.test_address(node, self.nodes[node].addmultisigaddress(2, [uncompressed_1, compressed_2])['address'], True, 'legacy') + # addmultisigaddress with all compressed keys should return the appropriate address type (even when the keys are not ours). + self.test_address(0, self.nodes[0].addmultisigaddress(2, [compressed_1, compressed_2])['address'], True, 'legacy') + self.test_address(1, self.nodes[1].addmultisigaddress(2, [compressed_1, compressed_2])['address'], True, 'p2sh-segwit') + self.test_address(2, self.nodes[2].addmultisigaddress(2, [compressed_1, compressed_2])['address'], True, 'p2sh-segwit') + self.test_address(3, self.nodes[3].addmultisigaddress(2, [compressed_1, compressed_2])['address'], True, 'bech32') + + for explicit_type, multisig, from_node in itertools.product([False, True], [False, True], range(4)): + address_type = None + if explicit_type and not multisig: + if from_node == 1: + address_type = 'bech32' + elif from_node == 0 or from_node == 3: + address_type = 'p2sh-segwit' + else: + address_type = 'legacy' + self.log.info("Sending from node {} ({}) with{} multisig using {}".format(from_node, self.extra_args[from_node], "" if multisig else "out", "default" if address_type is None else address_type)) + old_balances = self.get_balances() + self.log.debug("Old balances are {}".format(old_balances)) + to_send = (old_balances[from_node] / 101).quantize(Decimal("0.00000001")) + sends = {} + + self.log.debug("Prepare sends") + for n, to_node in enumerate(range(from_node, from_node + 4)): + to_node %= 4 + change = False + if not multisig: + if from_node == to_node: + # When sending non-multisig to self, use getrawchangeaddress + address = self.nodes[to_node].getrawchangeaddress(address_type=address_type) + change = True + else: + address = self.nodes[to_node].getnewaddress(address_type=address_type) + else: + addr1 = self.nodes[to_node].getnewaddress() + addr2 = self.nodes[to_node].getnewaddress() + address = self.nodes[to_node].addmultisigaddress(2, [addr1, addr2])['address'] + + # Do some sanity checking on the created address + if address_type is not None: + typ = address_type + elif to_node == 0: + typ = 'legacy' + elif to_node == 1 or (to_node == 2 and not change): + typ = 'p2sh-segwit' + else: + typ = 'bech32' + self.test_address(to_node, address, multisig, typ) + + # Output entry + sends[address] = to_send * 10 * (1 + n) + + self.log.debug("Sending: {}".format(sends)) + self.nodes[from_node].sendmany("", sends) + sync_mempools(self.nodes) + + unconf_balances = self.get_balances(False) + self.log.debug("Check unconfirmed balances: {}".format(unconf_balances)) + assert_equal(unconf_balances[from_node], 0) + for n, to_node in enumerate(range(from_node + 1, from_node + 4)): + to_node %= 4 + assert_equal(unconf_balances[to_node], to_send * 10 * (2 + n)) + + # node5 collects fee and block subsidy to keep accounting simple + self.nodes[5].generate(1) + sync_blocks(self.nodes) + + new_balances = self.get_balances() + self.log.debug("Check new balances: {}".format(new_balances)) + # We don't know what fee was set, so we can only check bounds on the balance of the sending node + assert_greater_than(new_balances[from_node], to_send * 10) + assert_greater_than(to_send * 11, new_balances[from_node]) + for n, to_node in enumerate(range(from_node + 1, from_node + 4)): + to_node %= 4 + assert_equal(new_balances[to_node], old_balances[to_node] + to_send * 10 * (2 + n)) + + # Get one p2sh/segwit address from node2 and two bech32 addresses from node3: + to_address_p2sh = self.nodes[2].getnewaddress() + to_address_bech32_1 = self.nodes[3].getnewaddress() + to_address_bech32_2 = self.nodes[3].getnewaddress() + + # Fund node 4: + self.nodes[5].sendtoaddress(self.nodes[4].getnewaddress(), Decimal("1")) + self.nodes[5].generate(1) + sync_blocks(self.nodes) + assert_equal(self.nodes[4].getbalance(), 1) + + self.log.info("Nodes with addresstype=legacy never use a P2WPKH change output") + self.test_change_output_type(0, [to_address_bech32_1], 'legacy') + + self.log.info("Nodes with addresstype=p2sh-segwit only use a P2WPKH change output if any destination address is bech32:") + self.test_change_output_type(1, [to_address_p2sh], 'p2sh-segwit') + self.test_change_output_type(1, [to_address_bech32_1], 'bech32') + self.test_change_output_type(1, [to_address_p2sh, to_address_bech32_1], 'bech32') + self.test_change_output_type(1, [to_address_bech32_1, to_address_bech32_2], 'bech32') + + self.log.info("Nodes with change_type=bech32 always use a P2WPKH change output:") + self.test_change_output_type(2, [to_address_bech32_1], 'bech32') + self.test_change_output_type(2, [to_address_p2sh], 'bech32') + + self.log.info("Nodes with addresstype=bech32 always use a P2WPKH change output (unless changetype is set otherwise):") + self.test_change_output_type(3, [to_address_bech32_1], 'bech32') + self.test_change_output_type(3, [to_address_p2sh], 'bech32') + + self.log.info('getrawchangeaddress defaults to addresstype if -changetype is not set and argument is absent') + self.test_address(3, self.nodes[3].getrawchangeaddress(), multisig=False, typ='bech32') + + self.log.info('getrawchangeaddress fails with invalid changetype argument') + assert_raises_rpc_error(-5, "Unknown address type 'bech23'", self.nodes[3].getrawchangeaddress, 'bech23') + + self.log.info("Nodes with changetype=p2sh-segwit never use a P2WPKH change output") + self.test_change_output_type(4, [to_address_bech32_1], 'p2sh-segwit') + self.test_address(4, self.nodes[4].getrawchangeaddress(), multisig=False, typ='p2sh-segwit') + self.log.info("Except for getrawchangeaddress if specified:") + self.test_address(4, self.nodes[4].getrawchangeaddress(), multisig=False, typ='p2sh-segwit') + self.test_address(4, self.nodes[4].getrawchangeaddress('bech32'), multisig=False, typ='bech32') + +if __name__ == '__main__': + AddressTypeTest().main() diff --git a/test/functional/walletbackup.py b/test/functional/wallet_backup.py index 8ef5620cd8..b4be7debb5 100755 --- a/test/functional/walletbackup.py +++ b/test/functional/wallet_backup.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet backup features. diff --git a/test/functional/wallet.py b/test/functional/wallet_basic.py index db60df18ed..a90dbc8adf 100755 --- a/test/functional/wallet.py +++ b/test/functional/wallet_basic.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet.""" @@ -27,6 +27,9 @@ class WalletTest(BitcoinTestFramework): assert_fee_amount(fee, tx_size, fee_per_byte * 1000) return curr_balance + def get_vsize(self, txn): + return self.nodes[0].decoderawtransaction(txn)['vsize'] + def run_test(self): # Check that there's no UTXO on none of the nodes assert_equal(len(self.nodes[0].listunspent()), 0) @@ -162,7 +165,7 @@ class WalletTest(BitcoinTestFramework): txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) self.nodes[2].generate(1) self.sync_all([self.nodes[0:3]]) - node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), Decimal('10')) # Send 10 BTC with subtract fee from amount @@ -171,14 +174,14 @@ class WalletTest(BitcoinTestFramework): self.sync_all([self.nodes[0:3]]) node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) - node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid))) # Sendmany 10 BTC txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) self.nodes[2].generate(1) self.sync_all([self.nodes[0:3]]) node_0_bal += Decimal('10') - node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid))) assert_equal(self.nodes[0].getbalance(), node_0_bal) # Sendmany 10 BTC with subtract fee from amount @@ -187,7 +190,7 @@ class WalletTest(BitcoinTestFramework): self.sync_all([self.nodes[0:3]]) node_2_bal -= Decimal('10') assert_equal(self.nodes[2].getbalance(), node_2_bal) - node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid))) # Test ResendWalletTransactions: # Create a couple of transactions, then start up a fourth diff --git a/test/functional/bumpfee.py b/test/functional/wallet_bumpfee.py index 008e83d5b2..2cd4127854 100755 --- a/test/functional/bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the bumpfee RPC. @@ -14,7 +14,7 @@ added in the future, they should try to follow the same convention and not make assumptions about execution order. """ -from segwit import send_to_witness +from test_framework.blocktools import send_to_witness from test_framework.test_framework import BitcoinTestFramework from test_framework import blocktools from test_framework.mininode import CTransaction @@ -33,7 +33,7 @@ class BumpFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [["-prematurewitness", "-walletprematurewitness", "-walletrbf={}".format(i)] + self.extra_args = [["-prematurewitness", "-walletprematurewitness", "-deprecatedrpc=addwitnessaddress", "-walletrbf={}".format(i)] for i in range(self.num_nodes)] def run_test(self): @@ -194,7 +194,7 @@ def test_settxfee(rbf_node, dest_address): requested_feerate = Decimal("0.00025000") rbf_node.settxfee(requested_feerate) bumped_tx = rbf_node.bumpfee(rbfid) - actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["size"] + actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["vsize"] # Assert that the difference between the requested feerate and the actual # feerate of the bumped transaction is small. assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate)) @@ -290,6 +290,7 @@ def submit_block_with_tx(node, tx): block.vtx.append(ctx) block.rehash() block.hashMerkleRoot = block.calc_merkle_root() + blocktools.add_witness_commitment(block) block.solve() node.submitblock(bytes_to_hex_str(block.serialize(True))) return block diff --git a/test/functional/disablewallet.py b/test/functional/wallet_disable.py index c75ef9b9f1..b0627d88ac 100755 --- a/test/functional/disablewallet.py +++ b/test/functional/wallet_disable.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2016 The Bitcoin Core developers +# Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test a node with the -disablewallet option. diff --git a/test/functional/wallet-dump.py b/test/functional/wallet_dump.py index 85812f9acc..77f90ffb81 100755 --- a/test/functional/wallet-dump.py +++ b/test/functional/wallet_dump.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the dumpwallet RPC.""" @@ -69,7 +69,7 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): class WalletDumpTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [["-keypool=90"]] + self.extra_args = [["-keypool=90", "-addresstype=legacy", "-deprecatedrpc=addwitnessaddress"]] def setup_network(self, split=False): # Use 1 minute timeout because the initial getnewaddress RPC can take @@ -94,7 +94,7 @@ class WalletDumpTest(BitcoinTestFramework): # Test scripts dump by adding a P2SH witness and a 1-of-1 multisig address witness_addr = self.nodes[0].addwitnessaddress(addrs[0]["address"], True) - multisig_addr = self.nodes[0].addmultisigaddress(1, [addrs[1]["address"]]) + multisig_addr = self.nodes[0].addmultisigaddress(1, [addrs[1]["address"]])["address"] script_addrs = [witness_addr, multisig_addr] # dump unencrypted wallet diff --git a/test/functional/wallet-encryption.py b/test/functional/wallet_encryption.py index db62e1e30f..3c927ee484 100755 --- a/test/functional/wallet-encryption.py +++ b/test/functional/wallet_encryption.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test Wallet encryption""" @@ -10,6 +10,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_raises_rpc_error, + assert_greater_than, + assert_greater_than_or_equal, ) class WalletEncryptionTest(BitcoinTestFramework): @@ -56,6 +58,23 @@ class WalletEncryptionTest(BitcoinTestFramework): assert_raises_rpc_error(-14, "wallet passphrase entered was incorrect", self.nodes[0].walletpassphrase, passphrase, 10) self.nodes[0].walletpassphrase(passphrase2, 10) assert_equal(privkey, self.nodes[0].dumpprivkey(address)) + self.nodes[0].walletlock() + + # Test timeout bounds + assert_raises_rpc_error(-8, "Timeout cannot be negative.", self.nodes[0].walletpassphrase, passphrase2, -10) + # Check the timeout + # Check a time less than the limit + expected_time = int(time.time()) + (1 << 30) - 600 + self.nodes[0].walletpassphrase(passphrase2, (1 << 30) - 600) + actual_time = self.nodes[0].getwalletinfo()['unlocked_until'] + assert_greater_than_or_equal(actual_time, expected_time) + assert_greater_than(expected_time + 5, actual_time) # 5 second buffer + # Check a time greater than the limit + expected_time = int(time.time()) + (1 << 30) - 1 + self.nodes[0].walletpassphrase(passphrase2, (1 << 33)) + actual_time = self.nodes[0].getwalletinfo()['unlocked_until'] + assert_greater_than_or_equal(actual_time, expected_time) + assert_greater_than(expected_time + 5, actual_time) # 5 second buffer if __name__ == '__main__': WalletEncryptionTest().main() diff --git a/test/functional/wallet-hd.py b/test/functional/wallet_hd.py index d21656a971..9f0e9acb47 100755 --- a/test/functional/wallet-hd.py +++ b/test/functional/wallet_hd.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test Hierarchical Deterministic wallet function.""" diff --git a/test/functional/import-rescan.py b/test/functional/wallet_import_rescan.py index 6807fa6696..d193a99d5b 100755 --- a/test/functional/import-rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test wallet import RPCs. @@ -119,7 +119,7 @@ class ImportRescanTest(BitcoinTestFramework): self.num_nodes = 2 + len(IMPORT_NODES) def setup_network(self): - extra_args = [[] for _ in range(self.num_nodes)] + extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)] for i, import_node in enumerate(IMPORT_NODES, 2): if import_node.prune: extra_args[i] += ["-prune=1"] diff --git a/test/functional/importmulti.py b/test/functional/wallet_importmulti.py index a691595f15..be9be83839 100755 --- a/test/functional/importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the importmulti RPC.""" @@ -9,6 +9,7 @@ from test_framework.util import * class ImportMultiTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"]] self.setup_clean_chain = True def setup_network(self): @@ -227,7 +228,7 @@ class ImportMultiTest (BitcoinTestFramework): sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) - multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) @@ -254,7 +255,7 @@ class ImportMultiTest (BitcoinTestFramework): sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) - multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) @@ -281,7 +282,7 @@ class ImportMultiTest (BitcoinTestFramework): sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) - multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) @@ -308,7 +309,7 @@ class ImportMultiTest (BitcoinTestFramework): sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) - multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']]) + multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']]) self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) diff --git a/test/functional/importprunedfunds.py b/test/functional/wallet_importprunedfunds.py index 068052409a..6b2919b5ae 100755 --- a/test/functional/importprunedfunds.py +++ b/test/functional/wallet_importprunedfunds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the importprunedfunds and removeprunedfunds RPCs.""" diff --git a/test/functional/keypool.py b/test/functional/wallet_keypool.py index f2701c36bd..45a5eed8ec 100755 --- a/test/functional/keypool.py +++ b/test/functional/wallet_keypool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet keypool and interaction with wallet encryption/locking.""" diff --git a/test/functional/keypool-topup.py b/test/functional/wallet_keypool_topup.py index e7af3c3987..e7af3c3987 100755 --- a/test/functional/keypool-topup.py +++ b/test/functional/wallet_keypool_topup.py diff --git a/test/functional/receivedby.py b/test/functional/wallet_listreceivedby.py index 97da19546f..1f2b3c8aa7 100755 --- a/test/functional/receivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the listreceivedbyaddress RPC.""" diff --git a/test/functional/listsinceblock.py b/test/functional/wallet_listsinceblock.py index 67e7744bf8..67e7744bf8 100755 --- a/test/functional/listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py diff --git a/test/functional/multiwallet.py b/test/functional/wallet_multiwallet.py index d0c40e5446..b07e451667 100755 --- a/test/functional/multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -15,63 +15,75 @@ from test_framework.util import assert_equal, assert_raises_rpc_error class MultiWalletTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True - self.num_nodes = 1 - self.extra_args = [['-wallet=w1', '-wallet=w2', '-wallet=w3', '-wallet=w']] + self.num_nodes = 2 + self.extra_args = [['-wallet=w1', '-wallet=w2', '-wallet=w3', '-wallet=w'], []] + self.supports_cli = True def run_test(self): - assert_equal(set(self.nodes[0].listwallets()), {"w1", "w2", "w3", "w"}) + node = self.nodes[0] - self.stop_node(0) + data_dir = lambda *p: os.path.join(node.datadir, 'regtest', *p) + wallet_dir = lambda *p: data_dir('wallets', *p) + wallet = lambda name: node.get_wallet_rpc(name) + + assert_equal(set(node.listwallets()), {"w1", "w2", "w3", "w"}) + + self.stop_nodes() + + self.assert_start_raises_init_error(0, ['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') + self.assert_start_raises_init_error(0, ['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) + self.assert_start_raises_init_error(0, ['-walletdir=debug.log'], 'Error: Specified -walletdir "debug.log" is not a directory', cwd=data_dir()) # should not initialize if there are duplicate wallets self.assert_start_raises_init_error(0, ['-wallet=w1', '-wallet=w1'], 'Error loading wallet w1. Duplicate -wallet filename specified.') # should not initialize if wallet file is a directory - wallet_dir = os.path.join(self.options.tmpdir, 'node0', 'regtest', 'wallets') - os.mkdir(os.path.join(wallet_dir, 'w11')) + os.mkdir(wallet_dir('w11')) self.assert_start_raises_init_error(0, ['-wallet=w11'], 'Error loading wallet w11. -wallet filename must be a regular file.') # should not initialize if one wallet is a copy of another - shutil.copyfile(os.path.join(wallet_dir, 'w2'), os.path.join(wallet_dir, 'w22')) + shutil.copyfile(wallet_dir('w2'), wallet_dir('w22')) self.assert_start_raises_init_error(0, ['-wallet=w2', '-wallet=w22'], 'duplicates fileid') # should not initialize if wallet file is a symlink - os.symlink(os.path.join(wallet_dir, 'w1'), os.path.join(wallet_dir, 'w12')) + os.symlink(wallet_dir('w1'), wallet_dir('w12')) self.assert_start_raises_init_error(0, ['-wallet=w12'], 'Error loading wallet w12. -wallet filename must be a regular file.') # should not initialize if the specified walletdir does not exist self.assert_start_raises_init_error(0, ['-walletdir=bad'], 'Error: Specified -walletdir "bad" does not exist') # should not initialize if the specified walletdir is not a directory - not_a_dir = os.path.join(wallet_dir, 'notadir') + not_a_dir = wallet_dir('notadir') open(not_a_dir, 'a').close() - self.assert_start_raises_init_error(0, ['-walletdir='+not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') + self.assert_start_raises_init_error(0, ['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') # if wallets/ doesn't exist, datadir should be the default wallet dir - wallet_dir2 = os.path.join(self.options.tmpdir, 'node0', 'regtest', 'walletdir') - os.rename(wallet_dir, wallet_dir2) + wallet_dir2 = data_dir('walletdir') + os.rename(wallet_dir(), wallet_dir2) self.start_node(0, ['-wallet=w4', '-wallet=w5']) - assert_equal(set(self.nodes[0].listwallets()), {"w4", "w5"}) - w5 = self.nodes[0].get_wallet_rpc("w5") + assert_equal(set(node.listwallets()), {"w4", "w5"}) + w5 = wallet("w5") w5.generate(1) - self.stop_node(0) # now if wallets/ exists again, but the rootdir is specified as the walletdir, w4 and w5 should still be loaded - os.rename(wallet_dir2, wallet_dir) - self.start_node(0, ['-wallet=w4', '-wallet=w5', '-walletdir=' + os.path.join(self.options.tmpdir, 'node0', 'regtest')]) - assert_equal(set(self.nodes[0].listwallets()), {"w4", "w5"}) - w5 = self.nodes[0].get_wallet_rpc("w5") + os.rename(wallet_dir2, wallet_dir()) + self.restart_node(0, ['-wallet=w4', '-wallet=w5', '-walletdir=' + data_dir()]) + assert_equal(set(node.listwallets()), {"w4", "w5"}) + w5 = wallet("w5") w5_info = w5.getwalletinfo() assert_equal(w5_info['immature_balance'], 50) - self.stop_node(0) + competing_wallet_dir = os.path.join(self.options.tmpdir, 'competing_walletdir') + os.mkdir(competing_wallet_dir) + self.restart_node(0, ['-walletdir='+competing_wallet_dir]) + self.assert_start_raises_init_error(1, ['-walletdir='+competing_wallet_dir], 'Error initializing wallet database environment') - self.start_node(0, self.extra_args[0]) + self.restart_node(0, self.extra_args[0]) - w1 = self.nodes[0].get_wallet_rpc("w1") - w2 = self.nodes[0].get_wallet_rpc("w2") - w3 = self.nodes[0].get_wallet_rpc("w3") - w4 = self.nodes[0].get_wallet_rpc("w") - wallet_bad = self.nodes[0].get_wallet_rpc("bad") + w1 = wallet("w1") + w2 = wallet("w2") + w3 = wallet("w3") + w4 = wallet("w") + wallet_bad = wallet("bad") w1.generate(1) @@ -79,7 +91,7 @@ class MultiWalletTest(BitcoinTestFramework): assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", wallet_bad.getwalletinfo) # accessing wallet RPC without using wallet endpoint fails - assert_raises_rpc_error(-19, "Wallet file not specified", self.nodes[0].getwalletinfo) + assert_raises_rpc_error(-19, "Wallet file not specified", node.getwalletinfo) # check w1 wallet balance w1_info = w1.getwalletinfo() diff --git a/test/functional/resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py index d959bb4c38..d959bb4c38 100755 --- a/test/functional/resendwallettransactions.py +++ b/test/functional/wallet_resendwallettransactions.py diff --git a/test/functional/txn_clone.py b/test/functional/wallet_txn_clone.py index 740bb2d4c5..ce26d6e0ee 100755 --- a/test/functional/txn_clone.py +++ b/test/functional/wallet_txn_clone.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs.""" @@ -14,6 +14,8 @@ class TxnMallTest(BitcoinTestFramework): def add_options(self, parser): parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true", help="Test double-spend of 1-confirmed transaction") + parser.add_option("--segwit", dest="segwit", default=False, action="store_true", + help="Test behaviour with SegWit txn (which should fail") def setup_network(self): # Start with split network: @@ -22,6 +24,11 @@ class TxnMallTest(BitcoinTestFramework): disconnect_nodes(self.nodes[2], 1) def run_test(self): + if self.options.segwit: + output_type="p2sh-segwit" + else: + output_type="legacy" + # All nodes should start with 1,250 BTC: starting_balance = 1250 for i in range(4): @@ -31,11 +38,11 @@ class TxnMallTest(BitcoinTestFramework): # Assign coins to foo and bar accounts: self.nodes[0].settxfee(.001) - node0_address_foo = self.nodes[0].getnewaddress("foo") + node0_address_foo = self.nodes[0].getnewaddress("foo", output_type) fund_foo_txid = self.nodes[0].sendfrom("", node0_address_foo, 1219) fund_foo_tx = self.nodes[0].gettransaction(fund_foo_txid) - node0_address_bar = self.nodes[0].getnewaddress("bar") + node0_address_bar = self.nodes[0].getnewaddress("bar", output_type) fund_bar_txid = self.nodes[0].sendfrom("", node0_address_bar, 29) fund_bar_tx = self.nodes[0].gettransaction(fund_bar_txid) @@ -106,6 +113,10 @@ class TxnMallTest(BitcoinTestFramework): # Send clone and its parent to miner self.nodes[2].sendrawtransaction(fund_foo_tx["hex"]) txid1_clone = self.nodes[2].sendrawtransaction(tx1_clone["hex"]) + if self.options.segwit: + assert_equal(txid1, txid1_clone) + return + # ... mine a block... self.nodes[2].generate(1) diff --git a/test/functional/txn_doublespend.py b/test/functional/wallet_txn_doublespend.py index 69629ef951..01129f3817 100755 --- a/test/functional/txn_doublespend.py +++ b/test/functional/wallet_txn_doublespend.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet accounts properly when there is a double-spend conflict.""" diff --git a/test/functional/zapwallettxes.py b/test/functional/wallet_zapwallettxes.py index 8cd622dc8e..87f44b2737 100755 --- a/test/functional/zapwallettxes.py +++ b/test/functional/wallet_zapwallettxes.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the zapwallettxes functionality. @@ -10,7 +10,7 @@ transactions are still available. - restart node 0 with zapwallettxes and persistmempool, and verify that both the confirmed and the unconfirmed transactions are still available. -- restart node 0 with just zapwallettxed and verify that the confirmed +- restart node 0 with just zapwallettxes and verify that the confirmed transactions are still available, but that the unconfirmed transaction has been zapped. """ @@ -59,6 +59,7 @@ class ZapWalletTXesTest (BitcoinTestFramework): self.start_node(0, ["-persistmempool=1", "-zapwallettxes=2"]) wait_until(lambda: self.nodes[0].getmempoolinfo()['size'] == 1, timeout=3) + self.nodes[0].syncwithvalidationinterfacequeue() # Flush mempool to wallet assert_equal(self.nodes[0].gettransaction(txid1)['txid'], txid1) assert_equal(self.nodes[0].gettransaction(txid2)['txid'], txid2) diff --git a/test/util/bitcoin-util-test.py b/test/util/bitcoin-util-test.py index ef34955d90..64e826ad0b 100755 --- a/test/util/bitcoin-util-test.py +++ b/test/util/bitcoin-util-test.py @@ -48,7 +48,7 @@ def main(): def bctester(testDir, input_basename, buildenv): """ Loads and parses the input file, runs all tests and reports results""" - input_filename = testDir + "/" + input_basename + input_filename = os.path.join(testDir, input_basename) raw_data = open(input_filename).read() input_data = json.loads(raw_data) @@ -77,7 +77,7 @@ def bctest(testDir, testObj, buildenv): are not as expected. Error is caught by bctester() and reported. """ # Get the exec names and arguments - execprog = buildenv["BUILDDIR"] + "/src/" + testObj['exec'] + buildenv["EXEEXT"] + execprog = os.path.join(buildenv["BUILDDIR"], "src", testObj["exec"] + buildenv["EXEEXT"]) execargs = testObj['args'] execrun = [execprog] + execargs @@ -85,24 +85,28 @@ def bctest(testDir, testObj, buildenv): stdinCfg = None inputData = None if "input" in testObj: - filename = testDir + "/" + testObj['input'] + filename = os.path.join(testDir, testObj["input"]) inputData = open(filename).read() stdinCfg = subprocess.PIPE # Read the expected output data (if there is any) outputFn = None outputData = None + outputType = None if "output_cmp" in testObj: outputFn = testObj['output_cmp'] outputType = os.path.splitext(outputFn)[1][1:] # output type from file extension (determines how to compare) try: - outputData = open(testDir + "/" + outputFn).read() + outputData = open(os.path.join(testDir, outputFn)).read() except: logging.error("Output file " + outputFn + " can not be opened") raise if not outputData: logging.error("Output data missing for " + outputFn) raise Exception + if not outputType: + logging.error("Output file %s does not have a file extension" % outputFn) + raise Exception # Run the test proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) |