Merge #7811: [0.12.2] qa Backports
6862627Add listunspent() test for spendable/unspendable UTXO (Joao Fonseca)28ba22c[qa] Remove misleading "errorString syntax" (MarcoFalke)f1f1b82[qa] py2: Unfiddle strings into bytes explicitly (MarcoFalke)c0d9e31Tests: make prioritise_transaction.py more robust (Suhas Daftuar)ff9b436[qa] Bug fixes and refactor (MarcoFalke)b1dd64b[qa] wallet: Wait for reindex to catch up (MarcoFalke)f23cb7c[qa] Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke)3316552[qa] Test walletpassphrase timeout (MarcoFalke)6aae129[qa] wallet: Print maintenance (MarcoFalke)ad8c743[qa] Extend tests (MarcoFalke)d89fbfe[qa] rpc-test: Normalize assert() (MarcoFalke)
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
# and for constructing a getheaders message
|
||||
#
|
||||
|
||||
from mininode import *
|
||||
from .mininode import *
|
||||
import dbm
|
||||
from io import BytesIO
|
||||
|
||||
class BlockStore(object):
|
||||
def __init__(self, datadir):
|
||||
@@ -21,7 +22,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()
|
||||
@@ -115,7 +116,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()
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# 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
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
# 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
|
||||
@@ -45,7 +45,7 @@ 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 +111,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):
|
||||
|
||||
@@ -20,11 +20,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 +34,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.2/"
|
||||
|
||||
MAX_INV_SZ = 50000
|
||||
MAX_BLOCK_SIZE = 1000000
|
||||
|
||||
COIN = 100000000L # 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)
|
||||
@@ -73,12 +76,12 @@ def deser_string(f):
|
||||
|
||||
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
|
||||
return struct.pack("<BH", 253, 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("<BI", 254, len(s)) + s
|
||||
return struct.pack("<BQ", 255, len(s)) + s
|
||||
|
||||
|
||||
def deser_uint256(f):
|
||||
@@ -128,15 +131,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))
|
||||
r = struct.pack("<BH", 253, len(l))
|
||||
elif len(l) < 0x100000000L:
|
||||
r = chr(254) + struct.pack("<I", len(l))
|
||||
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
|
||||
@@ -158,15 +161,15 @@ def deser_uint256_vector(f):
|
||||
|
||||
|
||||
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))
|
||||
r = struct.pack("<BH", 253, len(l))
|
||||
elif len(l) < 0x100000000L:
|
||||
r = chr(254) + struct.pack("<I", len(l))
|
||||
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
|
||||
@@ -190,13 +193,13 @@ def deser_string_vector(f):
|
||||
def ser_string_vector(l):
|
||||
r = ""
|
||||
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))
|
||||
r = struct.pack("<BH", 253, len(l))
|
||||
elif len(l) < 0x100000000L:
|
||||
r = chr(254) + struct.pack("<I", len(l))
|
||||
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
|
||||
@@ -218,34 +221,34 @@ def deser_int_vector(f):
|
||||
|
||||
|
||||
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))
|
||||
r = struct.pack("<BH", 253, len(l))
|
||||
elif len(l) < 0x100000000L:
|
||||
r = chr(254) + struct.pack("<I", len(l))
|
||||
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 +259,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)
|
||||
@@ -283,7 +286,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 +306,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 +326,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 +336,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 +351,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 +359,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 +373,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 +410,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 +424,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 +474,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 +485,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 +493,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 +516,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
|
||||
@@ -568,9 +571,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 +591,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,8 +616,8 @@ 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)
|
||||
@@ -633,12 +636,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 +672,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 +691,7 @@ class msg_version(object):
|
||||
|
||||
|
||||
class msg_verack(object):
|
||||
command = "verack"
|
||||
command = b"verack"
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -697,14 +700,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 +723,7 @@ class msg_addr(object):
|
||||
|
||||
|
||||
class msg_alert(object):
|
||||
command = "alert"
|
||||
command = b"alert"
|
||||
|
||||
def __init__(self):
|
||||
self.alert = CAlert()
|
||||
@@ -730,7 +733,7 @@ class msg_alert(object):
|
||||
self.alert.deserialize(f)
|
||||
|
||||
def serialize(self):
|
||||
r = ""
|
||||
r = b""
|
||||
r += self.alert.serialize()
|
||||
return r
|
||||
|
||||
@@ -739,7 +742,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 +761,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,7 +777,7 @@ class msg_getdata(object):
|
||||
|
||||
|
||||
class msg_getblocks(object):
|
||||
command = "getblocks"
|
||||
command = b"getblocks"
|
||||
|
||||
def __init__(self):
|
||||
self.locator = CBlockLocator()
|
||||
@@ -786,7 +789,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 +800,7 @@ class msg_getblocks(object):
|
||||
|
||||
|
||||
class msg_tx(object):
|
||||
command = "tx"
|
||||
command = b"tx"
|
||||
|
||||
def __init__(self, tx=CTransaction()):
|
||||
self.tx = tx
|
||||
@@ -813,7 +816,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 +835,7 @@ class msg_block(object):
|
||||
|
||||
|
||||
class msg_getaddr(object):
|
||||
command = "getaddr"
|
||||
command = b"getaddr"
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -841,14 +844,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,14 +860,14 @@ 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):
|
||||
self.nonce = nonce
|
||||
@@ -873,7 +876,7 @@ class msg_ping(object):
|
||||
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 +885,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 +903,7 @@ class msg_pong(object):
|
||||
|
||||
|
||||
class msg_mempool(object):
|
||||
command = "mempool"
|
||||
command = b"mempool"
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -909,13 +912,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 +927,7 @@ class msg_sendheaders(object):
|
||||
pass
|
||||
|
||||
def serialize(self):
|
||||
return ""
|
||||
return b""
|
||||
|
||||
def __repr__(self):
|
||||
return "msg_sendheaders()"
|
||||
@@ -934,7 +937,7 @@ 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()
|
||||
@@ -946,7 +949,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 +962,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,11 +982,11 @@ class msg_headers(object):
|
||||
|
||||
|
||||
class msg_reject(object):
|
||||
command = "reject"
|
||||
command = b"reject"
|
||||
|
||||
def __init__(self):
|
||||
self.message = ""
|
||||
self.code = ""
|
||||
self.message = b""
|
||||
self.code = 0
|
||||
self.reason = ""
|
||||
self.data = 0L
|
||||
|
||||
@@ -1006,7 +1009,6 @@ class msg_reject(object):
|
||||
return "msg_reject: %s %d %s [%064x]" \
|
||||
% (self.message, self.code, self.reason, self.data)
|
||||
|
||||
|
||||
# This is what a callback should look like for NodeConn
|
||||
# Reimplement the on_* functions to provide handling for events
|
||||
class NodeConnCB(object):
|
||||
@@ -1088,27 +1090,27 @@ class NodeConnCB(object):
|
||||
# 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,
|
||||
}
|
||||
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 +1119,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
|
||||
@@ -1155,8 +1157,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 +1192,46 @@ 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:
|
||||
try:
|
||||
while True:
|
||||
if len(self.recvbuf) < 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:
|
||||
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)
|
||||
|
||||
def send_message(self, message, pushbuf=False):
|
||||
if self.state != "connected" and not pushbuf:
|
||||
@@ -1236,7 +1241,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 +1253,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)
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
# 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,4 @@ 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')
|
||||
|
||||
@@ -629,7 +629,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)
|
||||
@@ -777,7 +777,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)
|
||||
|
||||
|
||||
@@ -102,7 +102,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 +117,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:
|
||||
|
||||
@@ -26,7 +26,7 @@ from .util import (
|
||||
check_json_precision,
|
||||
initialize_chain_clean,
|
||||
)
|
||||
from authproxy import AuthServiceProxy, JSONRPCException
|
||||
from .authproxy import AuthServiceProxy, JSONRPCException
|
||||
|
||||
|
||||
class BitcoinTestFramework(object):
|
||||
@@ -140,7 +140,7 @@ 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 Exception as e:
|
||||
print("Unexpected exception caught during testing: "+str(e))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright (c) 2014-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.
|
||||
|
||||
|
||||
#
|
||||
# Helpful routines for regression testing
|
||||
#
|
||||
@@ -9,6 +11,8 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
from base64 import b64encode
|
||||
from decimal import Decimal, ROUND_DOWN
|
||||
import json
|
||||
import random
|
||||
@@ -70,6 +74,15 @@ def check_json_precision():
|
||||
def count_bytes(hex_string):
|
||||
return len(bytearray.fromhex(hex_string))
|
||||
|
||||
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):
|
||||
"""
|
||||
Wait until everybody has the same block count
|
||||
@@ -424,9 +437,40 @@ def assert_is_hash_string(string, length=64):
|
||||
raise AssertionError(
|
||||
"String %r contains invalid characters for a hash." % string)
|
||||
|
||||
def satoshi_round(amount):
|
||||
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
|
||||
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:
|
||||
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)
|
||||
|
||||
# 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()
|
||||
@@ -454,6 +498,8 @@ 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)
|
||||
@@ -472,6 +518,16 @@ 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 = []
|
||||
|
||||
Reference in New Issue
Block a user