Merge #7811: [0.12.2] qa Backports

6862627 Add listunspent() test for spendable/unspendable UTXO (Joao Fonseca)
28ba22c [qa] Remove misleading "errorString syntax" (MarcoFalke)
f1f1b82 [qa] py2: Unfiddle strings into bytes explicitly (MarcoFalke)
c0d9e31 Tests: 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:
MarcoFalke
2016-04-25 14:53:14 +02:00
44 changed files with 564 additions and 574 deletions

View File

@@ -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()

View File

@@ -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

View File

@@ -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):

View File

@@ -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)

View File

@@ -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')

View File

@@ -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)

View File

@@ -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:

View File

@@ -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))

View File

@@ -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 = []