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/bignum.py58
-rwxr-xr-xtest/functional/test_framework/messages.py63
-rwxr-xr-xtest/functional/test_framework/mininode.py20
-rw-r--r--test/functional/test_framework/script.py285
-rw-r--r--test/functional/test_framework/util.py6
5 files changed, 234 insertions, 198 deletions
diff --git a/test/functional/test_framework/bignum.py b/test/functional/test_framework/bignum.py
deleted file mode 100644
index db5ccd62c2..0000000000
--- a/test/functional/test_framework/bignum.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python3
-#
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Big number routines.
-
-This file is copied from python-bitcoinlib.
-"""
-
-import struct
-
-
-# generic big endian MPI format
-
-def bn_bytes(v, have_ext=False):
- ext = 0
- if have_ext:
- ext = 1
- return ((v.bit_length()+7)//8) + ext
-
-def bn2bin(v):
- s = bytearray()
- i = bn_bytes(v)
- while i > 0:
- s.append((v >> ((i-1) * 8)) & 0xff)
- i -= 1
- return s
-
-def bn2mpi(v):
- have_ext = False
- if v.bit_length() > 0:
- have_ext = (v.bit_length() & 0x07) == 0
-
- neg = False
- if v < 0:
- neg = True
- v = -v
-
- s = struct.pack(b">I", bn_bytes(v, have_ext))
- ext = bytearray()
- if have_ext:
- ext.append(0)
- v_bin = bn2bin(v)
- if neg:
- if have_ext:
- ext[0] |= 0x80
- else:
- v_bin[0] |= 0x80
- return s + ext + v_bin
-
-# bitcoin-specific little endian format, with implicit size
-def mpi2vch(s):
- r = s[4:] # strip size
- r = r[::-1] # reverse string, converting BE->LE
- return r
-
-def bn2vch(v):
- return bytes(mpi2vch(bn2mpi(v)))
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 4f7a9a8b13..ff0c763b72 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -39,6 +39,7 @@ MAX_LOCATOR_SZ = 101
MAX_BLOCK_BASE_SIZE = 1000000
COIN = 100000000 # 1 btc in satoshis
+MAX_MONEY = 21000000 * COIN
BIP125_SEQUENCE_NUMBER = 0xfffffffd # Sequence number that is BIP 125 opt-in and BIP 68-opt-out
@@ -50,6 +51,7 @@ NODE_NETWORK_LIMITED = (1 << 10)
MSG_TX = 1
MSG_BLOCK = 2
+MSG_FILTERED_BLOCK = 3
MSG_WITNESS_FLAG = 1 << 30
MSG_TYPE_MASK = 0xffffffff >> 2
@@ -224,10 +226,11 @@ class CInv:
typemap = {
0: "Error",
- 1: "TX",
- 2: "Block",
- 1|MSG_WITNESS_FLAG: "WitnessTx",
- 2|MSG_WITNESS_FLAG : "WitnessBlock",
+ MSG_TX: "TX",
+ MSG_BLOCK: "Block",
+ MSG_TX | MSG_WITNESS_FLAG: "WitnessTx",
+ MSG_BLOCK | MSG_WITNESS_FLAG: "WitnessBlock",
+ MSG_FILTERED_BLOCK: "filtered Block",
4: "CompactBlock"
}
@@ -1317,6 +1320,58 @@ class msg_headers:
return "msg_headers(headers=%s)" % repr(self.headers)
+class msg_merkleblock:
+ command = b"merkleblock"
+
+ def deserialize(self, f):
+ pass # Placeholder for now
+
+
+class msg_filterload:
+ __slots__ = ("data", "nHashFuncs", "nTweak", "nFlags")
+ command = b"filterload"
+
+ def __init__(self, data=b'00', nHashFuncs=0, nTweak=0, nFlags=0):
+ self.data = data
+ self.nHashFuncs = nHashFuncs
+ self.nTweak = nTweak
+ self.nFlags = nFlags
+
+ def deserialize(self, f):
+ self.data = deser_string(f)
+ self.nHashFuncs = struct.unpack("<I", f.read(4))[0]
+ self.nTweak = struct.unpack("<I", f.read(4))[0]
+ self.nFlags = struct.unpack("<B", f.read(1))[0]
+
+ def serialize(self):
+ r = b""
+ r += ser_string(self.data)
+ r += struct.pack("<I", self.nHashFuncs)
+ r += struct.pack("<I", self.nTweak)
+ r += struct.pack("<B", self.nFlags)
+ return r
+
+ def __repr__(self):
+ return "msg_filterload(data={}, nHashFuncs={}, nTweak={}, nFlags={})".format(
+ self.data, self.nHashFuncs, self.nTweak, self.nFlags)
+
+
+class msg_filterclear:
+ __slots__ = ()
+ command = b"filterclear"
+
+ def __init__(self):
+ pass
+
+ def deserialize(self, f):
+ pass
+
+ def serialize(self):
+ return b""
+
+ def __repr__(self):
+ return "msg_filterclear()"
+
class msg_feefilter:
__slots__ = ("feerate",)
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index a9e669fea9..ce51513ce9 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -30,6 +30,8 @@ from test_framework.messages import (
msg_blocktxn,
msg_cmpctblock,
msg_feefilter,
+ msg_filterclear,
+ msg_filterload,
msg_getaddr,
msg_getblocks,
msg_getblocktxn,
@@ -38,6 +40,7 @@ from test_framework.messages import (
msg_headers,
msg_inv,
msg_mempool,
+ msg_merkleblock,
msg_notfound,
msg_ping,
msg_pong,
@@ -62,6 +65,8 @@ MESSAGEMAP = {
b"blocktxn": msg_blocktxn,
b"cmpctblock": msg_cmpctblock,
b"feefilter": msg_feefilter,
+ b"filterclear": msg_filterclear,
+ b"filterload": msg_filterload,
b"getaddr": msg_getaddr,
b"getblocks": msg_getblocks,
b"getblocktxn": msg_getblocktxn,
@@ -70,6 +75,7 @@ MESSAGEMAP = {
b"headers": msg_headers,
b"inv": msg_inv,
b"mempool": msg_mempool,
+ b"merkleblock": msg_merkleblock,
b"notfound": msg_notfound,
b"ping": msg_ping,
b"pong": msg_pong,
@@ -318,6 +324,8 @@ class P2PInterface(P2PConnection):
def on_blocktxn(self, message): pass
def on_cmpctblock(self, message): pass
def on_feefilter(self, message): pass
+ def on_filterclear(self, message): pass
+ def on_filterload(self, message): pass
def on_getaddr(self, message): pass
def on_getblocks(self, message): pass
def on_getblocktxn(self, message): pass
@@ -325,6 +333,7 @@ class P2PInterface(P2PConnection):
def on_getheaders(self, message): pass
def on_headers(self, message): pass
def on_mempool(self, message): pass
+ def on_merkleblock(self, message): pass
def on_notfound(self, message): pass
def on_pong(self, message): pass
def on_reject(self, message): pass
@@ -385,6 +394,17 @@ class P2PInterface(P2PConnection):
wait_until(test_function, timeout=timeout, lock=mininode_lock)
+ def wait_for_merkleblock(self, timeout=60):
+ def test_function():
+ assert self.is_connected
+ last_filtered_block = self.last_message.get('merkleblock')
+ if not last_filtered_block:
+ return False
+ # TODO change this method to take a hash value and only return true if the correct block has been received
+ return True
+
+ wait_until(test_function, timeout=timeout, lock=mininode_lock)
+
def wait_for_getdata(self, timeout=60):
"""Waits for a getdata message.
diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py
index 51aa9057f7..92725dfcf4 100644
--- a/test/functional/test_framework/script.py
+++ b/test/functional/test_framework/script.py
@@ -6,21 +6,35 @@
This file is modified from python-bitcoinlib.
"""
-
-from .messages import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string
-
import hashlib
import struct
-from .bignum import bn2vch
+from .messages import (
+ CTransaction,
+ CTxOut,
+ hash256,
+ ser_string,
+ ser_uint256,
+ sha256,
+ uint256_from_str,
+)
MAX_SCRIPT_ELEMENT_SIZE = 520
-
OPCODE_NAMES = {}
def hash160(s):
return hashlib.new('ripemd160', sha256(s)).digest()
+def bn2vch(v):
+ """Convert number to bitcoin-specific little endian format."""
+ # We need v.bit_length() bits, plus a sign bit for every nonzero number.
+ n_bits = v.bit_length() + (v != 0)
+ # The number of bytes for that is:
+ n_bytes = (n_bits + 7) // 8
+ # Convert number to absolute value + sign in top bit.
+ encoded_v = 0 if v == 0 else abs(v) | ((v < 0) << (n_bytes * 8 - 1))
+ # Serialize to bytes
+ return encoded_v.to_bytes(n_bytes, 'little')
_opcode_instances = []
class CScriptOp(int):
@@ -31,13 +45,13 @@ class CScriptOp(int):
def encode_op_pushdata(d):
"""Encode a PUSHDATA op, returning bytes"""
if len(d) < 0x4c:
- return b'' + bytes([len(d)]) + d # OP_PUSHDATA
+ return b'' + bytes([len(d)]) + d # OP_PUSHDATA
elif len(d) <= 0xff:
- return b'\x4c' + bytes([len(d)]) + d # OP_PUSHDATA1
+ return b'\x4c' + bytes([len(d)]) + d # OP_PUSHDATA1
elif len(d) <= 0xffff:
- return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
+ return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
elif len(d) <= 0xffffffff:
- return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4
+ return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4
else:
raise ValueError("Data too long to encode in a PUSHDATA op")
@@ -50,7 +64,7 @@ class CScriptOp(int):
if n == 0:
return OP_0
else:
- return CScriptOp(OP_1 + n-1)
+ return CScriptOp(OP_1 + n - 1)
def decode_op_n(self):
"""Decode a small integer opcode, returning an integer"""
@@ -60,7 +74,7 @@ class CScriptOp(int):
if not (self == OP_0 or OP_1 <= self <= OP_16):
raise ValueError('op %r is not an OP_N' % self)
- return int(self - OP_1+1)
+ return int(self - OP_1 + 1)
def is_small_int(self):
"""Return true if the op pushes a small integer to the stack"""
@@ -87,7 +101,7 @@ class CScriptOp(int):
return _opcode_instances[n]
# Populate opcode instance table
-for n in range(0xff+1):
+for n in range(0xff + 1):
CScriptOp(n)
@@ -100,7 +114,7 @@ OP_PUSHDATA4 = CScriptOp(0x4e)
OP_1NEGATE = CScriptOp(0x4f)
OP_RESERVED = CScriptOp(0x50)
OP_1 = CScriptOp(0x51)
-OP_TRUE=OP_1
+OP_TRUE = OP_1
OP_2 = CScriptOp(0x52)
OP_3 = CScriptOp(0x53)
OP_4 = CScriptOp(0x54)
@@ -232,122 +246,122 @@ OP_PUBKEY = CScriptOp(0xfe)
OP_INVALIDOPCODE = CScriptOp(0xff)
OPCODE_NAMES.update({
- OP_0 : 'OP_0',
- OP_PUSHDATA1 : 'OP_PUSHDATA1',
- OP_PUSHDATA2 : 'OP_PUSHDATA2',
- OP_PUSHDATA4 : 'OP_PUSHDATA4',
- OP_1NEGATE : 'OP_1NEGATE',
- OP_RESERVED : 'OP_RESERVED',
- OP_1 : 'OP_1',
- OP_2 : 'OP_2',
- OP_3 : 'OP_3',
- OP_4 : 'OP_4',
- OP_5 : 'OP_5',
- OP_6 : 'OP_6',
- OP_7 : 'OP_7',
- OP_8 : 'OP_8',
- OP_9 : 'OP_9',
- OP_10 : 'OP_10',
- OP_11 : 'OP_11',
- OP_12 : 'OP_12',
- OP_13 : 'OP_13',
- OP_14 : 'OP_14',
- OP_15 : 'OP_15',
- OP_16 : 'OP_16',
- OP_NOP : 'OP_NOP',
- OP_VER : 'OP_VER',
- OP_IF : 'OP_IF',
- OP_NOTIF : 'OP_NOTIF',
- OP_VERIF : 'OP_VERIF',
- OP_VERNOTIF : 'OP_VERNOTIF',
- OP_ELSE : 'OP_ELSE',
- OP_ENDIF : 'OP_ENDIF',
- OP_VERIFY : 'OP_VERIFY',
- OP_RETURN : 'OP_RETURN',
- OP_TOALTSTACK : 'OP_TOALTSTACK',
- OP_FROMALTSTACK : 'OP_FROMALTSTACK',
- OP_2DROP : 'OP_2DROP',
- OP_2DUP : 'OP_2DUP',
- OP_3DUP : 'OP_3DUP',
- OP_2OVER : 'OP_2OVER',
- OP_2ROT : 'OP_2ROT',
- OP_2SWAP : 'OP_2SWAP',
- OP_IFDUP : 'OP_IFDUP',
- OP_DEPTH : 'OP_DEPTH',
- OP_DROP : 'OP_DROP',
- OP_DUP : 'OP_DUP',
- OP_NIP : 'OP_NIP',
- OP_OVER : 'OP_OVER',
- OP_PICK : 'OP_PICK',
- OP_ROLL : 'OP_ROLL',
- OP_ROT : 'OP_ROT',
- OP_SWAP : 'OP_SWAP',
- OP_TUCK : 'OP_TUCK',
- OP_CAT : 'OP_CAT',
- OP_SUBSTR : 'OP_SUBSTR',
- OP_LEFT : 'OP_LEFT',
- OP_RIGHT : 'OP_RIGHT',
- OP_SIZE : 'OP_SIZE',
- OP_INVERT : 'OP_INVERT',
- OP_AND : 'OP_AND',
- OP_OR : 'OP_OR',
- OP_XOR : 'OP_XOR',
- OP_EQUAL : 'OP_EQUAL',
- OP_EQUALVERIFY : 'OP_EQUALVERIFY',
- OP_RESERVED1 : 'OP_RESERVED1',
- OP_RESERVED2 : 'OP_RESERVED2',
- OP_1ADD : 'OP_1ADD',
- OP_1SUB : 'OP_1SUB',
- OP_2MUL : 'OP_2MUL',
- OP_2DIV : 'OP_2DIV',
- OP_NEGATE : 'OP_NEGATE',
- OP_ABS : 'OP_ABS',
- OP_NOT : 'OP_NOT',
- OP_0NOTEQUAL : 'OP_0NOTEQUAL',
- OP_ADD : 'OP_ADD',
- OP_SUB : 'OP_SUB',
- OP_MUL : 'OP_MUL',
- OP_DIV : 'OP_DIV',
- OP_MOD : 'OP_MOD',
- OP_LSHIFT : 'OP_LSHIFT',
- OP_RSHIFT : 'OP_RSHIFT',
- OP_BOOLAND : 'OP_BOOLAND',
- OP_BOOLOR : 'OP_BOOLOR',
- OP_NUMEQUAL : 'OP_NUMEQUAL',
- OP_NUMEQUALVERIFY : 'OP_NUMEQUALVERIFY',
- OP_NUMNOTEQUAL : 'OP_NUMNOTEQUAL',
- OP_LESSTHAN : 'OP_LESSTHAN',
- OP_GREATERTHAN : 'OP_GREATERTHAN',
- OP_LESSTHANOREQUAL : 'OP_LESSTHANOREQUAL',
- OP_GREATERTHANOREQUAL : 'OP_GREATERTHANOREQUAL',
- OP_MIN : 'OP_MIN',
- OP_MAX : 'OP_MAX',
- OP_WITHIN : 'OP_WITHIN',
- OP_RIPEMD160 : 'OP_RIPEMD160',
- OP_SHA1 : 'OP_SHA1',
- OP_SHA256 : 'OP_SHA256',
- OP_HASH160 : 'OP_HASH160',
- OP_HASH256 : 'OP_HASH256',
- OP_CODESEPARATOR : 'OP_CODESEPARATOR',
- OP_CHECKSIG : 'OP_CHECKSIG',
- OP_CHECKSIGVERIFY : 'OP_CHECKSIGVERIFY',
- OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
- OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
- OP_NOP1 : 'OP_NOP1',
- OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY',
- OP_CHECKSEQUENCEVERIFY : 'OP_CHECKSEQUENCEVERIFY',
- OP_NOP4 : 'OP_NOP4',
- OP_NOP5 : 'OP_NOP5',
- OP_NOP6 : 'OP_NOP6',
- OP_NOP7 : 'OP_NOP7',
- OP_NOP8 : 'OP_NOP8',
- OP_NOP9 : 'OP_NOP9',
- OP_NOP10 : 'OP_NOP10',
- OP_SMALLINTEGER : 'OP_SMALLINTEGER',
- OP_PUBKEYS : 'OP_PUBKEYS',
- OP_PUBKEYHASH : 'OP_PUBKEYHASH',
- OP_PUBKEY : 'OP_PUBKEY',
- OP_INVALIDOPCODE : 'OP_INVALIDOPCODE',
+ OP_0: 'OP_0',
+ OP_PUSHDATA1: 'OP_PUSHDATA1',
+ OP_PUSHDATA2: 'OP_PUSHDATA2',
+ OP_PUSHDATA4: 'OP_PUSHDATA4',
+ OP_1NEGATE: 'OP_1NEGATE',
+ OP_RESERVED: 'OP_RESERVED',
+ OP_1: 'OP_1',
+ OP_2: 'OP_2',
+ OP_3: 'OP_3',
+ OP_4: 'OP_4',
+ OP_5: 'OP_5',
+ OP_6: 'OP_6',
+ OP_7: 'OP_7',
+ OP_8: 'OP_8',
+ OP_9: 'OP_9',
+ OP_10: 'OP_10',
+ OP_11: 'OP_11',
+ OP_12: 'OP_12',
+ OP_13: 'OP_13',
+ OP_14: 'OP_14',
+ OP_15: 'OP_15',
+ OP_16: 'OP_16',
+ OP_NOP: 'OP_NOP',
+ OP_VER: 'OP_VER',
+ OP_IF: 'OP_IF',
+ OP_NOTIF: 'OP_NOTIF',
+ OP_VERIF: 'OP_VERIF',
+ OP_VERNOTIF: 'OP_VERNOTIF',
+ OP_ELSE: 'OP_ELSE',
+ OP_ENDIF: 'OP_ENDIF',
+ OP_VERIFY: 'OP_VERIFY',
+ OP_RETURN: 'OP_RETURN',
+ OP_TOALTSTACK: 'OP_TOALTSTACK',
+ OP_FROMALTSTACK: 'OP_FROMALTSTACK',
+ OP_2DROP: 'OP_2DROP',
+ OP_2DUP: 'OP_2DUP',
+ OP_3DUP: 'OP_3DUP',
+ OP_2OVER: 'OP_2OVER',
+ OP_2ROT: 'OP_2ROT',
+ OP_2SWAP: 'OP_2SWAP',
+ OP_IFDUP: 'OP_IFDUP',
+ OP_DEPTH: 'OP_DEPTH',
+ OP_DROP: 'OP_DROP',
+ OP_DUP: 'OP_DUP',
+ OP_NIP: 'OP_NIP',
+ OP_OVER: 'OP_OVER',
+ OP_PICK: 'OP_PICK',
+ OP_ROLL: 'OP_ROLL',
+ OP_ROT: 'OP_ROT',
+ OP_SWAP: 'OP_SWAP',
+ OP_TUCK: 'OP_TUCK',
+ OP_CAT: 'OP_CAT',
+ OP_SUBSTR: 'OP_SUBSTR',
+ OP_LEFT: 'OP_LEFT',
+ OP_RIGHT: 'OP_RIGHT',
+ OP_SIZE: 'OP_SIZE',
+ OP_INVERT: 'OP_INVERT',
+ OP_AND: 'OP_AND',
+ OP_OR: 'OP_OR',
+ OP_XOR: 'OP_XOR',
+ OP_EQUAL: 'OP_EQUAL',
+ OP_EQUALVERIFY: 'OP_EQUALVERIFY',
+ OP_RESERVED1: 'OP_RESERVED1',
+ OP_RESERVED2: 'OP_RESERVED2',
+ OP_1ADD: 'OP_1ADD',
+ OP_1SUB: 'OP_1SUB',
+ OP_2MUL: 'OP_2MUL',
+ OP_2DIV: 'OP_2DIV',
+ OP_NEGATE: 'OP_NEGATE',
+ OP_ABS: 'OP_ABS',
+ OP_NOT: 'OP_NOT',
+ OP_0NOTEQUAL: 'OP_0NOTEQUAL',
+ OP_ADD: 'OP_ADD',
+ OP_SUB: 'OP_SUB',
+ OP_MUL: 'OP_MUL',
+ OP_DIV: 'OP_DIV',
+ OP_MOD: 'OP_MOD',
+ OP_LSHIFT: 'OP_LSHIFT',
+ OP_RSHIFT: 'OP_RSHIFT',
+ OP_BOOLAND: 'OP_BOOLAND',
+ OP_BOOLOR: 'OP_BOOLOR',
+ OP_NUMEQUAL: 'OP_NUMEQUAL',
+ OP_NUMEQUALVERIFY: 'OP_NUMEQUALVERIFY',
+ OP_NUMNOTEQUAL: 'OP_NUMNOTEQUAL',
+ OP_LESSTHAN: 'OP_LESSTHAN',
+ OP_GREATERTHAN: 'OP_GREATERTHAN',
+ OP_LESSTHANOREQUAL: 'OP_LESSTHANOREQUAL',
+ OP_GREATERTHANOREQUAL: 'OP_GREATERTHANOREQUAL',
+ OP_MIN: 'OP_MIN',
+ OP_MAX: 'OP_MAX',
+ OP_WITHIN: 'OP_WITHIN',
+ OP_RIPEMD160: 'OP_RIPEMD160',
+ OP_SHA1: 'OP_SHA1',
+ OP_SHA256: 'OP_SHA256',
+ OP_HASH160: 'OP_HASH160',
+ OP_HASH256: 'OP_HASH256',
+ OP_CODESEPARATOR: 'OP_CODESEPARATOR',
+ OP_CHECKSIG: 'OP_CHECKSIG',
+ OP_CHECKSIGVERIFY: 'OP_CHECKSIGVERIFY',
+ OP_CHECKMULTISIG: 'OP_CHECKMULTISIG',
+ OP_CHECKMULTISIGVERIFY: 'OP_CHECKMULTISIGVERIFY',
+ OP_NOP1: 'OP_NOP1',
+ OP_CHECKLOCKTIMEVERIFY: 'OP_CHECKLOCKTIMEVERIFY',
+ OP_CHECKSEQUENCEVERIFY: 'OP_CHECKSEQUENCEVERIFY',
+ OP_NOP4: 'OP_NOP4',
+ OP_NOP5: 'OP_NOP5',
+ OP_NOP6: 'OP_NOP6',
+ OP_NOP7: 'OP_NOP7',
+ OP_NOP8: 'OP_NOP8',
+ OP_NOP9: 'OP_NOP9',
+ OP_NOP10: 'OP_NOP10',
+ OP_SMALLINTEGER: 'OP_SMALLINTEGER',
+ OP_PUBKEYS: 'OP_PUBKEYS',
+ OP_PUBKEYHASH: 'OP_PUBKEYHASH',
+ OP_PUBKEY: 'OP_PUBKEY',
+ OP_INVALIDOPCODE: 'OP_INVALIDOPCODE',
})
class CScriptInvalidError(Exception):
@@ -392,10 +406,10 @@ class CScriptNum:
if len(value) == 0:
return result
for i, byte in enumerate(value):
- result |= int(byte) << 8*i
+ result |= int(byte) << 8 * i
if value[-1] >= 0x80:
# Mask for all but the highest result bit
- num_mask = (2**(len(value)*8) - 1) >> 1
+ num_mask = (2**(len(value) * 8) - 1) >> 1
result &= num_mask
result *= -1
return result
@@ -493,21 +507,20 @@ class CScript(bytes):
pushdata_type = 'PUSHDATA2'
if i + 1 >= len(self):
raise CScriptInvalidError('PUSHDATA2: missing data length')
- datasize = self[i] + (self[i+1] << 8)
+ datasize = self[i] + (self[i + 1] << 8)
i += 2
elif opcode == OP_PUSHDATA4:
pushdata_type = 'PUSHDATA4'
if i + 3 >= len(self):
raise CScriptInvalidError('PUSHDATA4: missing data length')
- datasize = self[i] + (self[i+1] << 8) + (self[i+2] << 16) + (self[i+3] << 24)
+ datasize = self[i] + (self[i + 1] << 8) + (self[i + 2] << 16) + (self[i + 3] << 24)
i += 4
else:
- assert False # shouldn't happen
-
+ assert False # shouldn't happen
- data = bytes(self[i:i+datasize])
+ data = bytes(self[i:i + datasize])
# Check for truncation
if len(data) < datasize:
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 5bb73aee7e..e89b4e9879 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -393,6 +393,7 @@ def connect_nodes(from_connection, node_num):
# with transaction relaying
wait_until(lambda: all(peer['version'] != 0 for peer in from_connection.getpeerinfo()))
+
def sync_blocks(rpc_connections, *, wait=1, timeout=60):
"""
Wait until everybody has the same tip.
@@ -406,9 +407,12 @@ def sync_blocks(rpc_connections, *, wait=1, timeout=60):
best_hash = [x.getbestblockhash() for x in rpc_connections]
if best_hash.count(best_hash[0]) == len(rpc_connections):
return
+ # Check that each peer has at least one connection
+ assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
time.sleep(wait)
raise AssertionError("Block sync timed out:{}".format("".join("\n {!r}".format(b) for b in best_hash)))
+
def sync_mempools(rpc_connections, *, wait=1, timeout=60, flush_scheduler=True):
"""
Wait until everybody has the same transactions in their memory
@@ -422,6 +426,8 @@ def sync_mempools(rpc_connections, *, wait=1, timeout=60, flush_scheduler=True):
for r in rpc_connections:
r.syncwithvalidationinterfacequeue()
return
+ # Check that each peer has at least one connection
+ assert (all([len(x.getpeerinfo()) for x in rpc_connections]))
time.sleep(wait)
raise AssertionError("Mempool sync timed out:{}".format("".join("\n {!r}".format(m) for m in pool)))