aboutsummaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rw-r--r--qa/README.md34
-rwxr-xr-xqa/pull-tester/rpc-tests.py221
-rw-r--r--qa/pull-tester/tests_config.py.in6
-rwxr-xr-xqa/rpc-tests/abandonconflict.py27
-rwxr-xr-xqa/rpc-tests/bip65-cltv-p2p.py25
-rwxr-xr-xqa/rpc-tests/bip65-cltv.py12
-rwxr-xr-xqa/rpc-tests/bip68-112-113-p2p.py539
-rwxr-xr-xqa/rpc-tests/bip68-sequence.py79
-rwxr-xr-xqa/rpc-tests/bip9-softforks.py240
-rwxr-xr-xqa/rpc-tests/bipdersig-p2p.py27
-rwxr-xr-xqa/rpc-tests/bipdersig.py12
-rwxr-xr-xqa/rpc-tests/blockchain.py31
-rwxr-xr-xqa/rpc-tests/create_cache.py23
-rwxr-xr-xqa/rpc-tests/decodescript.py37
-rwxr-xr-xqa/rpc-tests/disablewallet.py27
-rwxr-xr-xqa/rpc-tests/forknotify.py9
-rwxr-xr-xqa/rpc-tests/fundrawtransaction.py150
-rwxr-xr-xqa/rpc-tests/getblocktemplate_longpoll.py33
-rwxr-xr-xqa/rpc-tests/getblocktemplate_proposals.py55
-rwxr-xr-xqa/rpc-tests/getchaintips.py9
-rwxr-xr-xqa/rpc-tests/httpbasics.py88
-rwxr-xr-xqa/rpc-tests/importprunedfunds.py143
-rwxr-xr-xqa/rpc-tests/invalidateblock.py39
-rwxr-xr-xqa/rpc-tests/invalidblockrequest.py24
-rwxr-xr-xqa/rpc-tests/invalidtxrequest.py18
-rwxr-xr-xqa/rpc-tests/keypool.py43
-rwxr-xr-xqa/rpc-tests/listtransactions.py94
-rwxr-xr-xqa/rpc-tests/maxblocksinflight.py70
-rwxr-xr-xqa/rpc-tests/maxuploadtarget.py52
-rwxr-xr-xqa/rpc-tests/mempool_limit.py19
-rwxr-xr-xqa/rpc-tests/mempool_packages.py36
-rwxr-xr-xqa/rpc-tests/mempool_reorg.py26
-rwxr-xr-xqa/rpc-tests/mempool_resurrect_test.py21
-rwxr-xr-xqa/rpc-tests/mempool_spendcoinbase.py19
-rwxr-xr-xqa/rpc-tests/merkle_blocks.py13
-rwxr-xr-xqa/rpc-tests/multi_rpc.py60
-rwxr-xr-xqa/rpc-tests/nodehandling.py22
-rwxr-xr-xqa/rpc-tests/p2p-acceptblock.py45
-rwxr-xr-xqa/rpc-tests/p2p-feefilter.py105
-rwxr-xr-xqa/rpc-tests/p2p-fullblocktest.py44
-rwxr-xr-xqa/rpc-tests/p2p-mempool.py99
-rwxr-xr-xqa/rpc-tests/p2p-versionbits-warning.py161
-rwxr-xr-xqa/rpc-tests/prioritise_transaction.py51
-rwxr-xr-xqa/rpc-tests/proxy_test.py89
-rwxr-xr-xqa/rpc-tests/pruning.py84
-rwxr-xr-xqa/rpc-tests/rawtransactions.py29
-rwxr-xr-xqa/rpc-tests/receivedby.py51
-rwxr-xr-xqa/rpc-tests/reindex.py31
-rwxr-xr-xqa/rpc-tests/replace-by-fee.py92
-rwxr-xr-xqa/rpc-tests/rest.py56
-rwxr-xr-xqa/rpc-tests/rpcbind_test.py10
-rwxr-xr-xqa/rpc-tests/sendheaders.py53
-rwxr-xr-xqa/rpc-tests/signmessages.py41
-rwxr-xr-xqa/rpc-tests/signrawtransactions.py13
-rwxr-xr-xqa/rpc-tests/smartfees.py30
-rw-r--r--qa/rpc-tests/test_framework/authproxy.py17
-rw-r--r--qa/rpc-tests/test_framework/bignum.py5
-rw-r--r--qa/rpc-tests/test_framework/blockstore.py20
-rw-r--r--qa/rpc-tests/test_framework/blocktools.py16
-rwxr-xr-xqa/rpc-tests/test_framework/comptool.py47
-rw-r--r--qa/rpc-tests/test_framework/coverage.py7
-rwxr-xr-xqa/rpc-tests/test_framework/mininode.py447
-rw-r--r--qa/rpc-tests/test_framework/netutil.py32
-rw-r--r--qa/rpc-tests/test_framework/script.py15
-rw-r--r--qa/rpc-tests/test_framework/socks5.py13
-rwxr-xr-xqa/rpc-tests/test_framework/test_framework.py61
-rw-r--r--qa/rpc-tests/test_framework/util.py230
-rwxr-xr-xqa/rpc-tests/txn_clone.py9
-rwxr-xr-xqa/rpc-tests/txn_doublespend.py9
-rwxr-xr-xqa/rpc-tests/wallet.py115
-rwxr-xr-xqa/rpc-tests/walletbackup.py15
-rwxr-xr-xqa/rpc-tests/zapwallettxes.py25
-rwxr-xr-xqa/rpc-tests/zmq_test.py58
73 files changed, 3225 insertions, 1383 deletions
diff --git a/qa/README.md b/qa/README.md
index 758d1f47e5..7489eb5130 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -5,18 +5,42 @@ Every pull request to the bitcoin repository is built and run through
the regression test suite. You can also run all or only individual
tests locally.
+Test dependencies
+=================
+Before running the tests, the following must be installed.
+
+Unix
+----
+The python3-zmq library is required. On Ubuntu or Debian it can be installed via:
+```
+sudo apt-get install python3-zmq
+```
+
Running tests
=============
-You can run any single test by calling `qa/pull-tester/rpc-tests.py <testname>`.
+You can run any single test by calling
+
+ qa/pull-tester/rpc-tests.py <testname>
+
+Or you can run any combination of tests by calling
+
+ qa/pull-tester/rpc-tests.py <testname1> <testname2> <testname3> ...
+
+Run the regression test suite with
+
+ qa/pull-tester/rpc-tests.py
+
+Run all possible tests with
-Or you can run any combination of tests by calling `qa/pull-tester/rpc-tests.py <testname1> <testname2> <testname3> ...`
+ qa/pull-tester/rpc-tests.py -extended
-Run the regression test suite with `qa/pull-tester/rpc-tests.py`
+By default, tests will be run in parallel if you want to specify how many
+tests should be run in parallel, append `-paralell=n` (default n=4).
-Run all possible tests with `qa/pull-tester/rpc-tests.py -extended`
+If you want to create a basic coverage report for the rpc test suite, append `--coverage`.
-Possible options:
+Possible options, which apply to each individual test run:
```
-h, --help show this help message and exit
diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py
index 7649c1183b..f810f89a59 100755
--- a/qa/pull-tester/rpc-tests.py
+++ b/qa/pull-tester/rpc-tests.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -31,49 +31,77 @@ import re
from tests_config import *
+BOLD = ("","")
+if os.name == 'posix':
+ # primitive formatting on supported
+ # terminal via ANSI escape sequences:
+ BOLD = ('\033[0m', '\033[1m')
+
+RPC_TESTS_DIR = BUILDDIR + '/qa/rpc-tests/'
+
#If imported values are not defined then set to zero (or disabled)
-if not vars().has_key('ENABLE_WALLET'):
+if 'ENABLE_WALLET' not in vars():
ENABLE_WALLET=0
-if not vars().has_key('ENABLE_BITCOIND'):
+if 'ENABLE_BITCOIND' not in vars():
ENABLE_BITCOIND=0
-if not vars().has_key('ENABLE_UTILS'):
+if 'ENABLE_UTILS' not in vars():
ENABLE_UTILS=0
-if not vars().has_key('ENABLE_ZMQ'):
+if 'ENABLE_ZMQ' not in vars():
ENABLE_ZMQ=0
ENABLE_COVERAGE=0
-#Create a set to store arguments and create the passOn string
+#Create a set to store arguments and create the passon string
opts = set()
-passOn = ""
-p = re.compile("^--")
+passon_args = []
+PASSON_REGEX = re.compile("^--")
+PARALLEL_REGEX = re.compile('^-parallel=')
-bold = ("","")
-if (os.name == 'posix'):
- bold = ('\033[0m', '\033[1m')
+print_help = False
+run_parallel = 4
for arg in sys.argv[1:]:
+ if arg == "--help" or arg == "-h" or arg == "-?":
+ print_help = True
+ break
if arg == '--coverage':
ENABLE_COVERAGE = 1
- elif (p.match(arg) or arg == "-h"):
- passOn += " " + arg
+ elif PASSON_REGEX.match(arg):
+ passon_args.append(arg)
+ elif PARALLEL_REGEX.match(arg):
+ run_parallel = int(arg.split(sep='=', maxsplit=1)[1])
else:
opts.add(arg)
#Set env vars
-buildDir = BUILDDIR
if "BITCOIND" not in os.environ:
- os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT
+ os.environ["BITCOIND"] = BUILDDIR + '/src/bitcoind' + EXEEXT
if "BITCOINCLI" not in os.environ:
- os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT
+ os.environ["BITCOINCLI"] = BUILDDIR + '/src/bitcoin-cli' + EXEEXT
-#Disable Windows tests by default
if EXEEXT == ".exe" and "-win" not in opts:
- print "Win tests currently disabled. Use -win option to enable"
+ # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9
+ # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964
+ print("Win tests currently disabled by default. Use -win option to enable")
sys.exit(0)
+if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1):
+ print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled")
+ sys.exit(0)
+
+# python3-zmq may not be installed. Handle this gracefully and with some helpful info
+if ENABLE_ZMQ:
+ try:
+ import zmq
+ except ImportError as e:
+ print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \
+ "to run zmq tests, see dependency info in /qa/README.md.")
+ ENABLE_ZMQ=0
+
#Tests
testScripts = [
+ 'walletbackup.py',
+ 'bip68-112-113-p2p.py',
'wallet.py',
'listtransactions.py',
'receivedby.py',
@@ -93,7 +121,6 @@ testScripts = [
'merkle_blocks.py',
'fundrawtransaction.py',
'signrawtransactions.py',
- 'walletbackup.py',
'nodehandling.py',
'reindex.py',
'decodescript.py',
@@ -106,8 +133,15 @@ testScripts = [
'invalidblockrequest.py',
'invalidtxrequest.py',
'abandonconflict.py',
+ 'p2p-versionbits-warning.py',
+ 'importprunedfunds.py',
+ 'signmessages.py',
]
+if ENABLE_ZMQ:
+ testScripts.append('zmq_test.py')
+
testScriptsExt = [
+ 'bip9-softforks.py',
'bip65-cltv.py',
'bip65-cltv-p2p.py',
'bip68-sequence.py',
@@ -117,7 +151,6 @@ testScriptsExt = [
'getblocktemplate_proposals.py',
'txn_doublespend.py',
'txn_clone.py --mineblock',
- 'pruning.py',
'forknotify.py',
'invalidateblock.py',
# 'rpcbind_test.py', #temporary, bug in libevent, see #6655
@@ -127,67 +160,109 @@ testScriptsExt = [
'mempool_packages.py',
'maxuploadtarget.py',
'replace-by-fee.py',
+ 'p2p-feefilter.py',
+ 'pruning.py', # leave pruning last as it takes a REALLY long time
]
-#Enable ZMQ tests
-if ENABLE_ZMQ == 1:
- testScripts.append('zmq_test.py')
-
def runtests():
+ test_list = []
+ if '-extended' in opts:
+ test_list = testScripts + testScriptsExt
+ elif len(opts) == 0 or (len(opts) == 1 and "-win" in opts):
+ test_list = testScripts
+ else:
+ for t in testScripts + testScriptsExt:
+ if t in opts or re.sub(".py$", "", t) in opts:
+ test_list.append(t)
+
+ if print_help:
+ # Only print help of the first script and exit
+ subprocess.check_call((RPC_TESTS_DIR + test_list[0]).split() + ['-h'])
+ sys.exit(0)
+
coverage = None
if ENABLE_COVERAGE:
coverage = RPCCoverage()
print("Initializing coverage directory at %s\n" % coverage.dir)
+ flags = ["--srcdir=%s/src" % BUILDDIR] + passon_args
+ if coverage:
+ flags.append(coverage.flag)
+
+ if len(test_list) > 1:
+ # Populate cache
+ subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags)
+
+ #Run Tests
+ max_len_name = len(max(test_list, key=len))
+ time_sum = 0
+ time0 = time.time()
+ job_queue = RPCTestHandler(run_parallel, test_list, flags)
+ results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0]
+ all_passed = True
+ for _ in range(len(test_list)):
+ (name, stdout, stderr, passed, duration) = job_queue.get_next()
+ all_passed = all_passed and passed
+ time_sum += duration
+
+ print('\n' + BOLD[1] + name + BOLD[0] + ":")
+ print(stdout)
+ print('stderr:\n' if not stderr == '' else '', stderr)
+ results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration)
+ print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration))
+ results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0]
+ print(results)
+ print("\nRuntime: %s s" % (int(time.time() - time0)))
+
+ if coverage:
+ coverage.report_rpc_coverage()
+
+ print("Cleaning up coverage data")
+ coverage.cleanup()
+
+ sys.exit(not all_passed)
+
+
+class RPCTestHandler:
+ """
+ Trigger the testscrips passed in via the list.
+ """
- if(ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1):
- rpcTestDir = buildDir + '/qa/rpc-tests/'
- run_extended = '-extended' in opts
- cov_flag = coverage.flag if coverage else ''
- flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn)
-
- #Run Tests
- for i in range(len(testScripts)):
- if (len(opts) == 0
- or (len(opts) == 1 and "-win" in opts )
- or run_extended
- or testScripts[i] in opts
- or re.sub(".py$", "", testScripts[i]) in opts ):
-
- print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0]))
- time0 = time.time()
- subprocess.check_call(
- rpcTestDir + testScripts[i] + flags, shell=True)
- print("Duration: %s s\n" % (int(time.time() - time0)))
-
- # exit if help is called so we print just one set of
- # instructions
- p = re.compile(" -h| --help")
- if p.match(passOn):
- sys.exit(0)
-
- # Run Extended Tests
- for i in range(len(testScriptsExt)):
- if (run_extended or testScriptsExt[i] in opts
- or re.sub(".py$", "", testScriptsExt[i]) in opts):
-
- print(
- "Running 2nd level testscript "
- + "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0]))
- time0 = time.time()
- subprocess.check_call(
- rpcTestDir + testScriptsExt[i] + flags, shell=True)
- print("Duration: %s s\n" % (int(time.time() - time0)))
-
- if coverage:
- coverage.report_rpc_coverage()
-
- print("Cleaning up coverage data")
- coverage.cleanup()
-
- else:
- print "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
+ def __init__(self, num_tests_parallel, test_list=None, flags=None):
+ assert(num_tests_parallel >= 1)
+ self.num_jobs = num_tests_parallel
+ self.test_list = test_list
+ self.flags = flags
+ self.num_running = 0
+ self.jobs = []
+
+ def get_next(self):
+ while self.num_running < self.num_jobs and self.test_list:
+ # Add tests
+ self.num_running += 1
+ t = self.test_list.pop(0)
+ port_seed = ["--portseed=%s" % len(self.test_list)]
+ self.jobs.append((t,
+ time.time(),
+ subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed,
+ universal_newlines=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)))
+ if not self.jobs:
+ raise IndexError('%s from empty list' % __name__)
+ while True:
+ # Return first proc that finishes
+ time.sleep(.5)
+ for j in self.jobs:
+ (name, time0, proc) = j
+ if proc.poll() is not None:
+ (stdout, stderr) = proc.communicate(timeout=3)
+ passed = stderr == "" and proc.returncode == 0
+ self.num_running -= 1
+ self.jobs.remove(j)
+ return name, stdout, stderr, passed, int(time.time() - time0)
+ print('.', end='', flush=True)
class RPCCoverage(object):
@@ -207,7 +282,7 @@ class RPCCoverage(object):
"""
def __init__(self):
self.dir = tempfile.mkdtemp(prefix="coverage")
- self.flag = '--coveragedir %s' % self.dir
+ self.flag = '--coveragedir=%s' % self.dir
def report_rpc_coverage(self):
"""
diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in
index 937b4231f1..2356b5200e 100644
--- a/qa/pull-tester/tests_config.py.in
+++ b/qa/pull-tester/tests_config.py.in
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2013-2014 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2013-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.
@@ -11,5 +11,3 @@ EXEEXT="@EXEEXT@"
@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1
-
-
diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py
index 38028df079..c50c3cc562 100755
--- a/qa/rpc-tests/abandonconflict.py
+++ b/qa/rpc-tests/abandonconflict.py
@@ -1,17 +1,18 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+import urllib.parse
class AbandonConflictTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
def setup_network(self):
self.nodes = []
@@ -34,7 +35,7 @@ class AbandonConflictTest(BitcoinTestFramework):
assert(balance - newbalance < Decimal("0.001")) #no more than fees lost
balance = newbalance
- url = urlparse.urlparse(self.nodes[1].url)
+ url = urllib.parse.urlparse(self.nodes[1].url)
self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
# Identify the 10btc outputs
@@ -83,6 +84,12 @@ class AbandonConflictTest(BitcoinTestFramework):
# inputs are still spent, but change not received
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("24.9996"))
+ # Unconfirmed received funds that are not in mempool, also shouldn't show
+ # up in unconfirmed balance
+ unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance()
+ assert(unconfbalance == newbalance)
+ # Also shouldn't show up in listunspent
+ assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)])
balance = newbalance
# Abandon original transaction and verify inputs are available again
@@ -145,9 +152,9 @@ class AbandonConflictTest(BitcoinTestFramework):
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
newbalance = self.nodes[0].getbalance()
#assert(newbalance == balance - Decimal("10"))
- print "If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer"
- print "conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315"
- print balance , " -> " , newbalance , " ?"
+ print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer")
+ print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315")
+ print(str(balance) + " -> " + str(newbalance) + " ?")
if __name__ == '__main__':
AbandonConflictTest().main()
diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py
index bbd518cf5f..754b6873b7 100755
--- a/qa/rpc-tests/bip65-cltv-p2p.py
+++ b/qa/rpc-tests/bip65-cltv-p2p.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
@@ -10,8 +9,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP
-from binascii import unhexlify
-import cStringIO
+from io import BytesIO
import time
def cltv_invalidate(tx):
@@ -39,11 +37,12 @@ Mine 1 old version block, see that the node rejects.
class BIP65Test(ComparisonTestFramework):
def __init__(self):
+ super().__init__()
self.num_nodes = 1
def setup_network(self):
# Must set the blockversion for this test
- self.nodes = start_nodes(1, self.options.tmpdir,
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']],
binary=[self.options.testbinary])
@@ -60,7 +59,7 @@ class BIP65Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
- f = cStringIO.StringIO(unhexlify(signresult['hex']))
+ f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
@@ -68,13 +67,13 @@ class BIP65Test(ComparisonTestFramework):
self.coinbase_blocks = self.nodes[0].generate(2)
height = 3 # height of the next block to build
- self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
- self.last_block_time = time.time()
+ self.last_block_time = int(time.time())
''' 98 more version 3 blocks '''
test_blocks = []
- for i in xrange(98):
+ for i in range(98):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()
@@ -87,7 +86,7 @@ class BIP65Test(ComparisonTestFramework):
''' Mine 749 version 4 blocks '''
test_blocks = []
- for i in xrange(749):
+ for i in range(749):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.rehash()
@@ -139,7 +138,7 @@ class BIP65Test(ComparisonTestFramework):
''' Mine 199 new version blocks on last valid tip '''
test_blocks = []
- for i in xrange(199):
+ for i in range(199):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.rehash()
diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py
index f666a07c9b..abba7fc20e 100755
--- a/qa/rpc-tests/bip65-cltv.py
+++ b/qa/rpc-tests/bip65-cltv.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -11,6 +11,10 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class BIP65Test(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 3
+ self.setup_clean_chain = False
def setup_network(self):
self.nodes = []
@@ -32,7 +36,7 @@ class BIP65Test(BitcoinTestFramework):
raise AssertionError("Failed to mine 100 version=3 blocks")
# Mine 750 new-version blocks
- for i in xrange(15):
+ for i in range(15):
self.nodes[2].generate(50)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 850):
@@ -49,7 +53,7 @@ class BIP65Test(BitcoinTestFramework):
# TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced
# Mine 198 new-version blocks
- for i in xrange(2):
+ for i in range(2):
self.nodes[2].generate(99)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1049):
diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py
new file mode 100755
index 0000000000..8ba0704384
--- /dev/null
+++ b/qa/rpc-tests/bip68-112-113-p2p.py
@@ -0,0 +1,539 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.mininode import ToHex, CTransaction, NetworkThread
+from test_framework.blocktools import create_coinbase, create_block
+from test_framework.comptool import TestInstance, TestManager
+from test_framework.script import *
+from io import BytesIO
+import time
+
+'''
+This test is meant to exercise activation of the first version bits soft fork
+This soft fork will activate the following BIPS:
+BIP 68 - nSequence relative lock times
+BIP 112 - CHECKSEQUENCEVERIFY
+BIP 113 - MedianTimePast semantics for nLockTime
+
+regtest lock-in with 108/144 block signalling
+activation after a further 144 blocks
+
+mine 82 blocks whose coinbases will be used to generate inputs for our tests
+mine 61 blocks to transition from DEFINED to STARTED
+mine 144 blocks only 100 of which are signaling readiness in order to fail to change state this period
+mine 144 blocks with 108 signaling and verify STARTED->LOCKED_IN
+mine 140 blocks and seed block chain with the 82 inputs will use for our tests at height 572
+mine 3 blocks and verify still at LOCKED_IN and test that enforcement has not triggered
+mine 1 block and test that enforcement has triggered (which triggers ACTIVE)
+Test BIP 113 is enforced
+Mine 4 blocks so next height is 580 and test BIP 68 is enforced for time and height
+Mine 1 block so next height is 581 and test BIP 68 now passes time but not height
+Mine 1 block so next height is 582 and test BIP 68 now passes time and height
+Test that BIP 112 is enforced
+
+Various transactions will be used to test that the BIPs rules are not enforced before the soft fork activates
+And that after the soft fork activates transactions pass and fail as they should according to the rules.
+For each BIP, transactions of versions 1 and 2 will be tested.
+----------------
+BIP 113:
+bip113tx - modify the nLocktime variable
+
+BIP 68:
+bip68txs - 16 txs with nSequence relative locktime of 10 with various bits set as per the relative_locktimes below
+
+BIP 112:
+bip112txs_vary_nSequence - 16 txs with nSequence relative_locktimes of 10 evaluated against 10 OP_CSV OP_DROP
+bip112txs_vary_nSequence_9 - 16 txs with nSequence relative_locktimes of 9 evaluated against 10 OP_CSV OP_DROP
+bip112txs_vary_OP_CSV - 16 txs with nSequence = 10 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP
+bip112txs_vary_OP_CSV_9 - 16 txs with nSequence = 9 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP
+bip112tx_special - test negative argument to OP_CSV
+'''
+
+base_relative_locktime = 10
+seq_disable_flag = 1<<31
+seq_random_high_bit = 1<<25
+seq_type_flag = 1<<22
+seq_random_low_bit = 1<<18
+
+# b31,b25,b22,b18 represent the 31st, 25th, 22nd and 18th bits respectively in the nSequence field
+# relative_locktimes[b31][b25][b22][b18] is a base_relative_locktime with the indicated bits set if their indices are 1
+relative_locktimes = []
+for b31 in range(2):
+ b25times = []
+ for b25 in range(2):
+ b22times = []
+ for b22 in range(2):
+ b18times = []
+ for b18 in range(2):
+ rlt = base_relative_locktime
+ if (b31):
+ rlt = rlt | seq_disable_flag
+ if (b25):
+ rlt = rlt | seq_random_high_bit
+ if (b22):
+ rlt = rlt | seq_type_flag
+ if (b18):
+ rlt = rlt | seq_random_low_bit
+ b18times.append(rlt)
+ b22times.append(b18times)
+ b25times.append(b22times)
+ relative_locktimes.append(b25times)
+
+def all_rlt_txs(txarray):
+ txs = []
+ for b31 in range(2):
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ txs.append(txarray[b31][b25][b22][b18])
+ return txs
+
+class BIP68_112_113Test(ComparisonTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 1
+
+ def setup_network(self):
+ # Must set the blockversion for this test
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=4']],
+ binary=[self.options.testbinary])
+
+ def run_test(self):
+ test = TestManager(self, self.options.tmpdir)
+ test.add_all_connections(self.nodes)
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+ def send_generic_input_tx(self, node, coinbases):
+ amount = Decimal("49.99")
+ return node.sendrawtransaction(ToHex(self.sign_transaction(node, self.create_transaction(node, node.getblock(coinbases.pop())['tx'][0], self.nodeaddress, amount))))
+
+ def create_transaction(self, node, txid, to_address, amount):
+ inputs = [{ "txid" : txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = node.createrawtransaction(inputs, outputs)
+ tx = CTransaction()
+ f = BytesIO(hex_str_to_bytes(rawtx))
+ tx.deserialize(f)
+ return tx
+
+ def sign_transaction(self, node, unsignedtx):
+ rawtx = ToHex(unsignedtx)
+ signresult = node.signrawtransaction(rawtx)
+ tx = CTransaction()
+ f = BytesIO(hex_str_to_bytes(signresult['hex']))
+ tx.deserialize(f)
+ return tx
+
+ def generate_blocks(self, number, version, test_blocks = []):
+ for i in range(number):
+ block = self.create_test_block([], version)
+ test_blocks.append([block, True])
+ self.last_block_time += 600
+ self.tip = block.sha256
+ self.tipheight += 1
+ return test_blocks
+
+ def create_test_block(self, txs, version = 536870912):
+ block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600)
+ block.nVersion = version
+ block.vtx.extend(txs)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+ return block
+
+ def create_bip68txs(self, bip68inputs, txversion, locktime_delta = 0):
+ txs = []
+ assert(len(bip68inputs) >= 16)
+ i = 0
+ for b31 in range(2):
+ b25txs = []
+ for b25 in range(2):
+ b22txs = []
+ for b22 in range(2):
+ b18txs = []
+ for b18 in range(2):
+ tx = self.create_transaction(self.nodes[0], bip68inputs[i], self.nodeaddress, Decimal("49.98"))
+ i += 1
+ tx.nVersion = txversion
+ tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta
+ b18txs.append(self.sign_transaction(self.nodes[0], tx))
+ b22txs.append(b18txs)
+ b25txs.append(b22txs)
+ txs.append(b25txs)
+ return txs
+
+ def create_bip112special(self, input, txversion):
+ tx = self.create_transaction(self.nodes[0], input, self.nodeaddress, Decimal("49.98"))
+ tx.nVersion = txversion
+ signtx = self.sign_transaction(self.nodes[0], tx)
+ signtx.vin[0].scriptSig = CScript([-1, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
+ return signtx
+
+ def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta = 0):
+ txs = []
+ assert(len(bip112inputs) >= 16)
+ i = 0
+ for b31 in range(2):
+ b25txs = []
+ for b25 in range(2):
+ b22txs = []
+ for b22 in range(2):
+ b18txs = []
+ for b18 in range(2):
+ tx = self.create_transaction(self.nodes[0], bip112inputs[i], self.nodeaddress, Decimal("49.98"))
+ i += 1
+ if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed
+ tx.vin[0].nSequence = base_relative_locktime + locktime_delta
+ else: # vary nSequence instead, OP_CSV is fixed
+ tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta
+ tx.nVersion = txversion
+ signtx = self.sign_transaction(self.nodes[0], tx)
+ if (varyOP_CSV):
+ signtx.vin[0].scriptSig = CScript([relative_locktimes[b31][b25][b22][b18], OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
+ else:
+ signtx.vin[0].scriptSig = CScript([base_relative_locktime, OP_NOP3, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
+ b18txs.append(signtx)
+ b22txs.append(b18txs)
+ b25txs.append(b22txs)
+ txs.append(b25txs)
+ return txs
+
+ def get_tests(self):
+ long_past_time = int(time.time()) - 600 * 1000 # enough to build up to 1000 blocks 10 minutes apart without worrying about getting into the future
+ self.nodes[0].setmocktime(long_past_time - 100) # enough so that the generated blocks will still all be before long_past_time
+ self.coinbase_blocks = self.nodes[0].generate(1 + 16 + 2*32 + 1) # 82 blocks generated for inputs
+ self.nodes[0].setmocktime(0) # set time back to present so yielded blocks aren't in the future as we advance last_block_time
+ self.tipheight = 82 # height of the next block to build
+ self.last_block_time = long_past_time
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
+ self.nodeaddress = self.nodes[0].getnewaddress()
+
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'defined')
+ test_blocks = self.generate_blocks(61, 4)
+ yield TestInstance(test_blocks, sync_every_block=False) # 1
+ # Advanced from DEFINED to STARTED, height = 143
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started')
+
+ # Fail to achieve LOCKED_IN 100 out of 144 signal bit 0
+ # using a variety of bits to simulate multiple parallel softforks
+ test_blocks = self.generate_blocks(50, 536870913) # 0x20000001 (signalling ready)
+ test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not)
+ test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready)
+ test_blocks = self.generate_blocks(24, 536936448, test_blocks) # 0x20010000 (signalling not)
+ yield TestInstance(test_blocks, sync_every_block=False) # 2
+ # Failed to advance past STARTED, height = 287
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started')
+
+ # 108 out of 144 signal bit 0 to achieve lock-in
+ # using a variety of bits to simulate multiple parallel softforks
+ test_blocks = self.generate_blocks(58, 536870913) # 0x20000001 (signalling ready)
+ test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not)
+ test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready)
+ test_blocks = self.generate_blocks(10, 536936448, test_blocks) # 0x20010000 (signalling not)
+ yield TestInstance(test_blocks, sync_every_block=False) # 3
+ # Advanced from STARTED to LOCKED_IN, height = 431
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in')
+
+ # 140 more version 4 blocks
+ test_blocks = self.generate_blocks(140, 4)
+ yield TestInstance(test_blocks, sync_every_block=False) # 4
+
+ ### Inputs at height = 572
+ # Put inputs for all tests in the chain at height 572 (tip now = 571) (time increases by 600s per block)
+ # Note we reuse inputs for v1 and v2 txs so must test these separately
+ # 16 normal inputs
+ bip68inputs = []
+ for i in range(16):
+ bip68inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
+ # 2 sets of 16 inputs with 10 OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
+ bip112basicinputs = []
+ for j in range(2):
+ inputs = []
+ for i in range(16):
+ inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
+ bip112basicinputs.append(inputs)
+ # 2 sets of 16 varied inputs with (relative_lock_time) OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
+ bip112diverseinputs = []
+ for j in range(2):
+ inputs = []
+ for i in range(16):
+ inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
+ bip112diverseinputs.append(inputs)
+ # 1 special input with -1 OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
+ bip112specialinput = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)
+ # 1 normal input
+ bip113input = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)
+
+ self.nodes[0].setmocktime(self.last_block_time + 600)
+ inputblockhash = self.nodes[0].generate(1)[0] # 1 block generated for inputs to be in chain at height 572
+ self.nodes[0].setmocktime(0)
+ self.tip = int("0x" + inputblockhash, 0)
+ self.tipheight += 1
+ self.last_block_time += 600
+ assert_equal(len(self.nodes[0].getblock(inputblockhash,True)["tx"]), 82+1)
+
+ # 2 more version 4 blocks
+ test_blocks = self.generate_blocks(2, 4)
+ yield TestInstance(test_blocks, sync_every_block=False) # 5
+ # Not yet advanced to ACTIVE, height = 574 (will activate for block 576, not 575)
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in')
+
+ # Test both version 1 and version 2 transactions for all tests
+ # BIP113 test transaction will be modified before each use to put in appropriate block time
+ bip113tx_v1 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98"))
+ bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE
+ bip113tx_v2 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98"))
+ bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE
+ bip113tx_v2.nVersion = 2
+
+ # For BIP68 test all 16 relative sequence locktimes
+ bip68txs_v1 = self.create_bip68txs(bip68inputs, 1)
+ bip68txs_v2 = self.create_bip68txs(bip68inputs, 2)
+
+ # For BIP112 test:
+ # 16 relative sequence locktimes of 10 against 10 OP_CSV OP_DROP inputs
+ bip112txs_vary_nSequence_v1 = self.create_bip112txs(bip112basicinputs[0], False, 1)
+ bip112txs_vary_nSequence_v2 = self.create_bip112txs(bip112basicinputs[0], False, 2)
+ # 16 relative sequence locktimes of 9 against 10 OP_CSV OP_DROP inputs
+ bip112txs_vary_nSequence_9_v1 = self.create_bip112txs(bip112basicinputs[1], False, 1, -1)
+ bip112txs_vary_nSequence_9_v2 = self.create_bip112txs(bip112basicinputs[1], False, 2, -1)
+ # sequence lock time of 10 against 16 (relative_lock_time) OP_CSV OP_DROP inputs
+ bip112txs_vary_OP_CSV_v1 = self.create_bip112txs(bip112diverseinputs[0], True, 1)
+ bip112txs_vary_OP_CSV_v2 = self.create_bip112txs(bip112diverseinputs[0], True, 2)
+ # sequence lock time of 9 against 16 (relative_lock_time) OP_CSV OP_DROP inputs
+ bip112txs_vary_OP_CSV_9_v1 = self.create_bip112txs(bip112diverseinputs[1], True, 1, -1)
+ bip112txs_vary_OP_CSV_9_v2 = self.create_bip112txs(bip112diverseinputs[1], True, 2, -1)
+ # -1 OP_CSV OP_DROP input
+ bip112tx_special_v1 = self.create_bip112special(bip112specialinput, 1)
+ bip112tx_special_v2 = self.create_bip112special(bip112specialinput, 2)
+
+
+ ### TESTING ###
+ ##################################
+ ### Before Soft Forks Activate ###
+ ##################################
+ # All txs should pass
+ ### Version 1 txs ###
+ success_txs = []
+ # add BIP113 tx and -1 CSV tx
+ bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
+ bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
+ success_txs.append(bip113signed1)
+ success_txs.append(bip112tx_special_v1)
+ # add BIP 68 txs
+ success_txs.extend(all_rlt_txs(bip68txs_v1))
+ # add BIP 112 with seq=10 txs
+ success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1))
+ success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v1))
+ # try BIP 112 with seq=9 txs
+ success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1))
+ success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v1))
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 6
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ ### Version 2 txs ###
+ success_txs = []
+ # add BIP113 tx and -1 CSV tx
+ bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
+ bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
+ success_txs.append(bip113signed2)
+ success_txs.append(bip112tx_special_v2)
+ # add BIP 68 txs
+ success_txs.extend(all_rlt_txs(bip68txs_v2))
+ # add BIP 112 with seq=10 txs
+ success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v2))
+ success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v2))
+ # try BIP 112 with seq=9 txs
+ success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2))
+ success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v2))
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 7
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+
+ # 1 more version 4 block to get us to height 575 so the fork should now be active for the next block
+ test_blocks = self.generate_blocks(1, 4)
+ yield TestInstance(test_blocks, sync_every_block=False) # 8
+ assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'active')
+
+
+ #################################
+ ### After Soft Forks Activate ###
+ #################################
+ ### BIP 113 ###
+ # BIP 113 tests should now fail regardless of version number if nLockTime isn't satisfied by new rules
+ bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
+ bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
+ bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
+ bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
+ for bip113tx in [bip113signed1, bip113signed2]:
+ yield TestInstance([[self.create_test_block([bip113tx]), False]]) # 9,10
+ # BIP 113 tests should now pass if the locktime is < MTP
+ bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block
+ bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
+ bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block
+ bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
+ for bip113tx in [bip113signed1, bip113signed2]:
+ yield TestInstance([[self.create_test_block([bip113tx]), True]]) # 11,12
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ # Next block height = 580 after 4 blocks of random version
+ test_blocks = self.generate_blocks(4, 1234)
+ yield TestInstance(test_blocks, sync_every_block=False) # 13
+
+ ### BIP 68 ###
+ ### Version 1 txs ###
+ # All still pass
+ success_txs = []
+ success_txs.extend(all_rlt_txs(bip68txs_v1))
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 14
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ ### Version 2 txs ###
+ bip68success_txs = []
+ # All txs with SEQUENCE_LOCKTIME_DISABLE_FLAG set pass
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ bip68success_txs.append(bip68txs_v2[1][b25][b22][b18])
+ yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 15
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+ # All txs without flag fail as we are at delta height = 8 < 10 and delta time = 8 * 600 < 10 * 512
+ bip68timetxs = []
+ for b25 in range(2):
+ for b18 in range(2):
+ bip68timetxs.append(bip68txs_v2[0][b25][1][b18])
+ for tx in bip68timetxs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 16 - 19
+ bip68heighttxs = []
+ for b25 in range(2):
+ for b18 in range(2):
+ bip68heighttxs.append(bip68txs_v2[0][b25][0][b18])
+ for tx in bip68heighttxs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 20 - 23
+
+ # Advance one block to 581
+ test_blocks = self.generate_blocks(1, 1234)
+ yield TestInstance(test_blocks, sync_every_block=False) # 24
+
+ # Height txs should fail and time txs should now pass 9 * 600 > 10 * 512
+ bip68success_txs.extend(bip68timetxs)
+ yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 25
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+ for tx in bip68heighttxs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 26 - 29
+
+ # Advance one block to 582
+ test_blocks = self.generate_blocks(1, 1234)
+ yield TestInstance(test_blocks, sync_every_block=False) # 30
+
+ # All BIP 68 txs should pass
+ bip68success_txs.extend(bip68heighttxs)
+ yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 31
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+
+ ### BIP 112 ###
+ ### Version 1 txs ###
+ # -1 OP_CSV tx should fail
+ yield TestInstance([[self.create_test_block([bip112tx_special_v1]), False]]) #32
+ # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass
+ success_txs = []
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ success_txs.append(bip112txs_vary_OP_CSV_v1[1][b25][b22][b18])
+ success_txs.append(bip112txs_vary_OP_CSV_9_v1[1][b25][b22][b18])
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 33
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ # If SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV, version 1 txs should now fail
+ fail_txs = []
+ fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1))
+ fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1))
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ fail_txs.append(bip112txs_vary_OP_CSV_v1[0][b25][b22][b18])
+ fail_txs.append(bip112txs_vary_OP_CSV_9_v1[0][b25][b22][b18])
+
+ for tx in fail_txs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 34 - 81
+
+ ### Version 2 txs ###
+ # -1 OP_CSV tx should fail
+ yield TestInstance([[self.create_test_block([bip112tx_special_v2]), False]]) #82
+
+ # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met)
+ success_txs = []
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ success_txs.append(bip112txs_vary_OP_CSV_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV
+ success_txs.append(bip112txs_vary_OP_CSV_9_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV_9
+
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 83
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ ## SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV for all remaining txs ##
+ # All txs with nSequence 9 should fail either due to earlier mismatch or failing the CSV check
+ fail_txs = []
+ fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) # 16/16 of vary_nSequence_9
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ fail_txs.append(bip112txs_vary_OP_CSV_9_v2[0][b25][b22][b18]) # 16/16 of vary_OP_CSV_9
+
+ for tx in fail_txs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 84 - 107
+
+ # If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail
+ fail_txs = []
+ for b25 in range(2):
+ for b22 in range(2):
+ for b18 in range(2):
+ fail_txs.append(bip112txs_vary_nSequence_v2[1][b25][b22][b18]) # 8/16 of vary_nSequence
+ for tx in fail_txs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 108-115
+
+ # If sequencelock types mismatch, tx should fail
+ fail_txs = []
+ for b25 in range(2):
+ for b18 in range(2):
+ fail_txs.append(bip112txs_vary_nSequence_v2[0][b25][1][b18]) # 12/16 of vary_nSequence
+ fail_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][1][b18]) # 12/16 of vary_OP_CSV
+ for tx in fail_txs:
+ yield TestInstance([[self.create_test_block([tx]), False]]) # 116-123
+
+ # Remaining txs should pass, just test masking works properly
+ success_txs = []
+ for b25 in range(2):
+ for b18 in range(2):
+ success_txs.append(bip112txs_vary_nSequence_v2[0][b25][0][b18]) # 16/16 of vary_nSequence
+ success_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][0][b18]) # 16/16 of vary_OP_CSV
+ yield TestInstance([[self.create_test_block(success_txs), True]]) # 124
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ # Additional test, of checking that comparison of two time types works properly
+ time_txs = []
+ for b25 in range(2):
+ for b18 in range(2):
+ tx = bip112txs_vary_OP_CSV_v2[0][b25][1][b18]
+ tx.vin[0].nSequence = base_relative_locktime | seq_type_flag
+ signtx = self.sign_transaction(self.nodes[0], tx)
+ time_txs.append(signtx)
+ yield TestInstance([[self.create_test_block(time_txs), True]]) # 125
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+
+ ### Missing aspects of test
+ ## Testing empty stack fails
+
+
+if __name__ == '__main__':
+ BIP68_112_113Test().main()
diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py
index bd61282fa1..a12bf10ebd 100755
--- a/qa/rpc-tests/bip68-sequence.py
+++ b/qa/rpc-tests/bip68-sequence.py
@@ -1,10 +1,10 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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 BIP68 implementation (mempool only)
+# Test BIP68 implementation
#
from test_framework.test_framework import BitcoinTestFramework
@@ -13,7 +13,6 @@ from test_framework.script import *
from test_framework.mininode import *
from test_framework.blocktools import *
-COIN = 100000000
SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31)
SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height)
SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift
@@ -23,31 +22,45 @@ SEQUENCE_LOCKTIME_MASK = 0x0000ffff
NOT_FINAL_ERROR = "64: non-BIP68-final"
class BIP68Test(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"]))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"]))
self.is_network_split = False
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
+ connect_nodes(self.nodes[0], 1)
def run_test(self):
# Generate some coins
self.nodes[0].generate(110)
- print "Running test disable flag"
+ print("Running test disable flag")
self.test_disable_flag()
- print "Running test sequence-lock-confirmed-inputs"
+ print("Running test sequence-lock-confirmed-inputs")
self.test_sequence_lock_confirmed_inputs()
- print "Running test sequence-lock-unconfirmed-inputs"
+ print("Running test sequence-lock-unconfirmed-inputs")
self.test_sequence_lock_unconfirmed_inputs()
- # This test needs to change when BIP68 becomes consensus
- print "Running test BIP68 not consensus"
+ print("Running test BIP68 not consensus before versionbits activation")
self.test_bip68_not_consensus()
- print "Passed\n"
+ print("Verifying nVersion=2 transactions aren't standard")
+ self.test_version2_relay(before_activation=True)
+
+ print("Activating BIP68 (and 112/113)")
+ self.activateCSV()
+
+ print("Verifying nVersion=2 transactions are now standard")
+ self.test_version2_relay(before_activation=False)
+
+ print("Passed\n")
# Test that BIP68 is not in effect if tx version is 1, or if
# the first sequence bit is set.
@@ -62,7 +75,7 @@ class BIP68Test(BitcoinTestFramework):
utxo = utxos[0]
tx1 = CTransaction()
- value = satoshi_round(utxo["amount"] - self.relayfee)*COIN
+ value = int(satoshi_round(utxo["amount"] - self.relayfee)*COIN)
# Check that the disable flag disables relative locktime.
# If sequence locks were used, this would require 1 block for the
@@ -116,7 +129,7 @@ class BIP68Test(BitcoinTestFramework):
random.shuffle(addresses)
num_outputs = random.randint(1, max_outputs)
outputs = {}
- for i in xrange(num_outputs):
+ for i in range(num_outputs):
outputs[addresses[i]] = random.randint(1, 20)*0.01
self.nodes[0].sendmany("", outputs)
self.nodes[0].generate(1)
@@ -128,7 +141,7 @@ class BIP68Test(BitcoinTestFramework):
# some of those inputs to be sequence locked (and randomly choose
# between height/time locking). Small random chance of making the locks
# all pass.
- for i in xrange(400):
+ for i in range(400):
# Randomly choose up to 10 inputs
num_inputs = random.randint(1, 10)
random.shuffle(utxos)
@@ -142,7 +155,7 @@ class BIP68Test(BitcoinTestFramework):
tx = CTransaction()
tx.nVersion = 2
value = 0
- for j in xrange(num_inputs):
+ for j in range(num_inputs):
sequence_value = 0xfffffffe # this disables sequence locks
# 50% chance we enable sequence locks
@@ -180,8 +193,8 @@ class BIP68Test(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value))
value += utxos[j]["amount"]*COIN
# Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output
- tx_size = len(ToHex(tx))/2 + 120*num_inputs + 50
- tx.vout.append(CTxOut(value-self.relayfee*tx_size*COIN/1000, CScript([b'a'])))
+ tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50
+ tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a'])))
rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"]
try:
@@ -250,7 +263,7 @@ class BIP68Test(BitcoinTestFramework):
# Use prioritisetransaction to lower the effective feerate to 0
self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN))
cur_time = int(time.time())
- for i in xrange(10):
+ for i in range(10):
self.nodes[0].setmocktime(cur_time + 600)
self.nodes[0].generate(1)
cur_time += 600
@@ -315,7 +328,7 @@ class BIP68Test(BitcoinTestFramework):
# tx3 to be removed.
tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16)
height = self.nodes[0].getblockcount()
- for i in xrange(2):
+ for i in range(2):
block = create_block(tip, create_coinbase(height), cur_time)
block.nVersion = 3
block.rehash()
@@ -334,8 +347,12 @@ class BIP68Test(BitcoinTestFramework):
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1))
self.nodes[0].generate(10)
- # Make sure that BIP68 isn't being used to validate blocks.
+ # Make sure that BIP68 isn't being used to validate blocks, prior to
+ # versionbits activation. If more blocks are mined prior to this test
+ # being run, then it's possible the test has activated the soft fork, and
+ # this test should be moved to run earlier, or deleted.
def test_bip68_not_consensus(self):
+ assert(get_bip9_status(self.nodes[0], 'csv')['status'] != 'active')
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2)
tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid))
@@ -382,6 +399,30 @@ class BIP68Test(BitcoinTestFramework):
self.nodes[0].submitblock(ToHex(block))
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
+ def activateCSV(self):
+ # activation should happen at block height 432 (3 periods)
+ min_activation_height = 432
+ height = self.nodes[0].getblockcount()
+ assert(height < 432)
+ self.nodes[0].generate(432-height)
+ assert(get_bip9_status(self.nodes[0], 'csv')['status'] == 'active')
+ sync_blocks(self.nodes)
+
+ # Use self.nodes[1] to test standardness relay policy
+ def test_version2_relay(self, before_activation):
+ inputs = [ ]
+ outputs = { self.nodes[1].getnewaddress() : 1.0 }
+ rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
+ rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex']
+ tx = FromHex(CTransaction(), rawtxfund)
+ tx.nVersion = 2
+ tx_signed = self.nodes[1].signrawtransaction(ToHex(tx))["hex"]
+ try:
+ tx_id = self.nodes[1].sendrawtransaction(tx_signed)
+ assert(before_activation == False)
+ except:
+ assert(before_activation)
+
if __name__ == '__main__':
BIP68Test().main()
diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py
new file mode 100755
index 0000000000..d7e8e5e5a5
--- /dev/null
+++ b/qa/rpc-tests/bip9-softforks.py
@@ -0,0 +1,240 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.blockstore import BlockStore
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.mininode import CTransaction, NetworkThread
+from test_framework.blocktools import create_coinbase, create_block
+from test_framework.comptool import TestInstance, TestManager
+from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP
+from io import BytesIO
+import time
+import itertools
+
+'''
+This test is meant to exercise BIP forks
+Connect to a single node.
+regtest lock-in with 108/144 block signalling
+activation after a further 144 blocks
+mine 2 block and save coinbases for later use
+mine 141 blocks to transition from DEFINED to STARTED
+mine 100 blocks signalling readiness and 44 not in order to fail to change state this period
+mine 108 blocks signalling readiness and 36 blocks not signalling readiness (STARTED->LOCKED_IN)
+mine a further 143 blocks (LOCKED_IN)
+test that enforcement has not triggered (which triggers ACTIVE)
+test that enforcement has triggered
+'''
+
+
+class BIP9SoftForksTest(ComparisonTestFramework):
+
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 1
+
+ def setup_network(self):
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1']],
+ binary=[self.options.testbinary])
+
+ def run_test(self):
+ self.test = TestManager(self, self.options.tmpdir)
+ self.test.add_all_connections(self.nodes)
+ NetworkThread().start() # Start up network handling in another thread
+ self.test.run()
+
+ def create_transaction(self, node, coinbase, to_address, amount):
+ from_txid = node.getblock(coinbase)['tx'][0]
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = node.createrawtransaction(inputs, outputs)
+ tx = CTransaction()
+ f = BytesIO(hex_str_to_bytes(rawtx))
+ tx.deserialize(f)
+ tx.nVersion = 2
+ return tx
+
+ def sign_transaction(self, node, tx):
+ signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize()))
+ tx = CTransaction()
+ f = BytesIO(hex_str_to_bytes(signresult['hex']))
+ tx.deserialize(f)
+ return tx
+
+ def generate_blocks(self, number, version, test_blocks = []):
+ for i in range(number):
+ block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
+ block.nVersion = version
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ self.height += 1
+ return test_blocks
+
+ def get_bip9_status(self, key):
+ info = self.nodes[0].getblockchaininfo()
+ return info['bip9_softforks'][key]
+
+ def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno):
+ # generate some coins for later
+ self.coinbase_blocks = self.nodes[0].generate(2)
+ self.height = 3 # height of the next block to build
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
+ self.nodeaddress = self.nodes[0].getnewaddress()
+ self.last_block_time = int(time.time())
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'defined')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert(bipName not in tmpl['vbavailable'])
+ assert_equal(tmpl['vbrequired'], 0)
+ assert_equal(tmpl['version'], 0x20000000)
+
+ # Test 1
+ # Advance from DEFINED to STARTED
+ test_blocks = self.generate_blocks(141, 4)
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'started')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert_equal(tmpl['vbavailable'][bipName], bitno)
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(tmpl['version'] & activated_version)
+
+ # Test 2
+ # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1
+ # using a variety of bits to simulate multiple parallel softforks
+ test_blocks = self.generate_blocks(50, activated_version) # 0x20000001 (signalling ready)
+ test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not)
+ test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready)
+ test_blocks = self.generate_blocks(24, 4, test_blocks) # 0x20010000 (signalling not)
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'started')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert_equal(tmpl['vbavailable'][bipName], bitno)
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(tmpl['version'] & activated_version)
+
+ # Test 3
+ # 108 out of 144 signal bit 1 to achieve LOCKED_IN
+ # using a variety of bits to simulate multiple parallel softforks
+ test_blocks = self.generate_blocks(58, activated_version) # 0x20000001 (signalling ready)
+ test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not)
+ test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready)
+ test_blocks = self.generate_blocks(10, 4, test_blocks) # 0x20010000 (signalling not)
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+
+ # Test 4
+ # 143 more version 536870913 blocks (waiting period-1)
+ test_blocks = self.generate_blocks(143, 4)
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+
+ # Test 5
+ # Check that the new rule is enforced
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[0], self.nodeaddress, 1.0)
+ invalidate(spendtx)
+ spendtx = self.sign_transaction(self.nodes[0], spendtx)
+ spendtx.rehash()
+ invalidatePostSignature(spendtx)
+ spendtx.rehash()
+ block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
+ block.nVersion = activated_version
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+
+ self.last_block_time += 1
+ self.tip = block.sha256
+ self.height += 1
+ yield TestInstance([[block, True]])
+
+ assert_equal(self.get_bip9_status(bipName)['status'], 'active')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName in tmpl['rules'])
+ assert(bipName not in tmpl['vbavailable'])
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(not (tmpl['version'] & (1 << bitno)))
+
+ # Test 6
+ # Check that the new sequence lock rules are enforced
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[1], self.nodeaddress, 1.0)
+ invalidate(spendtx)
+ spendtx = self.sign_transaction(self.nodes[0], spendtx)
+ spendtx.rehash()
+ invalidatePostSignature(spendtx)
+ spendtx.rehash()
+
+ block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
+ block.nVersion = 5
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ yield TestInstance([[block, False]])
+
+ # Restart all
+ self.test.block_store.close()
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ shutil.rmtree(self.options.tmpdir)
+ self.setup_chain()
+ self.setup_network()
+ self.test.block_store = BlockStore(self.options.tmpdir)
+ self.test.clear_all_connections()
+ self.test.add_all_connections(self.nodes)
+ NetworkThread().start() # Start up network handling in another thread
+
+
+ def get_tests(self):
+ for test in itertools.chain(
+ self.test_BIP('csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0),
+ self.test_BIP('csv', 0x20000001, self.mtp_invalidate, self.donothing, 0),
+ self.test_BIP('csv', 0x20000001, self.donothing, self.csv_invalidate, 0)
+ ):
+ yield test
+
+ def donothing(self, tx):
+ return
+
+ def csv_invalidate(self, tx):
+ '''Modify the signature in vin 0 of the tx to fail CSV
+ Prepends -1 CSV DROP in the scriptSig itself.
+ '''
+ tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP3, OP_DROP] +
+ list(CScript(tx.vin[0].scriptSig)))
+
+ def sequence_lock_invalidate(self, tx):
+ '''Modify the nSequence to make it fails once sequence lock rule is activated (high timespan)
+ '''
+ tx.vin[0].nSequence = 0x00FFFFFF
+ tx.nLockTime = 0
+
+ def mtp_invalidate(self, tx):
+ '''Modify the nLockTime to make it fails once MTP rule is activated
+ '''
+ # Disable Sequence lock, Activate nLockTime
+ tx.vin[0].nSequence = 0x90FFFFFF
+ tx.nLockTime = self.last_block_time
+
+if __name__ == '__main__':
+ BIP9SoftForksTest().main()
diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py
index 544e4a9670..4e4936a4ae 100755
--- a/qa/rpc-tests/bipdersig-p2p.py
+++ b/qa/rpc-tests/bipdersig-p2p.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
@@ -10,8 +9,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript
-from binascii import unhexlify
-import cStringIO
+from io import BytesIO
import time
# A canonical signature consists of:
@@ -25,7 +23,7 @@ def unDERify(tx):
newscript = []
for i in scriptSig:
if (len(newscript) == 0):
- newscript.append(i[0:-1] + '\0' + i[-1])
+ newscript.append(i[0:-1] + b'\0' + i[-1:])
else:
newscript.append(i)
tx.vin[0].scriptSig = CScript(newscript)
@@ -47,11 +45,12 @@ Mine 1 old version block, see that the node rejects.
class BIP66Test(ComparisonTestFramework):
def __init__(self):
+ super().__init__()
self.num_nodes = 1
def setup_network(self):
# Must set the blockversion for this test
- self.nodes = start_nodes(1, self.options.tmpdir,
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']],
binary=[self.options.testbinary])
@@ -68,7 +67,7 @@ class BIP66Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
- f = cStringIO.StringIO(unhexlify(signresult['hex']))
+ f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
@@ -76,13 +75,13 @@ class BIP66Test(ComparisonTestFramework):
self.coinbase_blocks = self.nodes[0].generate(2)
height = 3 # height of the next block to build
- self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
- self.last_block_time = time.time()
+ self.last_block_time = int(time.time())
''' 98 more version 2 blocks '''
test_blocks = []
- for i in xrange(98):
+ for i in range(98):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 2
block.rehash()
@@ -95,7 +94,7 @@ class BIP66Test(ComparisonTestFramework):
''' Mine 749 version 3 blocks '''
test_blocks = []
- for i in xrange(749):
+ for i in range(749):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()
@@ -147,7 +146,7 @@ class BIP66Test(ComparisonTestFramework):
''' Mine 199 new version blocks on last valid tip '''
test_blocks = []
- for i in xrange(199):
+ for i in range(199):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()
diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py
index be9121c456..17c2ced79a 100755
--- a/qa/rpc-tests/bipdersig.py
+++ b/qa/rpc-tests/bipdersig.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -11,6 +11,10 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class BIP66Test(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 3
+ self.setup_clean_chain = False
def setup_network(self):
self.nodes = []
@@ -32,7 +36,7 @@ class BIP66Test(BitcoinTestFramework):
raise AssertionError("Failed to mine 100 version=2 blocks")
# Mine 750 new-version blocks
- for i in xrange(15):
+ for i in range(15):
self.nodes[2].generate(50)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 850):
@@ -49,7 +53,7 @@ class BIP66Test(BitcoinTestFramework):
# TODO: check that new DERSIG rules are enforced
# Mine 198 new-version blocks
- for i in xrange(2):
+ for i in range(2):
self.nodes[2].generate(99)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1049):
diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py
index 7045ae435c..410b85d15e 100755
--- a/qa/rpc-tests/blockchain.py
+++ b/qa/rpc-tests/blockchain.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -13,7 +13,6 @@ from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import (
- initialize_chain,
assert_equal,
assert_raises,
assert_is_hex_string,
@@ -28,15 +27,17 @@ class BlockchainTest(BitcoinTestFramework):
Test blockchain-related RPC calls:
- gettxoutsetinfo
+ - verifychain
"""
- def setup_chain(self):
- print("Initializing test directory " + self.options.tmpdir)
- initialize_chain(self.options.tmpdir)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = False
+ self.num_nodes = 2
def setup_network(self, split=False):
- self.nodes = start_nodes(2, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
connect_nodes_bi(self.nodes, 0, 1)
self.is_network_split = False
self.sync_all()
@@ -44,18 +45,19 @@ class BlockchainTest(BitcoinTestFramework):
def run_test(self):
self._test_gettxoutsetinfo()
self._test_getblockheader()
+ self.nodes[0].verifychain(4, 0)
def _test_gettxoutsetinfo(self):
node = self.nodes[0]
res = node.gettxoutsetinfo()
- assert_equal(res[u'total_amount'], Decimal('8725.00000000'))
- assert_equal(res[u'transactions'], 200)
- assert_equal(res[u'height'], 200)
- assert_equal(res[u'txouts'], 200)
- assert_equal(res[u'bytes_serialized'], 13924),
- assert_equal(len(res[u'bestblock']), 64)
- assert_equal(len(res[u'hash_serialized']), 64)
+ assert_equal(res['total_amount'], Decimal('8725.00000000'))
+ assert_equal(res['transactions'], 200)
+ assert_equal(res['height'], 200)
+ assert_equal(res['txouts'], 200)
+ assert_equal(res['bytes_serialized'], 13924),
+ assert_equal(len(res['bestblock']), 64)
+ assert_equal(len(res['hash_serialized']), 64)
def _test_getblockheader(self):
node = self.nodes[0]
@@ -80,6 +82,7 @@ class BlockchainTest(BitcoinTestFramework):
assert isinstance(header['mediantime'], int)
assert isinstance(header['nonce'], int)
assert isinstance(header['version'], int)
+ assert isinstance(int(header['versionHex'], 16), int)
assert isinstance(header['difficulty'], Decimal)
if __name__ == '__main__':
diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py
new file mode 100755
index 0000000000..b6161e0917
--- /dev/null
+++ b/qa/rpc-tests/create_cache.py
@@ -0,0 +1,23 @@
+#!/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.
+
+#
+# Helper script to create the cache
+# (see BitcoinTestFramework.setup_chain)
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+
+class CreateCache(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Don't setup any test nodes
+ self.options.noshutdown = True
+
+ def run_test(self):
+ pass
+
+if __name__ == '__main__':
+ CreateCache().main()
diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py
index 490808d49d..24768c2655 100755
--- a/qa/rpc-tests/decodescript.py
+++ b/qa/rpc-tests/decodescript.py
@@ -1,23 +1,23 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.mininode import *
-from binascii import hexlify, unhexlify
-from cStringIO import StringIO
+from io import BytesIO
class DecodeScriptTest(BitcoinTestFramework):
"""Tests decoding scripts via RPC command "decodescript"."""
- def setup_chain(self):
- print('Initializing test directory ' + self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 1)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
def setup_network(self, split=False):
- self.nodes = start_nodes(1, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False
def decodescript_script_sig(self):
@@ -131,7 +131,7 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm'])
assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
txSave = CTransaction()
- txSave.deserialize(StringIO(unhexlify(tx)))
+ txSave.deserialize(BytesIO(hex_str_to_bytes(tx)))
# make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
@@ -147,7 +147,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# some more full transaction tests of varying specific scriptSigs. used instead of
# tests in decodescript_script_sig because the decodescript RPC is specifically
# for working on scriptPubKeys (argh!).
- push_signature = hexlify(txSave.vin[0].scriptSig)[2:(0x48*2+4)]
+ push_signature = bytes_to_hex_str(txSave.vin[0].scriptSig)[2:(0x48*2+4)]
signature = push_signature[2:]
der_signature = signature[:-2]
signature_sighash_decoded = der_signature + '[ALL]'
@@ -156,25 +156,24 @@ class DecodeScriptTest(BitcoinTestFramework):
signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
# 1) P2PK scriptSig
- txSave.vin[0].scriptSig = unhexlify(push_signature)
- rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
+ txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature)
+ rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# make sure that the sighash decodes come out correctly for a more complex / lesser used case.
- txSave.vin[0].scriptSig = unhexlify(push_signature_2)
- rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
+ txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2)
+ rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 2) multisig scriptSig
- txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2)
- rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
+ txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature + push_signature_2)
+ rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 3) test a scriptSig that contains more than push operations.
# in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
- txSave.vin[0].scriptSig = unhexlify('6a143011020701010101010101020601010101010101')
- rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
- print(hexlify('636174'))
+ txSave.vin[0].scriptSig = hex_str_to_bytes('6a143011020701010101010101020601010101010101')
+ rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self):
diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py
index 6964348d55..36c147edad 100755
--- a/qa/rpc-tests/disablewallet.py
+++ b/qa/rpc-tests/disablewallet.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -13,12 +13,13 @@ from test_framework.util import *
class DisableWalletTest (BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 1)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
def setup_network(self, split=False):
- self.nodes = start_nodes(1, self.options.tmpdir, [['-disablewallet']])
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [['-disablewallet']])
self.is_network_split = False
self.sync_all()
@@ -29,5 +30,19 @@ class DisableWalletTest (BitcoinTestFramework):
x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
assert(x['isvalid'] == True)
+ # Checking mining to an address without a wallet
+ try:
+ self.nodes[0].generatetoaddress(1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
+ except JSONRPCException as e:
+ assert("Invalid address" not in e.error['message'])
+ assert("ProcessNewBlock, block not accepted" not in e.error['message'])
+ assert("Couldn't create new block" not in e.error['message'])
+
+ try:
+ self.nodes[0].generatetoaddress(1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
+ raise AssertionError("Must not mine to invalid address!")
+ except JSONRPCException as e:
+ assert("Invalid address" in e.error['message'])
+
if __name__ == '__main__':
DisableWalletTest ().main ()
diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py
index 20e6ce9619..5a3f75c808 100755
--- a/qa/rpc-tests/forknotify.py
+++ b/qa/rpc-tests/forknotify.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -12,6 +12,11 @@ from test_framework.util import *
class ForkNotifyTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
+
alert_filename = None # Set by setup_network
def setup_network(self):
diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py
index 0287965b97..998f822afe 100755
--- a/qa/rpc-tests/fundrawtransaction.py
+++ b/qa/rpc-tests/fundrawtransaction.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -9,12 +9,13 @@ from test_framework.util import *
# Create one-input, one-output, no-fee transaction:
class RawTransactionsTest(BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 4)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 4
def setup_network(self, split=False):
- self.nodes = start_nodes(4, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
@@ -25,7 +26,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
- print "Mining blocks..."
+ print("Mining blocks...")
min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
# This test is not meant to test fee estimation and we'd like
@@ -48,7 +49,7 @@ class RawTransactionsTest(BitcoinTestFramework):
watchonly_address = self.nodes[0].getnewaddress()
watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
- watchonly_amount = 200
+ watchonly_amount = Decimal(200)
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
@@ -71,7 +72,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
- assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enought inputs
+ assert(len(dec_tx['vin']) > 0) #test if we have enought inputs
##############################
# simple test with two coins #
@@ -84,7 +85,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
- assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs
+ assert(len(dec_tx['vin']) > 0) #test if we have enough inputs
##############################
# simple test with two coins #
@@ -97,7 +98,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
- assert_equal(len(dec_tx['vin']) > 0, True)
+ assert(len(dec_tx['vin']) > 0)
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@@ -116,7 +117,7 @@ class RawTransactionsTest(BitcoinTestFramework):
for out in dec_tx['vout']:
totalOut += out['value']
- assert_equal(len(dec_tx['vin']) > 0, True)
+ assert(len(dec_tx['vin']) > 0)
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@@ -130,7 +131,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx
break
- assert_equal(utx!=False, True)
+ assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
@@ -148,7 +149,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
-
#####################################################################
# test a fundrawtransaction with which will not get a change output #
#####################################################################
@@ -159,7 +159,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx
break
- assert_equal(utx!=False, True)
+ assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
@@ -178,6 +178,82 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
+ ####################################################
+ # test a fundrawtransaction with an invalid option #
+ ####################################################
+ utx = False
+ listunspent = self.nodes[2].listunspent()
+ for aUtx in listunspent:
+ if aUtx['amount'] == 5.0:
+ utx = aUtx
+ break
+
+ assert_equal(utx!=False, True)
+
+ inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
+ outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
+ rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
+ dec_tx = self.nodes[2].decoderawtransaction(rawtx)
+ assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
+
+ try:
+ self.nodes[2].fundrawtransaction(rawtx, {'foo': 'bar'})
+ raise AssertionError("Accepted invalid option foo")
+ except JSONRPCException as e:
+ assert("Unexpected key foo" in e.error['message'])
+
+
+ ############################################################
+ # test a fundrawtransaction with an invalid change address #
+ ############################################################
+ utx = False
+ listunspent = self.nodes[2].listunspent()
+ for aUtx in listunspent:
+ if aUtx['amount'] == 5.0:
+ utx = aUtx
+ break
+
+ assert_equal(utx!=False, True)
+
+ inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
+ outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
+ rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
+ dec_tx = self.nodes[2].decoderawtransaction(rawtx)
+ assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
+
+ try:
+ self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': 'foobar'})
+ raise AssertionError("Accepted invalid bitcoin address")
+ except JSONRPCException as e:
+ assert("changeAddress must be a valid bitcoin address" in e.error['message'])
+
+
+
+ ############################################################
+ # test a fundrawtransaction with a provided change address #
+ ############################################################
+ utx = False
+ listunspent = self.nodes[2].listunspent()
+ for aUtx in listunspent:
+ if aUtx['amount'] == 5.0:
+ utx = aUtx
+ break
+
+ assert_equal(utx!=False, True)
+
+ inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
+ outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
+ rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
+ dec_tx = self.nodes[2].decoderawtransaction(rawtx)
+ assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
+
+ change = self.nodes[2].getnewaddress()
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0})
+ dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
+ out = dec_tx['vout'][0];
+ assert_equal(change, out['scriptPubKey']['addresses'][0])
+
+
#########################################################################
# test a fundrawtransaction with a VIN smaller than the required amount #
@@ -189,7 +265,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx
break
- assert_equal(utx!=False, True)
+ assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
@@ -209,7 +285,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for i, out in enumerate(dec_tx['vout']):
totalOut += out['value']
- if outputs.has_key(out['scriptPubKey']['addresses'][0]):
+ if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
else:
assert_equal(i, rawtxfund['changepos'])
@@ -234,7 +310,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx
- assert_equal(utx!=False, True)
+ assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0 }
@@ -249,7 +325,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
- if outputs.has_key(out['scriptPubKey']['addresses'][0]):
+ if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 1)
@@ -276,7 +352,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx
- assert_equal(utx!=False, True)
+ assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
@@ -291,7 +367,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
- if outputs.has_key(out['scriptPubKey']['addresses'][0]):
+ if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 2)
@@ -306,14 +382,11 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
- errorString = ""
try:
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
- except JSONRPCException,e:
- errorString = e.error['message']
-
- assert("Insufficient" in errorString)
-
+ raise AssertionError("Spent more than available")
+ except JSONRPCException as e:
+ assert("Insufficient" in e.error['message'])
############################################################
@@ -449,7 +522,7 @@ class RawTransactionsTest(BitcoinTestFramework):
stop_nodes(self.nodes)
wait_bitcoinds()
- self.nodes = start_nodes(4, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
# This test is not meant to test fee estimation and we'd like
# to be sure all txs are sent at a consistent desired feerate
for node in self.nodes:
@@ -462,12 +535,11 @@ class RawTransactionsTest(BitcoinTestFramework):
self.is_network_split=False
self.sync_all()
- error = False
try:
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2)
- except:
- error = True
- assert(error)
+ raise AssertionError("Wallet unlocked without passphrase")
+ except JSONRPCException as e:
+ assert('walletpassphrase' in e.error['message'])
oldBalance = self.nodes[0].getbalance()
@@ -488,7 +560,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
-
###############################################
# multiple (~19) inputs tx test | Compare fee #
###############################################
@@ -575,12 +646,12 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
- result = self.nodes[3].fundrawtransaction(rawtx, True)
+ result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True })
res_dec = self.nodes[0].decoderawtransaction(result["hex"])
assert_equal(len(res_dec["vin"]), 1)
assert_equal(res_dec["vin"][0]["txid"], watchonly_txid)
- assert_equal("fee" in result.keys(), True)
+ assert("fee" in result.keys())
assert_greater_than(result["changepos"], -1)
###############################################################
@@ -591,6 +662,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {self.nodes[2].getnewaddress() : watchonly_amount}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
+ # Backward compatibility test (2nd param is includeWatching)
result = self.nodes[3].fundrawtransaction(rawtx, True)
res_dec = self.nodes[0].decoderawtransaction(result["hex"])
assert_equal(len(res_dec["vin"]), 2)
@@ -606,6 +678,14 @@ class RawTransactionsTest(BitcoinTestFramework):
assert(signedtx["complete"])
self.nodes[0].sendrawtransaction(signedtx["hex"])
+ inputs = []
+ outputs = {self.nodes[2].getnewaddress() : 1}
+ rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
+ result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
+ result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
+ result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee})
+ assert_equal(result['fee']*2, result2['fee'])
+ assert_equal(result['fee']*10, result3['fee'])
if __name__ == '__main__':
RawTransactionsTest().main()
diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py
index 3e85957ae2..3cddf4046a 100755
--- a/qa/rpc-tests/getblocktemplate_longpoll.py
+++ b/qa/rpc-tests/getblocktemplate_longpoll.py
@@ -1,33 +1,11 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-
-def check_array_result(object_array, to_match, expected):
- """
- Pass in array of JSON objects, a dictionary with key/value pairs
- to match against, and another dictionary with expected key/value
- pairs.
- """
- num_matched = 0
- for item in object_array:
- all_match = True
- for key,value in to_match.items():
- if item[key] != value:
- all_match = False
- if not all_match:
- continue
- for key,value in expected.items():
- if item[key] != value:
- raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
- num_matched = num_matched+1
- if num_matched == 0:
- raise AssertionError("No objects matched %s"%(str(to_match)))
-
import threading
class LongpollThread(threading.Thread):
@@ -48,8 +26,13 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
Test longpolling with getblocktemplate.
'''
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
def run_test(self):
- print "Warning: this test will take about 70 seconds in the best case. Be patient."
+ print("Warning: this test will take about 70 seconds in the best case. Be patient.")
self.nodes[0].generate(10)
templat = self.nodes[0].getblocktemplate()
longpollid = templat['longpollid']
diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py
index f83b5f140d..7a4f8f8fdc 100755
--- a/qa/rpc-tests/getblocktemplate_proposals.py
+++ b/qa/rpc-tests/getblocktemplate_proposals.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -10,28 +10,6 @@ from binascii import a2b_hex, b2a_hex
from hashlib import sha256
from struct import pack
-
-def check_array_result(object_array, to_match, expected):
- """
- Pass in array of JSON objects, a dictionary with key/value pairs
- to match against, and another dictionary with expected key/value
- pairs.
- """
- num_matched = 0
- for item in object_array:
- all_match = True
- for key,value in to_match.items():
- if item[key] != value:
- all_match = False
- if not all_match:
- continue
- for key,value in expected.items():
- if item[key] != value:
- raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
- num_matched = num_matched+1
- if num_matched == 0:
- raise AssertionError("No objects matched %s"%(str(to_match)))
-
def b2x(b):
return b2a_hex(b).decode('ascii')
@@ -68,7 +46,7 @@ def genmrklroot(leaflist):
cur = n
return cur[0]
-def template_to_bytes(tmpl, txlist):
+def template_to_bytearray(tmpl, txlist):
blkver = pack('<L', tmpl['version'])
mrklroot = genmrklroot(list(dblsha(a) for a in txlist))
timestamp = pack('<L', tmpl['curtime'])
@@ -77,10 +55,10 @@ def template_to_bytes(tmpl, txlist):
blk += varlenEncode(len(txlist))
for tx in txlist:
blk += tx
- return blk
+ return bytearray(blk)
def template_to_hex(tmpl, txlist):
- return b2x(template_to_bytes(tmpl, txlist))
+ return b2x(template_to_bytearray(tmpl, txlist))
def assert_template(node, tmpl, txlist, expect):
rsp = node.getblocktemplate({'data':template_to_hex(tmpl, txlist),'mode':'proposal'})
@@ -92,6 +70,15 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
Test block proposals with getblocktemplate.
'''
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
+
+ def setup_network(self):
+ self.nodes = self.setup_nodes()
+ connect_nodes_bi(self.nodes, 0, 1)
+
def run_test(self):
node = self.nodes[0]
node.generate(1) # Mine a block to leave initial block download
@@ -120,10 +107,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 3: Truncated final tx
lastbyte = txlist[-1].pop()
- try:
- assert_template(node, tmpl, txlist, 'n/a')
- except JSONRPCException:
- pass # Expected
+ assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
txlist[-1].append(lastbyte)
# Test 4: Add an invalid tx to the end (duplicate of gen tx)
@@ -133,7 +117,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 5: Add an invalid tx to the end (non-duplicate)
txlist.append(bytearray(txlist[0]))
- txlist[-1][4+1] = b'\xff'
+ txlist[-1][4+1] = 0xff
assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
txlist.pop()
@@ -144,10 +128,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 7: Bad tx count
txlist.append(b'')
- try:
- assert_template(node, tmpl, txlist, 'n/a')
- except JSONRPCException:
- pass # Expected
+ assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
txlist.pop()
# Test 8: Bad bits
@@ -157,7 +138,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
tmpl['bits'] = realbits
# Test 9: Bad merkle root
- rawtmpl = template_to_bytes(tmpl, txlist)
+ rawtmpl = template_to_bytearray(tmpl, txlist)
rawtmpl[4+32] = (rawtmpl[4+32] + 1) % 0x100
rsp = node.getblocktemplate({'data':b2x(rawtmpl),'mode':'proposal'})
if rsp != 'bad-txnmrklroot':
diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py
index dd260836bb..1c66b8c289 100755
--- a/qa/rpc-tests/getchaintips.py
+++ b/qa/rpc-tests/getchaintips.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -11,9 +11,12 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class GetChainTipsTest (BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
def run_test (self):
- BitcoinTestFramework.run_test (self)
tips = self.nodes[0].getchaintips ()
assert_equal (len (tips), 1)
diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py
index eb548aee9d..10bc927e1a 100755
--- a/qa/rpc-tests/httpbasics.py
+++ b/qa/rpc-tests/httpbasics.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -9,106 +9,104 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-import base64
-try:
- import http.client as httplib
-except ImportError:
- import httplib
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+import http.client
+import urllib.parse
class HTTPBasicsTest (BitcoinTestFramework):
- def setup_nodes(self):
- return start_nodes(4, self.options.tmpdir)
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 3
+ self.setup_clean_chain = False
+
+ def setup_network(self):
+ self.nodes = self.setup_nodes()
def run_test(self):
#################################################
# lowlevel check for http persistent connection #
#################################################
- url = urlparse.urlparse(self.nodes[0].url)
+ url = urllib.parse.urlparse(self.nodes[0].url)
authpair = url.username + ':' + url.password
- headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True)
- assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ assert(b'"error":null' in out1)
+ assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
- out2 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
- assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ out1 = conn.getresponse().read()
+ assert(b'"error":null' in out1) #must also response with a correct json-rpc message
+ assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close()
#same should be if we add keep-alive because this should be the std. behaviour
- headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection": "keep-alive"}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True)
- assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ assert(b'"error":null' in out1)
+ assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
- out2 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
- assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ out1 = conn.getresponse().read()
+ assert(b'"error":null' in out1) #must also response with a correct json-rpc message
+ assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close()
#now do the same with "Connection: close"
- headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection":"close"}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True)
- assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
+ assert(b'"error":null' in out1)
+ assert(conn.sock==None) #now the connection must be closed after the response
#node1 (2nd node) is running with disabled keep-alive option
- urlNode1 = urlparse.urlparse(self.nodes[1].url)
+ urlNode1 = urllib.parse.urlparse(self.nodes[1].url)
authpair = urlNode1.username + ':' + urlNode1.password
- headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
- conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
+ conn = http.client.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True)
+ assert(b'"error":null' in out1)
#node2 (third node) is running with standard keep-alive parameters which means keep-alive is on
- urlNode2 = urlparse.urlparse(self.nodes[2].url)
+ urlNode2 = urllib.parse.urlparse(self.nodes[2].url)
authpair = urlNode2.username + ':' + urlNode2.password
- headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
- conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
- assert_equal('"error":null' in out1, True)
- assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
+ assert(b'"error":null' in out1)
+ assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default
# Check excessive request size
- conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('GET', '/' + ('x'*1000), '', headers)
out1 = conn.getresponse()
- assert_equal(out1.status, httplib.NOT_FOUND)
+ assert_equal(out1.status, http.client.NOT_FOUND)
- conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('GET', '/' + ('x'*10000), '', headers)
out1 = conn.getresponse()
- assert_equal(out1.status, httplib.BAD_REQUEST)
+ assert_equal(out1.status, http.client.BAD_REQUEST)
if __name__ == '__main__':
diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py
new file mode 100755
index 0000000000..d86f51b7f3
--- /dev/null
+++ b/qa/rpc-tests/importprunedfunds.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import decimal
+
+class ImportPrunedFundsTest(BitcoinTestFramework):
+
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 2
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test (self):
+ import time
+ begintime = int(time.time())
+
+ print("Mining blocks...")
+ self.nodes[0].generate(101)
+
+ # sync
+ self.sync_all()
+
+ # address
+ address1 = self.nodes[0].getnewaddress()
+ # pubkey
+ address2 = self.nodes[0].getnewaddress()
+ address2_pubkey = self.nodes[0].validateaddress(address2)['pubkey'] # Using pubkey
+ # privkey
+ address3 = self.nodes[0].getnewaddress()
+ address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
+
+ #Check only one address
+ address_info = self.nodes[0].validateaddress(address1)
+ assert_equal(address_info['ismine'], True)
+
+ self.sync_all()
+
+ #Node 1 sync test
+ assert_equal(self.nodes[1].getblockcount(),101)
+
+ #Address Test - before import
+ address_info = self.nodes[1].validateaddress(address1)
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], False)
+
+ address_info = self.nodes[1].validateaddress(address2)
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], False)
+
+ address_info = self.nodes[1].validateaddress(address3)
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], False)
+
+ #Send funds to self
+ txnid1 = self.nodes[0].sendtoaddress(address1, 0.1)
+ self.nodes[0].generate(1)
+ rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex']
+ proof1 = self.nodes[0].gettxoutproof([txnid1])
+
+ txnid2 = self.nodes[0].sendtoaddress(address2, 0.05)
+ self.nodes[0].generate(1)
+ rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex']
+ proof2 = self.nodes[0].gettxoutproof([txnid2])
+
+
+ txnid3 = self.nodes[0].sendtoaddress(address3, 0.025)
+ self.nodes[0].generate(1)
+ rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex']
+ proof3 = self.nodes[0].gettxoutproof([txnid3])
+
+ self.sync_all()
+
+ #Import with no affiliated address
+ try:
+ result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "")
+ except JSONRPCException as e:
+ assert('No addresses' in e.error['message'])
+ else:
+ assert(False)
+
+
+ balance1 = self.nodes[1].getbalance("", 0, True)
+ assert_equal(balance1, Decimal(0))
+
+ #Import with affiliated address with no rescan
+ self.nodes[1].importaddress(address2, "", False)
+ result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2, "")
+ balance2 = Decimal(self.nodes[1].getbalance("", 0, True))
+ assert_equal(balance2, Decimal('0.05'))
+
+ #Import with private key with no rescan
+ self.nodes[1].importprivkey(address3_privkey, "", False)
+ result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3, "")
+ balance3 = Decimal(self.nodes[1].getbalance("", 0, False))
+ assert_equal(balance3, Decimal('0.025'))
+ balance3 = Decimal(self.nodes[1].getbalance("", 0, True))
+ assert_equal(balance3, Decimal('0.075'))
+
+ #Addresses Test - after import
+ address_info = self.nodes[1].validateaddress(address1)
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], False)
+ address_info = self.nodes[1].validateaddress(address2)
+ assert_equal(address_info['iswatchonly'], True)
+ assert_equal(address_info['ismine'], False)
+ address_info = self.nodes[1].validateaddress(address3)
+ assert_equal(address_info['iswatchonly'], False)
+ assert_equal(address_info['ismine'], True)
+
+ #Remove transactions
+
+ try:
+ self.nodes[1].removeprunedfunds(txnid1)
+ except JSONRPCException as e:
+ assert('does not exist' in e.error['message'])
+ else:
+ assert(False)
+
+
+ balance1 = Decimal(self.nodes[1].getbalance("", 0, True))
+ assert_equal(balance1, Decimal('0.075'))
+
+
+ self.nodes[1].removeprunedfunds(txnid2)
+ balance2 = Decimal(self.nodes[1].getbalance("", 0, True))
+ assert_equal(balance2, Decimal('0.025'))
+
+ self.nodes[1].removeprunedfunds(txnid3)
+ balance3 = Decimal(self.nodes[1].getbalance("", 0, True))
+ assert_equal(balance3, Decimal('0.0'))
+
+if __name__ == '__main__':
+ ImportPrunedFundsTest ().main ()
diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py
index 0e78a3c806..0faadd33ab 100755
--- a/qa/rpc-tests/invalidateblock.py
+++ b/qa/rpc-tests/invalidateblock.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -13,10 +13,11 @@ from test_framework.util import *
class InvalidateTest(BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 3)
-
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 3
+
def setup_network(self):
self.nodes = []
self.is_network_split = False
@@ -25,46 +26,46 @@ class InvalidateTest(BitcoinTestFramework):
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
def run_test(self):
- print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
- print "Mine 4 blocks on Node 0"
+ print("Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:")
+ print("Mine 4 blocks on Node 0")
self.nodes[0].generate(4)
assert(self.nodes[0].getblockcount() == 4)
besthash = self.nodes[0].getbestblockhash()
- print "Mine competing 6 blocks on Node 1"
+ print("Mine competing 6 blocks on Node 1")
self.nodes[1].generate(6)
assert(self.nodes[1].getblockcount() == 6)
- print "Connect nodes to force a reorg"
+ print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes,0,1)
sync_blocks(self.nodes[0:2])
assert(self.nodes[0].getblockcount() == 6)
badhash = self.nodes[1].getblockhash(2)
- print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
+ print("Invalidate block 2 on node 0 and verify we reorg to node 0's original chain")
self.nodes[0].invalidateblock(badhash)
newheight = self.nodes[0].getblockcount()
newhash = self.nodes[0].getbestblockhash()
if (newheight != 4 or newhash != besthash):
raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
- print "\nMake sure we won't reorg to a lower work chain:"
+ print("\nMake sure we won't reorg to a lower work chain:")
connect_nodes_bi(self.nodes,1,2)
- print "Sync node 2 to node 1 so both have 6 blocks"
+ print("Sync node 2 to node 1 so both have 6 blocks")
sync_blocks(self.nodes[1:3])
assert(self.nodes[2].getblockcount() == 6)
- print "Invalidate block 5 on node 1 so its tip is now at 4"
+ print("Invalidate block 5 on node 1 so its tip is now at 4")
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
assert(self.nodes[1].getblockcount() == 4)
- print "Invalidate block 3 on node 2, so its tip is now 2"
+ print("Invalidate block 3 on node 2, so its tip is now 2")
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
assert(self.nodes[2].getblockcount() == 2)
- print "..and then mine a block"
+ print("..and then mine a block")
self.nodes[2].generate(1)
- print "Verify all nodes are at the right height"
+ print("Verify all nodes are at the right height")
time.sleep(5)
- for i in xrange(3):
- print i,self.nodes[i].getblockcount()
+ for i in range(3):
+ print(i,self.nodes[i].getblockcount())
assert(self.nodes[2].getblockcount() == 3)
assert(self.nodes[0].getblockcount() == 4)
node1height = self.nodes[1].getblockcount()
diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py
index f91a8da015..3d8107a76c 100755
--- a/qa/rpc-tests/invalidblockrequest.py
+++ b/qa/rpc-tests/invalidblockrequest.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
@@ -26,6 +25,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
''' Can either run this test as 1 node with expected answers, or two and compare them.
Change the "outcome" variable from each TestInstance object to only do the comparison. '''
def __init__(self):
+ super().__init__()
self.num_nodes = 1
def run_test(self):
@@ -38,7 +38,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
def get_tests(self):
if self.tip is None:
- self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.block_time = int(time.time())+1
'''
@@ -58,7 +58,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
Now we need that block to mature so we can spend the coinbase.
'''
test = TestInstance(sync_every_block=False)
- for i in xrange(100):
+ for i in range(100):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.tip = block.sha256
@@ -77,9 +77,9 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
block2 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1
- # chr(81) is OP_TRUE
- tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000)
- tx2 = create_transaction(tx1, 0, chr(81), 50*100000000)
+ # b'0x51' is OP_TRUE
+ tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN)
+ tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN)
block2.vtx.extend([tx1, tx2])
block2.hashMerkleRoot = block2.calc_merkle_root()
@@ -95,7 +95,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
assert(block2_orig.vtx != block2.vtx)
self.tip = block2.sha256
- yield TestInstance([[block2, RejectResult(16,'bad-txns-duplicate')], [block2_orig, True]])
+ yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]])
height += 1
'''
@@ -103,14 +103,14 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
'''
block3 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1
- block3.vtx[0].vout[0].nValue = 100*100000000 # Too high!
+ block3.vtx[0].vout[0].nValue = 100 * COIN # Too high!
block3.vtx[0].sha256=None
block3.vtx[0].calc_sha256()
block3.hashMerkleRoot = block3.calc_merkle_root()
block3.rehash()
block3.solve()
- yield TestInstance([[block3, RejectResult(16,'bad-cb-amount')]])
+ yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]])
if __name__ == '__main__':
diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py
index c2fe4f1dff..93205d79de 100755
--- a/qa/rpc-tests/invalidtxrequest.py
+++ b/qa/rpc-tests/invalidtxrequest.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.comptool import TestManager, TestInstance, RejectResult
@@ -20,6 +19,7 @@ class InvalidTxRequestTest(ComparisonTestFramework):
''' Can either run this test as 1 node with expected answers, or two and compare them.
Change the "outcome" variable from each TestInstance object to only do the comparison. '''
def __init__(self):
+ super().__init__()
self.num_nodes = 1
def run_test(self):
@@ -32,7 +32,7 @@ class InvalidTxRequestTest(ComparisonTestFramework):
def get_tests(self):
if self.tip is None:
- self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.block_time = int(time.time())+1
'''
@@ -52,7 +52,7 @@ class InvalidTxRequestTest(ComparisonTestFramework):
Now we need that block to mature so we can spend the coinbase.
'''
test = TestInstance(sync_every_block=False)
- for i in xrange(100):
+ for i in range(100):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.tip = block.sha256
@@ -61,10 +61,10 @@ class InvalidTxRequestTest(ComparisonTestFramework):
height += 1
yield test
- # chr(100) is OP_NOTIF
+ # b'\x64' is OP_NOTIF
# Transaction will be rejected with code 16 (REJECT_INVALID)
- tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000 - 12000)
- yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]])
+ tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 50 * COIN - 12000)
+ yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]])
# TODO: test further transactions...
diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py
index 95d0d6832a..c75303ecbf 100755
--- a/qa/rpc-tests/keypool.py
+++ b/qa/rpc-tests/keypool.py
@@ -1,37 +1,13 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
# Exercise the wallet keypool, and interaction with wallet encryption/locking
-# Add python-bitcoinrpc to module search path:
-
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-
-def check_array_result(object_array, to_match, expected):
- """
- Pass in array of JSON objects, a dictionary with key/value pairs
- to match against, and another dictionary with expected key/value
- pairs.
- """
- num_matched = 0
- for item in object_array:
- all_match = True
- for key,value in to_match.items():
- if item[key] != value:
- all_match = False
- if not all_match:
- continue
- for key,value in expected.items():
- if item[key] != value:
- raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
- num_matched = num_matched+1
- if num_matched == 0:
- raise AssertionError("No objects matched %s"%(str(to_match)))
-
class KeyPoolTest(BitcoinTestFramework):
def run_test(self):
@@ -46,7 +22,7 @@ class KeyPoolTest(BitcoinTestFramework):
try:
addr = nodes[0].getnewaddress()
raise AssertionError('Keypool should be exhausted after one address')
- except JSONRPCException,e:
+ except JSONRPCException as e:
assert(e.error['code']==-12)
# put three new keys in the keypool
@@ -66,7 +42,7 @@ class KeyPoolTest(BitcoinTestFramework):
try:
addr = nodes[0].getrawchangeaddress()
raise AssertionError('Keypool should be exhausted after three addresses')
- except JSONRPCException,e:
+ except JSONRPCException as e:
assert(e.error['code']==-12)
# refill keypool with three new addresses
@@ -84,15 +60,16 @@ class KeyPoolTest(BitcoinTestFramework):
try:
nodes[0].generate(1)
raise AssertionError('Keypool should be exhausted after three addesses')
- except JSONRPCException,e:
+ except JSONRPCException as e:
assert(e.error['code']==-12)
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain(self.options.tmpdir)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = False
+ self.num_nodes = 1
def setup_network(self):
- self.nodes = start_nodes(1, self.options.tmpdir)
+ self.nodes = self.setup_nodes()
if __name__ == '__main__':
KeyPoolTest().main()
diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py
index 45ede8f040..5ec6ce17e0 100755
--- a/qa/rpc-tests/listtransactions.py
+++ b/qa/rpc-tests/listtransactions.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -7,70 +7,52 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-from test_framework.mininode import CTransaction
-import cStringIO
-import binascii
+from test_framework.mininode import CTransaction, COIN
+from io import BytesIO
def txFromHex(hexstring):
tx = CTransaction()
- f = cStringIO.StringIO(binascii.unhexlify(hexstring))
+ f = BytesIO(hex_str_to_bytes(hexstring))
tx.deserialize(f)
return tx
-def check_array_result(object_array, to_match, expected):
- """
- Pass in array of JSON objects, a dictionary with key/value pairs
- to match against, and another dictionary with expected key/value
- pairs.
- """
- num_matched = 0
- for item in object_array:
- all_match = True
- for key,value in to_match.items():
- if item[key] != value:
- all_match = False
- if not all_match:
- continue
- for key,value in expected.items():
- if item[key] != value:
- raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
- num_matched = num_matched+1
- if num_matched == 0:
- raise AssertionError("No objects matched %s"%(str(to_match)))
-
class ListTransactionsTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
- return start_nodes(4, self.options.tmpdir)
+ return start_nodes(self.num_nodes, self.options.tmpdir)
def run_test(self):
# Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all()
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0})
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"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()
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1})
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"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)
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid, "category":"send"},
{"amount":Decimal("-0.2")})
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid, "category":"receive"},
{"amount":Decimal("0.2")})
@@ -81,28 +63,28 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].getaccountaddress("toself") : 0.44 }
txid = self.nodes[1].sendmany("", send_to)
self.sync_all()
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.11")},
{"txid":txid} )
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.11")},
{"txid":txid} )
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.22")},
{"txid":txid} )
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.22")},
{"txid":txid} )
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.33")},
{"txid":txid} )
- check_array_result(self.nodes[0].listtransactions(),
+ assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.33")},
{"txid":txid, "account" : "from1"} )
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.44")},
{"txid":txid, "account" : ""} )
- check_array_result(self.nodes[1].listtransactions(),
+ assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.44")},
{"txid":txid, "account" : "toself"} )
@@ -112,7 +94,7 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].generate(1)
self.sync_all()
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
- check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
+ assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
{"category":"receive","amount":Decimal("0.1")},
{"txid":txid, "account" : "watchonly"} )
@@ -140,9 +122,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))
- check_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)
- check_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[1], txid_1)
@@ -156,9 +138,9 @@ class ListTransactionsTest(BitcoinTestFramework):
# ...and check the result
assert(not is_opt_in(self.nodes[1], txid_2))
- check_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)
- check_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)
@@ -167,14 +149,14 @@ class ListTransactionsTest(BitcoinTestFramework):
tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
tx3_modified = txFromHex(tx3)
tx3_modified.vin[0].nSequence = 0
- tx3 = binascii.hexlify(tx3_modified.serialize()).decode('utf-8')
+ tx3 = bytes_to_hex_str(tx3_modified.serialize())
tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex']
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
assert(is_opt_in(self.nodes[0], txid_3))
- check_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)
- check_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.
@@ -186,21 +168,21 @@ class ListTransactionsTest(BitcoinTestFramework):
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
assert(not is_opt_in(self.nodes[1], txid_4))
- check_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)
- check_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 -= 0.004*100000000 # bump the fee
- tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8')
+ 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].signrawtransaction(tx3_b)['hex']
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
assert(is_opt_in(self.nodes[0], txid_3b))
- check_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)
- check_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]:
diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py
index 0313bce736..1df1c484be 100755
--- a/qa/rpc-tests/maxblocksinflight.py
+++ b/qa/rpc-tests/maxblocksinflight.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
@@ -41,52 +40,49 @@ class TestManager(NodeConnCB):
self.disconnectOkay = False
def run(self):
- try:
- fail = False
- self.connection.rpc.generate(1) # Leave IBD
-
- numBlocksToGenerate = [ 8, 16, 128, 1024 ]
- for count in range(len(numBlocksToGenerate)):
- current_invs = []
- for i in range(numBlocksToGenerate[count]):
- current_invs.append(CInv(2, random.randrange(0, 1<<256)))
- if len(current_invs) >= 50000:
- self.connection.send_message(msg_inv(current_invs))
- current_invs = []
- if len(current_invs) > 0:
+ self.connection.rpc.generate(1) # Leave IBD
+
+ numBlocksToGenerate = [8, 16, 128, 1024]
+ for count in range(len(numBlocksToGenerate)):
+ current_invs = []
+ for i in range(numBlocksToGenerate[count]):
+ current_invs.append(CInv(2, random.randrange(0, 1 << 256)))
+ if len(current_invs) >= 50000:
self.connection.send_message(msg_inv(current_invs))
-
- # Wait and see how many blocks were requested
- time.sleep(2)
-
- total_requests = 0
- with mininode_lock:
- for key in self.blockReqCounts:
- total_requests += self.blockReqCounts[key]
- if self.blockReqCounts[key] > 1:
- raise AssertionError("Error, test failed: block %064x requested more than once" % key)
- if total_requests > MAX_REQUESTS:
- raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
- print "Round %d: success (total requests: %d)" % (count, total_requests)
- except AssertionError as e:
- print "TEST FAILED: ", e.args
+ current_invs = []
+ if len(current_invs) > 0:
+ self.connection.send_message(msg_inv(current_invs))
+
+ # Wait and see how many blocks were requested
+ time.sleep(2)
+
+ total_requests = 0
+ with mininode_lock:
+ for key in self.blockReqCounts:
+ total_requests += self.blockReqCounts[key]
+ if self.blockReqCounts[key] > 1:
+ raise AssertionError("Error, test failed: block %064x requested more than once" % key)
+ if total_requests > MAX_REQUESTS:
+ raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
+ print("Round %d: success (total requests: %d)" % (count, total_requests))
self.disconnectOkay = True
self.connection.disconnect_node()
-
+
class MaxBlocksInFlightTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
default=os.getenv("BITCOIND", "bitcoind"),
help="Binary to test max block requests behavior")
- def setup_chain(self):
- print "Initializing test directory "+self.options.tmpdir
- initialize_chain_clean(self.options.tmpdir, 1)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
def setup_network(self):
- self.nodes = start_nodes(1, self.options.tmpdir,
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1']],
binary=[self.options.testbinary])
diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py
index 4d6b343f77..5087f07620 100755
--- a/qa/rpc-tests/maxuploadtarget.py
+++ b/qa/rpc-tests/maxuploadtarget.py
@@ -1,13 +1,11 @@
-#!/usr/bin/env python2
-#
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-from test_framework.comptool import wait_until
import time
'''
@@ -82,17 +80,19 @@ class TestNode(NodeConnCB):
return success
class MaxUploadTest(BitcoinTestFramework):
- def __init__(self):
- self.utxo = []
- self.txouts = gen_return_txouts()
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
default=os.getenv("BITCOIND", "bitcoind"),
help="bitcoind binary to test")
- def setup_chain(self):
- initialize_chain_clean(self.options.tmpdir, 2)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
+
+ self.utxo = []
+ self.txouts = gen_return_txouts()
def setup_network(self):
# Start a node with maxuploadtarget of 200 MB (/24h)
@@ -102,7 +102,7 @@ class MaxUploadTest(BitcoinTestFramework):
def mine_full_block(self, node, address):
# Want to create a full block
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
- for j in xrange(14):
+ for j in range(14):
if len(self.utxo) < 14:
self.utxo = node.listunspent()
inputs=[]
@@ -140,7 +140,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes = []
connections = []
- for i in xrange(3):
+ for i in range(3):
test_nodes.append(TestNode())
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i]))
test_nodes[i].add_connection(connections[i])
@@ -176,13 +176,13 @@ class MaxUploadTest(BitcoinTestFramework):
getdata_request.inv.append(CInv(2, big_old_block))
max_bytes_per_day = 200*1024*1024
- daily_buffer = 144 * 1000000
+ daily_buffer = 144 * MAX_BLOCK_SIZE
max_bytes_available = max_bytes_per_day - daily_buffer
- success_count = max_bytes_available / old_block_size
+ success_count = max_bytes_available // old_block_size
# 144MB will be reserved for relaying new blocks, so expect this to
# succeed for ~70 tries.
- for i in xrange(success_count):
+ for i in range(success_count):
test_nodes[0].send_message(getdata_request)
test_nodes[0].sync_with_ping()
assert_equal(test_nodes[0].block_receive_map[big_old_block], i+1)
@@ -190,22 +190,22 @@ class MaxUploadTest(BitcoinTestFramework):
assert_equal(len(self.nodes[0].getpeerinfo()), 3)
# At most a couple more tries should succeed (depending on how long
# the test has been running so far).
- for i in xrange(3):
+ for i in range(3):
test_nodes[0].send_message(getdata_request)
test_nodes[0].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 2)
- print "Peer 0 disconnected after downloading old block too many times"
+ print("Peer 0 disconnected after downloading old block too many times")
# Requesting the current block on test_nodes[1] should succeed indefinitely,
# even when over the max upload target.
# We'll try 200 times
getdata_request.inv = [CInv(2, big_new_block)]
- for i in xrange(200):
+ for i in range(200):
test_nodes[1].send_message(getdata_request)
test_nodes[1].sync_with_ping()
assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1)
- print "Peer 1 able to repeatedly download new block"
+ print("Peer 1 able to repeatedly download new block")
# But if test_nodes[1] tries for an old block, it gets disconnected too.
getdata_request.inv = [CInv(2, big_old_block)]
@@ -213,9 +213,9 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[1].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 1)
- print "Peer 1 disconnected after trying to download old block"
+ print("Peer 1 disconnected after trying to download old block")
- print "Advancing system time on node to clear counters..."
+ print("Advancing system time on node to clear counters...")
# If we advance the time by 24 hours, then the counters should reset,
# and test_nodes[2] should be able to retrieve the old block.
@@ -225,12 +225,12 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[2].sync_with_ping()
assert_equal(test_nodes[2].block_receive_map[big_old_block], 1)
- print "Peer 2 able to download old block"
+ print("Peer 2 able to download old block")
[c.disconnect_node() for c in connections]
#stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1
- print "Restarting nodes with -whitelist=127.0.0.1"
+ print("Restarting nodes with -whitelist=127.0.0.1")
stop_node(self.nodes[0], 0)
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1", "-maxuploadtarget=1", "-blockmaxsize=999000"])
@@ -238,7 +238,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes = []
connections = []
- for i in xrange(3):
+ for i in range(3):
test_nodes.append(TestNode())
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i]))
test_nodes[i].add_connection(connections[i])
@@ -248,7 +248,7 @@ class MaxUploadTest(BitcoinTestFramework):
#retrieve 20 blocks which should be enough to break the 1MB limit
getdata_request.inv = [CInv(2, big_new_block)]
- for i in xrange(20):
+ for i in range(20):
test_nodes[1].send_message(getdata_request)
test_nodes[1].sync_with_ping()
assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1)
@@ -258,7 +258,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[1].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 3) #node is still connected because of the whitelist
- print "Peer 1 still connected after trying to download old block (whitelisted)"
+ print("Peer 1 still connected after trying to download old block (whitelisted)")
[c.disconnect_node() for c in connections]
diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py
index 7914ceea22..4438c152df 100755
--- a/qa/rpc-tests/mempool_limit.py
+++ b/qa/rpc-tests/mempool_limit.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -10,9 +10,6 @@ from test_framework.util import *
class MempoolLimitTest(BitcoinTestFramework):
- def __init__(self):
- self.txouts = gen_return_txouts()
-
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"]))
@@ -20,9 +17,12 @@ class MempoolLimitTest(BitcoinTestFramework):
self.sync_all()
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 2)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
+
+ self.txouts = gen_return_txouts()
def run_test(self):
txids = []
@@ -38,11 +38,10 @@ class MempoolLimitTest(BitcoinTestFramework):
self.nodes[0].settxfee(0) # return to automatic fee selection
txFS = self.nodes[0].signrawtransaction(txF['hex'])
txid = self.nodes[0].sendrawtransaction(txFS['hex'])
- self.nodes[0].lockunspent(True, [us0])
relayfee = self.nodes[0].getnetworkinfo()['relayfee']
base_fee = relayfee*100
- for i in xrange (4):
+ for i in range (4):
txids.append([])
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py
index 47c1028b9f..693ff593b3 100755
--- a/qa/rpc-tests/mempool_packages.py
+++ b/qa/rpc-tests/mempool_packages.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -7,11 +7,16 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
+from test_framework.mininode import COIN
MAX_ANCESTORS = 25
MAX_DESCENDANTS = 25
class MempoolPackagesTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
def setup_network(self):
self.nodes = []
@@ -27,7 +32,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
send_value = satoshi_round((value - fee)/num_outputs)
inputs = [ {'txid' : parent_txid, 'vout' : vout} ]
outputs = {}
- for i in xrange(num_outputs):
+ for i in range(num_outputs):
outputs[node.getnewaddress()] = send_value
rawtx = node.createrawtransaction(inputs, outputs)
signedtx = node.signrawtransaction(rawtx)
@@ -47,7 +52,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
fee = Decimal("0.0001")
# MAX_ANCESTORS transactions off a confirmed tx should be fine
chain = []
- for i in xrange(MAX_ANCESTORS):
+ for i in range(MAX_ANCESTORS):
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, 0, value, fee, 1)
value = sent_value
chain.append(txid)
@@ -59,13 +64,12 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_count = 1
descendant_fees = 0
descendant_size = 0
- SATOSHIS = 100000000
for x in reversed(chain):
assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee'])
- assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees)
+ assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN)
descendant_size += mempool[x]['size']
assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1
@@ -78,13 +82,13 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees = 0
for x in reversed(chain):
descendant_fees += mempool[x]['fee']
- assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+1000)
+ assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 1000)
# Adding one more transaction on to the chain should fail.
try:
self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1)
except JSONRPCException as e:
- print "too-long-ancestor-chain successfully rejected"
+ print("too-long-ancestor-chain successfully rejected")
# Check that prioritising a tx before it's added to the mempool works
# First clear the mempool by mining a block.
@@ -106,7 +110,7 @@ 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]['descendantfees'], SATOSHIS*descendant_fees+2000)
+ assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 2000)
# TODO: check that node1's mempool is as expected
@@ -121,22 +125,22 @@ class MempoolPackagesTest(BitcoinTestFramework):
# First create one parent tx with 10 children
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 10)
parent_transaction = txid
- for i in xrange(10):
+ for i in range(10):
transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value})
- for i in xrange(MAX_DESCENDANTS):
+ for i in range(MAX_DESCENDANTS):
utxo = transaction_package.pop(0)
try:
(txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10)
- for j in xrange(10):
+ for j in range(10):
transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value})
if i == MAX_DESCENDANTS - 2:
mempool = self.nodes[0].getrawmempool(True)
assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS)
except JSONRPCException as e:
- print e.error['message']
+ print(e.error['message'])
assert_equal(i, MAX_DESCENDANTS - 1)
- print "tx that would create too large descendant package successfully rejected"
+ print("tx that would create too large descendant package successfully rejected")
# TODO: check that node1's mempool is as expected
@@ -171,7 +175,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
send_value = satoshi_round((value - fee)/2)
inputs = [ {'txid' : txid, 'vout' : vout} ]
outputs = {}
- for i in xrange(2):
+ for i in range(2):
outputs[self.nodes[0].getnewaddress()] = send_value
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
signedtx = self.nodes[0].signrawtransaction(rawtx)
@@ -185,7 +189,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
# Create tx2-7
vout = 1
txid = tx0_id
- for i in xrange(6):
+ for i in range(6):
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1)
vout = 0
value = sent_value
diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py
index 40684e7fbb..301b094eb0 100755
--- a/qa/rpc-tests/mempool_reorg.py
+++ b/qa/rpc-tests/mempool_reorg.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -13,6 +13,10 @@ from test_framework.util import *
# Create one-input, one-output, no-fee transaction:
class MempoolCoinbaseTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
alert_filename = None # Set by setup_network
@@ -25,14 +29,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.is_network_split = False
self.sync_all()
- def create_tx(self, from_txid, to_address, amount):
- inputs = [{ "txid" : from_txid, "vout" : 0}]
- outputs = { to_address : amount }
- rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- signresult = self.nodes[0].signrawtransaction(rawtx)
- assert_equal(signresult["complete"], True)
- return signresult["hex"]
-
def run_test(self):
start_count = self.nodes[0].getblockcount()
@@ -52,9 +48,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# and make sure the mempool code behaves correctly.
b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
- spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 49.99)
- spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 49.99)
- spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 49.99)
+ spend_101_raw = create_tx(self.nodes[0], coinbase_txids[1], node1_address, 49.99)
+ spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 49.99)
+ spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 49.99)
# Create a block-height-locked transaction which will be invalid after reorg
timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99})
@@ -71,8 +67,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx)
# Create 102_1 and 103_1:
- spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 49.98)
- spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 49.98)
+ spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 49.98)
+ spend_103_1_raw = create_tx(self.nodes[0], spend_103_id, node1_address, 49.98)
# Broadcast and mine 103_1:
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py
index 9fcc88a2a3..3db12cbf76 100755
--- a/qa/rpc-tests/mempool_resurrect_test.py
+++ b/qa/rpc-tests/mempool_resurrect_test.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -14,6 +14,11 @@ from test_framework.util import *
# Create one-input, one-output, no-fee transaction:
class MempoolCoinbaseTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 1
+ self.setup_clean_chain = False
+
def setup_network(self):
# Just need one node for this test
args = ["-checkmempool", "-debug=mempool"]
@@ -21,14 +26,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.is_network_split = False
- def create_tx(self, from_txid, to_address, amount):
- inputs = [{ "txid" : from_txid, "vout" : 0}]
- outputs = { to_address : amount }
- rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- signresult = self.nodes[0].signrawtransaction(rawtx)
- assert_equal(signresult["complete"], True)
- return signresult["hex"]
-
def run_test(self):
node0_address = self.nodes[0].getnewaddress()
# Spend block 1/2/3's coinbase transactions
@@ -43,13 +40,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
- spends1_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ]
+ spends1_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.99) for txid in coinbase_txids ]
spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
blocks = []
blocks.extend(self.nodes[0].generate(1))
- spends2_raw = [ self.create_tx(txid, node0_address, 49.98) for txid in spends1_id ]
+ spends2_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.98) for txid in spends1_id ]
spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
blocks.extend(self.nodes[0].generate(1))
diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py
index 16f512db38..d5e4bf52d2 100755
--- a/qa/rpc-tests/mempool_spendcoinbase.py
+++ b/qa/rpc-tests/mempool_spendcoinbase.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -19,6 +19,11 @@ from test_framework.util import *
# Create one-input, one-output, no-fee transaction:
class MempoolSpendCoinbaseTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 1
+ self.setup_clean_chain = False
+
def setup_network(self):
# Just need one node for this test
args = ["-checkmempool", "-debug=mempool"]
@@ -26,14 +31,6 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.is_network_split = False
- def create_tx(self, from_txid, to_address, amount):
- inputs = [{ "txid" : from_txid, "vout" : 0}]
- outputs = { to_address : amount }
- rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- signresult = self.nodes[0].signrawtransaction(rawtx)
- assert_equal(signresult["complete"], True)
- return signresult["hex"]
-
def run_test(self):
chain_height = self.nodes[0].getblockcount()
assert_equal(chain_height, 200)
@@ -44,7 +41,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
# is too immature to spend.
b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
- spends_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ]
+ spends_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.99) for txid in coinbase_txids ]
spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py
index eb718f39e4..b2155d7fc3 100755
--- a/qa/rpc-tests/merkle_blocks.py
+++ b/qa/rpc-tests/merkle_blocks.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -12,9 +12,10 @@ from test_framework.util import *
class MerkleBlockTest(BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 4)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 4
def setup_network(self):
self.nodes = []
@@ -32,7 +33,7 @@ class MerkleBlockTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
- print "Mining blocks..."
+ print("Mining blocks...")
self.nodes[0].generate(105)
self.sync_all()
diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py
index 2452b77319..24373b257d 100755
--- a/qa/rpc-tests/multi_rpc.py
+++ b/qa/rpc-tests/multi_rpc.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -8,25 +8,21 @@
#
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-import base64
-
-try:
- import http.client as httplib
-except ImportError:
- import httplib
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+from test_framework.util import str_to_b64str, assert_equal
+
+import os
+import http.client
+import urllib.parse
class HTTPBasicsTest (BitcoinTestFramework):
- def setup_nodes(self):
- return start_nodes(4, self.options.tmpdir)
+
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = False
+ self.num_nodes = 1
def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain(self.options.tmpdir)
+ super().setup_chain()
#Append rpcauth to bitcoin.conf before initialization
rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144"
rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e"
@@ -34,12 +30,15 @@ class HTTPBasicsTest (BitcoinTestFramework):
f.write(rpcauth+"\n")
f.write(rpcauth2+"\n")
+ def setup_network(self):
+ self.nodes = self.setup_nodes()
+
def run_test(self):
##################################################
# Check correctness of the rpcauth config option #
##################################################
- url = urlparse.urlparse(self.nodes[0].url)
+ url = urllib.parse.urlparse(self.nodes[0].url)
#Old authpair
authpair = url.username + ':' + url.password
@@ -53,9 +52,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
authpairnew = "rt:"+password
- headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -63,9 +62,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close()
#Use new authpair to confirm both work
- headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -74,9 +73,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong login name with rt's password
authpairnew = "rtwrong:"+password
- headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -85,9 +84,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt
authpairnew = "rt:"+password+"wrong"
- headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -96,9 +95,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Correct for rt2
authpairnew = "rt2:"+password2
- headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -107,9 +106,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt2
authpairnew = "rt2:"+password2+"wrong"
- headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
+ headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
- conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -117,6 +116,5 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close()
-
if __name__ == '__main__':
HTTPBasicsTest ().main ()
diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py
index c6c8c436e9..e9682c4908 100755
--- a/qa/rpc-tests/nodehandling.py
+++ b/qa/rpc-tests/nodehandling.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -10,16 +10,16 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-try:
- import http.client as httplib
-except ImportError:
- import httplib
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+import http.client
+import urllib.parse
class NodeHandlingTest (BitcoinTestFramework):
+
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
def run_test(self):
###########################
# setban/listbanned tests #
@@ -69,7 +69,7 @@ class NodeHandlingTest (BitcoinTestFramework):
###########################
# RPC disconnectnode test #
###########################
- url = urlparse.urlparse(self.nodes[1].url)
+ url = urllib.parse.urlparse(self.nodes[1].url)
self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
time.sleep(2) #disconnecting a node needs a little bit of time
for node in self.nodes[0].getpeerinfo():
diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py
index bf355780c1..015ec34eff 100755
--- a/qa/rpc-tests/p2p-acceptblock.py
+++ b/qa/rpc-tests/p2p-acceptblock.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
@@ -112,8 +111,10 @@ class AcceptBlockTest(BitcoinTestFramework):
default=os.getenv("BITCOIND", "bitcoind"),
help="bitcoind binary to test")
- def setup_chain(self):
- initialize_chain_clean(self.options.tmpdir, 2)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 2
def setup_network(self):
# Node0 will be used to test behavior of processing unrequested blocks
@@ -145,13 +146,13 @@ class AcceptBlockTest(BitcoinTestFramework):
# 1. Have both nodes mine a block (leave IBD)
[ n.generate(1) for n in self.nodes ]
- tips = [ int ("0x" + n.getbestblockhash() + "L", 0) for n in self.nodes ]
+ tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ]
# 2. Send one block that builds on each tip.
# This should be accepted.
blocks_h2 = [] # the height 2 blocks on each node's chain
- block_time = time.time() + 1
- for i in xrange(2):
+ block_time = int(time.time()) + 1
+ for i in range(2):
blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time))
blocks_h2[i].solve()
block_time += 1
@@ -161,11 +162,11 @@ class AcceptBlockTest(BitcoinTestFramework):
[ x.sync_with_ping() for x in [test_node, white_node] ]
assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 2)
- print "First height 2 block accepted by both nodes"
+ print("First height 2 block accepted by both nodes")
# 3. Send another block that builds on the original tip.
blocks_h2f = [] # Blocks at height 2 that fork off the main chain
- for i in xrange(2):
+ for i in range(2):
blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1))
blocks_h2f[i].solve()
test_node.send_message(msg_block(blocks_h2f[0]))
@@ -180,11 +181,11 @@ class AcceptBlockTest(BitcoinTestFramework):
if x['hash'] == blocks_h2f[1].hash:
assert_equal(x['status'], "valid-headers")
- print "Second height 2 block accepted only from whitelisted peer"
+ print("Second height 2 block accepted only from whitelisted peer")
# 4. Now send another block that builds on the forking chain.
blocks_h3 = []
- for i in xrange(2):
+ for i in range(2):
blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1))
blocks_h3[i].solve()
test_node.send_message(msg_block(blocks_h3[0]))
@@ -200,13 +201,13 @@ class AcceptBlockTest(BitcoinTestFramework):
# But this block should be accepted by node0 since it has more work.
try:
self.nodes[0].getblock(blocks_h3[0].hash)
- print "Unrequested more-work block accepted from non-whitelisted peer"
+ print("Unrequested more-work block accepted from non-whitelisted peer")
except:
raise AssertionError("Unrequested more work block was not processed")
# Node1 should have accepted and reorged.
assert_equal(self.nodes[1].getblockcount(), 3)
- print "Successfully reorged to length 3 chain from whitelisted peer"
+ print("Successfully reorged to length 3 chain from whitelisted peer")
# 4b. Now mine 288 more blocks and deliver; all should be processed but
# the last (height-too-high) on node0. Node1 should process the tip if
@@ -214,8 +215,8 @@ class AcceptBlockTest(BitcoinTestFramework):
tips = blocks_h3
headers_message = msg_headers()
all_blocks = [] # node0's blocks
- for j in xrange(2):
- for i in xrange(288):
+ for j in range(2):
+ for i in range(288):
next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1)
next_block.solve()
if j==0:
@@ -233,7 +234,7 @@ class AcceptBlockTest(BitcoinTestFramework):
raise AssertionError("Unrequested block too far-ahead should have been ignored")
except:
if x == all_blocks[287]:
- print "Unrequested block too far-ahead not processed"
+ print("Unrequested block too far-ahead not processed")
else:
raise AssertionError("Unrequested block with more work should have been accepted")
@@ -243,7 +244,7 @@ class AcceptBlockTest(BitcoinTestFramework):
try:
white_node.sync_with_ping()
self.nodes[1].getblock(tips[1].hash)
- print "Unrequested block far ahead of tip accepted from whitelisted peer"
+ print("Unrequested block far ahead of tip accepted from whitelisted peer")
except:
raise AssertionError("Unrequested block from whitelisted peer not accepted")
@@ -259,7 +260,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# a getdata request for this block.
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 2)
- print "Unrequested block that would complete more-work chain was ignored"
+ print("Unrequested block that would complete more-work chain was ignored")
# 6. Try to get node to request the missing block.
# Poke the node with an inv for block at height 3 and see if that
@@ -275,14 +276,14 @@ class AcceptBlockTest(BitcoinTestFramework):
# Check that the getdata includes the right block
assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256)
- print "Inv at tip triggered getdata for unprocessed block"
+ print("Inv at tip triggered getdata for unprocessed block")
# 7. Send the missing block for the third time (now it is requested)
test_node.send_message(msg_block(blocks_h2f[0]))
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 290)
- print "Successfully reorged to longer chain from non-whitelisted peer"
+ print("Successfully reorged to longer chain from non-whitelisted peer")
[ c.disconnect_node() for c in connections ]
diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py
new file mode 100755
index 0000000000..cd0501a314
--- /dev/null
+++ b/qa/rpc-tests/p2p-feefilter.py
@@ -0,0 +1,105 @@
+#!/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.
+#
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import time
+
+'''
+FeeFilterTest -- test processing of feefilter messages
+'''
+
+def hashToHex(hash):
+ return format(hash, '064x')
+
+# Wait up to 60 secs to see if the testnode has received all the expected invs
+def allInvsMatch(invsExpected, testnode):
+ for x in range(60):
+ with mininode_lock:
+ if (sorted(invsExpected) == sorted(testnode.txinvs)):
+ return True;
+ time.sleep(1)
+ return False;
+
+# TestNode: bare-bones "peer". Used to track which invs are received from a node
+# and to send the node feefilter messages.
+class TestNode(SingleNodeConnCB):
+ def __init__(self):
+ SingleNodeConnCB.__init__(self)
+ self.txinvs = []
+
+ def on_inv(self, conn, message):
+ for i in message.inv:
+ if (i.type == 1):
+ self.txinvs.append(hashToHex(i.hash))
+
+ def clear_invs(self):
+ with mininode_lock:
+ self.txinvs = []
+
+ def send_filter(self, feerate):
+ self.send_message(msg_feefilter(feerate))
+ self.sync_with_ping()
+
+class FeeFilterTest(BitcoinTestFramework):
+
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 2
+ self.setup_clean_chain = False
+
+ def setup_network(self):
+ # Node1 will be used to generate txs which should be relayed from Node0
+ # to our test node
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros"]))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros"]))
+ connect_nodes(self.nodes[0], 1)
+
+ def run_test(self):
+ node1 = self.nodes[1]
+ # Get out of IBD
+ node1.generate(1)
+ sync_blocks(self.nodes)
+
+ # Setup the p2p connections and start up the network thread.
+ test_node = TestNode()
+ connection = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)
+ test_node.add_connection(connection)
+ NetworkThread().start()
+ test_node.wait_for_verack()
+
+ # Test that invs are received for all txs at feerate of 20 sat/byte
+ node1.settxfee(Decimal("0.00020000"))
+ txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)]
+ assert(allInvsMatch(txids, test_node))
+ test_node.clear_invs()
+
+ # Set a filter of 15 sat/byte
+ test_node.send_filter(15000)
+
+ # Test that txs are still being received (paying 20 sat/byte)
+ txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)]
+ assert(allInvsMatch(txids, test_node))
+ test_node.clear_invs()
+
+ # Change tx fee rate to 10 sat/byte and test they are no longer received
+ node1.settxfee(Decimal("0.00010000"))
+ [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)]
+ sync_mempools(self.nodes) # must be sure node 0 has received all txs
+ time.sleep(10) # wait 10 secs to be sure its doesn't relay any
+ assert(allInvsMatch([], test_node))
+ test_node.clear_invs()
+
+ # Remove fee filter and check that txs are received again
+ test_node.send_filter(0)
+ txids = [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)]
+ assert(allInvsMatch(txids, test_node))
+ test_node.clear_invs()
+
+if __name__ == '__main__':
+ FeeFilterTest().main()
diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py
index b1e8ca53ee..aa0501c5e9 100755
--- a/qa/rpc-tests/p2p-fullblocktest.py
+++ b/qa/rpc-tests/p2p-fullblocktest.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
@@ -30,10 +29,11 @@ class FullBlockTest(ComparisonTestFramework):
''' Can either run this test as 1 node with expected answers, or two and compare them.
Change the "outcome" variable from each TestInstance object to only do the comparison. '''
def __init__(self):
+ super().__init__()
self.num_nodes = 1
self.block_heights = {}
self.coinbase_key = CECKey()
- self.coinbase_key.set_secretbytes(bytes("horsebattery"))
+ self.coinbase_key.set_secretbytes(b"horsebattery")
self.coinbase_pubkey = self.coinbase_key.get_pubkey()
self.block_time = int(time.time())+1
self.tip = None
@@ -70,7 +70,7 @@ class FullBlockTest(ComparisonTestFramework):
block = create_block(base_block_hash, coinbase, self.block_time)
if (spend != None):
tx = CTransaction()
- tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), "", 0xffffffff)) # no signature yet
+ tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), b"", 0xffffffff)) # no signature yet
# This copies the java comparison tool testing behavior: the first
# txout has a garbage scriptPubKey, "to make sure we're not
# pre-verifying too much" (?)
@@ -80,7 +80,7 @@ class FullBlockTest(ComparisonTestFramework):
else:
tx.vout.append(CTxOut(1, script))
# Now sign it if necessary
- scriptSig = ""
+ scriptSig = b""
scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey)
if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend
scriptSig = CScript([OP_TRUE])
@@ -225,7 +225,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
tip(6)
block(9, spend=out4, additional_coinbase_value=1)
- yield rejected(RejectResult(16, 'bad-cb-amount'))
+ yield rejected(RejectResult(16, b'bad-cb-amount'))
# Create a fork that ends in a block with too much fee (the one that causes the reorg)
@@ -237,7 +237,7 @@ class FullBlockTest(ComparisonTestFramework):
yield rejected()
block(11, spend=out4, additional_coinbase_value=1)
- yield rejected(RejectResult(16, 'bad-cb-amount'))
+ yield rejected(RejectResult(16, b'bad-cb-amount'))
# Try again, but with a valid fork first
@@ -269,7 +269,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
# Test that a block with a lot of checksigs is okay
- lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1))
+ lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50 - 1))
tip(13)
block(15, spend=out5, script=lots_of_checksigs)
yield accepted()
@@ -277,9 +277,9 @@ class FullBlockTest(ComparisonTestFramework):
# Test that a block with too many checksigs is rejected
out6 = get_spendable_output()
- too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50))
+ too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50))
block(16, spend=out6, script=too_many_checksigs)
- yield rejected(RejectResult(16, 'bad-blk-sigops'))
+ yield rejected(RejectResult(16, b'bad-blk-sigops'))
# Attempt to spend a transaction created on a different fork
@@ -288,7 +288,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
tip(15)
block(17, spend=txout_b3)
- yield rejected(RejectResult(16, 'bad-txns-inputs-missingorspent'))
+ yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
# Attempt to spend a transaction created on a different fork (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -309,7 +309,7 @@ class FullBlockTest(ComparisonTestFramework):
tip(15)
out7 = get_spendable_output()
block(20, spend=out7)
- yield rejected(RejectResult(16, 'bad-txns-premature-spend-of-coinbase'))
+ yield rejected(RejectResult(16, b'bad-txns-premature-spend-of-coinbase'))
# Attempt to spend a coinbase at depth too low (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -333,7 +333,7 @@ class FullBlockTest(ComparisonTestFramework):
old_hash = b23.sha256
tx = CTransaction()
script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69
- script_output = CScript([chr(0)*script_length])
+ script_output = CScript([b'\x00' * script_length])
tx.vout.append(CTxOut(0, script_output))
tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1)))
b23 = update_block(23, [tx])
@@ -345,11 +345,11 @@ class FullBlockTest(ComparisonTestFramework):
tip(15)
b24 = block(24, spend=out6)
script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69
- script_output = CScript([chr(0)*(script_length+1)])
+ script_output = CScript([b'\x00' * (script_length+1)])
tx.vout = [CTxOut(0, script_output)]
b24 = update_block(24, [tx])
assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1)
- yield rejected(RejectResult(16, 'bad-blk-length'))
+ yield rejected(RejectResult(16, b'bad-blk-length'))
b25 = block(25, spend=out7)
yield rejected()
@@ -361,12 +361,12 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
tip(15)
b26 = block(26, spend=out6)
- b26.vtx[0].vin[0].scriptSig = chr(0)
+ b26.vtx[0].vin[0].scriptSig = b'\x00'
b26.vtx[0].rehash()
# update_block causes the merkle root to get updated, even with no new
# transactions, and updates the required state.
b26 = update_block(26, [])
- yield rejected(RejectResult(16, 'bad-cb-length'))
+ yield rejected(RejectResult(16, b'bad-cb-length'))
# Extend the b26 chain to make sure bitcoind isn't accepting b26
b27 = block(27, spend=out7)
@@ -375,10 +375,10 @@ class FullBlockTest(ComparisonTestFramework):
# Now try a too-large-coinbase script
tip(15)
b28 = block(28, spend=out6)
- b28.vtx[0].vin[0].scriptSig = chr(0)*101
+ b28.vtx[0].vin[0].scriptSig = b'\x00' * 101
b28.vtx[0].rehash()
b28 = update_block(28, [])
- yield rejected(RejectResult(16, 'bad-cb-length'))
+ yield rejected(RejectResult(16, b'bad-cb-length'))
# Extend the b28 chain to make sure bitcoind isn't accepted b28
b29 = block(29, spend=out7)
@@ -390,7 +390,7 @@ class FullBlockTest(ComparisonTestFramework):
# b30 has a max-sized coinbase scriptSig.
tip(23)
b30 = block(30)
- b30.vtx[0].vin[0].scriptSig = chr(0)*100
+ b30.vtx[0].vin[0].scriptSig = b'\x00' * 100
b30.vtx[0].rehash()
b30 = update_block(30, [])
yield accepted()
diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py
new file mode 100755
index 0000000000..5d2daf39f8
--- /dev/null
+++ b/qa/rpc-tests/p2p-mempool.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import time
+
+class TestNode(NodeConnCB):
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
+ self.block_receive_map = {}
+
+ def add_connection(self, conn):
+ self.connection = conn
+ self.peer_disconnected = False
+
+ def on_inv(self, conn, message):
+ pass
+
+ # Track the last getdata message we receive (used in the test)
+ def on_getdata(self, conn, message):
+ self.last_getdata = message
+
+ def on_block(self, conn, message):
+ message.block.calc_sha256()
+ try:
+ self.block_receive_map[message.block.sha256] += 1
+ except KeyError as e:
+ self.block_receive_map[message.block.sha256] = 1
+
+ # Spin until verack message is received from the node.
+ # We use this to signal that our test can begin. This
+ # is called from the testing thread, so it needs to acquire
+ # the global lock.
+ def wait_for_verack(self):
+ def veracked():
+ return self.verack_received
+ return wait_until(veracked, timeout=10)
+
+ def wait_for_disconnect(self):
+ def disconnected():
+ return self.peer_disconnected
+ return wait_until(disconnected, timeout=10)
+
+ # Wrapper for the NodeConn's send_message function
+ def send_message(self, message):
+ self.connection.send_message(message)
+
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ def on_close(self, conn):
+ self.peer_disconnected = True
+
+ # Sync up with the node after delivery of a block
+ def sync_with_ping(self, timeout=30):
+ def received_pong():
+ return (self.last_pong.nonce == self.ping_counter)
+ self.connection.send_message(msg_ping(nonce=self.ping_counter))
+ success = wait_until(received_pong, timeout)
+ self.ping_counter += 1
+ return success
+
+ def send_mempool(self):
+ self.lastInv = []
+ self.send_message(msg_mempool())
+
+class P2PMempoolTests(BitcoinTestFramework):
+ def setup_chain(self):
+ initialize_chain_clean(self.options.tmpdir, 2)
+
+ def setup_network(self):
+ # Start a node with maxuploadtarget of 200 MB (/24h)
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-peerbloomfilters=0"]))
+
+ def run_test(self):
+ #connect a mininode
+ aTestNode = TestNode()
+ node = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], aTestNode)
+ aTestNode.add_connection(node)
+ NetworkThread().start()
+ aTestNode.wait_for_verack()
+
+ #request mempool
+ aTestNode.send_mempool()
+ aTestNode.wait_for_disconnect()
+
+ #mininode must be disconnected at this point
+ assert_equal(len(self.nodes[0].getpeerinfo()), 0)
+
+if __name__ == '__main__':
+ P2PMempoolTests().main()
diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py
new file mode 100755
index 0000000000..962cafef0b
--- /dev/null
+++ b/qa/rpc-tests/p2p-versionbits-warning.py
@@ -0,0 +1,161 @@
+#!/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.
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import time
+from test_framework.blocktools import create_block, create_coinbase
+
+'''
+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.
+'''
+
+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
+
+# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending
+# p2p messages to a node, generating the messages in the main testing logic.
+class TestNode(NodeConnCB):
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
+
+ def add_connection(self, conn):
+ self.connection = conn
+
+ def on_inv(self, conn, message):
+ pass
+
+ # Wrapper for the NodeConn's send_message function
+ def send_message(self, message):
+ self.connection.send_message(message)
+
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ # Sync up with the node after delivery of a block
+ def sync_with_ping(self, timeout=30):
+ self.connection.send_message(msg_ping(nonce=self.ping_counter))
+ received_pong = False
+ sleep_time = 0.05
+ while not received_pong and timeout > 0:
+ time.sleep(sleep_time)
+ timeout -= sleep_time
+ with mininode_lock:
+ if self.last_pong.nonce == self.ping_counter:
+ received_pong = True
+ self.ping_counter += 1
+ return received_pong
+
+
+class VersionBitsWarningTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
+
+ def setup_network(self):
+ self.nodes = []
+ 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') as f:
+ pass
+ self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]
+ self.nodes.append(start_node(0, self.options.tmpdir, self.node_options))
+
+ import re
+ self.vb_pattern = re.compile("^Warning.*versionbit")
+
+ # 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 i 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') as f:
+ alert_text = f.read()
+ assert(self.vb_pattern.match(alert_text))
+
+ def run_test(self):
+ # Setup the p2p connection and start up the network thread.
+ test_node = TestNode()
+
+ connections = []
+ connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node))
+ test_node.add_connection(connections[0])
+
+ NetworkThread().start() # Start up network handling in another thread
+
+ # Test logic begins here
+ test_node.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(test_node, 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
+ # getinfo()
+ assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"]))
+
+ # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling
+ # some unknown bit
+ self.send_blocks_with_version(test_node, 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 getinfo() shows some kind of error.
+ assert(len(self.nodes[0].getinfo()["errors"]) != 0)
+
+ # 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)
+ stop_node(self.nodes[0], 0)
+ wait_bitcoinds()
+ # Empty out the alert file
+ with open(self.alert_filename, 'w') as f:
+ pass
+ self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])
+
+ # Connecting one block should be enough to generate an error.
+ self.nodes[0].generate(1)
+ assert(len(self.nodes[0].getinfo()["errors"]) != 0)
+ stop_node(self.nodes[0], 0)
+ wait_bitcoinds()
+ self.test_versionbits_in_alert_file()
+
+ # Test framework expects the node to still be running...
+ self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])
+
+
+if __name__ == '__main__':
+ VersionBitsWarningTest().main()
diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py
index 4a79d38da0..e1771231c0 100755
--- a/qa/rpc-tests/prioritise_transaction.py
+++ b/qa/rpc-tests/prioritise_transaction.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -9,17 +9,16 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-
-COIN = 100000000
+from test_framework.mininode import COIN, MAX_BLOCK_SIZE
class PrioritiseTransactionTest(BitcoinTestFramework):
def __init__(self):
- self.txouts = gen_return_txouts()
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 1)
+ self.txouts = gen_return_txouts()
def setup_network(self):
self.nodes = []
@@ -29,14 +28,29 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
def run_test(self):
- utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90)
+ utxo_count = 90
+ utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], utxo_count)
base_fee = self.relayfee*100 # our transactions are smaller than 100kb
txids = []
# Create 3 batches of transactions at 3 different fee rate levels
- for i in xrange(3):
+ range_size = utxo_count // 3
+ for i in range(3):
txids.append([])
- txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
+ start_range = i * range_size
+ end_range = start_range + range_size
+ txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], (i+1)*base_fee)
+
+ # Make sure that the size of each group of transactions exceeds
+ # MAX_BLOCK_SIZE -- otherwise the test needs to be revised to create
+ # more transactions.
+ mempool = self.nodes[0].getrawmempool(True)
+ sizes = [0, 0, 0]
+ for i in range(3):
+ for j in txids[i]:
+ assert(j in mempool)
+ sizes[i] += mempool[j]['size']
+ assert(sizes[i] > MAX_BLOCK_SIZE) # Fail => raise utxo_count
# add a fee delta to something in the cheapest bucket and make sure it gets mined
# also check that a different entry in the cheapest bucket is NOT mined (lower
@@ -47,7 +61,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.nodes[0].generate(1)
mempool = self.nodes[0].getrawmempool()
- print "Assert that prioritised transasction was mined"
+ print("Assert that prioritised transaction was mined")
assert(txids[0][0] not in mempool)
assert(txids[0][1] in mempool)
@@ -60,7 +74,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
assert(high_fee_tx != None)
# Add a prioritisation before a tx is in the mempool (de-prioritising a
- # high-fee transaction).
+ # high-fee transaction so that it's now low fee).
self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN))
# Add everything back to mempool
@@ -70,13 +84,16 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
mempool = self.nodes[0].getrawmempool()
assert(high_fee_tx in mempool)
- # Now verify the high feerate transaction isn't mined.
- self.nodes[0].generate(5)
+ # Now verify the modified-high feerate transaction isn't mined before
+ # the other high fee transactions. Keep mining until our mempool has
+ # decreased by all the high fee size that we calculated above.
+ while (self.nodes[0].getmempoolinfo()['bytes'] > sizes[0] + sizes[1]):
+ self.nodes[0].generate(1)
# High fee transaction should not have been mined, but other high fee rate
# transactions should have been.
mempool = self.nodes[0].getrawmempool()
- print "Assert that de-prioritised transaction is still in mempool"
+ print("Assert that de-prioritised transaction is still in mempool")
assert(high_fee_tx in mempool)
for x in txids[2]:
if (x != high_fee_tx):
@@ -118,7 +135,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
# accepted.
self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN))
- print "Assert that prioritised free transaction is accepted to mempool"
+ print("Assert that prioritised free transaction is accepted to mempool")
assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id)
assert(tx2_id in self.nodes[0].getrawmempool())
diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py
index 7f77e664d2..27160cae07 100755
--- a/qa/rpc-tests/proxy_test.py
+++ b/qa/rpc-tests/proxy_test.py
@@ -1,12 +1,14 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
+
import socket
from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
+from test_framework.netutil import test_ipv6_local
'''
Test plan:
- Start bitcoind's with different proxy configurations
@@ -34,6 +36,11 @@ addnode connect to generic DNS name
class ProxyTest(BitcoinTestFramework):
def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
+ self.have_ipv6 = test_ipv6_local()
# Create two proxies on different ports
# ... one unauthenticated
self.conf1 = Socks5Configuration()
@@ -45,29 +52,36 @@ class ProxyTest(BitcoinTestFramework):
self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000))
self.conf2.unauth = True
self.conf2.auth = True
- # ... one on IPv6 with similar configuration
- self.conf3 = Socks5Configuration()
- self.conf3.af = socket.AF_INET6
- self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
- self.conf3.unauth = True
- self.conf3.auth = True
+ if self.have_ipv6:
+ # ... one on IPv6 with similar configuration
+ self.conf3 = Socks5Configuration()
+ self.conf3.af = socket.AF_INET6
+ self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
+ self.conf3.unauth = True
+ self.conf3.auth = True
+ else:
+ print("Warning: testing without local IPv6 support")
self.serv1 = Socks5Server(self.conf1)
self.serv1.start()
self.serv2 = Socks5Server(self.conf2)
self.serv2.start()
- self.serv3 = Socks5Server(self.conf3)
- self.serv3.start()
+ if self.have_ipv6:
+ self.serv3 = Socks5Server(self.conf3)
+ self.serv3.start()
def setup_nodes(self):
# Note: proxies are not used to connect to local nodes
# this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
- return start_nodes(4, self.options.tmpdir, extra_args=[
+ args = [
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
- ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
- ])
+ []
+ ]
+ if self.have_ipv6:
+ args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
+ return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=args)
def node_test(self, node, proxies, auth, test_onion=True):
rv = []
@@ -77,25 +91,26 @@ class ProxyTest(BitcoinTestFramework):
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
- assert_equal(cmd.addr, "15.61.23.23")
+ assert_equal(cmd.addr, b"15.61.23.23")
assert_equal(cmd.port, 1234)
if not auth:
assert_equal(cmd.username, None)
assert_equal(cmd.password, None)
rv.append(cmd)
- # Test: outgoing IPv6 connection through node
- node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
- cmd = proxies[1].queue.get()
- assert(isinstance(cmd, Socks5Command))
- # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
- assert_equal(cmd.atyp, AddressType.DOMAINNAME)
- assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534")
- assert_equal(cmd.port, 5443)
- if not auth:
- assert_equal(cmd.username, None)
- assert_equal(cmd.password, None)
- rv.append(cmd)
+ if self.have_ipv6:
+ # Test: outgoing IPv6 connection through node
+ node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
+ cmd = proxies[1].queue.get()
+ assert(isinstance(cmd, Socks5Command))
+ # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534")
+ assert_equal(cmd.port, 5443)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
if test_onion:
# Test: outgoing onion connection through node
@@ -103,7 +118,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[2].queue.get()
assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
- assert_equal(cmd.addr, "bitcoinostk4e4re.onion")
+ assert_equal(cmd.addr, b"bitcoinostk4e4re.onion")
assert_equal(cmd.port, 8333)
if not auth:
assert_equal(cmd.username, None)
@@ -115,7 +130,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[3].queue.get()
assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
- assert_equal(cmd.addr, "node.noumenon")
+ assert_equal(cmd.addr, b"node.noumenon")
assert_equal(cmd.port, 8333)
if not auth:
assert_equal(cmd.username, None)
@@ -135,10 +150,11 @@ class ProxyTest(BitcoinTestFramework):
rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
# Check that credentials as used for -proxyrandomize connections are unique
credentials = set((x.username,x.password) for x in rv)
- assert_equal(len(credentials), 4)
+ assert_equal(len(credentials), len(rv))
- # proxy on IPv6 localhost
- self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
+ if self.have_ipv6:
+ # proxy on IPv6 localhost
+ self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
def networks_dict(d):
r = {}
@@ -167,11 +183,12 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n2[net]['proxy_randomize_credentials'], True)
assert_equal(n2['onion']['reachable'], True)
- n3 = networks_dict(self.nodes[3].getnetworkinfo())
- for net in ['ipv4','ipv6']:
- assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
- assert_equal(n3[net]['proxy_randomize_credentials'], False)
- assert_equal(n3['onion']['reachable'], False)
+ if self.have_ipv6:
+ n3 = networks_dict(self.nodes[3].getnetworkinfo())
+ for net in ['ipv4','ipv6']:
+ assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
+ assert_equal(n3[net]['proxy_randomize_credentials'], False)
+ assert_equal(n3['onion']['reachable'], False)
if __name__ == '__main__':
ProxyTest().main()
diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py
index b0f4b88aee..d225e29b50 100755
--- a/qa/rpc-tests/pruning.py
+++ b/qa/rpc-tests/pruning.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -15,19 +15,19 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
def calc_usage(blockdir):
- return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024)
+ return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.)
class PruneTest(BitcoinTestFramework):
def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 3
+
self.utxo = []
self.address = ["",""]
self.txouts = gen_return_txouts()
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 3)
-
def setup_network(self):
self.nodes = []
self.is_network_split = False
@@ -56,8 +56,8 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1].generate(200)
sync_blocks(self.nodes[0:2])
self.nodes[0].generate(150)
- # Then mine enough full blocks to create more than 550MB of data
- for i in xrange(645):
+ # Then mine enough full blocks to create more than 550MiB of data
+ for i in range(645):
self.mine_full_block(self.nodes[0], self.address[0])
sync_blocks(self.nodes[0:3])
@@ -65,30 +65,30 @@ class PruneTest(BitcoinTestFramework):
def test_height_min(self):
if not os.path.isfile(self.prunedir+"blk00000.dat"):
raise AssertionError("blk00000.dat is missing, pruning too early")
- print "Success"
- print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)
- print "Mining 25 more blocks should cause the first block file to be pruned"
+ print("Success")
+ print("Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir))
+ print("Mining 25 more blocks should cause the first block file to be pruned")
# Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
- for i in xrange(25):
+ for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
waitstart = time.time()
while os.path.isfile(self.prunedir+"blk00000.dat"):
time.sleep(0.1)
- if time.time() - waitstart > 10:
+ if time.time() - waitstart > 30:
raise AssertionError("blk00000.dat not pruned when it should be")
- print "Success"
+ print("Success")
usage = calc_usage(self.prunedir)
- print "Usage should be below target:", usage
+ print("Usage should be below target:", usage)
if (usage > 550):
raise AssertionError("Pruning target not being met")
def create_chain_with_staleblocks(self):
# Create stale blocks in manageable sized chunks
- print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds"
+ print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds")
- for j in xrange(12):
+ for j in range(12):
# Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
# Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
# Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
@@ -96,7 +96,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)
# Mine 24 blocks in node 1
self.utxo = self.nodes[1].listunspent()
- for i in xrange(24):
+ for i in range(24):
if j == 0:
self.mine_full_block(self.nodes[1],self.address[1])
else:
@@ -104,7 +104,7 @@ class PruneTest(BitcoinTestFramework):
# Reorg back with 25 block chain from node 0
self.utxo = self.nodes[0].listunspent()
- for i in xrange(25):
+ for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
# Create connections in the order so both nodes can see the reorg at the same time
@@ -112,7 +112,7 @@ class PruneTest(BitcoinTestFramework):
connect_nodes(self.nodes[2], 0)
sync_blocks(self.nodes[0:3])
- print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir)
+ print("Usage can be over target because of high stale rate:", calc_usage(self.prunedir))
def reorg_test(self):
# Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip
@@ -123,11 +123,11 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
height = self.nodes[1].getblockcount()
- print "Current block height:", height
+ print("Current block height:", height)
invalidheight = height-287
badhash = self.nodes[1].getblockhash(invalidheight)
- print "Invalidating block at height:",invalidheight,badhash
+ print("Invalidating block at height:",invalidheight,badhash)
self.nodes[1].invalidateblock(badhash)
# We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
@@ -139,29 +139,29 @@ class PruneTest(BitcoinTestFramework):
curhash = self.nodes[1].getblockhash(invalidheight - 1)
assert(self.nodes[1].getblockcount() == invalidheight - 1)
- print "New best height", self.nodes[1].getblockcount()
+ print("New best height", self.nodes[1].getblockcount())
# Reboot node1 to clear those giant tx's from mempool
stop_node(self.nodes[1],1)
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
- print "Generating new longer chain of 300 more blocks"
+ print("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
- print "Reconnect nodes"
+ print("Reconnect nodes")
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[2], 1)
sync_blocks(self.nodes[0:3])
- print "Verify height on node 2:",self.nodes[2].getblockcount()
- print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)
+ print("Verify height on node 2:",self.nodes[2].getblockcount())
+ print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir))
- print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)"
+ print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)")
self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects
sync_blocks(self.nodes[0:3])
usage = calc_usage(self.prunedir)
- print "Usage should be below target:", usage
+ print("Usage should be below target:", usage)
if (usage > 550):
raise AssertionError("Pruning target not being met")
@@ -173,7 +173,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[2].getblock(self.forkhash)
raise AssertionError("Old block wasn't pruned so can't test redownload")
except JSONRPCException as e:
- print "Will need to redownload block",self.forkheight
+ print("Will need to redownload block",self.forkheight)
# Verify that we have enough history to reorg back to the fork point
# Although this is more than 288 blocks, because this chain was written more recently
@@ -197,14 +197,14 @@ class PruneTest(BitcoinTestFramework):
# At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg
if self.nodes[2].getblockcount() < self.mainchainheight:
blocks_to_mine = first_reorg_height + 1 - self.mainchainheight
- print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine
+ print("Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine)
self.nodes[0].invalidateblock(curchainhash)
assert(self.nodes[0].getblockcount() == self.mainchainheight)
assert(self.nodes[0].getbestblockhash() == self.mainchainhash2)
goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1]
goalbestheight = first_reorg_height + 1
- print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload"
+ print("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload")
waitstart = time.time()
while self.nodes[2].getblockcount() < goalbestheight:
time.sleep(0.1)
@@ -217,7 +217,7 @@ class PruneTest(BitcoinTestFramework):
def mine_full_block(self, node, address):
# Want to create a full block
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
- for j in xrange(14):
+ for j in range(14):
if len(self.utxo) < 14:
self.utxo = node.listunspent()
inputs=[]
@@ -241,8 +241,8 @@ class PruneTest(BitcoinTestFramework):
def run_test(self):
- print "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)"
- print "Mining a big blockchain of 995 blocks"
+ print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)")
+ print("Mining a big blockchain of 995 blocks")
self.create_big_chain()
# Chain diagram key:
# * blocks on main chain
@@ -253,12 +253,12 @@ class PruneTest(BitcoinTestFramework):
# Start by mining a simple chain that all nodes have
# N0=N1=N2 **...*(995)
- print "Check that we haven't started pruning yet because we're below PruneAfterHeight"
+ print("Check that we haven't started pruning yet because we're below PruneAfterHeight")
self.test_height_min()
# Extend this chain past the PruneAfterHeight
# N0=N1=N2 **...*(1020)
- print "Check that we'll exceed disk space target if we have a very high stale block rate"
+ print("Check that we'll exceed disk space target if we have a very high stale block rate")
self.create_chain_with_staleblocks()
# Disconnect N0
# And mine a 24 block chain on N1 and a separate 25 block chain on N0
@@ -282,7 +282,7 @@ class PruneTest(BitcoinTestFramework):
self.mainchainheight = self.nodes[2].getblockcount() #1320
self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight)
- print "Check that we can survive a 288 block reorg still"
+ print("Check that we can survive a 288 block reorg still")
(self.forkheight,self.forkhash) = self.reorg_test() #(1033, )
# Now create a 288 block reorg by mining a longer chain on N1
# First disconnect N1
@@ -311,11 +311,11 @@ class PruneTest(BitcoinTestFramework):
# \ \
# ++...++(1044) ..
#
- # N0 ********************(1032) @@...@@@(1552)
+ # N0 ********************(1032) @@...@@@(1552)
# \
# *...**(1320)
- print "Test that we can rerequest a block we previously pruned if needed for a reorg"
+ print("Test that we can rerequest a block we previously pruned if needed for a reorg")
self.reorg_back()
# Verify that N2 still has block 1033 on current chain (@), but not on main chain (*)
# Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to
@@ -335,7 +335,7 @@ class PruneTest(BitcoinTestFramework):
#
# N1 doesn't change because 1033 on main chain (*) is invalid
- print "Done"
+ print("Done")
if __name__ == '__main__':
PruneTest().main()
diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py
index dd9e5e28a5..aa403f058c 100755
--- a/qa/rpc-tests/rawtransactions.py
+++ b/qa/rpc-tests/rawtransactions.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -14,12 +14,13 @@ from test_framework.util import *
# Create one-input, one-output, no-fee transaction:
class RawTransactionsTest(BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 3)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 3
def setup_network(self, split=False):
- self.nodes = start_nodes(3, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
#connect to a local machine for debugging
#url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332)
@@ -56,13 +57,13 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
rawtx = self.nodes[2].signrawtransaction(rawtx)
- errorString = ""
try:
rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
- except JSONRPCException,e:
- errorString = e.error['message']
+ except JSONRPCException as e:
+ assert("Missing inputs" in e.error['message'])
+ else:
+ assert(False)
- assert("Missing inputs" in errorString)
#########################
# RAW TX MULTISIG TESTS #
@@ -88,8 +89,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
-
-
# 2of3 test from different nodes
bal = self.nodes[2].getbalance()
addr1 = self.nodes[1].getnewaddress()
@@ -139,5 +138,11 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
+ inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
+ outputs = { self.nodes[0].getnewaddress() : 1 }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ decrawtx= self.nodes[0].decoderawtransaction(rawtx)
+ assert_equal(decrawtx['vin'][0]['sequence'], 1000)
+
if __name__ == '__main__':
RawTransactionsTest().main()
diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py
index 606426b394..4f17b661cb 100755
--- a/qa/rpc-tests/receivedby.py
+++ b/qa/rpc-tests/receivedby.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -25,38 +25,17 @@ def get_sub_array_from_array(object_array, to_match):
return item
return []
-def check_array_result(object_array, to_match, expected, should_not_find = False):
- """
- Pass in array of JSON objects, a dictionary with key/value pairs
- to match against, and another dictionary with expected key/value
- pairs.
- If the should_not_find flag is true, to_match should not be found in object_array
- """
- if should_not_find == True:
- expected = { }
- num_matched = 0
- for item in object_array:
- all_match = True
- for key,value in to_match.items():
- if item[key] != value:
- all_match = False
- if not all_match:
- continue
- for key,value in expected.items():
- if item[key] != value:
- raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
- num_matched = num_matched+1
- if num_matched == 0 and should_not_find != True:
- raise AssertionError("No objects matched %s"%(str(to_match)))
- if num_matched > 0 and should_not_find == True:
- raise AssertionError("Objects was matched %s"%(str(to_match)))
-
class ReceivedByTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
- return start_nodes(4, self.options.tmpdir)
+ return start_nodes(self.num_nodes, self.options.tmpdir)
def run_test(self):
'''
@@ -68,26 +47,26 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all()
#Check not listed in listreceivedbyaddress because has 0 confirmations
- check_array_result(self.nodes[1].listreceivedbyaddress(),
+ assert_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr},
{ },
True)
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress
self.nodes[1].generate(10)
self.sync_all()
- check_array_result(self.nodes[1].listreceivedbyaddress(),
+ assert_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence < 10
- check_array_result(self.nodes[1].listreceivedbyaddress(5),
+ assert_array_result(self.nodes[1].listreceivedbyaddress(5),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence > 10, should not find Tx
- check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
+ assert_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
#Empty Tx
addr = self.nodes[1].getnewaddress()
- check_array_result(self.nodes[1].listreceivedbyaddress(0,True),
+ assert_array_result(self.nodes[1].listreceivedbyaddress(0,True),
{"address":addr},
{"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
@@ -131,7 +110,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all()
# listreceivedbyaccount should return received_by_account_json because of 0 confirmations
- check_array_result(self.nodes[1].listreceivedbyaccount(),
+ assert_array_result(self.nodes[1].listreceivedbyaccount(),
{"account":account},
received_by_account_json)
@@ -143,7 +122,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.nodes[1].generate(10)
self.sync_all()
# listreceivedbyaccount should return updated account balance
- check_array_result(self.nodes[1].listreceivedbyaccount(),
+ assert_array_result(self.nodes[1].listreceivedbyaccount(),
{"account":account},
{"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})
diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py
index 321c2fe422..abbbb10336 100755
--- a/qa/rpc-tests/reindex.py
+++ b/qa/rpc-tests/reindex.py
@@ -1,32 +1,43 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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 -reindex with CheckBlockIndex
+# Test -reindex and -reindex-chainstate with CheckBlockIndex
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
+import time
class ReindexTest(BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 1)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
def setup_network(self):
self.nodes = []
self.is_network_split = False
self.nodes.append(start_node(0, self.options.tmpdir))
- def run_test(self):
+ def reindex(self, justchainstate=False):
self.nodes[0].generate(3)
+ blockcount = self.nodes[0].getblockcount()
stop_node(self.nodes[0], 0)
wait_bitcoinds()
- self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
- assert_equal(self.nodes[0].getblockcount(), 3)
- print "Success"
+ self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"])
+ while self.nodes[0].getblockcount() < blockcount:
+ time.sleep(0.1)
+ assert_equal(self.nodes[0].getblockcount(), blockcount)
+ print("Success")
+
+ def run_test(self):
+ self.reindex(False)
+ self.reindex(True)
+ self.reindex(False)
+ self.reindex(True)
if __name__ == '__main__':
ReindexTest().main()
diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py
index ba1956853a..34c0f9d795 100755
--- a/qa/rpc-tests/replace-by-fee.py
+++ b/qa/rpc-tests/replace-by-fee.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -11,16 +11,11 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.script import *
from test_framework.mininode import *
-import binascii
-COIN = 100000000
MAX_REPLACEMENT_LIMIT = 100
-def satoshi_round(amount):
- return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
-
def txToHex(tx):
- return binascii.hexlify(tx.serialize()).decode('utf-8')
+ return bytes_to_hex_str(tx.serialize())
def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
"""Create a txout with a given amount and scriptPubKey
@@ -54,9 +49,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
tx2.vout = [CTxOut(amount, scriptPubKey)]
tx2.rehash()
- binascii.hexlify(tx2.serialize()).decode('utf-8')
-
- signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8'))
+ signed_tx = node.signrawtransaction(txToHex(tx2))
txid = node.sendrawtransaction(signed_tx['hex'], True)
@@ -75,6 +68,11 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
class ReplaceByFeeTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 1
+ self.setup_clean_chain = False
+
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug",
@@ -89,38 +87,38 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def run_test(self):
make_utxo(self.nodes[0], 1*COIN)
- print "Running test simple doublespend..."
+ print("Running test simple doublespend...")
self.test_simple_doublespend()
- print "Running test doublespend chain..."
+ print("Running test doublespend chain...")
self.test_doublespend_chain()
- print "Running test doublespend tree..."
+ print("Running test doublespend tree...")
self.test_doublespend_tree()
- print "Running test replacement feeperkb..."
+ print("Running test replacement feeperkb...")
self.test_replacement_feeperkb()
- print "Running test spends of conflicting outputs..."
+ print("Running test spends of conflicting outputs...")
self.test_spends_of_conflicting_outputs()
- print "Running test new unconfirmed inputs..."
+ print("Running test new unconfirmed inputs...")
self.test_new_unconfirmed_inputs()
- print "Running test too many replacements..."
+ print("Running test too many replacements...")
self.test_too_many_replacements()
- print "Running test opt-in..."
+ print("Running test opt-in...")
self.test_opt_in()
- print "Running test prioritised transactions..."
+ print("Running test prioritised transactions...")
self.test_prioritised_transactions()
- print "Passed\n"
+ print("Passed\n")
def test_simple_doublespend(self):
"""Simple doublespend"""
- tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@@ -144,7 +142,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Extra 0.1 BTC fee
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
+ tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
@@ -236,7 +234,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
_total_txs=_total_txs):
yield x
- fee = 0.0001*COIN
+ fee = int(0.0001*COIN)
n = MAX_REPLACEMENT_LIMIT
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
@@ -269,7 +267,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Try again, but with more total transactions than the "max txs
# double-spent at once" anti-DoS limit.
for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2):
- fee = 0.0001*COIN
+ fee = int(0.0001*COIN)
tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
@@ -292,7 +290,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_replacement_feeperkb(self):
"""Replacement requires fee-per-KB to be higher"""
- tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@@ -304,7 +302,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# rejected.
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*999000]))]
+ tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
tx1b_hex = txToHex(tx1b)
try:
@@ -316,12 +314,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_spends_of_conflicting_outputs(self):
"""Replacements that spend conflicting tx outputs are rejected"""
- utxo1 = make_utxo(self.nodes[0], 1.2*COIN)
- utxo2 = make_utxo(self.nodes[0], 3.0*COIN)
+ utxo1 = make_utxo(self.nodes[0], int(1.2*COIN))
+ utxo2 = make_utxo(self.nodes[0], 3*COIN)
tx1a = CTransaction()
tx1a.vin = [CTxIn(utxo1, nSequence=0)]
- tx1a.vout = [CTxOut(1.1*COIN, CScript([b'a']))]
+ tx1a.vout = [CTxOut(int(1.1*COIN), CScript([b'a']))]
tx1a_hex = txToHex(tx1a)
tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
@@ -344,7 +342,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Spend tx1a's output to test the indirect case.
tx1b = CTransaction()
tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
- tx1b.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
+ tx1b.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx1b_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
tx1b_txid = int(tx1b_txid, 16)
@@ -364,12 +362,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_new_unconfirmed_inputs(self):
"""Replacements that add new unconfirmed inputs are rejected"""
- confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN)
- unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False)
+ confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
+ unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)
tx1 = CTransaction()
tx1.vin = [CTxIn(confirmed_utxo)]
- tx1.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
+ tx1.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx1_hex = txToHex(tx1)
tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True)
@@ -393,7 +391,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Start by creating a single transaction with many outputs
initial_nValue = 10*COIN
utxo = make_utxo(self.nodes[0], initial_nValue)
- fee = 0.0001*COIN
+ fee = int(0.0001*COIN)
split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1))
actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1)
@@ -446,7 +444,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_opt_in(self):
""" Replacing should only work if orig tx opted in """
- tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
# Create a non-opting in transaction
tx1a = CTransaction()
@@ -458,7 +456,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Shouldn't be able to double-spend
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
+ tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
try:
@@ -466,10 +464,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
except JSONRPCException as exp:
assert_equal(exp.error['code'], -26)
else:
- print tx1b_txid
+ print(tx1b_txid)
assert(False)
- tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
# Create a different non-opting in transaction
tx2a = CTransaction()
@@ -481,7 +479,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Still shouldn't be able to double-spend
tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
- tx2b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
+ tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx2b_hex = txToHex(tx2b)
try:
@@ -501,19 +499,19 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx3a = CTransaction()
tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff),
CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)]
- tx3a.vout = [CTxOut(0.9*COIN, CScript([b'c'])), CTxOut(0.9*COIN, CScript([b'd']))]
+ tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))]
tx3a_hex = txToHex(tx3a)
self.nodes[0].sendrawtransaction(tx3a_hex, True)
tx3b = CTransaction()
tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
- tx3b.vout = [CTxOut(0.5*COIN, CScript([b'e']))]
+ tx3b.vout = [CTxOut(int(0.5*COIN), CScript([b'e']))]
tx3b_hex = txToHex(tx3b)
tx3c = CTransaction()
tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)]
- tx3c.vout = [CTxOut(0.5*COIN, CScript([b'f']))]
+ tx3c.vout = [CTxOut(int(0.5*COIN), CScript([b'f']))]
tx3c_hex = txToHex(tx3c)
self.nodes[0].sendrawtransaction(tx3b_hex, True)
@@ -526,7 +524,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# correctly used by replacement logic
# 1. Check that feeperkb uses modified fees
- tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@@ -537,7 +535,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Higher fee, but the actual fee per KB is much lower.
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
- tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))]
+ tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))]
tx1b_hex = txToHex(tx1b)
# Verify tx1b cannot replace tx1a.
@@ -557,7 +555,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert(tx1b_txid in self.nodes[0].getrawmempool())
# 2. Check that absolute fee checks use modified fee.
- tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+ tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx2a = CTransaction()
tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
@@ -568,7 +566,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Lower fee, but we'll prioritise it
tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
- tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))]
+ tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))]
tx2b.rehash()
tx2b_hex = txToHex(tx2b)
diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py
index 8c83536501..c9c2eaf7f3 100755
--- a/qa/rpc-tests/rest.py
+++ b/qa/rpc-tests/rest.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -11,17 +11,11 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from struct import *
-import binascii
-import StringIO
-
-try:
- import http.client as httplib
-except ImportError:
- import httplib
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+from io import BytesIO
+from codecs import encode
+
+import http.client
+import urllib.parse
def deser_uint256(f):
r = 0
@@ -32,17 +26,17 @@ def deser_uint256(f):
#allows simple http get calls
def http_get_call(host, port, path, response_object = 0):
- conn = httplib.HTTPConnection(host, port)
+ conn = http.client.HTTPConnection(host, port)
conn.request('GET', path)
if response_object:
return conn.getresponse()
- return conn.getresponse().read()
+ return conn.getresponse().read().decode('utf-8')
#allows simple http post calls with a request body
def http_post_call(host, port, path, requestdata = '', response_object = 0):
- conn = httplib.HTTPConnection(host, port)
+ conn = http.client.HTTPConnection(host, port)
conn.request('POST', path, requestdata)
if response_object:
@@ -53,12 +47,13 @@ def http_post_call(host, port, path, requestdata = '', response_object = 0):
class RESTTest (BitcoinTestFramework):
FORMAT_SEPARATOR = "."
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 3)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 3
def setup_network(self, split=False):
- self.nodes = start_nodes(3, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
@@ -66,8 +61,8 @@ class RESTTest (BitcoinTestFramework):
self.sync_all()
def run_test(self):
- url = urlparse.urlparse(self.nodes[0].url)
- print "Mining blocks..."
+ url = urllib.parse.urlparse(self.nodes[0].url)
+ print("Mining blocks...")
self.nodes[0].generate(1)
self.sync_all()
@@ -140,17 +135,17 @@ class RESTTest (BitcoinTestFramework):
bb_hash = self.nodes[0].getbestblockhash()
binaryRequest = b'\x01\x02'
- binaryRequest += binascii.unhexlify(txid)
+ binaryRequest += hex_str_to_bytes(txid)
binaryRequest += pack("i", n)
- binaryRequest += binascii.unhexlify(vintx)
+ binaryRequest += hex_str_to_bytes(vintx)
binaryRequest += pack("i", 0)
bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest)
- output = StringIO.StringIO()
+ output = BytesIO()
output.write(bin_response)
output.seek(0)
chainHeight = unpack("i", output.read(4))[0]
- hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(65).rstrip("L")
+ hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(64)
assert_equal(bb_hash, hashFromBinResponse) #check if getutxo's chaintip during calculation was fine
assert_equal(chainHeight, 102) #chain height must be 102
@@ -233,7 +228,7 @@ class RESTTest (BitcoinTestFramework):
assert_equal(response_hex.status, 200)
assert_greater_than(int(response_hex.getheader('content-length')), 160)
response_hex_str = response_hex.read()
- assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160])
+ assert_equal(encode(response_str, "hex_codec")[0:160], response_hex_str[0:160])
# compare with hex block header
response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True)
@@ -241,7 +236,7 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response_header_hex.getheader('content-length')), 160)
response_header_hex_str = response_header_hex.read()
assert_equal(response_hex_str[0:160], response_header_hex_str[0:160])
- assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160])
+ assert_equal(encode(response_header_str, "hex_codec")[0:160], response_header_hex_str[0:160])
# check json format
block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json')
@@ -251,7 +246,7 @@ class RESTTest (BitcoinTestFramework):
# compare with json block header
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True)
assert_equal(response_header_json.status, 200)
- response_header_json_str = response_header_json.read()
+ response_header_json_str = response_header_json.read().decode('utf-8')
json_obj = json.loads(response_header_json_str, parse_float=Decimal)
assert_equal(len(json_obj), 1) #ensure that there is one header in the json response
assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
@@ -275,7 +270,7 @@ class RESTTest (BitcoinTestFramework):
self.sync_all()
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", True)
assert_equal(response_header_json.status, 200)
- response_header_json_str = response_header_json.read()
+ response_header_json_str = response_header_json.read().decode('utf-8')
json_obj = json.loads(response_header_json_str)
assert_equal(len(json_obj), 5) #now we should have 5 header objects
@@ -291,7 +286,6 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response.getheader('content-length')), 10)
-
# check block tx details
# let's make 3 tx and mine them on node 1
txs = []
diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py
index 10a48b5556..572273566b 100755
--- a/qa/rpc-tests/rpcbind_test.py
+++ b/qa/rpc-tests/rpcbind_test.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -24,7 +24,7 @@ def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected):
if allow_ips:
base_args += ['-rpcallowip=' + x for x in allow_ips]
binds = ['-rpcbind='+addr for addr in addresses]
- nodes = start_nodes(1, tmpdir, [base_args + binds], connect_to)
+ nodes = start_nodes(self.num_nodes, tmpdir, [base_args + binds], connect_to)
try:
pid = bitcoind_processes[0].pid
assert_equal(set(get_bind_addrs(pid)), set(expected))
@@ -38,7 +38,7 @@ def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport):
at a non-localhost IP.
'''
base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
- nodes = start_nodes(1, tmpdir, [base_args])
+ nodes = start_nodes(self.num_nodes, tmpdir, [base_args])
try:
# connect to node through non-loopback interface
url = "http://rt:rt@%s:%d" % (rpchost, rpcport,)
@@ -51,7 +51,7 @@ def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport):
def run_test(tmpdir):
- assert(sys.platform == 'linux2') # due to OS-specific network stats queries, this test works only on Linux
+ assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux
# find the first non-loopback interface for testing
non_loopback_ip = None
for name,ip in all_interfaces():
diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py
index 2bc32584b5..6ab17d59b3 100755
--- a/qa/rpc-tests/sendheaders.py
+++ b/qa/rpc-tests/sendheaders.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
-#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
@@ -209,12 +208,14 @@ class TestNode(BaseNode):
BaseNode.__init__(self)
class SendHeadersTest(BitcoinTestFramework):
- def setup_chain(self):
- initialize_chain_clean(self.options.tmpdir, 2)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 2
def setup_network(self):
self.nodes = []
- self.nodes = start_nodes(2, self.options.tmpdir, [["-debug", "-logtimemicros=1"]]*2)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [["-debug", "-logtimemicros=1"]]*2)
connect_nodes(self.nodes[0], 1)
# mine count blocks and return the new tip
@@ -266,8 +267,8 @@ class SendHeadersTest(BitcoinTestFramework):
# PART 1
# 1. Mine a block; expect inv announcements each time
- print "Part 1: headers don't start before sendheaders message..."
- for i in xrange(4):
+ print("Part 1: headers don't start before sendheaders message...")
+ for i in range(4):
old_tip = tip
tip = self.mine_blocks(1)
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
@@ -297,14 +298,14 @@ class SendHeadersTest(BitcoinTestFramework):
inv_node.clear_last_announcement()
test_node.clear_last_announcement()
- print "Part 1: success!"
- print "Part 2: announce blocks with headers after sendheaders message..."
+ print("Part 1: success!")
+ print("Part 2: announce blocks with headers after sendheaders message...")
# PART 2
# 2. Send a sendheaders message and test that headers announcements
# commence and keep working.
test_node.send_message(msg_sendheaders())
prev_tip = int(self.nodes[0].getbestblockhash(), 16)
- test_node.get_headers(locator=[prev_tip], hashstop=0L)
+ test_node.get_headers(locator=[prev_tip], hashstop=0)
test_node.sync_with_ping()
# Now that we've synced headers, headers announcements should work
@@ -314,14 +315,14 @@ class SendHeadersTest(BitcoinTestFramework):
height = self.nodes[0].getblockcount()+1
block_time += 10 # Advance far enough ahead
- for i in xrange(10):
+ for i in range(10):
# Mine i blocks, and alternate announcing either via
# inv (of tip) or via headers. After each, new blocks
# mined by the node should successfully be announced
# with block header, even though the blocks are never requested
- for j in xrange(2):
+ for j in range(2):
blocks = []
- for b in xrange(i+1):
+ for b in range(i+1):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -360,13 +361,13 @@ class SendHeadersTest(BitcoinTestFramework):
height += 1
block_time += 1
- print "Part 2: success!"
+ print("Part 2: success!")
- print "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer..."
+ print("Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer...")
# PART 3. Headers announcements can stop after large reorg, and resume after
# getheaders or inv from peer.
- for j in xrange(2):
+ for j in range(2):
# First try mining a reorg that can propagate with header announcement
new_block_hashes = self.mine_reorg(length=7)
tip = new_block_hashes[-1]
@@ -392,7 +393,7 @@ class SendHeadersTest(BitcoinTestFramework):
test_node.get_data(new_block_hashes)
test_node.wait_for_block(new_block_hashes[-1])
- for i in xrange(3):
+ for i in range(3):
# Mine another block, still should get only an inv
tip = self.mine_blocks(1)
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
@@ -414,7 +415,7 @@ class SendHeadersTest(BitcoinTestFramework):
# of headers announcements, or mine a new block and inv it, also
# triggering resumption of headers announcements.
if j == 0:
- test_node.get_headers(locator=[tip], hashstop=0L)
+ test_node.get_headers(locator=[tip], hashstop=0)
test_node.sync_with_ping()
else:
test_node.send_block_inv(tip)
@@ -424,9 +425,9 @@ class SendHeadersTest(BitcoinTestFramework):
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
assert_equal(test_node.check_last_announcement(headers=[tip]), True)
- print "Part 3: success!"
+ print("Part 3: success!")
- print "Part 4: Testing direct fetch behavior..."
+ print("Part 4: Testing direct fetch behavior...")
tip = self.mine_blocks(1)
height = self.nodes[0].getblockcount() + 1
last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time']
@@ -434,7 +435,7 @@ class SendHeadersTest(BitcoinTestFramework):
# Create 2 blocks. Send the blocks, then send the headers.
blocks = []
- for b in xrange(2):
+ for b in range(2):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -452,7 +453,7 @@ class SendHeadersTest(BitcoinTestFramework):
# This time, direct fetch should work
blocks = []
- for b in xrange(3):
+ for b in range(3):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -473,7 +474,7 @@ class SendHeadersTest(BitcoinTestFramework):
blocks = []
# Create extra blocks for later
- for b in xrange(20):
+ for b in range(20):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -507,7 +508,7 @@ class SendHeadersTest(BitcoinTestFramework):
with mininode_lock:
assert_equal(test_node.last_getdata, None)
- print "Part 4: success!"
+ print("Part 4: success!")
# Finally, check that the inv node never received a getdata request,
# throughout the test
diff --git a/qa/rpc-tests/signmessages.py b/qa/rpc-tests/signmessages.py
new file mode 100755
index 0000000000..31b6f14a26
--- /dev/null
+++ b/qa/rpc-tests/signmessages.py
@@ -0,0 +1,41 @@
+#!/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.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+class SignMessagesTest(BitcoinTestFramework):
+ """Tests RPC commands for signing and verifying messages."""
+
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
+ self.is_network_split = False
+
+ def run_test(self):
+ message = 'This is just a test message'
+
+ # Test the signing with a privkey
+ privKey = 'cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'
+ address = 'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB'
+ signature = self.nodes[0].signmessagewithprivkey(privKey, message)
+
+ # Verify the message
+ assert(self.nodes[0].verifymessage(address, signature, message))
+
+ # Test the signing with an address with wallet
+ address = self.nodes[0].getnewaddress()
+ signature = self.nodes[0].signmessage(address, message)
+
+ # Verify the message
+ assert(self.nodes[0].verifymessage(address, signature, message))
+
+if __name__ == '__main__':
+ SignMessagesTest().main()
diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py
index d51d6ee610..c61a280616 100755
--- a/qa/rpc-tests/signrawtransactions.py
+++ b/qa/rpc-tests/signrawtransactions.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -10,12 +10,13 @@ from test_framework.util import *
class SignRawTransactionsTest(BitcoinTestFramework):
"""Tests transaction signing via RPC command "signrawtransaction"."""
- def setup_chain(self):
- print('Initializing test directory ' + self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 1)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 1
def setup_network(self, split=False):
- self.nodes = start_nodes(1, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False
def successful_signing_test(self):
diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py
index b209ae0c16..d76fba4b07 100755
--- a/qa/rpc-tests/smartfees.py
+++ b/qa/rpc-tests/smartfees.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -7,6 +7,7 @@
# Test fee estimation code
#
+from collections import OrderedDict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
@@ -22,7 +23,7 @@ SCRIPT_SIG = ["0451025175", "0451025275"]
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
'''
Create and send a transaction with a random fee.
- The transaction pays to a trival P2SH script, and assumes that its inputs
+ The transaction pays to a trivial P2SH script, and assumes that its inputs
are of the same form.
The function takes a list of confirmed outputs and unconfirmed outputs
and attempts to use the confirmed list first for its inputs.
@@ -49,10 +50,10 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
if total_in <= amount + fee:
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
outputs = {}
- outputs[P2SH_1] = total_in - amount - fee
- outputs[P2SH_2] = amount
+ outputs = OrderedDict([(P2SH_1, total_in - amount - fee),
+ (P2SH_2, amount)])
rawtx = from_node.createrawtransaction(inputs, outputs)
- # Createrawtransaction constructions a transaction that is ready to be signed
+ # createrawtransaction constructs a transaction that is ready to be signed.
# These transactions don't need to be signed, but we still have to insert the ScriptSig
# that will satisfy the ScriptPubKey.
completetx = rawtx[0:10]
@@ -78,12 +79,10 @@ def split_inputs(from_node, txins, txouts, initial_split = False):
'''
prevtxout = txins.pop()
inputs = []
- outputs = {}
inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] })
half_change = satoshi_round(prevtxout["amount"]/2)
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
- outputs[P2SH_1] = half_change
- outputs[P2SH_2] = rem_change
+ outputs = OrderedDict([(P2SH_1, half_change), (P2SH_2, rem_change)])
rawtx = from_node.createrawtransaction(inputs, outputs)
# If this is the initial split we actually need to sign the transaction
# Otherwise we just need to insert the property ScriptSig
@@ -105,7 +104,7 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
delta = 1.0e-6 # account for rounding error
last_e = max(fees_seen)
- for e in filter(lambda x: x >= 0, all_estimates):
+ for e in [x for x in all_estimates if x >= 0]:
# Estimates should be within the bounds of what transactions fees actually were:
if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
@@ -146,6 +145,11 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
class EstimateFeeTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 3
+ self.setup_clean_chain = False
+
def setup_network(self):
'''
We'll setup the network to have 3 nodes that all mine with different parameters.
@@ -219,12 +223,12 @@ class EstimateFeeTest(BitcoinTestFramework):
from_index = random.randint(1,2)
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
self.memutxo, Decimal("0.005"), min_fee, min_fee)
- tx_kbytes = (len(txhex)/2)/1000.0
+ tx_kbytes = (len(txhex) // 2) / 1000.0
self.fees_per_kb.append(float(fee)/tx_kbytes)
sync_mempools(self.nodes[0:3],.1)
mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]
sync_blocks(self.nodes[0:3],.1)
- #update which txouts are confirmed
+ # update which txouts are confirmed
newmem = []
for utx in self.memutxo:
if utx["txid"] in mined:
@@ -239,7 +243,7 @@ class EstimateFeeTest(BitcoinTestFramework):
self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting
print("Will output estimates for 1/2/3/6/15/25 blocks")
- for i in xrange(2):
+ for i in range(2):
print("Creating transactions and mining them with a block size that can't keep up")
# Create transactions and mine 10 small blocks with node 2, but create txs faster than we can mine
self.transact_and_mine(10, self.nodes[2])
diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py
index fba469a0dd..95b2be658c 100644
--- a/qa/rpc-tests/test_framework/authproxy.py
+++ b/qa/rpc-tests/test_framework/authproxy.py
@@ -61,7 +61,7 @@ class JSONRPCException(Exception):
def EncodeDecimal(o):
if isinstance(o, decimal.Decimal):
- return round(o, 8)
+ return str(o)
raise TypeError(repr(o) + " is not JSON serializable")
class AuthServiceProxy(object):
@@ -92,11 +92,10 @@ class AuthServiceProxy(object):
self.__conn = connection
elif self.__url.scheme == 'https':
self.__conn = httplib.HTTPSConnection(self.__url.hostname, port,
- None, None, False,
- timeout)
+ timeout=timeout)
else:
self.__conn = httplib.HTTPConnection(self.__url.hostname, port,
- False, timeout)
+ timeout=timeout)
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
@@ -125,6 +124,11 @@ class AuthServiceProxy(object):
return self._get_response()
else:
raise
+ except BrokenPipeError:
+ # Python 3.5+ raises this instead of BadStatusLine when the connection was reset
+ self.__conn.close()
+ self.__conn.request(method, path, postdata, headers)
+ return self._get_response()
def __call__(self, *args):
AuthServiceProxy.__id_count += 1
@@ -155,6 +159,11 @@ class AuthServiceProxy(object):
raise JSONRPCException({
'code': -342, 'message': 'missing HTTP response from server'})
+ content_type = http_response.getheader('Content-Type')
+ if content_type != 'application/json':
+ raise JSONRPCException({
+ 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)})
+
responsedata = http_response.read().decode('utf8')
response = json.loads(responsedata, parse_float=decimal.Decimal)
if "error" in response and response["error"] is None:
diff --git a/qa/rpc-tests/test_framework/bignum.py b/qa/rpc-tests/test_framework/bignum.py
index b0c58ccd47..ef800e4d57 100644
--- a/qa/rpc-tests/test_framework/bignum.py
+++ b/qa/rpc-tests/test_framework/bignum.py
@@ -1,16 +1,15 @@
-#
+#!/usr/bin/env python3
#
# bignum.py
#
# This file is copied from python-bitcoinlib.
#
-# Distributed under the MIT/X11 software license, see the accompanying
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
"""Bignum routines"""
-from __future__ import absolute_import, division, print_function, unicode_literals
import struct
diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py
index b9775b477c..4bc279032b 100644
--- a/qa/rpc-tests/test_framework/blockstore.py
+++ b/qa/rpc-tests/test_framework/blockstore.py
@@ -1,15 +1,17 @@
+#!/usr/bin/env python3
# BlockStore: a helper class that keeps a map of blocks and implements
# helper functions for responding to getheaders and getdata,
# and for constructing a getheaders message
#
-from mininode import *
-import dbm
+from .mininode import *
+from io import BytesIO
+import dbm.ndbm
class BlockStore(object):
def __init__(self, datadir):
- self.blockDB = dbm.open(datadir + "/blocks", 'c')
- self.currentBlock = 0L
+ self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c')
+ self.currentBlock = 0
self.headers_map = dict()
def close(self):
@@ -21,7 +23,7 @@ class BlockStore(object):
serialized_block = self.blockDB[repr(blockhash)]
except KeyError:
return None
- f = cStringIO.StringIO(serialized_block)
+ f = BytesIO(serialized_block)
ret = CBlock()
ret.deserialize(f)
ret.calc_sha256()
@@ -66,7 +68,7 @@ class BlockStore(object):
try:
self.blockDB[repr(block.sha256)] = bytes(block.serialize())
except TypeError as e:
- print "Unexpected error: ", sys.exc_info()[0], e.args
+ print("Unexpected error: ", sys.exc_info()[0], e.args)
self.currentBlock = block.sha256
self.headers_map[block.sha256] = CBlockHeader(block)
@@ -104,7 +106,7 @@ class BlockStore(object):
class TxStore(object):
def __init__(self, datadir):
- self.txDB = dbm.open(datadir + "/transactions", 'c')
+ self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c')
def close(self):
self.txDB.close()
@@ -115,7 +117,7 @@ class TxStore(object):
serialized_tx = self.txDB[repr(txhash)]
except KeyError:
return None
- f = cStringIO.StringIO(serialized_tx)
+ f = BytesIO(serialized_tx)
ret = CTransaction()
ret.deserialize(f)
ret.calc_sha256()
@@ -126,7 +128,7 @@ class TxStore(object):
try:
self.txDB[repr(tx.sha256)] = bytes(tx.serialize())
except TypeError as e:
- print "Unexpected error: ", sys.exc_info()[0], e.args
+ print("Unexpected error: ", sys.exc_info()[0], e.args)
def get_transactions(self, inv):
responses = []
diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py
index 7eea41b75c..44232153ac 100644
--- a/qa/rpc-tests/test_framework/blocktools.py
+++ b/qa/rpc-tests/test_framework/blocktools.py
@@ -1,11 +1,11 @@
+#!/usr/bin/env python3
# blocktools.py - utilities for manipulating blocks and transactions
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+# Copyright (c) 2015-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.
-#
-from mininode import *
-from script import CScript, OP_TRUE, OP_CHECKSIG
+from .mininode import *
+from .script import CScript, OP_TRUE, OP_CHECKSIG
# Create a block (with regtest difficulty)
def create_block(hashprev, coinbase, nTime=None):
@@ -29,7 +29,7 @@ def serialize_script_num(value):
neg = value < 0
absvalue = -value if neg else value
while (absvalue):
- r.append(chr(absvalue & 0xff))
+ r.append(int(absvalue & 0xff))
absvalue >>= 8
if r[-1] & 0x80:
r.append(0x80 if neg else 0)
@@ -45,7 +45,7 @@ def create_coinbase(height, pubkey = None):
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
ser_string(serialize_script_num(height)), 0xffffffff))
coinbaseoutput = CTxOut()
- coinbaseoutput.nValue = 50*100000000
+ coinbaseoutput.nValue = 50 * COIN
halvings = int(height/150) # regtest
coinbaseoutput.nValue >>= halvings
if (pubkey != None):
@@ -62,6 +62,6 @@ def create_transaction(prevtx, n, sig, value):
tx = CTransaction()
assert(n < len(prevtx.vout))
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
- tx.vout.append(CTxOut(value, ""))
+ tx.vout.append(CTxOut(value, b""))
tx.calc_sha256()
return tx
diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py
index a4cd4d0a89..7c92d3f828 100755
--- a/qa/rpc-tests/test_framework/comptool.py
+++ b/qa/rpc-tests/test_framework/comptool.py
@@ -1,12 +1,11 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
-from mininode import *
-from blockstore import BlockStore, TxStore
-from util import p2p_port
+from .mininode import *
+from .blockstore import BlockStore, TxStore
+from .util import p2p_port
'''
This is a tool for comparing two or more bitcoinds to each other
@@ -27,25 +26,11 @@ generator that returns TestInstance objects. See below for definition.
global mininode_lock
-def wait_until(predicate, attempts=float('inf'), timeout=float('inf')):
- attempt = 0
- elapsed = 0
-
- while attempt < attempts and elapsed < timeout:
- with mininode_lock:
- if predicate():
- return True
- attempt += 1
- elapsed += 0.05
- time.sleep(0.05)
-
- return False
-
class RejectResult(object):
'''
Outcome that expects rejection of a transaction or block.
'''
- def __init__(self, code, reason=''):
+ def __init__(self, code, reason=b''):
self.code = code
self.reason = reason
def match(self, other):
@@ -111,9 +96,9 @@ class TestNode(NodeConnCB):
raise AssertionError("Got pong for unknown ping [%s]" % repr(message))
def on_reject(self, conn, message):
- if message.message == 'tx':
+ if message.message == b'tx':
self.tx_reject_map[message.data] = RejectResult(message.code, message.reason)
- if message.message == 'block':
+ if message.message == b'block':
self.block_reject_map[message.data] = RejectResult(message.code, message.reason)
def send_inv(self, obj):
@@ -193,6 +178,10 @@ class TestManager(object):
# associated NodeConn
test_node.add_connection(self.connections[-1])
+ def clear_all_connections(self):
+ self.connections = []
+ self.test_nodes = []
+
def wait_for_disconnections(self):
def disconnected():
return all(node.closed for node in self.test_nodes)
@@ -269,10 +258,10 @@ class TestManager(object):
if c.cb.bestblockhash == blockhash:
return False
if blockhash not in c.cb.block_reject_map:
- print 'Block not in reject map: %064x' % (blockhash)
+ print('Block not in reject map: %064x' % (blockhash))
return False
if not outcome.match(c.cb.block_reject_map[blockhash]):
- print 'Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash)
+ print('Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash))
return False
elif ((c.cb.bestblockhash == blockhash) != outcome):
# print c.cb.bestblockhash, blockhash, outcome
@@ -297,10 +286,10 @@ class TestManager(object):
if txhash in c.cb.lastInv:
return False
if txhash not in c.cb.tx_reject_map:
- print 'Tx not in reject map: %064x' % (txhash)
+ print('Tx not in reject map: %064x' % (txhash))
return False
if not outcome.match(c.cb.tx_reject_map[txhash]):
- print 'Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash)
+ print('Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash))
return False
elif ((txhash in c.cb.lastInv) != outcome):
# print c.rpc.getrawmempool(), c.cb.lastInv
@@ -403,7 +392,7 @@ class TestManager(object):
if (not self.check_mempool(tx.sha256, tx_outcome)):
raise AssertionError("Mempool test failed at test %d" % test_number)
- print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]
+ print("Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ])
test_number += 1
[ c.disconnect_node() for c in self.connections ]
diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py
index d21a001b6e..23fce61014 100644
--- a/qa/rpc-tests/test_framework/coverage.py
+++ b/qa/rpc-tests/test_framework/coverage.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
-#
"""
This module contains utilities for doing coverage analysis on the RPC
diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py
index 81bb439cea..1617daa200 100755
--- a/qa/rpc-tests/test_framework/mininode.py
+++ b/qa/rpc-tests/test_framework/mininode.py
@@ -1,7 +1,12 @@
-# mininode.py - Bitcoin P2P network half-a-node
-#
-# Distributed under the MIT/X11 software license, see the accompanying
+#!/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
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# mininode.py - Bitcoin P2P network half-a-node
#
# This python code was modified from ArtForz' public domain half-a-node, as
# found in the mini-node branch of http://github.com/jgarzik/pynode.
@@ -20,11 +25,12 @@
import struct
import socket
import asyncore
-import binascii
import time
import sys
import random
-import cStringIO
+from binascii import hexlify, unhexlify
+from io import BytesIO
+from codecs import encode
import hashlib
from threading import RLock
from threading import Thread
@@ -33,11 +39,13 @@ import copy
BIP0031_VERSION = 60000
MY_VERSION = 60001 # past bip-31 for ping/pong
-MY_SUBVERSION = "/python-mininode-tester:0.0.1/"
+MY_SUBVERSION = b"/python-mininode-tester:0.0.3/"
MAX_INV_SZ = 50000
MAX_BLOCK_SIZE = 1000000
+COIN = 100000000 # 1 btc in satoshis
+
# Keep our own socket map for asyncore, so that we can track disconnects
# ourselves (to workaround an issue with closing an asyncore socket when
# using select)
@@ -70,44 +78,42 @@ def deser_string(f):
nit = struct.unpack("<Q", f.read(8))[0]
return f.read(nit)
-
def ser_string(s):
if len(s) < 253:
- return chr(len(s)) + s
+ return struct.pack("B", len(s)) + s
elif len(s) < 0x10000:
- return chr(253) + struct.pack("<H", len(s)) + s
- elif len(s) < 0x100000000L:
- return chr(254) + struct.pack("<I", len(s)) + s
- return chr(255) + struct.pack("<Q", len(s)) + s
-
+ return struct.pack("<BH", 253, len(s)) + s
+ elif len(s) < 0x100000000:
+ return struct.pack("<BI", 254, len(s)) + s
+ return struct.pack("<BQ", 255, len(s)) + s
def deser_uint256(f):
- r = 0L
- for i in xrange(8):
+ r = 0
+ for i in range(8):
t = struct.unpack("<I", f.read(4))[0]
r += t << (i * 32)
return r
def ser_uint256(u):
- rs = ""
- for i in xrange(8):
- rs += struct.pack("<I", u & 0xFFFFFFFFL)
+ rs = b""
+ for i in range(8):
+ rs += struct.pack("<I", u & 0xFFFFFFFF)
u >>= 32
return rs
def uint256_from_str(s):
- r = 0L
+ r = 0
t = struct.unpack("<IIIIIIII", s[:32])
- for i in xrange(8):
+ for i in range(8):
r += t[i] << (i * 32)
return r
def uint256_from_compact(c):
nbytes = (c >> 24) & 0xFF
- v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
+ v = (c & 0xFFFFFF) << (8 * (nbytes - 3))
return v
@@ -120,7 +126,7 @@ def deser_vector(f, c):
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
r = []
- for i in xrange(nit):
+ for i in range(nit):
t = c()
t.deserialize(f)
r.append(t)
@@ -128,15 +134,15 @@ def deser_vector(f, c):
def ser_vector(l):
- r = ""
+ r = b""
if len(l) < 253:
- r = chr(len(l))
+ r = struct.pack("B", len(l))
elif len(l) < 0x10000:
- r = chr(253) + struct.pack("<H", len(l))
- elif len(l) < 0x100000000L:
- r = chr(254) + struct.pack("<I", len(l))
+ r = struct.pack("<BH", 253, len(l))
+ elif len(l) < 0x100000000:
+ r = struct.pack("<BI", 254, len(l))
else:
- r = chr(255) + struct.pack("<Q", len(l))
+ r = struct.pack("<BQ", 255, len(l))
for i in l:
r += i.serialize()
return r
@@ -151,22 +157,22 @@ def deser_uint256_vector(f):
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
r = []
- for i in xrange(nit):
+ for i in range(nit):
t = deser_uint256(f)
r.append(t)
return r
def ser_uint256_vector(l):
- r = ""
+ r = b""
if len(l) < 253:
- r = chr(len(l))
+ r = struct.pack("B", len(l))
elif len(l) < 0x10000:
- r = chr(253) + struct.pack("<H", len(l))
- elif len(l) < 0x100000000L:
- r = chr(254) + struct.pack("<I", len(l))
+ r = struct.pack("<BH", 253, len(l))
+ elif len(l) < 0x100000000:
+ r = struct.pack("<BI", 254, len(l))
else:
- r = chr(255) + struct.pack("<Q", len(l))
+ r = struct.pack("<BQ", 255, len(l))
for i in l:
r += ser_uint256(i)
return r
@@ -181,22 +187,22 @@ def deser_string_vector(f):
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
r = []
- for i in xrange(nit):
+ for i in range(nit):
t = deser_string(f)
r.append(t)
return r
def ser_string_vector(l):
- r = ""
+ r = b""
if len(l) < 253:
- r = chr(len(l))
+ r = struct.pack("B", len(l))
elif len(l) < 0x10000:
- r = chr(253) + struct.pack("<H", len(l))
- elif len(l) < 0x100000000L:
- r = chr(254) + struct.pack("<I", len(l))
+ r = struct.pack("<BH", 253, len(l))
+ elif len(l) < 0x100000000:
+ r = struct.pack("<BI", 254, len(l))
else:
- r = chr(255) + struct.pack("<Q", len(l))
+ r = struct.pack("<BQ", 255, len(l))
for sv in l:
r += ser_string(sv)
return r
@@ -211,41 +217,41 @@ def deser_int_vector(f):
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
r = []
- for i in xrange(nit):
+ for i in range(nit):
t = struct.unpack("<i", f.read(4))[0]
r.append(t)
return r
def ser_int_vector(l):
- r = ""
+ r = b""
if len(l) < 253:
- r = chr(len(l))
+ r = struct.pack("B", len(l))
elif len(l) < 0x10000:
- r = chr(253) + struct.pack("<H", len(l))
- elif len(l) < 0x100000000L:
- r = chr(254) + struct.pack("<I", len(l))
+ r = struct.pack("<BH", 253, len(l))
+ elif len(l) < 0x100000000:
+ r = struct.pack("<BI", 254, len(l))
else:
- r = chr(255) + struct.pack("<Q", len(l))
+ r = struct.pack("<BQ", 255, len(l))
for i in l:
r += struct.pack("<i", i)
return r
# Deserialize from a hex string representation (eg from RPC)
def FromHex(obj, hex_string):
- obj.deserialize(cStringIO.StringIO(binascii.unhexlify(hex_string)))
+ obj.deserialize(BytesIO(unhexlify(hex_string.encode('ascii'))))
return obj
# Convert a binary-serializable object to hex (eg for submission via RPC)
def ToHex(obj):
- return binascii.hexlify(obj.serialize()).decode('utf-8')
+ return hexlify(obj.serialize()).decode('ascii')
# Objects that map to bitcoind objects, which can be serialized/deserialized
class CAddress(object):
def __init__(self):
self.nServices = 1
- self.pchReserved = "\x00" * 10 + "\xff" * 2
+ self.pchReserved = b"\x00" * 10 + b"\xff" * 2
self.ip = "0.0.0.0"
self.port = 0
@@ -256,7 +262,7 @@ class CAddress(object):
self.port = struct.unpack(">H", f.read(2))[0]
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<Q", self.nServices)
r += self.pchReserved
r += socket.inet_aton(self.ip)
@@ -274,7 +280,7 @@ class CInv(object):
1: "TX",
2: "Block"}
- def __init__(self, t=0, h=0L):
+ def __init__(self, t=0, h=0):
self.type = t
self.hash = h
@@ -283,7 +289,7 @@ class CInv(object):
self.hash = deser_uint256(f)
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.type)
r += ser_uint256(self.hash)
return r
@@ -303,7 +309,7 @@ class CBlockLocator(object):
self.vHave = deser_uint256_vector(f)
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += ser_uint256_vector(self.vHave)
return r
@@ -323,7 +329,7 @@ class COutPoint(object):
self.n = struct.unpack("<I", f.read(4))[0]
def serialize(self):
- r = ""
+ r = b""
r += ser_uint256(self.hash)
r += struct.pack("<I", self.n)
return r
@@ -333,7 +339,7 @@ class COutPoint(object):
class CTxIn(object):
- def __init__(self, outpoint=None, scriptSig="", nSequence=0):
+ def __init__(self, outpoint=None, scriptSig=b"", nSequence=0):
if outpoint is None:
self.prevout = COutPoint()
else:
@@ -348,7 +354,7 @@ class CTxIn(object):
self.nSequence = struct.unpack("<I", f.read(4))[0]
def serialize(self):
- r = ""
+ r = b""
r += self.prevout.serialize()
r += ser_string(self.scriptSig)
r += struct.pack("<I", self.nSequence)
@@ -356,12 +362,12 @@ class CTxIn(object):
def __repr__(self):
return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \
- % (repr(self.prevout), binascii.hexlify(self.scriptSig),
+ % (repr(self.prevout), hexlify(self.scriptSig),
self.nSequence)
class CTxOut(object):
- def __init__(self, nValue=0, scriptPubKey=""):
+ def __init__(self, nValue=0, scriptPubKey=b""):
self.nValue = nValue
self.scriptPubKey = scriptPubKey
@@ -370,15 +376,15 @@ class CTxOut(object):
self.scriptPubKey = deser_string(f)
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<q", self.nValue)
r += ser_string(self.scriptPubKey)
return r
def __repr__(self):
return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \
- % (self.nValue // 100000000, self.nValue % 100000000,
- binascii.hexlify(self.scriptPubKey))
+ % (self.nValue // COIN, self.nValue % COIN,
+ hexlify(self.scriptPubKey))
class CTransaction(object):
@@ -407,7 +413,7 @@ class CTransaction(object):
self.hash = None
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += ser_vector(self.vin)
r += ser_vector(self.vout)
@@ -421,12 +427,12 @@ class CTransaction(object):
def calc_sha256(self):
if self.sha256 is None:
self.sha256 = uint256_from_str(hash256(self.serialize()))
- self.hash = hash256(self.serialize())[::-1].encode('hex_codec')
+ self.hash = encode(hash256(self.serialize())[::-1], 'hex_codec').decode('ascii')
def is_valid(self):
self.calc_sha256()
for tout in self.vout:
- if tout.nValue < 0 or tout.nValue > 21000000L * 100000000L:
+ if tout.nValue < 0 or tout.nValue > 21000000 * COIN:
return False
return True
@@ -471,7 +477,7 @@ class CBlockHeader(object):
self.hash = None
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += ser_uint256(self.hashPrevBlock)
r += ser_uint256(self.hashMerkleRoot)
@@ -482,7 +488,7 @@ class CBlockHeader(object):
def calc_sha256(self):
if self.sha256 is None:
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += ser_uint256(self.hashPrevBlock)
r += ser_uint256(self.hashMerkleRoot)
@@ -490,7 +496,7 @@ class CBlockHeader(object):
r += struct.pack("<I", self.nBits)
r += struct.pack("<I", self.nNonce)
self.sha256 = uint256_from_str(hash256(r))
- self.hash = hash256(r)[::-1].encode('hex_codec')
+ self.hash = encode(hash256(r)[::-1], 'hex_codec').decode('ascii')
def rehash(self):
self.sha256 = None
@@ -513,7 +519,7 @@ class CBlock(CBlockHeader):
self.vtx = deser_vector(f, CTransaction)
def serialize(self):
- r = ""
+ r = b""
r += super(CBlock, self).serialize()
r += ser_vector(self.vtx)
return r
@@ -525,7 +531,7 @@ class CBlock(CBlockHeader):
hashes.append(ser_uint256(tx.sha256))
while len(hashes) > 1:
newhashes = []
- for i in xrange(0, len(hashes), 2):
+ for i in range(0, len(hashes), 2):
i2 = min(i+1, len(hashes)-1)
newhashes.append(hash256(hashes[i] + hashes[i2]))
hashes = newhashes
@@ -568,9 +574,9 @@ class CUnsignedAlert(object):
self.nMaxVer = 0
self.setSubVer = []
self.nPriority = 0
- self.strComment = ""
- self.strStatusBar = ""
- self.strReserved = ""
+ self.strComment = b""
+ self.strStatusBar = b""
+ self.strReserved = b""
def deserialize(self, f):
self.nVersion = struct.unpack("<i", f.read(4))[0]
@@ -588,7 +594,7 @@ class CUnsignedAlert(object):
self.strReserved = deser_string(f)
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += struct.pack("<q", self.nRelayUntil)
r += struct.pack("<q", self.nExpiration)
@@ -613,15 +619,15 @@ class CUnsignedAlert(object):
class CAlert(object):
def __init__(self):
- self.vchMsg = ""
- self.vchSig = ""
+ self.vchMsg = b""
+ self.vchSig = b""
def deserialize(self, f):
self.vchMsg = deser_string(f)
self.vchSig = deser_string(f)
def serialize(self):
- r = ""
+ r = b""
r += ser_string(self.vchMsg)
r += ser_string(self.vchSig)
return r
@@ -633,12 +639,12 @@ class CAlert(object):
# Objects that correspond to messages on the wire
class msg_version(object):
- command = "version"
+ command = b"version"
def __init__(self):
self.nVersion = MY_VERSION
self.nServices = 1
- self.nTime = time.time()
+ self.nTime = int(time.time())
self.addrTo = CAddress()
self.addrFrom = CAddress()
self.nNonce = random.getrandbits(64)
@@ -669,7 +675,7 @@ class msg_version(object):
self.nStartingHeight = None
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<i", self.nVersion)
r += struct.pack("<Q", self.nServices)
r += struct.pack("<q", self.nTime)
@@ -688,7 +694,7 @@ class msg_version(object):
class msg_verack(object):
- command = "verack"
+ command = b"verack"
def __init__(self):
pass
@@ -697,14 +703,14 @@ class msg_verack(object):
pass
def serialize(self):
- return ""
+ return b""
def __repr__(self):
return "msg_verack()"
class msg_addr(object):
- command = "addr"
+ command = b"addr"
def __init__(self):
self.addrs = []
@@ -720,7 +726,7 @@ class msg_addr(object):
class msg_alert(object):
- command = "alert"
+ command = b"alert"
def __init__(self):
self.alert = CAlert()
@@ -730,7 +736,7 @@ class msg_alert(object):
self.alert.deserialize(f)
def serialize(self):
- r = ""
+ r = b""
r += self.alert.serialize()
return r
@@ -739,7 +745,7 @@ class msg_alert(object):
class msg_inv(object):
- command = "inv"
+ command = b"inv"
def __init__(self, inv=None):
if inv is None:
@@ -758,7 +764,7 @@ class msg_inv(object):
class msg_getdata(object):
- command = "getdata"
+ command = b"getdata"
def __init__(self, inv=None):
self.inv = inv if inv != None else []
@@ -774,11 +780,11 @@ class msg_getdata(object):
class msg_getblocks(object):
- command = "getblocks"
+ command = b"getblocks"
def __init__(self):
self.locator = CBlockLocator()
- self.hashstop = 0L
+ self.hashstop = 0
def deserialize(self, f):
self.locator = CBlockLocator()
@@ -786,7 +792,7 @@ class msg_getblocks(object):
self.hashstop = deser_uint256(f)
def serialize(self):
- r = ""
+ r = b""
r += self.locator.serialize()
r += ser_uint256(self.hashstop)
return r
@@ -797,7 +803,7 @@ class msg_getblocks(object):
class msg_tx(object):
- command = "tx"
+ command = b"tx"
def __init__(self, tx=CTransaction()):
self.tx = tx
@@ -813,7 +819,7 @@ class msg_tx(object):
class msg_block(object):
- command = "block"
+ command = b"block"
def __init__(self, block=None):
if block is None:
@@ -832,7 +838,7 @@ class msg_block(object):
class msg_getaddr(object):
- command = "getaddr"
+ command = b"getaddr"
def __init__(self):
pass
@@ -841,14 +847,14 @@ class msg_getaddr(object):
pass
def serialize(self):
- return ""
+ return b""
def __repr__(self):
return "msg_getaddr()"
class msg_ping_prebip31(object):
- command = "ping"
+ command = b"ping"
def __init__(self):
pass
@@ -857,23 +863,23 @@ class msg_ping_prebip31(object):
pass
def serialize(self):
- return ""
+ return b""
def __repr__(self):
return "msg_ping() (pre-bip31)"
class msg_ping(object):
- command = "ping"
+ command = b"ping"
- def __init__(self, nonce=0L):
+ def __init__(self, nonce=0):
self.nonce = nonce
def deserialize(self, f):
self.nonce = struct.unpack("<Q", f.read(8))[0]
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<Q", self.nonce)
return r
@@ -882,16 +888,16 @@ class msg_ping(object):
class msg_pong(object):
- command = "pong"
+ command = b"pong"
- def __init__(self, nonce=0L):
+ def __init__(self, nonce=0):
self.nonce = nonce
def deserialize(self, f):
self.nonce = struct.unpack("<Q", f.read(8))[0]
def serialize(self):
- r = ""
+ r = b""
r += struct.pack("<Q", self.nonce)
return r
@@ -900,7 +906,7 @@ class msg_pong(object):
class msg_mempool(object):
- command = "mempool"
+ command = b"mempool"
def __init__(self):
pass
@@ -909,13 +915,13 @@ class msg_mempool(object):
pass
def serialize(self):
- return ""
+ return b""
def __repr__(self):
return "msg_mempool()"
class msg_sendheaders(object):
- command = "sendheaders"
+ command = b"sendheaders"
def __init__(self):
pass
@@ -924,7 +930,7 @@ class msg_sendheaders(object):
pass
def serialize(self):
- return ""
+ return b""
def __repr__(self):
return "msg_sendheaders()"
@@ -934,11 +940,11 @@ class msg_sendheaders(object):
# vector of hashes
# hash_stop (hash of last desired block header, 0 to get as many as possible)
class msg_getheaders(object):
- command = "getheaders"
+ command = b"getheaders"
def __init__(self):
self.locator = CBlockLocator()
- self.hashstop = 0L
+ self.hashstop = 0
def deserialize(self, f):
self.locator = CBlockLocator()
@@ -946,7 +952,7 @@ class msg_getheaders(object):
self.hashstop = deser_uint256(f)
def serialize(self):
- r = ""
+ r = b""
r += self.locator.serialize()
r += ser_uint256(self.hashstop)
return r
@@ -959,7 +965,7 @@ class msg_getheaders(object):
# headers message has
# <count> <vector of block headers>
class msg_headers(object):
- command = "headers"
+ command = b"headers"
def __init__(self):
self.headers = []
@@ -979,26 +985,29 @@ class msg_headers(object):
class msg_reject(object):
- command = "reject"
+ command = b"reject"
+ REJECT_MALFORMED = 1
def __init__(self):
- self.message = ""
- self.code = ""
- self.reason = ""
- self.data = 0L
+ self.message = b""
+ self.code = 0
+ self.reason = b""
+ self.data = 0
def deserialize(self, f):
self.message = deser_string(f)
self.code = struct.unpack("<B", f.read(1))[0]
self.reason = deser_string(f)
- if (self.message == "block" or self.message == "tx"):
+ if (self.code != self.REJECT_MALFORMED and
+ (self.message == b"block" or self.message == b"tx")):
self.data = deser_uint256(f)
def serialize(self):
r = ser_string(self.message)
r += struct.pack("<B", self.code)
r += ser_string(self.reason)
- if (self.message == "block" or self.message == "tx"):
+ if (self.code != self.REJECT_MALFORMED and
+ (self.message == b"block" or self.message == b"tx")):
r += ser_uint256(self.data)
return r
@@ -1006,6 +1015,37 @@ class msg_reject(object):
return "msg_reject: %s %d %s [%064x]" \
% (self.message, self.code, self.reason, self.data)
+# Helper function
+def wait_until(predicate, attempts=float('inf'), timeout=float('inf')):
+ attempt = 0
+ elapsed = 0
+
+ while attempt < attempts and elapsed < timeout:
+ with mininode_lock:
+ if predicate():
+ return True
+ attempt += 1
+ elapsed += 0.05
+ time.sleep(0.05)
+
+ return False
+
+class msg_feefilter(object):
+ command = b"feefilter"
+
+ def __init__(self, feerate=0):
+ self.feerate = feerate
+
+ def deserialize(self, f):
+ self.feerate = struct.unpack("<Q", f.read(8))[0]
+
+ def serialize(self):
+ r = b""
+ r += struct.pack("<Q", self.feerate)
+ return r
+
+ def __repr__(self):
+ return "msg_feefilter(feerate=%08x)" % self.feerate
# This is what a callback should look like for NodeConn
# Reimplement the on_* functions to provide handling for events
@@ -1042,10 +1082,10 @@ class NodeConnCB(object):
time.sleep(deliver_sleep)
with mininode_lock:
try:
- getattr(self, 'on_' + message.command)(conn, message)
+ getattr(self, 'on_' + message.command.decode('ascii'))(conn, message)
except:
- print "ERROR delivering %s (%s)" % (repr(message),
- sys.exc_info()[0])
+ print("ERROR delivering %s (%s)" % (repr(message),
+ sys.exc_info()[0]))
def on_version(self, conn, message):
if message.nVersion >= 209:
@@ -1082,33 +1122,61 @@ class NodeConnCB(object):
def on_close(self, conn): pass
def on_mempool(self, conn): pass
def on_pong(self, conn, message): pass
+ def on_feefilter(self, conn, message): pass
+# More useful callbacks and functions for NodeConnCB's which have a single NodeConn
+class SingleNodeConnCB(NodeConnCB):
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
+
+ def add_connection(self, conn):
+ self.connection = conn
+
+ # Wrapper for the NodeConn's send_message function
+ def send_message(self, message):
+ self.connection.send_message(message)
+
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ # Sync up with the node
+ def sync_with_ping(self, timeout=30):
+ def received_pong():
+ return (self.last_pong.nonce == self.ping_counter)
+ self.send_message(msg_ping(nonce=self.ping_counter))
+ success = wait_until(received_pong, timeout)
+ self.ping_counter += 1
+ return success
# The actual NodeConn class
# This class provides an interface for a p2p connection to a specified node
class NodeConn(asyncore.dispatcher):
messagemap = {
- "version": msg_version,
- "verack": msg_verack,
- "addr": msg_addr,
- "alert": msg_alert,
- "inv": msg_inv,
- "getdata": msg_getdata,
- "getblocks": msg_getblocks,
- "tx": msg_tx,
- "block": msg_block,
- "getaddr": msg_getaddr,
- "ping": msg_ping,
- "pong": msg_pong,
- "headers": msg_headers,
- "getheaders": msg_getheaders,
- "reject": msg_reject,
- "mempool": msg_mempool
+ b"version": msg_version,
+ b"verack": msg_verack,
+ b"addr": msg_addr,
+ b"alert": msg_alert,
+ b"inv": msg_inv,
+ b"getdata": msg_getdata,
+ b"getblocks": msg_getblocks,
+ b"tx": msg_tx,
+ b"block": msg_block,
+ b"getaddr": msg_getaddr,
+ b"ping": msg_ping,
+ b"pong": msg_pong,
+ b"headers": msg_headers,
+ b"getheaders": msg_getheaders,
+ b"reject": msg_reject,
+ b"mempool": msg_mempool,
+ b"feefilter": msg_feefilter
}
MAGIC_BYTES = {
- "mainnet": "\xf9\xbe\xb4\xd9", # mainnet
- "testnet3": "\x0b\x11\x09\x07", # testnet3
- "regtest": "\xfa\xbf\xb5\xda" # regtest
+ "mainnet": b"\xf9\xbe\xb4\xd9", # mainnet
+ "testnet3": b"\x0b\x11\x09\x07", # testnet3
+ "regtest": b"\xfa\xbf\xb5\xda" # regtest
}
def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1):
@@ -1117,8 +1185,8 @@ class NodeConn(asyncore.dispatcher):
self.dstaddr = dstaddr
self.dstport = dstport
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sendbuf = ""
- self.recvbuf = ""
+ self.sendbuf = b""
+ self.recvbuf = b""
self.ver_send = 209
self.ver_recv = 209
self.last_sent = 0
@@ -1135,8 +1203,8 @@ class NodeConn(asyncore.dispatcher):
vt.addrFrom.ip = "0.0.0.0"
vt.addrFrom.port = 0
self.send_message(vt, True)
- print 'MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \
- + str(dstport)
+ print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \
+ + str(dstport))
try:
self.connect((dstaddr, dstport))
@@ -1155,8 +1223,8 @@ class NodeConn(asyncore.dispatcher):
self.show_debug_msg("MiniNode: Closing Connection to %s:%d... "
% (self.dstaddr, self.dstport))
self.state = "closed"
- self.recvbuf = ""
- self.sendbuf = ""
+ self.recvbuf = b""
+ self.sendbuf = b""
try:
self.close()
except:
@@ -1190,43 +1258,48 @@ class NodeConn(asyncore.dispatcher):
self.sendbuf = self.sendbuf[sent:]
def got_data(self):
- while True:
- if len(self.recvbuf) < 4:
- return
- if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]:
- raise ValueError("got garbage %s" % repr(self.recvbuf))
- if self.ver_recv < 209:
- if len(self.recvbuf) < 4 + 12 + 4:
- return
- command = self.recvbuf[4:4+12].split("\x00", 1)[0]
- msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
- checksum = None
- if len(self.recvbuf) < 4 + 12 + 4 + msglen:
- return
- msg = self.recvbuf[4+12+4:4+12+4+msglen]
- self.recvbuf = self.recvbuf[4+12+4+msglen:]
- else:
- if len(self.recvbuf) < 4 + 12 + 4 + 4:
- return
- command = self.recvbuf[4:4+12].split("\x00", 1)[0]
- msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
- checksum = self.recvbuf[4+12+4:4+12+4+4]
- if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
+ try:
+ while True:
+ if len(self.recvbuf) < 4:
return
- msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
- th = sha256(msg)
- h = sha256(th)
- if checksum != h[:4]:
- raise ValueError("got bad checksum " + repr(self.recvbuf))
- self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
- if command in self.messagemap:
- f = cStringIO.StringIO(msg)
- t = self.messagemap[command]()
- t.deserialize(f)
- self.got_message(t)
- else:
- self.show_debug_msg("Unknown command: '" + command + "' " +
- repr(msg))
+ if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]:
+ raise ValueError("got garbage %s" % repr(self.recvbuf))
+ if self.ver_recv < 209:
+ if len(self.recvbuf) < 4 + 12 + 4:
+ return
+ command = self.recvbuf[4:4+12].split(b"\x00", 1)[0]
+ msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
+ checksum = None
+ if len(self.recvbuf) < 4 + 12 + 4 + msglen:
+ return
+ msg = self.recvbuf[4+12+4:4+12+4+msglen]
+ self.recvbuf = self.recvbuf[4+12+4+msglen:]
+ else:
+ if len(self.recvbuf) < 4 + 12 + 4 + 4:
+ return
+ command = self.recvbuf[4:4+12].split(b"\x00", 1)[0]
+ msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
+ checksum = self.recvbuf[4+12+4:4+12+4+4]
+ if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
+ return
+ msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
+ th = sha256(msg)
+ h = sha256(th)
+ if checksum != h[:4]:
+ raise ValueError("got bad checksum " + repr(self.recvbuf))
+ self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
+ if command in self.messagemap:
+ f = BytesIO(msg)
+ t = self.messagemap[command]()
+ t.deserialize(f)
+ self.got_message(t)
+ else:
+ self.show_debug_msg("Unknown command: '" + command + "' " +
+ repr(msg))
+ except Exception as e:
+ print('got_data:', repr(e))
+ # import traceback
+ # traceback.print_tb(sys.exc_info()[2])
def send_message(self, message, pushbuf=False):
if self.state != "connected" and not pushbuf:
@@ -1236,7 +1309,7 @@ class NodeConn(asyncore.dispatcher):
data = message.serialize()
tmsg = self.MAGIC_BYTES[self.network]
tmsg += command
- tmsg += "\x00" * (12 - len(command))
+ tmsg += b"\x00" * (12 - len(command))
tmsg += struct.pack("<I", len(data))
if self.ver_send >= 209:
th = sha256(data)
@@ -1248,11 +1321,11 @@ class NodeConn(asyncore.dispatcher):
self.last_sent = time.time()
def got_message(self, message):
- if message.command == "version":
+ if message.command == b"version":
if message.nVersion <= BIP0031_VERSION:
- self.messagemap['ping'] = msg_ping_prebip31
+ self.messagemap[b'ping'] = msg_ping_prebip31
if self.last_sent + 30 * 60 < time.time():
- self.send_message(self.messagemap['ping']())
+ self.send_message(self.messagemap[b'ping']())
self.show_debug_msg("Recv %s" % repr(message))
self.cb.deliver(self, message)
diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py
index 50daa87937..573b06772d 100644
--- a/qa/rpc-tests/test_framework/netutil.py
+++ b/qa/rpc-tests/test_framework/netutil.py
@@ -1,16 +1,17 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
# Linux network utilities
+
import sys
import socket
import fcntl
import struct
import array
import os
-import binascii
+from binascii import unhexlify, hexlify
# Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
STATE_ESTABLISHED = '01'
@@ -43,9 +44,9 @@ def _remove_empty(array):
def _convert_ip_port(array):
host,port = array.split(':')
# convert host from mangled-per-four-bytes form as used by kernel
- host = binascii.unhexlify(host)
+ host = unhexlify(host)
host_out = ''
- for x in range(0, len(host)/4):
+ for x in range(0, len(host) // 4):
(val,) = struct.unpack('=I', host[x*4:(x+1)*4])
host_out += '%08x' % val
@@ -94,7 +95,7 @@ def all_interfaces():
max_possible = 8 # initial value
while True:
bytes = max_possible * struct_size
- names = array.array('B', '\0' * bytes)
+ names = array.array('B', b'\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
@@ -105,7 +106,7 @@ def all_interfaces():
else:
break
namestr = names.tostring()
- return [(namestr[i:i+16].split('\0', 1)[0],
+ return [(namestr[i:i+16].split(b'\0', 1)[0],
socket.inet_ntoa(namestr[i+20:i+24]))
for i in range(0, outbytes, struct_size)]
@@ -136,4 +137,19 @@ def addr_to_hex(addr):
addr = sub[0] + ([0] * nullbytes) + sub[1]
else:
raise ValueError('Could not parse address %s' % addr)
- return binascii.hexlify(bytearray(addr))
+ return hexlify(bytearray(addr)).decode('ascii')
+
+def test_ipv6_local():
+ '''
+ Check for (local) IPv6 support.
+ '''
+ import socket
+ # By using SOCK_DGRAM this will not actually make a connection, but it will
+ # fail if there is no route to IPv6 localhost.
+ have_ipv6 = True
+ try:
+ s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ s.connect(('::1', 0))
+ except socket.error:
+ have_ipv6 = False
+ return have_ipv6
diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py
index bf5e25fb27..44a894fc8f 100644
--- a/qa/rpc-tests/test_framework/script.py
+++ b/qa/rpc-tests/test_framework/script.py
@@ -1,18 +1,19 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
+
#
# script.py
#
# This file is modified from python-bitcoinlib.
#
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#
"""Scripts
Functionality to build scripts, as well as SignatureHash().
"""
-from __future__ import absolute_import, division, print_function, unicode_literals
from .mininode import CTransaction, CTxOut, hash256
from binascii import hexlify
@@ -629,7 +630,7 @@ class CScriptNum(object):
neg = obj.value < 0
absvalue = -obj.value if neg else obj.value
while (absvalue):
- r.append(chr(absvalue & 0xff))
+ r.append(absvalue & 0xff)
absvalue >>= 8
if r[-1] & 0x80:
r.append(0x80 if neg else 0)
@@ -658,7 +659,7 @@ class CScript(bytes):
other = bchr(CScriptOp(OP_0))
else:
other = CScriptNum.encode(other)
- elif isinstance(other, (int, long)):
+ elif isinstance(other, int):
if 0 <= other <= 16:
other = bytes(bchr(CScriptOp.encode_op_n(other)))
elif other == -1:
@@ -777,7 +778,7 @@ class CScript(bytes):
# need to change
def _repr(o):
if isinstance(o, bytes):
- return "x('%s')" % hexlify(o).decode('utf8')
+ return b"x('%s')" % hexlify(o).decode('ascii')
else:
return repr(o)
diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py
index 1dbfb98d5d..372f5ed605 100644
--- a/qa/rpc-tests/test_framework/socks5.py
+++ b/qa/rpc-tests/test_framework/socks5.py
@@ -1,11 +1,12 @@
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
'''
Dummy Socks5 server for testing.
'''
-from __future__ import print_function, division, unicode_literals
-import socket, threading, Queue
+
+import socket, threading, queue
import traceback, sys
### Protocol constants
@@ -102,7 +103,7 @@ class Socks5Connection(object):
addr = recvall(self.conn, 4)
elif atyp == AddressType.DOMAINNAME:
n = recvall(self.conn, 1)[0]
- addr = str(recvall(self.conn, n))
+ addr = recvall(self.conn, n)
elif atyp == AddressType.IPV6:
addr = recvall(self.conn, 16)
else:
@@ -117,7 +118,7 @@ class Socks5Connection(object):
self.serv.queue.put(cmdin)
print('Proxy: ', cmdin)
# Fall through to disconnect
- except Exception,e:
+ except Exception as e:
traceback.print_exc(file=sys.stderr)
self.serv.queue.put(e)
finally:
@@ -132,7 +133,7 @@ class Socks5Server(object):
self.s.listen(5)
self.running = False
self.thread = None
- self.queue = Queue.Queue() # report connections and exceptions to client
+ self.queue = queue.Queue() # report connections and exceptions to client
def run(self):
while self.running:
diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py
index 584f318d0b..30e8b5755d 100755
--- a/qa/rpc-tests/test_framework/test_framework.py
+++ b/qa/rpc-tests/test_framework/test_framework.py
@@ -1,21 +1,20 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
# Base class for RPC testing
-# Add python-bitcoinrpc to module search path:
+import logging
+import optparse
import os
import sys
-
import shutil
import tempfile
import traceback
from .util import (
initialize_chain,
- assert_equal,
start_nodes,
connect_nodes_bi,
sync_blocks,
@@ -25,27 +24,33 @@ from .util import (
enable_coverage,
check_json_precision,
initialize_chain_clean,
+ PortSeed,
)
-from authproxy import AuthServiceProxy, JSONRPCException
+from .authproxy import JSONRPCException
class BitcoinTestFramework(object):
- # These may be over-ridden by subclasses:
+ def __init__(self):
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+ self.nodes = None
+
def run_test(self):
- for node in self.nodes:
- assert_equal(node.getblockcount(), 200)
- assert_equal(node.getbalance(), 25*50)
+ raise NotImplementedError
def add_options(self, parser):
pass
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
- initialize_chain(self.options.tmpdir)
+ if self.setup_clean_chain:
+ initialize_chain_clean(self.options.tmpdir, self.num_nodes)
+ else:
+ initialize_chain(self.options.tmpdir, self.num_nodes)
def setup_nodes(self):
- return start_nodes(4, self.options.tmpdir)
+ return start_nodes(self.num_nodes, self.options.tmpdir)
def setup_network(self, split = False):
self.nodes = self.setup_nodes()
@@ -95,31 +100,35 @@ class BitcoinTestFramework(object):
self.setup_network(False)
def main(self):
- import optparse
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
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="../../src",
+ parser.add_option("--srcdir", dest="srcdir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__))+"/../../../src"),
help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
help="Root directory for datadirs")
parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
help="Print out all RPC calls as they are made")
+ parser.add_option("--portseed", dest="port_seed", default=os.getpid(), type='int',
+ help="The seed to use for assigning port numbers (default: current process id)")
parser.add_option("--coveragedir", dest="coveragedir",
help="Write tested RPC commands into this directory")
self.add_options(parser)
(self.options, self.args) = parser.parse_args()
+ self.options.tmpdir += '/' + str(self.options.port_seed)
+
if self.options.trace_rpc:
- import logging
- logging.basicConfig(level=logging.DEBUG)
+ logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
if self.options.coveragedir:
enable_coverage(self.options.coveragedir)
+ PortSeed.n = self.options.port_seed
+
os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH']
check_json_precision()
@@ -140,11 +149,16 @@ class BitcoinTestFramework(object):
print("JSONRPC error: "+e.error['message'])
traceback.print_tb(sys.exc_info()[2])
except AssertionError as e:
- print("Assertion failed: "+e.message)
+ print("Assertion failed: " + str(e))
+ traceback.print_tb(sys.exc_info()[2])
+ except KeyError as e:
+ print("key not found: "+ str(e))
traceback.print_tb(sys.exc_info()[2])
except Exception as e:
- print("Unexpected exception caught during testing: "+str(e))
+ print("Unexpected exception caught during testing: " + repr(e))
traceback.print_tb(sys.exc_info()[2])
+ except KeyboardInterrupt as e:
+ print("Exiting after " + repr(e))
if not self.options.noshutdown:
print("Stopping nodes")
@@ -153,9 +167,11 @@ class BitcoinTestFramework(object):
else:
print("Note: bitcoinds were not stopped and may still be running")
- if not self.options.nocleanup and not self.options.noshutdown:
+ if not self.options.nocleanup and not self.options.noshutdown and success:
print("Cleaning up")
shutil.rmtree(self.options.tmpdir)
+ else:
+ print("Not cleaning up dir %s" % self.options.tmpdir)
if success:
print("Tests successful")
@@ -173,9 +189,10 @@ class BitcoinTestFramework(object):
class ComparisonTestFramework(BitcoinTestFramework):
- # Can override the num_nodes variable to indicate how many nodes to run.
def __init__(self):
+ super().__init__()
self.num_nodes = 2
+ self.setup_clean_chain = True
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
@@ -185,10 +202,6 @@ class ComparisonTestFramework(BitcoinTestFramework):
default=os.getenv("BITCOIND", "bitcoind"),
help="bitcoind binary to use for reference nodes (if any)")
- def setup_chain(self):
- print "Initializing test directory "+self.options.tmpdir
- initialize_chain_clean(self.options.tmpdir, self.num_nodes)
-
def setup_network(self):
self.nodes = start_nodes(
self.num_nodes, self.options.tmpdir,
diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py
index 8c472a518d..fc66ef287d 100644
--- a/qa/rpc-tests/test_framework/util.py
+++ b/qa/rpc-tests/test_framework/util.py
@@ -1,27 +1,47 @@
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
+
+
#
# Helpful routines for regression testing
#
-# Add python-bitcoinrpc to module search path:
import os
import sys
+from binascii import hexlify, unhexlify
+from base64 import b64encode
from decimal import Decimal, ROUND_DOWN
import json
+import http.client
import random
import shutil
import subprocess
import time
import re
+import errno
from . import coverage
from .authproxy import AuthServiceProxy, JSONRPCException
COVERAGE_DIR = None
+# The maximum number of nodes a single test can spawn
+MAX_NODES = 8
+# Don't assign rpc or p2p ports lower than this
+PORT_MIN = 11000
+# The number of ports to "reserve" for p2p and rpc, each
+PORT_RANGE = 5000
+
+BITCOIND_PROC_WAIT_TIMEOUT = 60
+
+
+class PortSeed:
+ # Must be initialized with a unique integer for each process
+ n = None
+
#Set Mocktime default to OFF.
#MOCKTIME is only needed for scripts that use the
#cached version of the blockchain. If the cached
@@ -76,9 +96,11 @@ def get_rpc_proxy(url, node_number, timeout=None):
def p2p_port(n):
- return 11000 + n + os.getpid()%999
+ assert(n <= MAX_NODES)
+ return PORT_MIN + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES)
+
def rpc_port(n):
- return 12000 + n + os.getpid()%999
+ return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES)
def check_json_precision():
"""Make sure json library being used does not lose precision converting BTC values"""
@@ -90,30 +112,43 @@ def check_json_precision():
def count_bytes(hex_string):
return len(bytearray.fromhex(hex_string))
-def sync_blocks(rpc_connections, wait=1):
+def bytes_to_hex_str(byte_str):
+ return hexlify(byte_str).decode('ascii')
+
+def hex_str_to_bytes(hex_str):
+ return unhexlify(hex_str.encode('ascii'))
+
+def str_to_b64str(string):
+ return b64encode(string.encode('utf-8')).decode('ascii')
+
+def sync_blocks(rpc_connections, wait=1, timeout=60):
"""
- Wait until everybody has the same block count
+ Wait until everybody has the same tip
"""
- while True:
- counts = [ x.getblockcount() for x in rpc_connections ]
- if counts == [ counts[0] ]*len(counts):
- break
+ while timeout > 0:
+ tips = [ x.getbestblockhash() for x in rpc_connections ]
+ if tips == [ tips[0] ]*len(tips):
+ return True
time.sleep(wait)
+ timeout -= wait
+ raise AssertionError("Block sync failed")
-def sync_mempools(rpc_connections, wait=1):
+def sync_mempools(rpc_connections, wait=1, timeout=60):
"""
Wait until everybody has the same transactions in their memory
pools
"""
- while True:
+ while timeout > 0:
pool = set(rpc_connections[0].getrawmempool())
num_match = 1
for i in range(1, len(rpc_connections)):
if set(rpc_connections[i].getrawmempool()) == pool:
num_match = num_match+1
if num_match == len(rpc_connections):
- break
+ return True
time.sleep(wait)
+ timeout -= wait
+ raise AssertionError("Mempool sync failed")
bitcoind_processes = {}
@@ -130,51 +165,75 @@ def initialize_datadir(dirname, n):
f.write("listenonion=0\n")
return datadir
-def initialize_chain(test_dir):
+def rpc_url(i, rpchost=None):
+ return "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
+
+def wait_for_bitcoind_start(process, url, i):
+ '''
+ Wait for bitcoind to start. This means that RPC is accessible and fully initialized.
+ Raise an exception if bitcoind exits during initialization.
+ '''
+ while True:
+ if process.poll() is not None:
+ raise Exception('bitcoind exited with status %i during initialization' % process.returncode)
+ try:
+ rpc = get_rpc_proxy(url, i)
+ blocks = rpc.getblockcount()
+ break # break out of loop on success
+ except IOError as e:
+ if e.errno != errno.ECONNREFUSED: # Port not yet open?
+ raise # unknown IO error
+ except JSONRPCException as e: # Initialization phase
+ if e.error['code'] != -28: # RPC in warmup?
+ raise # unkown JSON RPC exception
+ time.sleep(0.25)
+
+def initialize_chain(test_dir, num_nodes):
"""
- Create (or copy from cache) a 200-block-long chain and
- 4 wallets.
- bitcoind and bitcoin-cli must be in search path.
+ Create a cache of a 200-block-long chain (with wallet) for MAX_NODES
+ Afterward, create num_nodes copies from the cache
"""
- if (not os.path.isdir(os.path.join("cache","node0"))
- or not os.path.isdir(os.path.join("cache","node1"))
- or not os.path.isdir(os.path.join("cache","node2"))
- or not os.path.isdir(os.path.join("cache","node3"))):
+ assert num_nodes <= MAX_NODES
+ create_cache = False
+ for i in range(MAX_NODES):
+ if not os.path.isdir(os.path.join('cache', 'node'+str(i))):
+ create_cache = True
+ break
+
+ if create_cache:
#find and delete old cache directories if any exist
- for i in range(4):
+ for i in range(MAX_NODES):
if os.path.isdir(os.path.join("cache","node"+str(i))):
shutil.rmtree(os.path.join("cache","node"+str(i)))
- devnull = open(os.devnull, "w")
# Create cache directories, run bitcoinds:
- for i in range(4):
+ for i in range(MAX_NODES):
datadir=initialize_datadir("cache", i)
args = [ os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir="+datadir, "-discover=0" ]
if i > 0:
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
bitcoind_processes[i] = subprocess.Popen(args)
if os.getenv("PYTHON_DEBUG", ""):
- print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
- subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir,
- "-rpcwait", "getblockcount"], stdout=devnull)
+ print("initialize_chain: bitcoind started, waiting for RPC to come up")
+ wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i)
if os.getenv("PYTHON_DEBUG", ""):
- print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed"
- devnull.close()
+ print("initialize_chain: RPC succesfully started")
rpcs = []
-
- for i in range(4):
+ for i in range(MAX_NODES):
try:
- url = "http://rt:rt@127.0.0.1:%d" % (rpc_port(i),)
- rpcs.append(get_rpc_proxy(url, i))
+ rpcs.append(get_rpc_proxy(rpc_url(i), i))
except:
sys.stderr.write("Error connecting to "+url+"\n")
sys.exit(1)
- # Create a 200-block-long chain; each of the 4 nodes
+ # Create a 200-block-long chain; each of the 4 first nodes
# gets 25 mature blocks and 25 immature.
+ # Note: To preserve compatibility with older versions of
+ # initialize_chain, only 4 nodes will generate coins.
+ #
# blocks are created with timestamps 10 minutes apart
# starting from 2010 minutes in the past
enable_mocktime()
@@ -192,13 +251,13 @@ def initialize_chain(test_dir):
stop_nodes(rpcs)
wait_bitcoinds()
disable_mocktime()
- for i in range(4):
+ for i in range(MAX_NODES):
os.remove(log_filename("cache", i, "debug.log"))
os.remove(log_filename("cache", i, "db.log"))
os.remove(log_filename("cache", i, "peers.dat"))
os.remove(log_filename("cache", i, "fee_estimates.dat"))
- for i in range(4):
+ for i in range(num_nodes):
from_dir = os.path.join("cache", "node"+str(i))
to_dir = os.path.join(test_dir, "node"+str(i))
shutil.copytree(from_dir, to_dir)
@@ -243,17 +302,12 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ]
if extra_args is not None: args.extend(extra_args)
bitcoind_processes[i] = subprocess.Popen(args)
- devnull = open(os.devnull, "w")
if os.getenv("PYTHON_DEBUG", ""):
- print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
- subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] +
- _rpchost_to_args(rpchost) +
- ["-rpcwait", "getblockcount"], stdout=devnull)
+ print("start_node: bitcoind started, waiting for RPC to come up")
+ url = rpc_url(i, rpchost)
+ wait_for_bitcoind_start(bitcoind_processes[i], url, i)
if os.getenv("PYTHON_DEBUG", ""):
- print "start_node: calling bitcoin-cli -rpcwait getblockcount returned"
- devnull.close()
- url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
-
+ print("start_node: RPC succesfully started")
proxy = get_rpc_proxy(url, i, timeout=timewait)
if COVERAGE_DIR:
@@ -265,21 +319,34 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
"""
Start multiple bitcoinds, return RPC connections to them
"""
- if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
- if binary is None: binary = [ None for i in range(num_nodes) ]
- return [ start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]) for i in range(num_nodes) ]
+ if extra_args is None: extra_args = [ None for _ in range(num_nodes) ]
+ if binary is None: binary = [ None for _ in range(num_nodes) ]
+ rpcs = []
+ try:
+ for i in range(num_nodes):
+ rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]))
+ except: # If one node failed to start, stop the others
+ stop_nodes(rpcs)
+ raise
+ return rpcs
def log_filename(dirname, n_node, logname):
return os.path.join(dirname, "node"+str(n_node), "regtest", logname)
def stop_node(node, i):
- node.stop()
- bitcoind_processes[i].wait()
+ try:
+ node.stop()
+ except http.client.CannotSendRequest as e:
+ print("WARN: Unable to stop node: " + repr(e))
+ bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT)
del bitcoind_processes[i]
def stop_nodes(nodes):
for node in nodes:
- node.stop()
+ try:
+ node.stop()
+ except http.client.CannotSendRequest as e:
+ print("WARN: Unable to stop node: " + repr(e))
del nodes[:] # Emptying array closes connections as a side effect
def set_node_times(nodes, t):
@@ -289,7 +356,7 @@ def set_node_times(nodes, t):
def wait_bitcoinds():
# Wait for all bitcoinds to cleanly exit
for bitcoind in bitcoind_processes.values():
- bitcoind.wait()
+ bitcoind.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT)
bitcoind_processes.clear()
def connect_nodes(from_connection, node_num):
@@ -436,7 +503,7 @@ def assert_is_hex_string(string):
"Couldn't interpret %r as hexadecimal; raised: %s" % (string, e))
def assert_is_hash_string(string, length=64):
- if not isinstance(string, basestring):
+ if not isinstance(string, str):
raise AssertionError("Expected a string, got type %r" % type(string))
elif length and len(string) != length:
raise AssertionError(
@@ -445,9 +512,40 @@ def assert_is_hash_string(string, length=64):
raise AssertionError(
"String %r contains invalid characters for a hash." % string)
+def assert_array_result(object_array, to_match, expected, should_not_find = False):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ If the should_not_find flag is true, to_match should not be found
+ in object_array
+ """
+ if should_not_find == True:
+ assert_equal(expected, { })
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ elif should_not_find == True:
+ num_matched = num_matched+1
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0 and should_not_find != True:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+ if num_matched > 0 and should_not_find == True:
+ raise AssertionError("Objects were found %s"%(str(to_match)))
+
def satoshi_round(amount):
- return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
+ return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
+# Helper to create at least "count" utxos
+# Pass in a fee that is sufficient for relay and mining new transactions.
def create_confirmed_utxos(fee, node, count):
node.generate(int(0.5*count)+101)
utxos = node.listunspent()
@@ -456,7 +554,7 @@ def create_confirmed_utxos(fee, node, count):
addr2 = node.getnewaddress()
if iterations <= 0:
return utxos
- for i in xrange(iterations):
+ for i in range(iterations):
t = utxos.pop()
inputs = []
inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
@@ -475,16 +573,18 @@ def create_confirmed_utxos(fee, node, count):
assert(len(utxos) >= count)
return utxos
+# Create large OP_RETURN txouts that can be appended to a transaction
+# to make it large (helper for constructing large transactions).
def gen_return_txouts():
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
# So we have big transactions (and therefore can't fit very many into each block)
# create one script_pubkey
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
- for i in xrange (512):
+ for i in range (512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
txouts = "81"
- for k in xrange(128):
+ for k in range(128):
# add txout value
txouts = txouts + "0000000000000000"
# add length of script_pubkey
@@ -493,10 +593,20 @@ def gen_return_txouts():
txouts = txouts + script_pubkey
return txouts
+def create_tx(node, coinbase, to_address, amount):
+ inputs = [{ "txid" : coinbase, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = node.createrawtransaction(inputs, outputs)
+ signresult = node.signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+# Create a spend of each passed-in utxo, splicing in "txouts" to each raw
+# transaction to make it large. See gen_return_txouts() above.
def create_lots_of_big_transactions(node, txouts, utxos, fee):
addr = node.getnewaddress()
txids = []
- for i in xrange(len(utxos)):
+ for i in range(len(utxos)):
t = utxos.pop()
inputs = []
inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
@@ -511,3 +621,7 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee):
txid = node.sendrawtransaction(signresult["hex"], True)
txids.append(txid)
return txids
+
+def get_bip9_status(node, key):
+ info = node.getblockchaininfo()
+ return info['bip9_softforks'][key]
diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py
index b132aec4b6..22f850ece6 100755
--- a/qa/rpc-tests/txn_clone.py
+++ b/qa/rpc-tests/txn_clone.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -12,6 +12,11 @@ from test_framework.util import *
class TxnMallTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
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")
diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py
index 8d7f6e505d..84944c3c19 100755
--- a/qa/rpc-tests/txn_doublespend.py
+++ b/qa/rpc-tests/txn_doublespend.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -12,6 +12,11 @@ from test_framework.util import *
class TxnMallTest(BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+ self.setup_clean_chain = False
+
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")
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index 6cd879e4a0..9dda712f4f 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -19,9 +19,10 @@ class WalletTest (BitcoinTestFramework):
raise AssertionError("Fee of %s BTC too high! (Should be %s BTC)"%(str(fee), str(target_fee)))
return curr_balance
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 4)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 4
def setup_network(self, split=False):
self.nodes = start_nodes(3, self.options.tmpdir)
@@ -32,7 +33,13 @@ class WalletTest (BitcoinTestFramework):
self.sync_all()
def run_test (self):
- print "Mining blocks..."
+
+ # Check that there's no UTXO on none of the nodes
+ assert_equal(len(self.nodes[0].listunspent()), 0)
+ assert_equal(len(self.nodes[1].listunspent()), 0)
+ assert_equal(len(self.nodes[2].listunspent()), 0)
+
+ print("Mining blocks...")
self.nodes[0].generate(1)
@@ -48,6 +55,11 @@ class WalletTest (BitcoinTestFramework):
assert_equal(self.nodes[1].getbalance(), 50)
assert_equal(self.nodes[2].getbalance(), 0)
+ # Check that only first and second nodes have UTXOs
+ assert_equal(len(self.nodes[0].listunspent()), 1)
+ assert_equal(len(self.nodes[1].listunspent()), 1)
+ assert_equal(len(self.nodes[2].listunspent()), 0)
+
# Send 21 BTC from 0 to 2 using sendtoaddress call.
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
@@ -59,6 +71,15 @@ class WalletTest (BitcoinTestFramework):
self.nodes[0].generate(1)
self.sync_all()
+ # Exercise locking of unspent outputs
+ unspent_0 = self.nodes[2].listunspent()[0]
+ unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]}
+ self.nodes[2].lockunspent(False, [unspent_0])
+ assert_raises(JSONRPCException, self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20)
+ assert_equal([unspent_0], self.nodes[2].listlockunspent())
+ self.nodes[2].lockunspent(True, [unspent_0])
+ assert_equal(len(self.nodes[2].listlockunspent()), 0)
+
# Have node1 generate 100 blocks (so node0 can recover the fee)
self.nodes[1].generate(100)
self.sync_all()
@@ -148,6 +169,10 @@ class WalletTest (BitcoinTestFramework):
assert(txid1 in self.nodes[3].getrawmempool())
+ # Exercise balance rpcs
+ 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
@@ -232,47 +257,87 @@ class WalletTest (BitcoinTestFramework):
txObj = self.nodes[0].gettransaction(txId)
assert_equal(txObj['amount'], Decimal('-0.0001'))
- #this should fail
- errorString = ""
try:
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4")
- except JSONRPCException,e:
- errorString = e.error['message']
+ except JSONRPCException as e:
+ assert("Invalid amount" in e.error['message'])
+ else:
+ raise AssertionError("Must not parse invalid amounts")
- assert_equal("Invalid amount" in errorString, True)
- errorString = ""
try:
- self.nodes[0].generate("2") #use a string to as block amount parameter must fail because it's not interpreted as amount
- except JSONRPCException,e:
- errorString = e.error['message']
+ self.nodes[0].generate("2")
+ raise AssertionError("Must not accept strings as numeric")
+ except JSONRPCException as e:
+ assert("not an integer" in e.error['message'])
+
+ # Import address and private key to check correct behavior of spendable unspents
+ # 1. Send some coins to generate new UTXO
+ address_to_import = self.nodes[2].getnewaddress()
+ txid = self.nodes[0].sendtoaddress(address_to_import, 1)
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ # 2. Import address from node2 to node1
+ self.nodes[1].importaddress(address_to_import)
- assert_equal("not an integer" in errorString, True)
+ # 3. Validate that the imported address is watch-only on node1
+ assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"])
- #check if wallet or blochchain maintenance changes the balance
+ # 4. Check that the unspents after import are not spendable
+ assert_array_result(self.nodes[1].listunspent(),
+ {"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)
+ self.nodes[1].importprivkey(priv_key)
+
+ # 6. Check that the unspents are now spendable on node1
+ assert_array_result(self.nodes[1].listunspent(),
+ {"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]
self.sync_all()
- self.nodes[0].generate(1)
+
+ # Check that the txid and balance is found by node1
+ self.nodes[1].gettransaction(cbTxId)
+
+ # check if wallet or blockchain maintenance changes the balance
+ self.sync_all()
+ blocks = self.nodes[0].generate(2)
self.sync_all()
balance_nodes = [self.nodes[i].getbalance() for i in range(3)]
+ block_count = self.nodes[0].getblockcount()
maintenance = [
'-rescan',
'-reindex',
'-zapwallettxes=1',
'-zapwallettxes=2',
- '-salvagewallet',
+ # disabled until issue is fixed: https://github.com/bitcoin/bitcoin/issues/7463
+ # '-salvagewallet',
]
for m in maintenance:
- print "check " + m
+ print("check " + m)
stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3)
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
- self.sync_all()
+ while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]:
+ # reindex will leave rpc warm up "early"; Wait for it to finish
+ time.sleep(0.1)
assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)])
+ # Exercise listsinceblock with the last two blocks
+ coinbase_tx_1 = self.nodes[0].listsinceblock(blocks[0])
+ assert_equal(coinbase_tx_1["lastblock"], blocks[1])
+ assert_equal(len(coinbase_tx_1["transactions"]), 1)
+ assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1])
+ assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0)
if __name__ == '__main__':
- WalletTest ().main ()
+ WalletTest().main()
diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py
index 1221a09116..b991d5c761 100755
--- a/qa/rpc-tests/walletbackup.py
+++ b/qa/rpc-tests/walletbackup.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -37,19 +37,20 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from random import randint
import logging
-logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout)
class WalletBackupTest(BitcoinTestFramework):
- def setup_chain(self):
- logging.info("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 4)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 4
# This mirrors how the network was setup in the bash test
def setup_network(self, split=False):
# nodes 1, 2,3 are spenders, let's give them a keypool=100
extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
- self.nodes = start_nodes(4, self.options.tmpdir, extra_args)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args)
connect_nodes(self.nodes[0], 3)
connect_nodes(self.nodes[1], 3)
connect_nodes(self.nodes[2], 3)
diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py
index 1ee0f79ac0..17ba53a844 100755
--- a/qa/rpc-tests/zapwallettxes.py
+++ b/qa/rpc-tests/zapwallettxes.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2014-2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2014-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.
@@ -9,12 +9,13 @@ from test_framework.util import *
class ZapWalletTXesTest (BitcoinTestFramework):
- def setup_chain(self):
- print("Initializing test directory "+self.options.tmpdir)
- initialize_chain_clean(self.options.tmpdir, 3)
+ def __init__(self):
+ super().__init__()
+ self.setup_clean_chain = True
+ self.num_nodes = 3
def setup_network(self, split=False):
- self.nodes = start_nodes(3, self.options.tmpdir)
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
@@ -22,7 +23,7 @@ class ZapWalletTXesTest (BitcoinTestFramework):
self.sync_all()
def run_test (self):
- print "Mining blocks..."
+ print("Mining blocks...")
self.nodes[0].generate(1)
self.sync_all()
self.nodes[1].generate(101)
@@ -65,14 +66,8 @@ class ZapWalletTXesTest (BitcoinTestFramework):
#restart bitcoind with zapwallettxes
self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
- aException = False
- try:
- tx3 = self.nodes[0].gettransaction(txid3)
- except JSONRPCException,e:
- print e
- aException = True
-
- assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now
+ assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3])
+ #there must be a expection because the unconfirmed wallettx0 must be gone by now
tx0 = self.nodes[0].gettransaction(txid0)
assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed
diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py
index 88532541ab..3a116317fe 100755
--- a/qa/rpc-tests/zmq_test.py
+++ b/qa/rpc-tests/zmq_test.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python2
-# Copyright (c) 2015 The Bitcoin Core developers
+#!/usr/bin/env python3
+# Copyright (c) 2015-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.
@@ -10,28 +10,26 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import zmq
-import binascii
+import struct
-try:
- import http.client as httplib
-except ImportError:
- import httplib
-try:
- import urllib.parse as urlparse
-except ImportError:
- import urlparse
+import http.client
+import urllib.parse
class ZMQTest (BitcoinTestFramework):
+ def __init__(self):
+ super().__init__()
+ self.num_nodes = 4
+
port = 28332
def setup_nodes(self):
self.zmqContext = zmq.Context()
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
- self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock")
- self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx")
+ self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock")
+ self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx")
self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port)
- return start_nodes(4, self.options.tmpdir, extra_args=[
+ return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[
['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)],
[],
[],
@@ -44,15 +42,21 @@ class ZMQTest (BitcoinTestFramework):
genhashes = self.nodes[0].generate(1)
self.sync_all()
- print "listen..."
+ print("listen...")
msg = self.zmqSubSocket.recv_multipart()
- topic = str(msg[0])
+ topic = msg[0]
+ assert_equal(topic, b"hashtx")
body = msg[1]
+ nseq = msg[2]
+ msgSequence = struct.unpack('<I', msg[-1])[-1]
+ assert_equal(msgSequence, 0) #must be sequence 0 on hashtx
msg = self.zmqSubSocket.recv_multipart()
- topic = str(msg[0])
+ topic = msg[0]
body = msg[1]
- blkhash = binascii.hexlify(body)
+ msgSequence = struct.unpack('<I', msg[-1])[-1]
+ assert_equal(msgSequence, 0) #must be sequence 0 on hashblock
+ blkhash = bytes_to_hex_str(body)
assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq
@@ -61,12 +65,16 @@ class ZMQTest (BitcoinTestFramework):
self.sync_all()
zmqHashes = []
+ blockcount = 0
for x in range(0,n*2):
msg = self.zmqSubSocket.recv_multipart()
- topic = str(msg[0])
+ topic = msg[0]
body = msg[1]
- if topic == "hashblock":
- zmqHashes.append(binascii.hexlify(body))
+ if topic == b"hashblock":
+ zmqHashes.append(bytes_to_hex_str(body))
+ msgSequence = struct.unpack('<I', msg[-1])[-1]
+ assert_equal(msgSequence, blockcount+1)
+ blockcount += 1
for x in range(0,n):
assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq
@@ -77,11 +85,13 @@ class ZMQTest (BitcoinTestFramework):
# now we should receive a zmq msg because the tx was broadcast
msg = self.zmqSubSocket.recv_multipart()
- topic = str(msg[0])
+ topic = msg[0]
body = msg[1]
hashZMQ = ""
- if topic == "hashtx":
- hashZMQ = binascii.hexlify(body)
+ if topic == b"hashtx":
+ hashZMQ = bytes_to_hex_str(body)
+ msgSequence = struct.unpack('<I', msg[-1])[-1]
+ assert_equal(msgSequence, blockcount+1)
assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq