aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_framework
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/test_framework')
-rw-r--r--test/functional/test_framework/blocktools.py6
-rw-r--r--test/functional/test_framework/descriptors.py55
-rwxr-xr-xtest/functional/test_framework/test_framework.py2
-rwxr-xr-xtest/functional/test_framework/test_node.py10
-rw-r--r--test/functional/test_framework/util.py4
5 files changed, 71 insertions, 6 deletions
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index 6b47cae4c3..15f4502994 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2015-2018 The Bitcoin Core developers
+# Copyright (c) 2015-2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Utilities for manipulating blocks and transactions."""
@@ -43,9 +43,13 @@ from io import BytesIO
MAX_BLOCK_SIGOPS = 20000
+# Genesis block time (regtest)
+TIME_GENESIS_BLOCK = 1296688602
+
# From BIP141
WITNESS_COMMITMENT_HEADER = b"\xaa\x21\xa9\xed"
+
def create_block(hashprev, coinbase, ntime=None, *, version=1):
"""Create a block (with regtest difficulty)."""
block = CBlock()
diff --git a/test/functional/test_framework/descriptors.py b/test/functional/test_framework/descriptors.py
new file mode 100644
index 0000000000..29482ce01e
--- /dev/null
+++ b/test/functional/test_framework/descriptors.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019 Pieter Wuille
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Utility functions related to output descriptors"""
+
+INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
+CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]
+
+def descsum_polymod(symbols):
+ """Internal function that computes the descriptor checksum."""
+ chk = 1
+ for value in symbols:
+ top = chk >> 35
+ chk = (chk & 0x7ffffffff) << 5 ^ value
+ for i in range(5):
+ chk ^= GENERATOR[i] if ((top >> i) & 1) else 0
+ return chk
+
+def descsum_expand(s):
+ """Internal function that does the character to symbol expansion"""
+ groups = []
+ symbols = []
+ for c in s:
+ if not c in INPUT_CHARSET:
+ return None
+ v = INPUT_CHARSET.find(c)
+ symbols.append(v & 31)
+ groups.append(v >> 5)
+ if len(groups) == 3:
+ symbols.append(groups[0] * 9 + groups[1] * 3 + groups[2])
+ groups = []
+ if len(groups) == 1:
+ symbols.append(groups[0])
+ elif len(groups) == 2:
+ symbols.append(groups[0] * 3 + groups[1])
+ return symbols
+
+def descsum_create(s):
+ """Add a checksum to a descriptor without"""
+ symbols = descsum_expand(s) + [0, 0, 0, 0, 0, 0, 0, 0]
+ checksum = descsum_polymod(symbols) ^ 1
+ return s + '#' + ''.join(CHECKSUM_CHARSET[(checksum >> (5 * (7 - i))) & 31] for i in range(8))
+
+def descsum_check(s, require=True):
+ """Verify that the checksum is correct in a descriptor"""
+ if not '#' in s:
+ return not require
+ if s[-9] != '#':
+ return False
+ if not all(x in CHECKSUM_CHARSET for x in s[-8:]):
+ return False
+ symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]
+ return descsum_polymod(symbols) == 1
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 8c4c0d7226..869b36673e 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -318,6 +318,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
bitcoin_cli=self.options.bitcoincli,
mocktime=self.mocktime,
coverage_dir=self.options.coveragedir,
+ cwd=self.options.tmpdir,
extra_conf=extra_confs[i],
extra_args=extra_args[i],
use_cli=self.options.usecli,
@@ -469,6 +470,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
bitcoin_cli=self.options.bitcoincli,
mocktime=self.mocktime,
coverage_dir=None,
+ cwd=self.options.tmpdir,
))
self.nodes[i].args = args
self.start_node(i)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 999ea68254..352774914d 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -61,7 +61,7 @@ class TestNode():
To make things easier for the test writer, any unrecognised messages will
be dispatched to the RPC connection."""
- def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False, start_perf=False):
+ def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False):
"""
Kwargs:
start_perf (bool): If True, begin profiling the node with `perf` as soon as
@@ -76,6 +76,7 @@ class TestNode():
self.rpc_timeout = timewait
self.binary = bitcoind
self.coverage_dir = coverage_dir
+ self.cwd = cwd
if extra_conf is not None:
append_config(datadir, extra_conf)
# Most callers will just need to add extra args to the standard list below.
@@ -171,7 +172,7 @@ class TestNode():
assert self.rpc_connected and self.rpc is not None, self._node_msg("Error: no RPC connection")
return getattr(self.rpc, name)
- def start(self, extra_args=None, *, stdout=None, stderr=None, **kwargs):
+ def start(self, extra_args=None, *, cwd=None, stdout=None, stderr=None, **kwargs):
"""Start the node."""
if extra_args is None:
extra_args = self.extra_args
@@ -184,6 +185,9 @@ class TestNode():
self.stderr = stderr
self.stdout = stdout
+ if cwd is None:
+ cwd = self.cwd
+
# Delete any existing cookie file -- if such a file exists (eg due to
# unclean shutdown), it will get overwritten anyway by bitcoind, and
# potentially interfere with our attempt to authenticate
@@ -192,7 +196,7 @@ class TestNode():
# add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
- self.process = subprocess.Popen(self.args + extra_args, env=subp_env, stdout=stdout, stderr=stderr, **kwargs)
+ self.process = subprocess.Popen(self.args + extra_args, env=subp_env, stdout=stdout, stderr=stderr, cwd=cwd, **kwargs)
self.running = True
self.log.debug("bitcoind started, waiting for RPC to come up")
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index d0a78d8dfd..fef9982412 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -410,12 +410,12 @@ def sync_mempools(rpc_connections, *, wait=1, timeout=60, flush_scheduler=True):
# Transaction/Block functions
#############################
-def find_output(node, txid, amount):
+def find_output(node, txid, amount, *, blockhash=None):
"""
Return index to output of txid with value amount
Raises exception if there is none.
"""
- txdata = node.getrawtransaction(txid, 1)
+ txdata = node.getrawtransaction(txid, 1, blockhash)
for i in range(len(txdata["vout"])):
if txdata["vout"][i]["value"] == amount:
return i