aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rwxr-xr-xtest/functional/feature_block.py22
-rwxr-xr-xtest/functional/feature_pruning.py4
-rwxr-xr-xtest/functional/feature_segwit.py12
-rwxr-xr-xtest/functional/interface_zmq.py3
-rwxr-xr-xtest/functional/mempool_packages.py7
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py2
-rwxr-xr-xtest/functional/p2p_invalid_tx.py109
-rwxr-xr-xtest/functional/p2p_unrequested_blocks.py6
-rwxr-xr-xtest/functional/rpc_decodescript.py60
-rwxr-xr-xtest/functional/rpc_deprecated.py1
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py2
-rwxr-xr-xtest/functional/test_framework/mininode.py11
-rwxr-xr-xtest/functional/test_framework/test_framework.py23
-rwxr-xr-xtest/functional/test_framework/test_node.py10
-rwxr-xr-xtest/functional/test_runner.py41
-rwxr-xr-xtest/functional/wallet_address_types.py5
-rwxr-xr-xtest/functional/wallet_basic.py165
-rwxr-xr-xtest/functional/wallet_import_rescan.py4
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py29
-rwxr-xr-xtest/functional/wallet_listreceivedby.py38
-rwxr-xr-xtest/functional/wallet_listsinceblock.py16
-rwxr-xr-xtest/functional/wallet_listtransactions.py117
-rwxr-xr-xtest/functional/wallet_txn_clone.py45
-rwxr-xr-xtest/functional/wallet_txn_doublespend.py28
24 files changed, 481 insertions, 279 deletions
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 38b76239e5..17d3ddae4a 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -82,10 +82,7 @@ class FullBlockTest(BitcoinTestFramework):
def run_test(self):
node = self.nodes[0] # convenience reference to the node
- # reconnect_p2p() expects the network thread to be running
- network_thread_start()
-
- self.reconnect_p2p()
+ self.bootstrap_p2p() # Add one p2p connection to the node
self.block_heights = {}
self.coinbase_key = CECKey()
@@ -1296,14 +1293,10 @@ class FullBlockTest(BitcoinTestFramework):
self.blocks[block_number] = block
return block
- def reconnect_p2p(self):
+ def bootstrap_p2p(self):
"""Add a P2P connection to the node.
- The node gets disconnected several times in this test. This helper
- method reconnects the p2p and restarts the network thread."""
-
- network_thread_join()
- self.nodes[0].disconnect_p2ps()
+ Helper to connect and wait for version handshake."""
self.nodes[0].add_p2p_connection(P2PDataStore())
network_thread_start()
# We need to wait for the initial getheaders from the peer before we
@@ -1314,6 +1307,15 @@ class FullBlockTest(BitcoinTestFramework):
# unexpectedly disconnected if the DoS score for that error is 50.
self.nodes[0].p2p.wait_for_getheaders(timeout=5)
+ def reconnect_p2p(self):
+ """Tear down and bootstrap the P2P connection to the node.
+
+ The node gets disconnected several times in this test. This helper
+ method reconnects the p2p and restarts the network thread."""
+ self.nodes[0].disconnect_p2ps()
+ network_thread_join()
+ self.bootstrap_p2p()
+
def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True, reconnect=False, timeout=60):
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index 3adde8dd73..11a52b9ee2 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -124,7 +124,7 @@ class PruneTest(BitcoinTestFramework):
# Reboot node 1 to clear its mempool (hopefully make the invalidate faster)
# Lower the block max size so we don't keep mining all our big mempool transactions (from disconnected blocks)
self.stop_node(1)
- self.start_node(1, extra_args=["-maxreceivebuffer=20000","-blockmaxweight=20000", "-checkblocks=5", "-disablesafemode"])
+ self.start_node(1, extra_args=["-maxreceivebuffer=20000","-blockmaxweight=20000", "-checkblocks=5"])
height = self.nodes[1].getblockcount()
self.log.info("Current block height: %d" % height)
@@ -147,7 +147,7 @@ class PruneTest(BitcoinTestFramework):
# Reboot node1 to clear those giant tx's from mempool
self.stop_node(1)
- self.start_node(1, extra_args=["-maxreceivebuffer=20000","-blockmaxweight=20000", "-checkblocks=5", "-disablesafemode"])
+ self.start_node(1, extra_args=["-maxreceivebuffer=20000","-blockmaxweight=20000", "-checkblocks=5"])
self.log.info("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index e835b9d777..a47c42829a 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -303,8 +303,10 @@ class SegWitTest(BitcoinTestFramework):
v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
- # bare and p2sh multisig with compressed keys should always be spendable
- spendable_anytime.extend([bare, p2sh])
+ # p2sh multisig with compressed keys should always be spendable
+ spendable_anytime.extend([p2sh])
+ # bare multisig can be watched and signed, but is not treated as ours
+ solvable_after_importaddress.extend([bare])
# P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after direct importaddress
spendable_after_importaddress.extend([p2wsh, p2sh_p2wsh])
else:
@@ -320,8 +322,10 @@ class SegWitTest(BitcoinTestFramework):
v = self.nodes[0].getaddressinfo(i)
if (v['isscript']):
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
- # bare and p2sh multisig with uncompressed keys should always be spendable
- spendable_anytime.extend([bare, p2sh])
+ # p2sh multisig with uncompressed keys should always be spendable
+ spendable_anytime.extend([p2sh])
+ # bare multisig can be watched and signed, but is not treated as ours
+ solvable_after_importaddress.extend([bare])
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
unseen_anytime.extend([p2wsh, p2sh_p2wsh])
else:
diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py
index 86ccea4394..af2e752b7a 100755
--- a/test/functional/interface_zmq.py
+++ b/test/functional/interface_zmq.py
@@ -4,7 +4,6 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the ZMQ notification interface."""
import configparser
-import os
import struct
from test_framework.test_framework import BitcoinTestFramework, SkipTest
@@ -47,8 +46,6 @@ class ZMQTest (BitcoinTestFramework):
# Check that bitcoin has been built with ZMQ enabled.
config = configparser.ConfigParser()
- if not self.options.configfile:
- self.options.configfile = os.path.abspath(os.path.join(os.path.dirname(__file__), "../config.ini"))
config.read_file(open(self.options.configfile))
if not config["components"].getboolean("ENABLE_ZMQ"):
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index 8880db8002..79cf159f43 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -70,7 +70,10 @@ class MempoolPackagesTest(BitcoinTestFramework):
assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee'])
+ assert_equal(mempool[x]['fees']['base'], mempool[x]['fee'])
+ assert_equal(mempool[x]['fees']['modified'], mempool[x]['modifiedfee'])
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN)
+ assert_equal(mempool[x]['fees']['descendant'], descendant_fees)
descendant_size += mempool[x]['size']
assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1
@@ -132,6 +135,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
ancestor_fees = 0
for x in chain:
ancestor_fees += mempool[x]['fee']
+ assert_equal(mempool[x]['fees']['ancestor'], ancestor_fees + Decimal('0.00001'))
assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000)
# Undo the prioritisetransaction for later tests
@@ -145,6 +149,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees = 0
for x in reversed(chain):
descendant_fees += mempool[x]['fee']
+ assert_equal(mempool[x]['fees']['descendant'], descendant_fees + Decimal('0.00001'))
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 1000)
# Adding one more transaction on to the chain should fail.
@@ -170,7 +175,9 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees += mempool[x]['fee']
if (x == chain[-1]):
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002))
+ assert_equal(mempool[x]['fees']['modified'], mempool[x]['fee']+satoshi_round(0.00002))
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 2000)
+ assert_equal(mempool[x]['fees']['descendant'], descendant_fees+satoshi_round(0.00002))
# TODO: check that node1's mempool is as expected
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index b433f11aa5..85f1af6682 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -120,7 +120,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"]
# This will raise an exception due to min relay fee not being met
- assert_raises_rpc_error(-26, "min relay fee not met, 0 < 134 (code 66)", self.nodes[0].sendrawtransaction, tx_hex)
+ assert_raises_rpc_error(-26, "min relay fee not met", self.nodes[0].sendrawtransaction, tx_hex)
assert(tx_id not in self.nodes[0].getrawmempool())
# This is a less than 1000-byte transaction, so just set the fee
diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
index 69ce529ad6..8a0961be1f 100755
--- a/test/functional/p2p_invalid_tx.py
+++ b/test/functional/p2p_invalid_tx.py
@@ -6,24 +6,48 @@
In this test we connect to one node over p2p, and test tx requests."""
from test_framework.blocktools import create_block, create_coinbase, create_transaction
-from test_framework.messages import COIN
-from test_framework.mininode import network_thread_start, P2PDataStore
+from test_framework.messages import (
+ COIN,
+ COutPoint,
+ CTransaction,
+ CTxIn,
+ CTxOut,
+)
+from test_framework.mininode import network_thread_start, P2PDataStore, network_thread_join
from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+ wait_until,
+)
-class InvalidTxRequestTest(BitcoinTestFramework):
+class InvalidTxRequestTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
- self.extra_args = [["-whitelist=127.0.0.1"]]
+
+ def bootstrap_p2p(self, *, num_connections=1):
+ """Add a P2P connection to the node.
+
+ Helper to connect and wait for version handshake."""
+ for _ in range(num_connections):
+ self.nodes[0].add_p2p_connection(P2PDataStore())
+ network_thread_start()
+ self.nodes[0].p2p.wait_for_verack()
+
+ def reconnect_p2p(self, **kwargs):
+ """Tear down and bootstrap the P2P connection to the node.
+
+ The node gets disconnected several times in this test. This helper
+ method reconnects the p2p and restarts the network thread."""
+ self.nodes[0].disconnect_p2ps()
+ network_thread_join()
+ self.bootstrap_p2p(**kwargs)
def run_test(self):
- # Add p2p connection to node0
node = self.nodes[0] # convenience reference to the node
- node.add_p2p_connection(P2PDataStore())
- network_thread_start()
- node.p2p.wait_for_verack()
+ self.bootstrap_p2p() # Add one p2p connection to the node
best_block = self.nodes[0].getbestblockhash()
tip = int(best_block, 16)
@@ -44,12 +68,73 @@ class InvalidTxRequestTest(BitcoinTestFramework):
# b'\x64' is OP_NOTIF
# Transaction will be rejected with code 16 (REJECT_INVALID)
+ # and we get disconnected immediately
+ self.log.info('Test a transaction that is rejected')
tx1 = create_transaction(block1.vtx[0], 0, b'\x64', 50 * COIN - 12000)
- node.p2p.send_txs_and_test([tx1], node, success=False, reject_code=16, reject_reason=b'mandatory-script-verify-flag-failed (Invalid OP_IF construction)')
+ node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
+
+ # Make two p2p connections to provide the node with orphans
+ # * p2ps[0] will send valid orphan txs (one with low fee)
+ # * p2ps[1] will send an invalid orphan tx (and is later disconnected for that)
+ self.reconnect_p2p(num_connections=2)
+
+ self.log.info('Test orphan transaction handling ... ')
+ # Create a root transaction that we withold until all dependend transactions
+ # are sent out and in the orphan cache
+ tx_withhold = CTransaction()
+ tx_withhold.vin.append(CTxIn(outpoint=COutPoint(block1.vtx[0].sha256, 0)))
+ tx_withhold.vout.append(CTxOut(nValue=50 * COIN - 12000, scriptPubKey=b'\x51'))
+ tx_withhold.calc_sha256()
+
+ # Our first orphan tx with some outputs to create further orphan txs
+ tx_orphan_1 = CTransaction()
+ tx_orphan_1.vin.append(CTxIn(outpoint=COutPoint(tx_withhold.sha256, 0)))
+ tx_orphan_1.vout = [CTxOut(nValue=10 * COIN, scriptPubKey=b'\x51')] * 3
+ tx_orphan_1.calc_sha256()
+
+ # A valid transaction with low fee
+ tx_orphan_2_no_fee = CTransaction()
+ tx_orphan_2_no_fee.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 0)))
+ tx_orphan_2_no_fee.vout.append(CTxOut(nValue=10 * COIN, scriptPubKey=b'\x51'))
+
+ # A valid transaction with sufficient fee
+ tx_orphan_2_valid = CTransaction()
+ tx_orphan_2_valid.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 1)))
+ tx_orphan_2_valid.vout.append(CTxOut(nValue=10 * COIN - 12000, scriptPubKey=b'\x51'))
+ tx_orphan_2_valid.calc_sha256()
+
+ # An invalid transaction with negative fee
+ tx_orphan_2_invalid = CTransaction()
+ tx_orphan_2_invalid.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 2)))
+ tx_orphan_2_invalid.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=b'\x51'))
+
+ self.log.info('Send the orphans ... ')
+ # Send valid orphan txs from p2ps[0]
+ node.p2p.send_txs_and_test([tx_orphan_1, tx_orphan_2_no_fee, tx_orphan_2_valid], node, success=False)
+ # Send invalid tx from p2ps[1]
+ node.p2ps[1].send_txs_and_test([tx_orphan_2_invalid], node, success=False)
+
+ assert_equal(0, node.getmempoolinfo()['size']) # Mempool should be empty
+ assert_equal(2, len(node.getpeerinfo())) # p2ps[1] is still connected
+
+ self.log.info('Send the withhold tx ... ')
+ node.p2p.send_txs_and_test([tx_withhold], node, success=True)
+
+ # Transactions that should end up in the mempool
+ expected_mempool = {
+ t.hash
+ for t in [
+ tx_withhold, # The transaction that is the root for all orphans
+ tx_orphan_1, # The orphan transaction that splits the coins
+ tx_orphan_2_valid, # The valid transaction (with sufficient fee)
+ ]
+ }
+ # Transactions that do not end up in the mempool
+ # tx_orphan_no_fee, because it has too low fee (p2ps[0] is not disconnected for relaying that tx)
+ # tx_orphan_invaid, because it has negative fee (p2ps[1] is disconnected for relaying that tx)
- # Verify valid transaction
- tx1 = create_transaction(block1.vtx[0], 0, b'', 50 * COIN - 12000)
- node.p2p.send_txs_and_test([tx1], node, success=True)
+ wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected
+ assert_equal(expected_mempool, set(node.getrawmempool()))
if __name__ == '__main__':
diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py
index 53b2856eb5..49c619a4ce 100755
--- a/test/functional/p2p_unrequested_blocks.py
+++ b/test/functional/p2p_unrequested_blocks.py
@@ -57,12 +57,8 @@ from test_framework.util import *
import time
from test_framework.blocktools import create_block, create_coinbase, create_transaction
-class AcceptBlockTest(BitcoinTestFramework):
- def add_options(self, parser):
- parser.add_option("--testbinary", dest="testbinary",
- default=os.getenv("BITCOIND", "bitcoind"),
- help="bitcoind binary to test")
+class AcceptBlockTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/rpc_decodescript.py b/test/functional/rpc_decodescript.py
index 1ffc570437..d588151768 100755
--- a/test/functional/rpc_decodescript.py
+++ b/test/functional/rpc_decodescript.py
@@ -50,8 +50,11 @@ class DecodeScriptTest(BitcoinTestFramework):
def decodescript_script_pub_key(self):
public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2'
push_public_key = '21' + public_key
- public_key_hash = '11695b6cd891484c2d49ec5aa738ec2b2f897777'
+ public_key_hash = '5dd1d3a048119c27b28293056724d9522f26d945'
push_public_key_hash = '14' + public_key_hash
+ uncompressed_public_key = '04b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb25e01fc8fde47c96c98a4f3a8123e33a38a50cf9025cc8c4494a518f991792bb7'
+ push_uncompressed_public_key = '41' + uncompressed_public_key
+ p2wsh_p2pk_script_hash = 'd8590cf8ea0674cf3d49fd7ca249b85ef7485dea62c138468bddeb20cd6519f7'
# below are test cases for all of the standard transaction types
@@ -59,18 +62,26 @@ class DecodeScriptTest(BitcoinTestFramework):
# <pubkey> OP_CHECKSIG
rpc_result = self.nodes[0].decodescript(push_public_key + 'ac')
assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm'])
+ # P2PK is translated to P2WPKH
+ assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
# 2) P2PKH scriptPubKey
# OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac')
assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm'])
+ # P2PKH is translated to P2WPKH
+ assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
# 3) multisig scriptPubKey
# <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG
# just imagine that the pub keys used below are different.
# for our purposes here it does not matter that they are the same even though it is unrealistic.
- rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_public_key + push_public_key + '53ae')
+ multisig_script = '52' + push_public_key + push_public_key + push_public_key + '53ae'
+ rpc_result = self.nodes[0].decodescript(multisig_script)
assert_equal('2 ' + public_key + ' ' + public_key + ' ' + public_key + ' 3 OP_CHECKMULTISIG', rpc_result['asm'])
+ # multisig in P2WSH
+ multisig_script_hash = bytes_to_hex_str(sha256(hex_str_to_bytes(multisig_script)))
+ assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm'])
# 4) P2SH scriptPubKey
# OP_HASH160 <Hash160(redeemScript)> OP_EQUAL.
@@ -78,6 +89,8 @@ class DecodeScriptTest(BitcoinTestFramework):
# but this works the same for purposes of this test.
rpc_result = self.nodes[0].decodescript('a9' + push_public_key_hash + '87')
assert_equal('OP_HASH160 ' + public_key_hash + ' OP_EQUAL', rpc_result['asm'])
+ # P2SH does not work in segwit secripts. decodescript should not return a result for it.
+ assert 'segwit' not in rpc_result
# 5) null data scriptPubKey
# use a signature look-alike here to make sure that we do not decode random data as a signature.
@@ -101,8 +114,49 @@ class DecodeScriptTest(BitcoinTestFramework):
# <sender-pubkey> OP_CHECKSIG
#
# lock until block 500,000
- rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac')
+ cltv_script = '63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac'
+ rpc_result = self.nodes[0].decodescript(cltv_script)
assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
+ # CLTV script in P2WSH
+ cltv_script_hash = bytes_to_hex_str(sha256(hex_str_to_bytes(cltv_script)))
+ assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm'])
+
+ # 7) P2PK scriptPubKey
+ # <pubkey> OP_CHECKSIG
+ rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac')
+ assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm'])
+ # uncompressed pubkeys are invalid for checksigs in segwit scripts.
+ # decodescript should not return a P2WPKH equivalent.
+ assert 'segwit' not in rpc_result
+
+ # 8) multisig scriptPubKey with an uncompressed pubkey
+ # <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG
+ # just imagine that the pub keys used below are different.
+ # the purpose of this test is to check that a segwit script is not returned for bare multisig scripts
+ # with an uncompressed pubkey in them.
+ rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_uncompressed_public_key +'52ae')
+ assert_equal('2 ' + public_key + ' ' + uncompressed_public_key + ' 2 OP_CHECKMULTISIG', rpc_result['asm'])
+ # uncompressed pubkeys are invalid for checksigs in segwit scripts.
+ # decodescript should not return a P2WPKH equivalent.
+ assert 'segwit' not in rpc_result
+
+ # 9) P2WPKH scriptpubkey
+ # 0 <PubKeyHash>
+ rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash)
+ assert_equal('0 ' + public_key_hash, rpc_result['asm'])
+ # segwit scripts do not work nested into each other.
+ # a nested segwit script should not be returned in the results.
+ assert 'segwit' not in rpc_result
+
+ # 10) P2WSH scriptpubkey
+ # 0 <ScriptHash>
+ # even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter
+ # for the purpose of this test.
+ rpc_result = self.nodes[0].decodescript('0020' + p2wsh_p2pk_script_hash)
+ assert_equal('0 ' + p2wsh_p2pk_script_hash, rpc_result['asm'])
+ # segwit scripts do not work nested into each other.
+ # a nested segwit script should not be returned in the results.
+ assert 'segwit' not in rpc_result
def decoderawtransaction_asm_sighashtype(self):
"""Test decoding scripts via RPC command "decoderawtransaction".
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
index 7b7c596506..2e0500e7c4 100755
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -49,6 +49,7 @@ class DeprecatedRpcTest(BitcoinTestFramework):
#
address0 = self.nodes[0].getnewaddress()
self.nodes[0].generatetoaddress(101, address0)
+ self.sync_all()
address1 = self.nodes[1].getnewaddress()
self.nodes[1].generatetoaddress(101, address1)
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 5fb9a361d9..0f09c3c552 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -224,7 +224,7 @@ class RawTransactionsTest(BitcoinTestFramework):
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': ''})
+ assert_raises_rpc_error(-5, "Unknown change type ''", self.nodes[2].fundrawtransaction, rawtx, {'change_type': ''})
rawtx = self.nodes[2].fundrawtransaction(rawtx, {'change_type': 'bech32'})
dec_tx = self.nodes[2].decoderawtransaction(rawtx['hex'])
assert_equal('witness_v0_keyhash', dec_tx['vout'][rawtx['changepos']]['scriptPubKey']['type'])
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index aba2841682..7c2125a177 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -554,13 +554,13 @@ class P2PDataStore(P2PInterface):
if reject_reason is not None:
wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock)
- def send_txs_and_test(self, txs, rpc, success=True, reject_code=None, reject_reason=None):
+ def send_txs_and_test(self, txs, rpc, success=True, expect_disconnect=False, reject_code=None, reject_reason=None):
"""Send txs to test node and test whether they're accepted to the mempool.
- add all txs to our tx_store
- send tx messages for all txs
- - if success is True: assert that the tx is accepted to the mempool
- - if success is False: assert that the tx is not accepted to the mempool
+ - if success is True/False: assert that the txs are/are not accepted to the mempool
+ - if expect_disconnect is True: Skip the sync with ping
- if reject_code and reject_reason are set: assert that the correct reject message is received."""
with mininode_lock:
@@ -573,7 +573,10 @@ class P2PDataStore(P2PInterface):
for tx in txs:
self.send_message(msg_tx(tx))
- self.sync_with_ping()
+ if expect_disconnect:
+ self.wait_for_disconnect()
+ else:
+ self.sync_with_ping()
raw_mempool = rpc.getrawmempool()
if success:
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 54ff9eb038..472664a314 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Base class for RPC testing."""
+import configparser
from enum import Enum
import logging
import optparse
@@ -97,10 +98,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
help="Don't stop bitcoinds after the test execution")
- parser.add_option("--srcdir", dest="srcdir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + "/../../../src"),
+ parser.add_option("--srcdir", dest="srcdir", default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../../src"),
help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
- parser.add_option("--cachedir", dest="cachedir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + "/../../cache"),
- help="Directory for caching pregenerated datadirs")
+ parser.add_option("--cachedir", dest="cachedir", default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../cache"),
+ help="Directory for caching pregenerated datadirs (default: %default)")
parser.add_option("--tmpdir", dest="tmpdir", help="Root directory for datadirs")
parser.add_option("-l", "--loglevel", dest="loglevel", default="INFO",
help="log events at this level and higher to the console. Can be set to DEBUG, INFO, WARNING, ERROR or CRITICAL. Passing --loglevel DEBUG will output all logs to console. Note that logs at all levels are always written to the test_framework.log file in the temporary test directory.")
@@ -111,7 +112,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
parser.add_option("--coveragedir", dest="coveragedir",
help="Write tested RPC commands into this directory")
parser.add_option("--configfile", dest="configfile",
- help="Location of the test framework config file")
+ default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../config.ini"),
+ help="Location of the test framework config file (default: %default)")
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",
@@ -129,6 +131,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.options.cachedir = os.path.abspath(self.options.cachedir)
+ config = configparser.ConfigParser()
+ config.read_file(open(self.options.configfile))
+ self.options.bitcoind = os.getenv("BITCOIND", default=config["environment"]["BUILDDIR"] + '/src/bitcoind' + config["environment"]["EXEEXT"])
+ self.options.bitcoincli = os.getenv("BITCOINCLI", default=config["environment"]["BUILDDIR"] + '/src/bitcoin-cli' + config["environment"]["EXEEXT"])
+
# Set up temp directory and start logging
if self.options.tmpdir:
self.options.tmpdir = os.path.abspath(self.options.tmpdir)
@@ -246,12 +253,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
if extra_args is None:
extra_args = [[]] * num_nodes
if binary is None:
- binary = [None] * num_nodes
+ binary = [self.options.bitcoind] * num_nodes
assert_equal(len(extra_confs), num_nodes)
assert_equal(len(extra_args), num_nodes)
assert_equal(len(binary), num_nodes)
for i in range(num_nodes):
- self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
+ self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
def start_node(self, i, *args, **kwargs):
"""Start a bitcoind"""
@@ -399,10 +406,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir = initialize_datadir(self.options.cachedir, i)
- args = [os.getenv("BITCOIND", "bitcoind"), "-datadir=" + datadir]
+ args = [self.options.bitcoind, "-datadir=" + datadir]
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
- self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[],rpchost=None, timewait=None, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None))
+ self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=None, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, stderr=None, mocktime=self.mocktime, coverage_dir=None))
self.nodes[i].args = args
self.start_node(i)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 54e533d6f6..5a6a659392 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -10,7 +10,6 @@ from enum import Enum
import http.client
import json
import logging
-import os
import re
import subprocess
import tempfile
@@ -56,7 +55,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, datadir, rpchost, timewait, binary, stderr, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False):
+ def __init__(self, i, datadir, rpchost, timewait, bitcoind, bitcoin_cli, stderr, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False):
self.index = i
self.datadir = datadir
self.rpchost = rpchost
@@ -65,10 +64,7 @@ class TestNode():
else:
# Wait for up to 60 seconds for the RPC server to respond
self.rpc_timeout = 60
- if binary is None:
- self.binary = os.getenv("BITCOIND", "bitcoind")
- else:
- self.binary = binary
+ self.binary = bitcoind
self.stderr = stderr
self.coverage_dir = coverage_dir
if extra_conf != None:
@@ -89,7 +85,7 @@ class TestNode():
"-noprinttoconsole"
]
- self.cli = TestNodeCLI(os.getenv("BITCOINCLI", "bitcoin-cli"), self.datadir)
+ self.cli = TestNodeCLI(bitcoin_cli, self.datadir)
self.use_cli = use_cli
self.running = False
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 8a82db222b..0989064fdc 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -202,6 +202,7 @@ def main():
parser.add_argument('--keepcache', '-k', action='store_true', help='the default behavior is to flush the cache directory on startup. --keepcache retains the cache from the previous testrun.')
parser.add_argument('--quiet', '-q', action='store_true', help='only print results summary and failure logs')
parser.add_argument('--tmpdirprefix', '-t', default=tempfile.gettempdir(), help="Root directory for datadirs")
+ parser.add_argument('--failfast', action='store_true', help='stop execution after the first test failure')
args, unknown_args = parser.parse_known_args()
# args to be passed on always start with two dashes; tests are the remaining unknown args
@@ -284,9 +285,21 @@ def main():
if not args.keepcache:
shutil.rmtree("%s/test/cache" % config["environment"]["BUILDDIR"], ignore_errors=True)
- run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], tmpdir, args.jobs, args.coverage, passon_args, args.combinedlogslen)
+ run_tests(
+ test_list,
+ config["environment"]["SRCDIR"],
+ config["environment"]["BUILDDIR"],
+ tmpdir,
+ jobs=args.jobs,
+ enable_coverage=args.coverage,
+ args=passon_args,
+ combined_logs_len=args.combinedlogslen,
+ failfast=args.failfast,
+ )
+
+def run_tests(test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=False, args=None, combined_logs_len=0, failfast=False):
+ args = args or []
-def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_coverage=False, args=[], combined_logs_len=0):
# Warn if bitcoind is already running (unix only)
try:
if subprocess.check_output(["pidof", "bitcoind"]) is not None:
@@ -299,11 +312,6 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove
if os.path.isdir(cache_dir):
print("%sWARNING!%s There is a cache directory here: %s. If tests fail unexpectedly, try deleting the cache directory." % (BOLD[1], BOLD[0], cache_dir))
- #Set env vars
- if "BITCOIND" not in os.environ:
- os.environ["BITCOIND"] = build_dir + '/src/bitcoind' + exeext
- os.environ["BITCOINCLI"] = build_dir + '/src/bitcoin-cli' + exeext
-
tests_dir = src_dir + '/test/functional/'
flags = ["--srcdir={}/src".format(build_dir)] + args
@@ -352,6 +360,10 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove
combined_logs, _ = subprocess.Popen([sys.executable, os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate()
print("\n".join(deque(combined_logs.splitlines(), combined_logs_len)))
+ if failfast:
+ logging.debug("Early exiting after test failure")
+ break
+
print_results(test_results, max_len_name, (int(time.time() - start_time)))
if coverage:
@@ -366,6 +378,10 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove
all_passed = all(map(lambda test_result: test_result.was_successful, test_results))
+ # This will be a no-op unless failfast is True in which case there may be dangling
+ # processes which need to be killed.
+ job_queue.kill_and_join()
+
sys.exit(not all_passed)
def print_results(test_results, max_len_name, runtime):
@@ -456,6 +472,17 @@ class TestHandler:
return TestResult(name, status, int(time.time() - start_time)), testdir, stdout, stderr
print('.', end='', flush=True)
+ def kill_and_join(self):
+ """Send SIGKILL to all jobs and block until all have ended."""
+ procs = [i[2] for i in self.jobs]
+
+ for proc in procs:
+ proc.kill()
+
+ for proc in procs:
+ proc.wait()
+
+
class TestResult():
def __init__(self, name, status, time):
self.name = name
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 5d2428e6ef..7658d78383 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -280,7 +280,10 @@ class AddressTypeTest(BitcoinTestFramework):
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')
+ self.log.info('test invalid address type arguments')
+ assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].addmultisigaddress, 2, [compressed_1, compressed_2], None, '')
+ assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].getnewaddress, None, '')
+ assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].getrawchangeaddress, '')
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")
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index bfe90957a7..0e095a6132 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -3,8 +3,20 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the wallet."""
+from decimal import Decimal
+import time
+
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
+from test_framework.util import (
+ assert_array_result,
+ assert_equal,
+ assert_fee_amount,
+ assert_raises_rpc_error,
+ connect_nodes_bi,
+ sync_blocks,
+ sync_mempools,
+ wait_until,
+)
class WalletTest(BitcoinTestFramework):
def set_test_params(self):
@@ -17,9 +29,9 @@ class WalletTest(BitcoinTestFramework):
self.start_node(0)
self.start_node(1)
self.start_node(2)
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
+ connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes_bi(self.nodes, 1, 2)
+ connect_nodes_bi(self.nodes, 0, 2)
self.sync_all([self.nodes[0:3]])
def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size):
@@ -112,11 +124,11 @@ class WalletTest(BitcoinTestFramework):
self.nodes[2].lockunspent(True, [unspent_0])
assert_equal(len(self.nodes[2].listlockunspent()), 0)
assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
- self.nodes[2].lockunspent, False,
- [{"txid": "0000000000000000000000000000000000", "vout": 0}])
+ self.nodes[2].lockunspent, False,
+ [{"txid": "0000000000000000000000000000000000", "vout": 0}])
assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds",
- self.nodes[2].lockunspent, False,
- [{"txid": unspent_0["txid"], "vout": 999}])
+ self.nodes[2].lockunspent, False,
+ [{"txid": unspent_0["txid"], "vout": 999}])
# Have node1 generate 100 blocks (so node0 can recover the fee)
self.nodes[1].generate(100)
@@ -124,7 +136,7 @@ class WalletTest(BitcoinTestFramework):
# node0 should end up with 100 btc in block rewards plus fees, but
# minus the 21 plus fees sent to node2
- assert_equal(self.nodes[0].getbalance(), 100-21)
+ assert_equal(self.nodes[0].getbalance(), 100 - 21)
assert_equal(self.nodes[2].getbalance(), 21)
# Node0 should have two unspent outputs.
@@ -138,7 +150,7 @@ class WalletTest(BitcoinTestFramework):
for utxo in node0utxos:
inputs = []
outputs = {}
- inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
+ inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
txns_to_send.append(self.nodes[0].signrawtransactionwithwallet(raw_tx))
@@ -153,7 +165,7 @@ class WalletTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getbalance(), 0)
assert_equal(self.nodes[2].getbalance(), 94)
- assert_equal(self.nodes[2].getbalance("from1"), 94-21)
+ assert_equal(self.nodes[2].getbalance("from1"), 94 - 21)
# Verify that a spent output cannot be locked anymore
spent_0 = {"txid": node0utxos[0]["txid"], "vout": node0utxos[0]["vout"]}
@@ -215,91 +227,90 @@ class WalletTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1)
assert_equal(self.nodes[0].getunconfirmedbalance(), 1)
- #check if we can list zero value tx as available coins
- #1. create rawtx
- #2. hex-changed one output to 0.0
- #3. sign and send
- #4. check if recipient (node0) can list the zero value tx
+ # check if we can list zero value tx as available coins
+ # 1. create raw_tx
+ # 2. hex-changed one output to 0.0
+ # 3. sign and send
+ # 4. check if recipient (node0) can list the zero value tx
usp = self.nodes[1].listunspent()
- inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
+ inputs = [{"txid": usp[0]['txid'], "vout": usp[0]['vout']}]
outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11}
- rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
- decRawTx = self.nodes[1].decoderawtransaction(rawTx)
- signedRawTx = self.nodes[1].signrawtransactionwithwallet(rawTx)
- decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
- zeroValueTxid= decRawTx['txid']
- self.nodes[1].sendrawtransaction(signedRawTx['hex'])
+ raw_tx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") # replace 11.11 with 0.0 (int32)
+ signed_raw_tx = self.nodes[1].signrawtransactionwithwallet(raw_tx)
+ decoded_raw_tx = self.nodes[1].decoderawtransaction(signed_raw_tx['hex'])
+ zero_value_txid = decoded_raw_tx['txid']
+ self.nodes[1].sendrawtransaction(signed_raw_tx['hex'])
self.sync_all()
- self.nodes[1].generate(1) #mine a block
+ self.nodes[1].generate(1) # mine a block
self.sync_all()
- unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
+ unspent_txs = self.nodes[0].listunspent() # zero value tx must be in listunspents output
found = False
- for uTx in unspentTxs:
- if uTx['txid'] == zeroValueTxid:
+ for uTx in unspent_txs:
+ if uTx['txid'] == zero_value_txid:
found = True
assert_equal(uTx['amount'], Decimal('0'))
assert(found)
- #do some -walletbroadcast tests
+ # do some -walletbroadcast tests
self.stop_nodes()
self.start_node(0, ["-walletbroadcast=0"])
self.start_node(1, ["-walletbroadcast=0"])
self.start_node(2, ["-walletbroadcast=0"])
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
+ connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes_bi(self.nodes, 1, 2)
+ connect_nodes_bi(self.nodes, 0, 2)
self.sync_all([self.nodes[0:3]])
- txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
- txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
- self.nodes[1].generate(1) #mine a block, tx should not be in there
+ txid_not_broadcast = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
+ tx_obj_not_broadcast = self.nodes[0].gettransaction(txid_not_broadcast)
+ self.nodes[1].generate(1) # mine a block, tx should not be in there
self.sync_all([self.nodes[0:3]])
- assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted
+ assert_equal(self.nodes[2].getbalance(), node_2_bal) # should not be changed because tx was not broadcasted
- #now broadcast from another node, mine a block, sync, and check the balance
- self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex'])
+ # now broadcast from another node, mine a block, sync, and check the balance
+ self.nodes[1].sendrawtransaction(tx_obj_not_broadcast['hex'])
self.nodes[1].generate(1)
self.sync_all([self.nodes[0:3]])
node_2_bal += 2
- txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
+ tx_obj_not_broadcast = self.nodes[0].gettransaction(txid_not_broadcast)
assert_equal(self.nodes[2].getbalance(), node_2_bal)
- #create another tx
- txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
+ # create another tx
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
- #restart the nodes with -walletbroadcast=1
+ # restart the nodes with -walletbroadcast=1
self.stop_nodes()
self.start_node(0)
self.start_node(1)
self.start_node(2)
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
+ connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes_bi(self.nodes, 1, 2)
+ connect_nodes_bi(self.nodes, 0, 2)
sync_blocks(self.nodes[0:3])
self.nodes[0].generate(1)
sync_blocks(self.nodes[0:3])
node_2_bal += 2
- #tx should be added to balance because after restarting the nodes tx should be broadcast
+ # tx should be added to balance because after restarting the nodes tx should be broadcast
assert_equal(self.nodes[2].getbalance(), node_2_bal)
- #send a tx with value in a string (PR#6380 +)
- txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2")
- txObj = self.nodes[0].gettransaction(txId)
- assert_equal(txObj['amount'], Decimal('-2'))
+ # send a tx with value in a string (PR#6380 +)
+ txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2")
+ tx_obj = self.nodes[0].gettransaction(txid)
+ assert_equal(tx_obj['amount'], Decimal('-2'))
- txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001")
- txObj = self.nodes[0].gettransaction(txId)
- assert_equal(txObj['amount'], Decimal('-0.0001'))
+ txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001")
+ tx_obj = self.nodes[0].gettransaction(txid)
+ assert_equal(tx_obj['amount'], Decimal('-0.0001'))
- #check if JSON parser can handle scientific notation in strings
- txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4")
- txObj = self.nodes[0].gettransaction(txId)
- assert_equal(txObj['amount'], Decimal('-0.0001'))
+ # check if JSON parser can handle scientific notation in strings
+ txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4")
+ tx_obj = self.nodes[0].gettransaction(txid)
+ assert_equal(tx_obj['amount'], Decimal('-0.0001'))
# This will raise an exception because the amount type is wrong
assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4")
@@ -322,8 +333,8 @@ class WalletTest(BitcoinTestFramework):
# 4. Check that the unspents after import are not spendable
assert_array_result(self.nodes[1].listunspent(),
- {"address": address_to_import},
- {"spendable": False})
+ {"address": address_to_import},
+ {"spendable": False})
# 5. Import private key of the previously imported address on node1
priv_key = self.nodes[2].dumpprivkey(address_to_import)
@@ -331,17 +342,17 @@ class WalletTest(BitcoinTestFramework):
# 6. Check that the unspents are now spendable on node1
assert_array_result(self.nodes[1].listunspent(),
- {"address": address_to_import},
- {"spendable": True})
+ {"address": address_to_import},
+ {"spendable": True})
# Mine a block from node0 to an address from node1
- cbAddr = self.nodes[1].getnewaddress()
- blkHash = self.nodes[0].generatetoaddress(1, cbAddr)[0]
- cbTxId = self.nodes[0].getblock(blkHash)['tx'][0]
+ coinbase_addr = self.nodes[1].getnewaddress()
+ block_hash = self.nodes[0].generatetoaddress(1, coinbase_addr)[0]
+ coinbase_txid = self.nodes[0].getblock(block_hash)['tx'][0]
self.sync_all([self.nodes[0:3]])
# Check that the txid and balance is found by node1
- self.nodes[1].gettransaction(cbTxId)
+ self.nodes[1].gettransaction(coinbase_txid)
# check if wallet or blockchain maintenance changes the balance
self.sync_all([self.nodes[0:3]])
@@ -361,7 +372,7 @@ class WalletTest(BitcoinTestFramework):
label = self.nodes[0].getaccount(addr)
assert_equal(label, s)
assert(s in self.nodes[0].listaccounts().keys())
- self.nodes[0].ensure_ascii = True # restore to default
+ self.nodes[0].ensure_ascii = True # restore to default
# maintenance tests
maintenance = [
@@ -377,9 +388,9 @@ class WalletTest(BitcoinTestFramework):
self.log.info("check " + m)
self.stop_nodes()
# set lower ancestor limit for later
- self.start_node(0, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
- self.start_node(1, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
- self.start_node(2, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
+ self.start_node(0, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
+ self.start_node(1, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
+ self.start_node(2, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
if m == '-reindex':
# reindex will leave rpc warm up "early"; Wait for it to finish
wait_until(lambda: [block_count] * 3 == [self.nodes[i].getblockcount() for i in range(3)])
@@ -400,7 +411,7 @@ class WalletTest(BitcoinTestFramework):
self.nodes[0].generate(1)
node0_balance = self.nodes[0].getbalance()
# Split into two chains
- rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')})
+ rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
self.nodes[0].generate(1)
@@ -411,10 +422,10 @@ class WalletTest(BitcoinTestFramework):
# So we should be able to generate exactly chainlimit txs for each original output
sending_addr = self.nodes[1].getnewaddress()
txid_list = []
- for i in range(chainlimit*2):
+ for i in range(chainlimit * 2):
txid_list.append(self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001')))
- assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2)
- assert_equal(len(txid_list), chainlimit*2)
+ assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit * 2)
+ assert_equal(len(txid_list), chainlimit * 2)
# Without walletrejectlongchains, we will still generate a txid
# The tx will be stored in the wallet but not accepted to the mempool
@@ -422,26 +433,26 @@ class WalletTest(BitcoinTestFramework):
assert(extra_txid not in self.nodes[0].getrawmempool())
assert(extra_txid in [tx["txid"] for tx in self.nodes[0].listtransactions()])
self.nodes[0].abandontransaction(extra_txid)
- total_txs = len(self.nodes[0].listtransactions("*",99999))
+ total_txs = len(self.nodes[0].listtransactions("*", 99999))
# Try with walletrejectlongchains
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
self.stop_node(0)
- self.start_node(0, extra_args=["-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)])
+ self.start_node(0, extra_args=["-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)])
# wait for loadmempool
timeout = 10
- while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit*2):
+ while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit * 2):
time.sleep(0.5)
timeout -= 0.5
- assert_equal(len(self.nodes[0].getrawmempool()), chainlimit*2)
+ assert_equal(len(self.nodes[0].getrawmempool()), chainlimit * 2)
node0_balance = self.nodes[0].getbalance()
# With walletrejectlongchains we will not create the tx and store it in our wallet.
assert_raises_rpc_error(-4, "Transaction has too long of a mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01'))
# Verify nothing new in wallet
- assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999)))
+ assert_equal(total_txs, len(self.nodes[0].listtransactions("*", 99999)))
# Test getaddressinfo. Note that these addresses are taken from disablewallet.py
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].getaddressinfo, "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy")
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
index 6775d8b46d..baf933f079 100755
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -46,10 +46,10 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")):
if self.call == Call.single:
if self.data == Data.address:
response = self.try_rpc(self.node.importaddress, self.address["address"], self.label,
- self.rescan == Rescan.yes)
+ self.rescan == Rescan.yes)
elif self.data == Data.pub:
response = self.try_rpc(self.node.importpubkey, self.address["pubkey"], self.label,
- self.rescan == Rescan.yes)
+ self.rescan == Rescan.yes)
elif self.data == Data.priv:
response = self.try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes)
assert_equal(response, None)
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
index d0ec290f36..9cee9aa49a 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -3,8 +3,13 @@
# 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."""
+from decimal import Decimal
+
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
+from test_framework.util import (
+ assert_equal,
+ assert_raises_rpc_error,
+)
class ImportPrunedFundsTest(BitcoinTestFramework):
def set_test_params(self):
@@ -24,18 +29,18 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
address2 = self.nodes[0].getnewaddress()
# privkey
address3 = self.nodes[0].getnewaddress()
- address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
+ address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
- #Check only one address
+ # Check only one address
address_info = self.nodes[0].getaddressinfo(address1)
assert_equal(address_info['ismine'], True)
self.sync_all()
- #Node 1 sync test
- assert_equal(self.nodes[1].getblockcount(),101)
+ # Node 1 sync test
+ assert_equal(self.nodes[1].getblockcount(), 101)
- #Address Test - before import
+ # Address Test - before import
address_info = self.nodes[1].getaddressinfo(address1)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
@@ -48,7 +53,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
- #Send funds to self
+ # Send funds to self
txnid1 = self.nodes[0].sendtoaddress(address1, 0.1)
self.nodes[0].generate(1)
rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex']
@@ -66,19 +71,19 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
self.sync_all()
- #Import with no affiliated address
+ # Import with no affiliated address
assert_raises_rpc_error(-5, "No addresses", self.nodes[1].importprunedfunds, rawtxn1, proof1)
balance1 = self.nodes[1].getbalance("", 0, True)
assert_equal(balance1, Decimal(0))
- #Import with affiliated address with no rescan
+ # Import with affiliated address with no rescan
self.nodes[1].importaddress(address2, "add2", False)
self.nodes[1].importprunedfunds(rawtxn2, proof2)
balance2 = self.nodes[1].getbalance("add2", 0, True)
assert_equal(balance2, Decimal('0.05'))
- #Import with private key with no rescan
+ # Import with private key with no rescan
self.nodes[1].importprivkey(privkey=address3_privkey, label="add3", rescan=False)
self.nodes[1].importprunedfunds(rawtxn3, proof3)
balance3 = self.nodes[1].getbalance("add3", 0, False)
@@ -86,7 +91,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
balance3 = self.nodes[1].getbalance("*", 0, True)
assert_equal(balance3, Decimal('0.075'))
- #Addresses Test - after import
+ # Addresses Test - after import
address_info = self.nodes[1].getaddressinfo(address1)
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], False)
@@ -97,7 +102,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
assert_equal(address_info['iswatchonly'], False)
assert_equal(address_info['ismine'], True)
- #Remove transactions
+ # Remove transactions
assert_raises_rpc_error(-8, "Transaction does not exist in wallet.", self.nodes[1].removeprunedfunds, txnid1)
balance1 = self.nodes[1].getbalance("*", 0, True)
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
index aba5d642bc..e0e20cc9a3 100755
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -51,37 +51,37 @@ class ReceivedByTest(BitcoinTestFramework):
{"address": empty_addr},
{"address": empty_addr, "label": "", "amount": 0, "confirmations": 0, "txids": []})
- #Test Address filtering
- #Only on addr
- expected = {"address":addr, "label":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}
+ # Test Address filtering
+ # Only on addr
+ expected = {"address": addr, "label": "", "amount": Decimal("0.1"), "confirmations": 10, "txids": [txid, ]}
res = self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True, address_filter=addr)
- assert_array_result(res, {"address":addr}, expected)
+ assert_array_result(res, {"address": addr}, expected)
assert_equal(len(res), 1)
- #Error on invalid address
+ # Error on invalid address
assert_raises_rpc_error(-4, "address_filter parameter was invalid", self.nodes[1].listreceivedbyaddress, minconf=0, include_empty=True, include_watchonly=True, address_filter="bamboozling")
- #Another address receive money
+ # Another address receive money
res = self.nodes[1].listreceivedbyaddress(0, True, True)
- assert_equal(len(res), 2) #Right now 2 entries
+ assert_equal(len(res), 2) # Right now 2 entries
other_addr = self.nodes[1].getnewaddress()
txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1)
self.nodes[0].generate(1)
self.sync_all()
- #Same test as above should still pass
- expected = {"address":addr, "label":"", "amount":Decimal("0.1"), "confirmations":11, "txids":[txid,]}
+ # Same test as above should still pass
+ expected = {"address": addr, "label": "", "amount": Decimal("0.1"), "confirmations": 11, "txids": [txid, ]}
res = self.nodes[1].listreceivedbyaddress(0, True, True, addr)
- assert_array_result(res, {"address":addr}, expected)
+ assert_array_result(res, {"address": addr}, expected)
assert_equal(len(res), 1)
- #Same test as above but with other_addr should still pass
- expected = {"address":other_addr, "label":"", "amount":Decimal("0.1"), "confirmations":1, "txids":[txid2,]}
+ # Same test as above but with other_addr should still pass
+ expected = {"address": other_addr, "label": "", "amount": Decimal("0.1"), "confirmations": 1, "txids": [txid2, ]}
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
- assert_array_result(res, {"address":other_addr}, expected)
+ assert_array_result(res, {"address": other_addr}, expected)
assert_equal(len(res), 1)
- #Should be two entries though without filter
+ # Should be two entries though without filter
res = self.nodes[1].listreceivedbyaddress(0, True, True)
- assert_equal(len(res), 3) #Became 3 entries
+ assert_equal(len(res), 3) # Became 3 entries
- #Not on random addr
- other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr
+ # Not on random addr
+ other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
assert_equal(len(res), 0)
@@ -112,8 +112,8 @@ class ReceivedByTest(BitcoinTestFramework):
self.log.info("listreceivedbylabel + getreceivedbylabel Test")
# set pre-state
- addrArr = self.nodes[1].getnewaddress()
- label = self.nodes[1].getaccount(addrArr)
+ address = self.nodes[1].getnewaddress()
+ label = self.nodes[1].getaccount(address)
received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel() if r["label"] == label][0]
balance_by_label = self.nodes[1].getreceivedbylabel(label)
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index 930bfcd7b0..50a3313e2f 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -150,26 +150,26 @@ class ListSinceBlockTest (BitcoinTestFramework):
# send from nodes[1] using utxo to nodes[0]
change = '%.8f' % (float(utxo['amount']) - 1.0003)
- recipientDict = {
+ recipient_dict = {
self.nodes[0].getnewaddress(): 1,
self.nodes[1].getnewaddress(): change,
}
- utxoDicts = [{
+ utxo_dicts = [{
'txid': utxo['txid'],
'vout': utxo['vout'],
}]
txid1 = self.nodes[1].sendrawtransaction(
self.nodes[1].signrawtransactionwithwallet(
- self.nodes[1].createrawtransaction(utxoDicts, recipientDict))['hex'])
+ self.nodes[1].createrawtransaction(utxo_dicts, recipient_dict))['hex'])
# send from nodes[2] using utxo to nodes[3]
- recipientDict2 = {
+ recipient_dict2 = {
self.nodes[3].getnewaddress(): 1,
self.nodes[2].getnewaddress(): change,
}
self.nodes[2].sendrawtransaction(
self.nodes[2].signrawtransactionwithwallet(
- self.nodes[2].createrawtransaction(utxoDicts, recipientDict2))['hex'])
+ self.nodes[2].createrawtransaction(utxo_dicts, recipient_dict2))['hex'])
# generate on both sides
lastblockhash = self.nodes[1].generate(3)[2]
@@ -225,16 +225,16 @@ class ListSinceBlockTest (BitcoinTestFramework):
utxos = self.nodes[2].listunspent()
utxo = utxos[0]
change = '%.8f' % (float(utxo['amount']) - 1.0003)
- recipientDict = {
+ recipient_dict = {
self.nodes[0].getnewaddress(): 1,
self.nodes[2].getnewaddress(): change,
}
- utxoDicts = [{
+ utxo_dicts = [{
'txid': utxo['txid'],
'vout': utxo['vout'],
}]
signedtxres = self.nodes[2].signrawtransactionwithwallet(
- self.nodes[2].createrawtransaction(utxoDicts, recipientDict))
+ self.nodes[2].createrawtransaction(utxo_dicts, recipient_dict))
assert signedtxres['complete']
signedtx = signedtxres['hex']
diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
index 5466bbf18b..883942cc19 100755
--- a/test/functional/wallet_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -3,13 +3,20 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the listtransactions API."""
-
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-from test_framework.mininode import CTransaction, COIN
+from decimal import Decimal
from io import BytesIO
-def txFromHex(hexstring):
+from test_framework.mininode import CTransaction, COIN
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_array_result,
+ assert_equal,
+ bytes_to_hex_str,
+ hex_str_to_bytes,
+ sync_mempools,
+)
+
+def tx_from_hex(hexstring):
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(hexstring))
tx.deserialize(f)
@@ -26,61 +33,61 @@ class ListTransactionsTest(BitcoinTestFramework):
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all()
assert_array_result(self.nodes[0].listtransactions(),
- {"txid":txid},
- {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0})
+ {"txid": txid},
+ {"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 0})
assert_array_result(self.nodes[1].listtransactions(),
- {"txid":txid},
- {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
+ {"txid": txid},
+ {"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 0})
# mine a block, confirmations should change:
self.nodes[0].generate(1)
self.sync_all()
assert_array_result(self.nodes[0].listtransactions(),
- {"txid":txid},
- {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1})
+ {"txid": txid},
+ {"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 1})
assert_array_result(self.nodes[1].listtransactions(),
- {"txid":txid},
- {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1})
+ {"txid": txid},
+ {"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 1})
# send-to-self:
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
assert_array_result(self.nodes[0].listtransactions(),
- {"txid":txid, "category":"send"},
- {"amount":Decimal("-0.2")})
+ {"txid": txid, "category": "send"},
+ {"amount": Decimal("-0.2")})
assert_array_result(self.nodes[0].listtransactions(),
- {"txid":txid, "category":"receive"},
- {"amount":Decimal("0.2")})
+ {"txid": txid, "category": "receive"},
+ {"amount": Decimal("0.2")})
# sendmany from node1: twice to self, twice to node2:
- send_to = { self.nodes[0].getnewaddress() : 0.11,
- self.nodes[1].getnewaddress() : 0.22,
- self.nodes[0].getaccountaddress("from1") : 0.33,
- self.nodes[1].getaccountaddress("toself") : 0.44 }
+ send_to = {self.nodes[0].getnewaddress(): 0.11,
+ self.nodes[1].getnewaddress(): 0.22,
+ self.nodes[0].getaccountaddress("from1"): 0.33,
+ self.nodes[1].getaccountaddress("toself"): 0.44}
txid = self.nodes[1].sendmany("", send_to)
self.sync_all()
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"send","amount":Decimal("-0.11")},
- {"txid":txid} )
+ {"category": "send", "amount": Decimal("-0.11")},
+ {"txid": txid})
assert_array_result(self.nodes[0].listtransactions(),
- {"category":"receive","amount":Decimal("0.11")},
- {"txid":txid} )
+ {"category": "receive", "amount": Decimal("0.11")},
+ {"txid": txid})
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"send","amount":Decimal("-0.22")},
- {"txid":txid} )
+ {"category": "send", "amount": Decimal("-0.22")},
+ {"txid": txid})
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"receive","amount":Decimal("0.22")},
- {"txid":txid} )
+ {"category": "receive", "amount": Decimal("0.22")},
+ {"txid": txid})
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"send","amount":Decimal("-0.33")},
- {"txid":txid} )
+ {"category": "send", "amount": Decimal("-0.33")},
+ {"txid": txid})
assert_array_result(self.nodes[0].listtransactions(),
- {"category":"receive","amount":Decimal("0.33")},
- {"txid":txid, "account" : "from1"} )
+ {"category": "receive", "amount": Decimal("0.33")},
+ {"txid": txid, "account": "from1"})
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"send","amount":Decimal("-0.44")},
- {"txid":txid, "account" : ""} )
+ {"category": "send", "amount": Decimal("-0.44")},
+ {"txid": txid, "account": ""})
assert_array_result(self.nodes[1].listtransactions(),
- {"category":"receive","amount":Decimal("0.44")},
- {"txid":txid, "account" : "toself"} )
+ {"category": "receive", "amount": Decimal("0.44")},
+ {"txid": txid, "account": "toself"})
pubkey = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
multisig = self.nodes[1].createmultisig(1, [pubkey])
@@ -90,8 +97,8 @@ class ListTransactionsTest(BitcoinTestFramework):
self.sync_all()
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
- {"category":"receive","amount":Decimal("0.1")},
- {"txid":txid, "account" : "watchonly"} )
+ {"category": "receive", "amount": Decimal("0.1")},
+ {"txid": txid, "account": "watchonly"})
self.run_rbf_opt_in_test()
@@ -117,9 +124,9 @@ class ListTransactionsTest(BitcoinTestFramework):
# 1. Chain a few transactions that don't opt-in.
txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
assert(not is_opt_in(self.nodes[0], txid_1))
- assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
+ assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable": "no"})
sync_mempools(self.nodes)
- assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
+ assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable": "no"})
# Tx2 will build off txid_1, still not opting in to RBF.
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_1)
@@ -129,7 +136,7 @@ class ListTransactionsTest(BitcoinTestFramework):
assert_equal(utxo_to_use["safe"], False)
# Create tx2 using createrawtransaction
- inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}]
+ inputs = [{"txid": utxo_to_use["txid"], "vout": utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.999}
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
tx2_signed = self.nodes[1].signrawtransactionwithwallet(tx2)["hex"]
@@ -137,51 +144,51 @@ class ListTransactionsTest(BitcoinTestFramework):
# ...and check the result
assert(not is_opt_in(self.nodes[1], txid_2))
- assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
+ assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable": "no"})
sync_mempools(self.nodes)
- assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
+ assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable": "no"})
# Tx3 will opt-in to RBF
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2)
- inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}]
+ inputs = [{"txid": txid_2, "vout": utxo_to_use["vout"]}]
outputs = {self.nodes[1].getnewaddress(): 0.998}
tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
- tx3_modified = txFromHex(tx3)
+ tx3_modified = tx_from_hex(tx3)
tx3_modified.vin[0].nSequence = 0
tx3 = bytes_to_hex_str(tx3_modified.serialize())
tx3_signed = self.nodes[0].signrawtransactionwithwallet(tx3)['hex']
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
assert(is_opt_in(self.nodes[0], txid_3))
- assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
+ assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable": "yes"})
sync_mempools(self.nodes)
- assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
+ assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable": "yes"})
# Tx4 will chain off tx3. Doesn't signal itself, but depends on one
# that does.
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3)
- inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}]
+ inputs = [{"txid": txid_3, "vout": utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.997}
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
tx4_signed = self.nodes[1].signrawtransactionwithwallet(tx4)["hex"]
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
assert(not is_opt_in(self.nodes[1], txid_4))
- assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
+ assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "yes"})
sync_mempools(self.nodes)
- assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
+ assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "yes"})
# Replace tx3, and check that tx4 becomes unknown
tx3_b = tx3_modified
- tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
+ tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
tx3_b = bytes_to_hex_str(tx3_b.serialize())
tx3_b_signed = self.nodes[0].signrawtransactionwithwallet(tx3_b)['hex']
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
assert(is_opt_in(self.nodes[0], txid_3b))
- assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
+ assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "unknown"})
sync_mempools(self.nodes)
- assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
+ assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "unknown"})
# Check gettransaction as well:
for n in self.nodes[0:2]:
@@ -197,7 +204,5 @@ class ListTransactionsTest(BitcoinTestFramework):
assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no")
assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown")
-
if __name__ == '__main__':
ListTransactionsTest().main()
-
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index aee84f7e90..b4e4cb1686 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -5,7 +5,12 @@
"""Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
+from test_framework.util import (
+ assert_equal,
+ connect_nodes,
+ disconnect_nodes,
+ sync_blocks,
+)
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
@@ -26,9 +31,9 @@ class TxnMallTest(BitcoinTestFramework):
def run_test(self):
if self.options.segwit:
- output_type="p2sh-segwit"
+ output_type = "p2sh-segwit"
else:
- output_type="legacy"
+ output_type = "legacy"
# All nodes should start with 1,250 BTC:
starting_balance = 1250
@@ -53,28 +58,27 @@ class TxnMallTest(BitcoinTestFramework):
# Coins are sent to node1_address
node1_address = self.nodes[1].getnewaddress("from0")
- # Send tx1, and another transaction tx2 that won't be cloned
+ # Send tx1, and another transaction tx2 that won't be cloned
txid1 = self.nodes[0].sendfrom("foo", node1_address, 40, 0)
txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0)
- # Construct a clone of tx1, to be malleated
- rawtx1 = self.nodes[0].getrawtransaction(txid1,1)
- clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}]
- clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"],
- rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]}
+ # Construct a clone of tx1, to be malleated
+ rawtx1 = self.nodes[0].getrawtransaction(txid1, 1)
+ clone_inputs = [{"txid": rawtx1["vin"][0]["txid"], "vout": rawtx1["vin"][0]["vout"]}]
+ clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][0]["value"],
+ rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][1]["value"]}
clone_locktime = rawtx1["locktime"]
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)
# createrawtransaction randomizes the order of its outputs, so swap them if necessary.
# output 0 is at version+#inputs+input+sigstub+sequence+#outputs
# 40 BTC serialized is 00286bee00000000
- pos0 = 2*(4+1+36+1+4+1)
+ pos0 = 2 * (4 + 1 + 36 + 1 + 4 + 1)
hex40 = "00286bee00000000"
- output_len = 16 + 2 + 2 * int("0x" + clone_raw[pos0 + 16 : pos0 + 16 + 2], 0)
- if (rawtx1["vout"][0]["value"] == 40 and clone_raw[pos0 : pos0 + 16] != hex40 or
- rawtx1["vout"][0]["value"] != 40 and clone_raw[pos0 : pos0 + 16] == hex40):
- output0 = clone_raw[pos0 : pos0 + output_len]
- output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len]
+ output_len = 16 + 2 + 2 * int("0x" + clone_raw[pos0 + 16:pos0 + 16 + 2], 0)
+ if (rawtx1["vout"][0]["value"] == 40 and clone_raw[pos0:pos0 + 16] != hex40 or rawtx1["vout"][0]["value"] != 40 and clone_raw[pos0:pos0 + 16] == hex40):
+ output0 = clone_raw[pos0:pos0 + output_len]
+ output1 = clone_raw[pos0 + output_len:pos0 + 2 * output_len]
clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:]
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
@@ -142,7 +146,7 @@ class TxnMallTest(BitcoinTestFramework):
# Check node0's total balance; should be same as before the clone, + 100 BTC for 2 matured,
# less possible orphaned matured subsidy
expected += 100
- if (self.options.mine_block):
+ if (self.options.mine_block):
expected -= 50
assert_equal(self.nodes[0].getbalance(), expected)
assert_equal(self.nodes[0].getbalance("*", 0), expected)
@@ -153,16 +157,11 @@ class TxnMallTest(BitcoinTestFramework):
# "bar" should have been debited by (possibly unconfirmed) tx2
assert_equal(self.nodes[0].getbalance("bar", 0), 29 + tx2["amount"] + tx2["fee"])
# "" should have starting balance, less funding txes, plus subsidies
- assert_equal(self.nodes[0].getbalance("", 0), starting_balance
- - 1219
- + fund_foo_tx["fee"]
- - 29
- + fund_bar_tx["fee"]
- + 100)
+ assert_equal(self.nodes[0].getbalance("", 0),
+ starting_balance - 1219 + fund_foo_tx["fee"] - 29 + fund_bar_tx["fee"] + 100)
# Node1's "from0" account balance
assert_equal(self.nodes[1].getbalance("from0", 0), -(tx1["amount"] + tx2["amount"]))
if __name__ == '__main__':
TxnMallTest().main()
-
diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py
index d644a94c73..d8d91132d1 100755
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -3,9 +3,16 @@
# 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."""
+from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
+from test_framework.util import (
+ assert_equal,
+ connect_nodes,
+ disconnect_nodes,
+ find_output,
+ sync_blocks,
+)
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
@@ -84,14 +91,14 @@ class TxnMallTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getbalance(), expected)
# foo and bar accounts should be debited:
- assert_equal(self.nodes[0].getbalance("foo", 0), 1219+tx1["amount"]+tx1["fee"])
- assert_equal(self.nodes[0].getbalance("bar", 0), 29+tx2["amount"]+tx2["fee"])
+ assert_equal(self.nodes[0].getbalance("foo", 0), 1219 + tx1["amount"] + tx1["fee"])
+ assert_equal(self.nodes[0].getbalance("bar", 0), 29 + tx2["amount"] + tx2["fee"])
if self.options.mine_block:
assert_equal(tx1["confirmations"], 1)
assert_equal(tx2["confirmations"], 1)
# Node1's "from0" balance should be both transaction amounts:
- assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"]))
+ assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"] + tx2["amount"]))
else:
assert_equal(tx1["confirmations"], 0)
assert_equal(tx2["confirmations"], 0)
@@ -117,7 +124,7 @@ class TxnMallTest(BitcoinTestFramework):
assert_equal(tx1["confirmations"], -2)
assert_equal(tx2["confirmations"], -2)
- # Node0's total balance should be starting balance, plus 100BTC for
+ # Node0's total balance should be starting balance, plus 100BTC for
# two more matured blocks, minus 1240 for the double-spend, plus fees (which are
# negative):
expected = starting_balance + 100 - 1240 + fund_foo_tx["fee"] + fund_bar_tx["fee"] + doublespend_fee
@@ -128,18 +135,11 @@ class TxnMallTest(BitcoinTestFramework):
# fees (which are negative)
assert_equal(self.nodes[0].getbalance("foo"), 1219)
assert_equal(self.nodes[0].getbalance("bar"), 29)
- assert_equal(self.nodes[0].getbalance(""), starting_balance
- -1219
- - 29
- -1240
- + 100
- + fund_foo_tx["fee"]
- + fund_bar_tx["fee"]
- + doublespend_fee)
+ assert_equal(self.nodes[0].getbalance(""),
+ starting_balance - 1219 - 29 - 1240 + 100 + fund_foo_tx["fee"] + fund_bar_tx["fee"] + doublespend_fee)
# Node1's "from0" account balance should be just the doublespend:
assert_equal(self.nodes[1].getbalance("from0"), 1240)
if __name__ == '__main__':
TxnMallTest().main()
-