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
commit 89ae85484c
No known key found for this signature in database
GPG Key ID: 2D7F2372E50FE137
44 changed files with 564 additions and 574 deletions

View File

@ -32,13 +32,13 @@ import re
from tests_config import * from tests_config import *
#If imported values are not defined then set to zero (or disabled) #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 ENABLE_WALLET=0
if not vars().has_key('ENABLE_BITCOIND'): if 'ENABLE_BITCOIND' not in vars():
ENABLE_BITCOIND=0 ENABLE_BITCOIND=0
if not vars().has_key('ENABLE_UTILS'): if 'ENABLE_UTILS' not in vars():
ENABLE_UTILS=0 ENABLE_UTILS=0
if not vars().has_key('ENABLE_ZMQ'): if 'ENABLE_ZMQ' not in vars():
ENABLE_ZMQ=0 ENABLE_ZMQ=0
ENABLE_COVERAGE=0 ENABLE_COVERAGE=0

View File

@ -10,8 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP
from binascii import unhexlify from io import BytesIO
import cStringIO
import time import time
def cltv_invalidate(tx): def cltv_invalidate(tx):
@ -60,7 +59,7 @@ class BIP65Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs) rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx) signresult = node.signrawtransaction(rawtx)
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex'])) f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f) tx.deserialize(f)
return tx return tx
@ -70,7 +69,7 @@ class BIP65Test(ComparisonTestFramework):
height = 3 # height of the next block to build 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() + "L", 0)
self.nodeaddress = self.nodes[0].getnewaddress() self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = time.time() self.last_block_time = int(time.time())
''' 98 more version 3 blocks ''' ''' 98 more version 3 blocks '''
test_blocks = [] test_blocks = []

View File

@ -10,8 +10,7 @@ from test_framework.mininode import ToHex, CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager from test_framework.comptool import TestInstance, TestManager
from test_framework.script import * from test_framework.script import *
from binascii import unhexlify from io import BytesIO
import cStringIO
import time import time
''' '''
@ -119,7 +118,7 @@ class BIP68_112_113Test(ComparisonTestFramework):
outputs = { to_address : amount } outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs) rawtx = node.createrawtransaction(inputs, outputs)
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(rawtx)) f = BytesIO(hex_str_to_bytes(rawtx))
tx.deserialize(f) tx.deserialize(f)
return tx return tx
@ -127,7 +126,7 @@ class BIP68_112_113Test(ComparisonTestFramework):
rawtx = ToHex(unsignedtx) rawtx = ToHex(unsignedtx)
signresult = node.signrawtransaction(rawtx) signresult = node.signrawtransaction(rawtx)
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex'])) f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f) tx.deserialize(f)
return tx return tx

View File

@ -13,7 +13,6 @@ from test_framework.script import *
from test_framework.mininode import * from test_framework.mininode import *
from test_framework.blocktools import * from test_framework.blocktools import *
COIN = 100000000
SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31)
SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height) SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height)
SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift

View File

@ -10,8 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP from test_framework.script import CScript, OP_1NEGATE, OP_NOP3, OP_DROP
from binascii import hexlify, unhexlify from io import BytesIO
import cStringIO
import time import time
import itertools import itertools
@ -30,7 +29,6 @@ test that enforcement has triggered
''' '''
class BIP9SoftForksTest(ComparisonTestFramework): class BIP9SoftForksTest(ComparisonTestFramework):
def __init__(self): def __init__(self):
@ -53,15 +51,15 @@ class BIP9SoftForksTest(ComparisonTestFramework):
outputs = { to_address : amount } outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs) rawtx = node.createrawtransaction(inputs, outputs)
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(rawtx)) f = BytesIO(hex_str_to_bytes(rawtx))
tx.deserialize(f) tx.deserialize(f)
tx.nVersion = 2 tx.nVersion = 2
return tx return tx
def sign_transaction(self, node, tx): def sign_transaction(self, node, tx):
signresult = node.signrawtransaction(hexlify(tx.serialize())) signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize()))
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex'])) f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f) tx.deserialize(f)
return tx return tx
@ -184,7 +182,6 @@ class BIP9SoftForksTest(ComparisonTestFramework):
NetworkThread().start() # Start up network handling in another thread NetworkThread().start() # Start up network handling in another thread
def get_tests(self): def get_tests(self):
for test in itertools.chain( for test in itertools.chain(
self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing), self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing),

View File

@ -10,8 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript from test_framework.script import CScript
from binascii import unhexlify from io import BytesIO
import cStringIO
import time import time
# A canonical signature consists of: # A canonical signature consists of:
@ -25,7 +24,7 @@ def unDERify(tx):
newscript = [] newscript = []
for i in scriptSig: for i in scriptSig:
if (len(newscript) == 0): if (len(newscript) == 0):
newscript.append(i[0:-1] + '\0' + i[-1]) newscript.append(i[0:-1] + b'\0' + i[-1:])
else: else:
newscript.append(i) newscript.append(i)
tx.vin[0].scriptSig = CScript(newscript) tx.vin[0].scriptSig = CScript(newscript)
@ -68,7 +67,7 @@ class BIP66Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs) rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx) signresult = node.signrawtransaction(rawtx)
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex'])) f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f) tx.deserialize(f)
return tx return tx
@ -78,7 +77,7 @@ class BIP66Test(ComparisonTestFramework):
height = 3 # height of the next block to build 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() + "L", 0)
self.nodeaddress = self.nodes[0].getnewaddress() self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = time.time() self.last_block_time = int(time.time())
''' 98 more version 2 blocks ''' ''' 98 more version 2 blocks '''
test_blocks = [] test_blocks = []

View File

@ -28,6 +28,7 @@ class BlockchainTest(BitcoinTestFramework):
Test blockchain-related RPC calls: Test blockchain-related RPC calls:
- gettxoutsetinfo - gettxoutsetinfo
- verifychain
""" """
@ -44,6 +45,7 @@ class BlockchainTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
self._test_gettxoutsetinfo() self._test_gettxoutsetinfo()
self._test_getblockheader() self._test_getblockheader()
self.nodes[0].verifychain(4, 0)
def _test_gettxoutsetinfo(self): def _test_gettxoutsetinfo(self):
node = self.nodes[0] node = self.nodes[0]

View File

@ -6,8 +6,7 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import * from test_framework.mininode import *
from binascii import hexlify, unhexlify from io import BytesIO
from cStringIO import StringIO
class DecodeScriptTest(BitcoinTestFramework): class DecodeScriptTest(BitcoinTestFramework):
"""Tests decoding scripts via RPC command "decodescript".""" """Tests decoding scripts via RPC command "decodescript"."""
@ -131,7 +130,7 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) 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']) assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
txSave = CTransaction() 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 # 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' tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
@ -147,7 +146,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# some more full transaction tests of varying specific scriptSigs. used instead of # some more full transaction tests of varying specific scriptSigs. used instead of
# tests in decodescript_script_sig because the decodescript RPC is specifically # tests in decodescript_script_sig because the decodescript RPC is specifically
# for working on scriptPubKeys (argh!). # 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:] signature = push_signature[2:]
der_signature = signature[:-2] der_signature = signature[:-2]
signature_sighash_decoded = der_signature + '[ALL]' signature_sighash_decoded = der_signature + '[ALL]'
@ -156,25 +155,24 @@ class DecodeScriptTest(BitcoinTestFramework):
signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]' signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
# 1) P2PK scriptSig # 1) P2PK scriptSig
txSave.vin[0].scriptSig = unhexlify(push_signature) txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) 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. # make sure that the sighash decodes come out correctly for a more complex / lesser used case.
txSave.vin[0].scriptSig = unhexlify(push_signature_2) txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 2) multisig scriptSig # 2) multisig scriptSig
txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2) txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature + push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) 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']) 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. # 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. # 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') txSave.vin[0].scriptSig = hex_str_to_bytes('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
print(hexlify('636174'))
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm']) assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self): def run_test(self):

View File

@ -48,7 +48,7 @@ class RawTransactionsTest(BitcoinTestFramework):
watchonly_address = self.nodes[0].getnewaddress() watchonly_address = self.nodes[0].getnewaddress()
watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
watchonly_amount = 200 watchonly_amount = Decimal(200)
self.nodes[3].importpubkey(watchonly_pubkey, "", True) self.nodes[3].importpubkey(watchonly_pubkey, "", True)
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
@ -71,7 +71,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee'] fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) 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 # # simple test with two coins #
@ -84,7 +84,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee'] fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) 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 # # simple test with two coins #
@ -97,7 +97,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee'] fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) 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'], '') assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@ -116,7 +116,7 @@ class RawTransactionsTest(BitcoinTestFramework):
for out in dec_tx['vout']: for out in dec_tx['vout']:
totalOut += out['value'] 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'], '') assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@ -130,7 +130,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx utx = aUtx
break break
assert_equal(utx!=False, True) assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 } outputs = { self.nodes[0].getnewaddress() : 1.0 }
@ -148,7 +148,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
##################################################################### #####################################################################
# test a fundrawtransaction with which will not get a change output # # test a fundrawtransaction with which will not get a change output #
##################################################################### #####################################################################
@ -159,7 +158,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx utx = aUtx
break break
assert_equal(utx!=False, True) assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance } outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
@ -178,7 +177,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
######################################################################### #########################################################################
# test a fundrawtransaction with a VIN smaller than the required amount # # test a fundrawtransaction with a VIN smaller than the required amount #
######################################################################### #########################################################################
@ -189,7 +187,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx = aUtx utx = aUtx
break break
assert_equal(utx!=False, True) assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 } outputs = { self.nodes[0].getnewaddress() : 1.0 }
@ -209,7 +207,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for i, out in enumerate(dec_tx['vout']): for i, out in enumerate(dec_tx['vout']):
totalOut += out['value'] totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]): if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1 matchingOuts+=1
else: else:
assert_equal(i, rawtxfund['changepos']) assert_equal(i, rawtxfund['changepos'])
@ -234,7 +232,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx utx2 = aUtx
assert_equal(utx!=False, True) assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0 } outputs = { self.nodes[0].getnewaddress() : 6.0 }
@ -249,7 +247,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for out in dec_tx['vout']: for out in dec_tx['vout']:
totalOut += out['value'] totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]): if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1 matchingOuts+=1
assert_equal(matchingOuts, 1) assert_equal(matchingOuts, 1)
@ -276,7 +274,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx utx2 = aUtx
assert_equal(utx!=False, True) assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] 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 } outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
@ -291,7 +289,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for out in dec_tx['vout']: for out in dec_tx['vout']:
totalOut += out['value'] totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]): if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1 matchingOuts+=1
assert_equal(matchingOuts, 2) assert_equal(matchingOuts, 2)
@ -306,14 +304,11 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx) dec_tx = self.nodes[2].decoderawtransaction(rawtx)
errorString = ""
try: try:
rawtxfund = self.nodes[2].fundrawtransaction(rawtx) rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
except JSONRPCException,e: raise AssertionError("Spent more than available")
errorString = e.error['message'] except JSONRPCException as e:
assert("Insufficient" in e.error['message'])
assert("Insufficient" in errorString)
############################################################ ############################################################
@ -462,12 +457,11 @@ class RawTransactionsTest(BitcoinTestFramework):
self.is_network_split=False self.is_network_split=False
self.sync_all() self.sync_all()
error = False
try: try:
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2)
except: raise AssertionError("Wallet unlocked without passphrase")
error = True except JSONRPCException as e:
assert(error) assert('walletpassphrase' in e.error['message'])
oldBalance = self.nodes[0].getbalance() oldBalance = self.nodes[0].getbalance()
@ -488,7 +482,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance()) assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
############################################### ###############################################
# multiple (~19) inputs tx test | Compare fee # # multiple (~19) inputs tx test | Compare fee #
############################################### ###############################################
@ -580,7 +573,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(len(res_dec["vin"]), 1) assert_equal(len(res_dec["vin"]), 1)
assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) 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) assert_greater_than(result["changepos"], -1)
############################################################### ###############################################################

View File

@ -6,28 +6,6 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * 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 import threading
class LongpollThread(threading.Thread): class LongpollThread(threading.Thread):

View File

@ -10,28 +10,6 @@ from binascii import a2b_hex, b2a_hex
from hashlib import sha256 from hashlib import sha256
from struct import pack 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): def b2x(b):
return b2a_hex(b).decode('ascii') return b2a_hex(b).decode('ascii')
@ -120,10 +98,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 3: Truncated final tx # Test 3: Truncated final tx
lastbyte = txlist[-1].pop() lastbyte = txlist[-1].pop()
try: assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
assert_template(node, tmpl, txlist, 'n/a')
except JSONRPCException:
pass # Expected
txlist[-1].append(lastbyte) txlist[-1].append(lastbyte)
# Test 4: Add an invalid tx to the end (duplicate of gen tx) # Test 4: Add an invalid tx to the end (duplicate of gen tx)
@ -133,7 +108,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 5: Add an invalid tx to the end (non-duplicate) # Test 5: Add an invalid tx to the end (non-duplicate)
txlist.append(bytearray(txlist[0])) 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') assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
txlist.pop() txlist.pop()
@ -144,10 +119,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 7: Bad tx count # Test 7: Bad tx count
txlist.append(b'') txlist.append(b'')
try: assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
assert_template(node, tmpl, txlist, 'n/a')
except JSONRPCException:
pass # Expected
txlist.pop() txlist.pop()
# Test 8: Bad bits # Test 8: Bad bits

View File

@ -9,7 +9,6 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
import base64
try: try:
import http.client as httplib import http.client as httplib
@ -31,71 +30,71 @@ class HTTPBasicsTest (BitcoinTestFramework):
################################################# #################################################
url = urlparse.urlparse(self.nodes[0].url) url = urlparse.urlparse(self.nodes[0].url)
authpair = url.username + ':' + url.password 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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read() out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) assert('"error":null' in out1)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection #send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers) conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read() out2 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert('"error":null' in out1) #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! assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close() conn.close()
#same should be if we add keep-alive because this should be the std. behaviour #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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read() out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) assert('"error":null' in out1)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection #send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers) conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read() out2 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert('"error":null' in out1) #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! assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close() conn.close()
#now do the same with "Connection: 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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read() out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) assert('"error":null' in out1)
assert_equal(conn.sock!=None, False) #now the connection must be closed after the response assert(conn.sock==None) #now the connection must be closed after the response
#node1 (2nd node) is running with disabled keep-alive option #node1 (2nd node) is running with disabled keep-alive option
urlNode1 = urlparse.urlparse(self.nodes[1].url) urlNode1 = urlparse.urlparse(self.nodes[1].url)
authpair = urlNode1.username + ':' + urlNode1.password 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 = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn.connect() conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read() out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) assert('"error":null' in out1)
#node2 (third node) is running with standard keep-alive parameters which means keep-alive is on #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on
urlNode2 = urlparse.urlparse(self.nodes[2].url) urlNode2 = urlparse.urlparse(self.nodes[2].url)
authpair = urlNode2.username + ':' + urlNode2.password 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 = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect() conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read() out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True) assert('"error":null' in out1)
assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default
# Check excessive request size # Check excessive request size
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)

View File

@ -77,9 +77,9 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
block2 = create_block(self.tip, create_coinbase(height), self.block_time) block2 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1 self.block_time += 1
# chr(81) is OP_TRUE # b'0x51' is OP_TRUE
tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000) tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN)
tx2 = create_transaction(tx1, 0, chr(81), 50*100000000) tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN)
block2.vtx.extend([tx1, tx2]) block2.vtx.extend([tx1, tx2])
block2.hashMerkleRoot = block2.calc_merkle_root() block2.hashMerkleRoot = block2.calc_merkle_root()
@ -95,7 +95,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
assert(block2_orig.vtx != block2.vtx) assert(block2_orig.vtx != block2.vtx)
self.tip = block2.sha256 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 height += 1
''' '''
@ -103,14 +103,14 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
''' '''
block3 = create_block(self.tip, create_coinbase(height), self.block_time) block3 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1 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].sha256=None
block3.vtx[0].calc_sha256() block3.vtx[0].calc_sha256()
block3.hashMerkleRoot = block3.calc_merkle_root() block3.hashMerkleRoot = block3.calc_merkle_root()
block3.rehash() block3.rehash()
block3.solve() block3.solve()
yield TestInstance([[block3, RejectResult(16,'bad-cb-amount')]]) yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]])
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -61,10 +61,10 @@ class InvalidTxRequestTest(ComparisonTestFramework):
height += 1 height += 1
yield test yield test
# chr(100) is OP_NOTIF # b'\x64' is OP_NOTIF
# Transaction will be rejected with code 16 (REJECT_INVALID) # Transaction will be rejected with code 16 (REJECT_INVALID)
tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000) tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 50 * COIN)
yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]])
# TODO: test further transactions... # TODO: test further transactions...

View File

@ -10,28 +10,6 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * 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): class KeyPoolTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
@ -46,7 +24,7 @@ class KeyPoolTest(BitcoinTestFramework):
try: try:
addr = nodes[0].getnewaddress() addr = nodes[0].getnewaddress()
raise AssertionError('Keypool should be exhausted after one address') raise AssertionError('Keypool should be exhausted after one address')
except JSONRPCException,e: except JSONRPCException as e:
assert(e.error['code']==-12) assert(e.error['code']==-12)
# put three new keys in the keypool # put three new keys in the keypool
@ -66,13 +44,15 @@ class KeyPoolTest(BitcoinTestFramework):
try: try:
addr = nodes[0].getrawchangeaddress() addr = nodes[0].getrawchangeaddress()
raise AssertionError('Keypool should be exhausted after three addresses') raise AssertionError('Keypool should be exhausted after three addresses')
except JSONRPCException,e: except JSONRPCException as e:
assert(e.error['code']==-12) assert(e.error['code']==-12)
# refill keypool with three new addresses # refill keypool with three new addresses
nodes[0].walletpassphrase('test', 12000) nodes[0].walletpassphrase('test', 1)
nodes[0].keypoolrefill(3) nodes[0].keypoolrefill(3)
nodes[0].walletlock() # test walletpassphrase timeout
time.sleep(1.1)
assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)
# drain them by mining # drain them by mining
nodes[0].generate(1) nodes[0].generate(1)
@ -82,7 +62,7 @@ class KeyPoolTest(BitcoinTestFramework):
try: try:
nodes[0].generate(1) nodes[0].generate(1)
raise AssertionError('Keypool should be exhausted after three addesses') raise AssertionError('Keypool should be exhausted after three addesses')
except JSONRPCException,e: except JSONRPCException as e:
assert(e.error['code']==-12) assert(e.error['code']==-12)
def setup_chain(self): def setup_chain(self):

View File

@ -7,65 +7,43 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import CTransaction from test_framework.mininode import CTransaction, COIN
import cStringIO from io import BytesIO
import binascii
def txFromHex(hexstring): def txFromHex(hexstring):
tx = CTransaction() tx = CTransaction()
f = cStringIO.StringIO(binascii.unhexlify(hexstring)) f = BytesIO(hex_str_to_bytes(hexstring))
tx.deserialize(f) tx.deserialize(f)
return tx 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): class ListTransactionsTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
# Simple send, 0 to 1: # Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all() self.sync_all()
check_array_result(self.nodes[0].listtransactions(), assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid}, {"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) {"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}, {"txid":txid},
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
# mine a block, confirmations should change: # mine a block, confirmations should change:
self.nodes[0].generate(1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
check_array_result(self.nodes[0].listtransactions(), assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid}, {"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) {"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}, {"txid":txid},
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1})
# send-to-self: # send-to-self:
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) 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"}, {"txid":txid, "category":"send"},
{"amount":Decimal("-0.2")}) {"amount":Decimal("-0.2")})
check_array_result(self.nodes[0].listtransactions(), assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid, "category":"receive"}, {"txid":txid, "category":"receive"},
{"amount":Decimal("0.2")}) {"amount":Decimal("0.2")})
@ -76,28 +54,28 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].getaccountaddress("toself") : 0.44 } self.nodes[1].getaccountaddress("toself") : 0.44 }
txid = self.nodes[1].sendmany("", send_to) txid = self.nodes[1].sendmany("", send_to)
self.sync_all() self.sync_all()
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.11")}, {"category":"send","amount":Decimal("-0.11")},
{"txid":txid} ) {"txid":txid} )
check_array_result(self.nodes[0].listtransactions(), assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.11")}, {"category":"receive","amount":Decimal("0.11")},
{"txid":txid} ) {"txid":txid} )
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.22")}, {"category":"send","amount":Decimal("-0.22")},
{"txid":txid} ) {"txid":txid} )
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.22")}, {"category":"receive","amount":Decimal("0.22")},
{"txid":txid} ) {"txid":txid} )
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.33")}, {"category":"send","amount":Decimal("-0.33")},
{"txid":txid} ) {"txid":txid} )
check_array_result(self.nodes[0].listtransactions(), assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.33")}, {"category":"receive","amount":Decimal("0.33")},
{"txid":txid, "account" : "from1"} ) {"txid":txid, "account" : "from1"} )
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.44")}, {"category":"send","amount":Decimal("-0.44")},
{"txid":txid, "account" : ""} ) {"txid":txid, "account" : ""} )
check_array_result(self.nodes[1].listtransactions(), assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.44")}, {"category":"receive","amount":Decimal("0.44")},
{"txid":txid, "account" : "toself"} ) {"txid":txid, "account" : "toself"} )
@ -107,7 +85,7 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].generate(1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0) 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")}, {"category":"receive","amount":Decimal("0.1")},
{"txid":txid, "account" : "watchonly"} ) {"txid":txid, "account" : "watchonly"} )
@ -135,9 +113,9 @@ class ListTransactionsTest(BitcoinTestFramework):
# 1. Chain a few transactions that don't opt-in. # 1. Chain a few transactions that don't opt-in.
txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
assert(not is_opt_in(self.nodes[0], txid_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) 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. # Tx2 will build off txid_1, still not opting in to RBF.
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1) utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1)
@ -151,9 +129,9 @@ class ListTransactionsTest(BitcoinTestFramework):
# ...and check the result # ...and check the result
assert(not is_opt_in(self.nodes[1], txid_2)) 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) 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 # Tx3 will opt-in to RBF
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2) utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2)
@ -162,14 +140,14 @@ class ListTransactionsTest(BitcoinTestFramework):
tx3 = self.nodes[0].createrawtransaction(inputs, outputs) tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
tx3_modified = txFromHex(tx3) tx3_modified = txFromHex(tx3)
tx3_modified.vin[0].nSequence = 0 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'] tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex']
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
assert(is_opt_in(self.nodes[0], txid_3)) 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) 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 # Tx4 will chain off tx3. Doesn't signal itself, but depends on one
# that does. # that does.
@ -181,21 +159,21 @@ class ListTransactionsTest(BitcoinTestFramework):
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed) txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
assert(not is_opt_in(self.nodes[1], txid_4)) 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) 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 # Replace tx3, and check that tx4 becomes unknown
tx3_b = tx3_modified tx3_b = tx3_modified
tx3_b.vout[0].nValue -= 0.004*100000000 # bump the fee tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') tx3_b = bytes_to_hex_str(tx3_b.serialize())
tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex']
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
assert(is_opt_in(self.nodes[0], txid_3b)) 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) 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: # Check gettransaction as well:
for n in self.nodes[0:2]: for n in self.nodes[0:2]:

View File

@ -176,9 +176,9 @@ class MaxUploadTest(BitcoinTestFramework):
getdata_request.inv.append(CInv(2, big_old_block)) getdata_request.inv.append(CInv(2, big_old_block))
max_bytes_per_day = 200*1024*1024 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 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 # 144MB will be reserved for relaying new blocks, so expect this to
# succeed for ~70 tries. # succeed for ~70 tries.

View File

@ -38,7 +38,6 @@ class MempoolLimitTest(BitcoinTestFramework):
self.nodes[0].settxfee(0) # return to automatic fee selection self.nodes[0].settxfee(0) # return to automatic fee selection
txFS = self.nodes[0].signrawtransaction(txF['hex']) txFS = self.nodes[0].signrawtransaction(txF['hex'])
txid = self.nodes[0].sendrawtransaction(txFS['hex']) txid = self.nodes[0].sendrawtransaction(txFS['hex'])
self.nodes[0].lockunspent(True, [us0])
relayfee = self.nodes[0].getnetworkinfo()['relayfee'] relayfee = self.nodes[0].getnetworkinfo()['relayfee']
base_fee = relayfee*100 base_fee = relayfee*100

View File

@ -7,6 +7,7 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import COIN
MAX_ANCESTORS = 25 MAX_ANCESTORS = 25
MAX_DESCENDANTS = 25 MAX_DESCENDANTS = 25
@ -59,13 +60,12 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_count = 1 descendant_count = 1
descendant_fees = 0 descendant_fees = 0
descendant_size = 0 descendant_size = 0
SATOSHIS = 100000000
for x in reversed(chain): for x in reversed(chain):
assert_equal(mempool[x]['descendantcount'], descendant_count) assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee'] descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['modifiedfee'], 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'] descendant_size += mempool[x]['size']
assert_equal(mempool[x]['descendantsize'], descendant_size) assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1 descendant_count += 1
@ -78,7 +78,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees = 0 descendant_fees = 0
for x in reversed(chain): for x in reversed(chain):
descendant_fees += mempool[x]['fee'] 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. # Adding one more transaction on to the chain should fail.
try: try:
@ -106,7 +106,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees += mempool[x]['fee'] descendant_fees += mempool[x]['fee']
if (x == chain[-1]): if (x == chain[-1]):
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002)) 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 # TODO: check that node1's mempool is as expected

View File

@ -53,7 +53,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI=" password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
authpairnew = "rt:"+password authpairnew = "rt:"+password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)} headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
conn = httplib.HTTPConnection(url.hostname, url.port) conn = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -63,7 +63,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close() conn.close()
#Use new authpair to confirm both work #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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -74,7 +74,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong login name with rt's password #Wrong login name with rt's password
authpairnew = "rtwrong:"+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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -85,7 +85,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt #Wrong password for rt
authpairnew = "rt:"+password+"wrong" 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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -96,7 +96,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Correct for rt2 #Correct for rt2
authpairnew = "rt2:"+password2 authpairnew = "rt2:"+password2
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port) conn = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -107,7 +107,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt2 #Wrong password for rt2
authpairnew = "rt2:"+password2+"wrong" 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 = httplib.HTTPConnection(url.hostname, url.port)
conn.connect() conn.connect()
@ -117,6 +117,5 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close() conn.close()
if __name__ == '__main__': if __name__ == '__main__':
HTTPBasicsTest ().main () HTTPBasicsTest ().main ()

View File

@ -150,7 +150,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# 2. Send one block that builds on each tip. # 2. Send one block that builds on each tip.
# This should be accepted. # This should be accepted.
blocks_h2 = [] # the height 2 blocks on each node's chain blocks_h2 = [] # the height 2 blocks on each node's chain
block_time = time.time() + 1 block_time = int(time.time()) + 1
for i in xrange(2): for i in xrange(2):
blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time))
blocks_h2[i].solve() blocks_h2[i].solve()

View File

@ -34,7 +34,7 @@ class FullBlockTest(ComparisonTestFramework):
self.num_nodes = 1 self.num_nodes = 1
self.block_heights = {} self.block_heights = {}
self.coinbase_key = CECKey() 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.coinbase_pubkey = self.coinbase_key.get_pubkey()
self.block_time = int(time.time())+1 self.block_time = int(time.time())+1
self.tip = None self.tip = None
@ -71,7 +71,7 @@ class FullBlockTest(ComparisonTestFramework):
block = create_block(base_block_hash, coinbase, self.block_time) block = create_block(base_block_hash, coinbase, self.block_time)
if (spend != None): if (spend != None):
tx = CTransaction() 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 # This copies the java comparison tool testing behavior: the first
# txout has a garbage scriptPubKey, "to make sure we're not # txout has a garbage scriptPubKey, "to make sure we're not
# pre-verifying too much" (?) # pre-verifying too much" (?)
@ -81,7 +81,7 @@ class FullBlockTest(ComparisonTestFramework):
else: else:
tx.vout.append(CTxOut(1, script)) tx.vout.append(CTxOut(1, script))
# Now sign it if necessary # Now sign it if necessary
scriptSig = "" scriptSig = b""
scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey) scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey)
if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend
scriptSig = CScript([OP_TRUE]) scriptSig = CScript([OP_TRUE])
@ -226,7 +226,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2) # \-> b3 (1) -> b4 (2)
tip(6) tip(6)
block(9, spend=out4, additional_coinbase_value=1) 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) # Create a fork that ends in a block with too much fee (the one that causes the reorg)
@ -238,7 +238,7 @@ class FullBlockTest(ComparisonTestFramework):
yield rejected() yield rejected()
block(11, spend=out4, additional_coinbase_value=1) 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 # Try again, but with a valid fork first
@ -270,7 +270,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2) # \-> b3 (1) -> b4 (2)
# Test that a block with a lot of checksigs is okay # 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) tip(13)
block(15, spend=out5, script=lots_of_checksigs) block(15, spend=out5, script=lots_of_checksigs)
yield accepted() yield accepted()
@ -278,9 +278,9 @@ class FullBlockTest(ComparisonTestFramework):
# Test that a block with too many checksigs is rejected # Test that a block with too many checksigs is rejected
out6 = get_spendable_output() 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) 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 # Attempt to spend a transaction created on a different fork
@ -289,7 +289,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2) # \-> b3 (1) -> b4 (2)
tip(15) tip(15)
block(17, spend=txout_b3) 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) # Attempt to spend a transaction created on a different fork (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@ -310,7 +310,7 @@ class FullBlockTest(ComparisonTestFramework):
tip(15) tip(15)
out7 = get_spendable_output() out7 = get_spendable_output()
block(20, spend=out7) 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) # Attempt to spend a coinbase at depth too low (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@ -334,7 +334,7 @@ class FullBlockTest(ComparisonTestFramework):
old_hash = b23.sha256 old_hash = b23.sha256
tx = CTransaction() tx = CTransaction()
script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69 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.vout.append(CTxOut(0, script_output))
tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1))) tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1)))
b23 = update_block(23, [tx]) b23 = update_block(23, [tx])
@ -346,11 +346,11 @@ class FullBlockTest(ComparisonTestFramework):
tip(15) tip(15)
b24 = block(24, spend=out6) b24 = block(24, spend=out6)
script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69 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)] tx.vout = [CTxOut(0, script_output)]
b24 = update_block(24, [tx]) b24 = update_block(24, [tx])
assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1) 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) b25 = block(25, spend=out7)
yield rejected() yield rejected()
@ -362,12 +362,12 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2) # \-> b3 (1) -> b4 (2)
tip(15) tip(15)
b26 = block(26, spend=out6) 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() b26.vtx[0].rehash()
# update_block causes the merkle root to get updated, even with no new # update_block causes the merkle root to get updated, even with no new
# transactions, and updates the required state. # transactions, and updates the required state.
b26 = update_block(26, []) 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 # Extend the b26 chain to make sure bitcoind isn't accepting b26
b27 = block(27, spend=out7) b27 = block(27, spend=out7)
@ -376,10 +376,10 @@ class FullBlockTest(ComparisonTestFramework):
# Now try a too-large-coinbase script # Now try a too-large-coinbase script
tip(15) tip(15)
b28 = block(28, spend=out6) 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.vtx[0].rehash()
b28 = update_block(28, []) 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 # Extend the b28 chain to make sure bitcoind isn't accepted b28
b29 = block(29, spend=out7) b29 = block(29, spend=out7)
@ -391,7 +391,7 @@ class FullBlockTest(ComparisonTestFramework):
# b30 has a max-sized coinbase scriptSig. # b30 has a max-sized coinbase scriptSig.
tip(23) tip(23)
b30 = block(30) 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.vtx[0].rehash()
b30 = update_block(30, []) b30 = update_block(30, [])
yield accepted() yield accepted()

View File

@ -9,8 +9,7 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import COIN, MAX_BLOCK_SIZE
COIN = 100000000
class PrioritiseTransactionTest(BitcoinTestFramework): class PrioritiseTransactionTest(BitcoinTestFramework):
@ -29,14 +28,29 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
def run_test(self): 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 base_fee = self.relayfee*100 # our transactions are smaller than 100kb
txids = [] txids = []
# Create 3 batches of transactions at 3 different fee rate levels # Create 3 batches of transactions at 3 different fee rate levels
range_size = utxo_count // 3
for i in xrange(3): for i in xrange(3):
txids.append([]) 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 xrange(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 # 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 # 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) self.nodes[0].generate(1)
mempool = self.nodes[0].getrawmempool() 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][0] not in mempool)
assert(txids[0][1] in mempool) assert(txids[0][1] in mempool)
@ -60,7 +74,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
assert(high_fee_tx != None) assert(high_fee_tx != None)
# Add a prioritisation before a tx is in the mempool (de-prioritising a # 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)) self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN))
# Add everything back to mempool # Add everything back to mempool
@ -70,8 +84,11 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
mempool = self.nodes[0].getrawmempool() mempool = self.nodes[0].getrawmempool()
assert(high_fee_tx in mempool) assert(high_fee_tx in mempool)
# Now verify the high feerate transaction isn't mined. # Now verify the modified-high feerate transaction isn't mined before
self.nodes[0].generate(5) # 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 # High fee transaction should not have been mined, but other high fee rate
# transactions should have been. # transactions should have been.

View File

@ -77,7 +77,7 @@ class ProxyTest(BitcoinTestFramework):
assert(isinstance(cmd, Socks5Command)) assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 # 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.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) assert_equal(cmd.port, 1234)
if not auth: if not auth:
assert_equal(cmd.username, None) assert_equal(cmd.username, None)
@ -90,7 +90,7 @@ class ProxyTest(BitcoinTestFramework):
assert(isinstance(cmd, Socks5Command)) assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 # 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.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534") assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534")
assert_equal(cmd.port, 5443) assert_equal(cmd.port, 5443)
if not auth: if not auth:
assert_equal(cmd.username, None) assert_equal(cmd.username, None)
@ -103,7 +103,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[2].queue.get() cmd = proxies[2].queue.get()
assert(isinstance(cmd, Socks5Command)) assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME) assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "bitcoinostk4e4re.onion") assert_equal(cmd.addr, b"bitcoinostk4e4re.onion")
assert_equal(cmd.port, 8333) assert_equal(cmd.port, 8333)
if not auth: if not auth:
assert_equal(cmd.username, None) assert_equal(cmd.username, None)
@ -115,7 +115,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[3].queue.get() cmd = proxies[3].queue.get()
assert(isinstance(cmd, Socks5Command)) assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME) assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "node.noumenon") assert_equal(cmd.addr, b"node.noumenon")
assert_equal(cmd.port, 8333) assert_equal(cmd.port, 8333)
if not auth: if not auth:
assert_equal(cmd.username, None) assert_equal(cmd.username, None)

View File

@ -15,7 +15,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
def calc_usage(blockdir): 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): class PruneTest(BitcoinTestFramework):
@ -56,7 +56,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1].generate(200) self.nodes[1].generate(200)
sync_blocks(self.nodes[0:2]) sync_blocks(self.nodes[0:2])
self.nodes[0].generate(150) self.nodes[0].generate(150)
# Then mine enough full blocks to create more than 550MB of data # Then mine enough full blocks to create more than 550MiB of data
for i in xrange(645): for i in xrange(645):
self.mine_full_block(self.nodes[0], self.address[0]) self.mine_full_block(self.nodes[0], self.address[0])
@ -66,7 +66,7 @@ class PruneTest(BitcoinTestFramework):
if not os.path.isfile(self.prunedir+"blk00000.dat"): if not os.path.isfile(self.prunedir+"blk00000.dat"):
raise AssertionError("blk00000.dat is missing, pruning too early") raise AssertionError("blk00000.dat is missing, pruning too early")
print "Success" print "Success"
print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir) 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" 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 # 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 xrange(25):

View File

@ -56,13 +56,13 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs) rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
rawtx = self.nodes[2].signrawtransaction(rawtx) rawtx = self.nodes[2].signrawtransaction(rawtx)
errorString = ""
try: try:
rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
except JSONRPCException,e: except JSONRPCException as e:
errorString = e.error['message'] assert("Missing inputs" in e.error['message'])
else:
assert(False)
assert("Missing inputs" in errorString)
######################### #########################
# RAW TX MULTISIG TESTS # # RAW TX MULTISIG TESTS #
@ -88,8 +88,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 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 # 2of3 test from different nodes
bal = self.nodes[2].getbalance() bal = self.nodes[2].getbalance()
addr1 = self.nodes[1].getnewaddress() addr1 = self.nodes[1].getnewaddress()

View File

@ -25,32 +25,6 @@ def get_sub_array_from_array(object_array, to_match):
return item return item
return [] 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): class ReceivedByTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
@ -63,26 +37,26 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all() self.sync_all()
#Check not listed in listreceivedbyaddress because has 0 confirmations #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}, {"address":addr},
{ }, { },
True) True)
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress #Bury Tx under 10 block so it will be returned by listreceivedbyaddress
self.nodes[1].generate(10) self.nodes[1].generate(10)
self.sync_all() self.sync_all()
check_array_result(self.nodes[1].listreceivedbyaddress(), assert_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr}, {"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence < 10 #With min confidence < 10
check_array_result(self.nodes[1].listreceivedbyaddress(5), assert_array_result(self.nodes[1].listreceivedbyaddress(5),
{"address":addr}, {"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence > 10, should not find Tx #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 #Empty Tx
addr = self.nodes[1].getnewaddress() 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},
{"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]}) {"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
@ -126,7 +100,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all() self.sync_all()
# listreceivedbyaccount should return received_by_account_json because of 0 confirmations # 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}, {"account":account},
received_by_account_json) received_by_account_json)
@ -138,7 +112,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.nodes[1].generate(10) self.nodes[1].generate(10)
self.sync_all() self.sync_all()
# listreceivedbyaccount should return updated account balance # listreceivedbyaccount should return updated account balance
check_array_result(self.nodes[1].listreceivedbyaccount(), assert_array_result(self.nodes[1].listreceivedbyaccount(),
{"account":account}, {"account":account},
{"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))}) {"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})

View File

@ -11,16 +11,11 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.script import * from test_framework.script import *
from test_framework.mininode import * from test_framework.mininode import *
import binascii
COIN = 100000000
MAX_REPLACEMENT_LIMIT = 100 MAX_REPLACEMENT_LIMIT = 100
def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
def txToHex(tx): 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])): def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
"""Create a txout with a given amount and scriptPubKey """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.vout = [CTxOut(amount, scriptPubKey)]
tx2.rehash() tx2.rehash()
binascii.hexlify(tx2.serialize()).decode('utf-8') signed_tx = node.signrawtransaction(txToHex(tx2))
signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8'))
txid = node.sendrawtransaction(signed_tx['hex'], True) txid = node.sendrawtransaction(signed_tx['hex'], True)
@ -120,7 +113,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_simple_doublespend(self): def test_simple_doublespend(self):
"""Simple doublespend""" """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 = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@ -144,7 +137,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Extra 0.1 BTC fee # Extra 0.1 BTC fee
tx1b = CTransaction() tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] 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_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
@ -236,7 +229,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
_total_txs=_total_txs): _total_txs=_total_txs):
yield x yield x
fee = 0.0001*COIN fee = int(0.0001*COIN)
n = MAX_REPLACEMENT_LIMIT n = MAX_REPLACEMENT_LIMIT
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n) assert_equal(len(tree_txs), n)
@ -269,7 +262,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Try again, but with more total transactions than the "max txs # Try again, but with more total transactions than the "max txs
# double-spent at once" anti-DoS limit. # double-spent at once" anti-DoS limit.
for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2): 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) tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n) assert_equal(len(tree_txs), n)
@ -292,7 +285,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_replacement_feeperkb(self): def test_replacement_feeperkb(self):
"""Replacement requires fee-per-KB to be higher""" """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 = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@ -304,7 +297,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# rejected. # rejected.
tx1b = CTransaction() tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] 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) tx1b_hex = txToHex(tx1b)
try: try:
@ -316,12 +309,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_spends_of_conflicting_outputs(self): def test_spends_of_conflicting_outputs(self):
"""Replacements that spend conflicting tx outputs are rejected""" """Replacements that spend conflicting tx outputs are rejected"""
utxo1 = make_utxo(self.nodes[0], 1.2*COIN) utxo1 = make_utxo(self.nodes[0], int(1.2*COIN))
utxo2 = make_utxo(self.nodes[0], 3.0*COIN) utxo2 = make_utxo(self.nodes[0], 3*COIN)
tx1a = CTransaction() tx1a = CTransaction()
tx1a.vin = [CTxIn(utxo1, nSequence=0)] 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_hex = txToHex(tx1a)
tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
@ -344,7 +337,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Spend tx1a's output to test the indirect case. # Spend tx1a's output to test the indirect case.
tx1b = CTransaction() tx1b = CTransaction()
tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] 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_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
tx1b_txid = int(tx1b_txid, 16) tx1b_txid = int(tx1b_txid, 16)
@ -364,12 +357,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_new_unconfirmed_inputs(self): def test_new_unconfirmed_inputs(self):
"""Replacements that add new unconfirmed inputs are rejected""" """Replacements that add new unconfirmed inputs are rejected"""
confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN) confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False) unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)
tx1 = CTransaction() tx1 = CTransaction()
tx1.vin = [CTxIn(confirmed_utxo)] 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_hex = txToHex(tx1)
tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True) tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True)
@ -393,7 +386,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Start by creating a single transaction with many outputs # Start by creating a single transaction with many outputs
initial_nValue = 10*COIN initial_nValue = 10*COIN
utxo = make_utxo(self.nodes[0], initial_nValue) 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)) split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1))
actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1) actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1)
@ -446,7 +439,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_opt_in(self): def test_opt_in(self):
""" Replacing should only work if orig tx opted in """ """ 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 # Create a non-opting in transaction
tx1a = CTransaction() tx1a = CTransaction()
@ -458,7 +451,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Shouldn't be able to double-spend # Shouldn't be able to double-spend
tx1b = CTransaction() tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] 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_hex = txToHex(tx1b)
try: try:
@ -469,7 +462,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
print tx1b_txid print tx1b_txid
assert(False) 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 # Create a different non-opting in transaction
tx2a = CTransaction() tx2a = CTransaction()
@ -481,7 +474,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Still shouldn't be able to double-spend # Still shouldn't be able to double-spend
tx2b = CTransaction() tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] 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) tx2b_hex = txToHex(tx2b)
try: try:
@ -501,19 +494,19 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx3a = CTransaction() tx3a = CTransaction()
tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff), tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff),
CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)] 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) tx3a_hex = txToHex(tx3a)
self.nodes[0].sendrawtransaction(tx3a_hex, True) self.nodes[0].sendrawtransaction(tx3a_hex, True)
tx3b = CTransaction() tx3b = CTransaction()
tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] 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) tx3b_hex = txToHex(tx3b)
tx3c = CTransaction() tx3c = CTransaction()
tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)] 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) tx3c_hex = txToHex(tx3c)
self.nodes[0].sendrawtransaction(tx3b_hex, True) self.nodes[0].sendrawtransaction(tx3b_hex, True)
@ -526,7 +519,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# correctly used by replacement logic # correctly used by replacement logic
# 1. Check that feeperkb uses modified fees # 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 = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@ -537,7 +530,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Higher fee, but the actual fee per KB is much lower. # Higher fee, but the actual fee per KB is much lower.
tx1b = CTransaction() tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] 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) tx1b_hex = txToHex(tx1b)
# Verify tx1b cannot replace tx1a. # Verify tx1b cannot replace tx1a.
@ -557,7 +550,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert(tx1b_txid in self.nodes[0].getrawmempool()) assert(tx1b_txid in self.nodes[0].getrawmempool())
# 2. Check that absolute fee checks use modified fee. # 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 = CTransaction()
tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)] tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
@ -568,7 +561,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Lower fee, but we'll prioritise it # Lower fee, but we'll prioritise it
tx2b = CTransaction() tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] 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.rehash()
tx2b_hex = txToHex(tx2b) tx2b_hex = txToHex(tx2b)

View File

@ -11,8 +11,9 @@
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from struct import * from struct import *
from io import BytesIO
from codecs import encode
import binascii import binascii
import StringIO
try: try:
import http.client as httplib import http.client as httplib
@ -38,7 +39,7 @@ def http_get_call(host, port, path, response_object = 0):
if response_object: if response_object:
return conn.getresponse() return conn.getresponse()
return conn.getresponse().read() return conn.getresponse().read().decode('utf-8')
#allows simple http post calls with a request body #allows simple http post calls with a request body
def http_post_call(host, port, path, requestdata = '', response_object = 0): def http_post_call(host, port, path, requestdata = '', response_object = 0):
@ -140,13 +141,13 @@ class RESTTest (BitcoinTestFramework):
bb_hash = self.nodes[0].getbestblockhash() bb_hash = self.nodes[0].getbestblockhash()
binaryRequest = b'\x01\x02' binaryRequest = b'\x01\x02'
binaryRequest += binascii.unhexlify(txid) binaryRequest += hex_str_to_bytes(txid)
binaryRequest += pack("i", n) binaryRequest += pack("i", n)
binaryRequest += binascii.unhexlify(vintx) binaryRequest += hex_str_to_bytes(vintx)
binaryRequest += pack("i", 0) binaryRequest += pack("i", 0)
bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) 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.write(bin_response)
output.seek(0) output.seek(0)
chainHeight = unpack("i", output.read(4))[0] chainHeight = unpack("i", output.read(4))[0]
@ -233,7 +234,7 @@ class RESTTest (BitcoinTestFramework):
assert_equal(response_hex.status, 200) assert_equal(response_hex.status, 200)
assert_greater_than(int(response_hex.getheader('content-length')), 160) assert_greater_than(int(response_hex.getheader('content-length')), 160)
response_hex_str = response_hex.read() 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 # 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) response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True)
@ -241,7 +242,7 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response_header_hex.getheader('content-length')), 160) assert_greater_than(int(response_header_hex.getheader('content-length')), 160)
response_header_hex_str = response_header_hex.read() response_header_hex_str = response_header_hex.read()
assert_equal(response_hex_str[0:160], response_header_hex_str[0:160]) 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 # check json format
block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json') block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json')
@ -251,7 +252,7 @@ class RESTTest (BitcoinTestFramework):
# compare with json block header # 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) 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) 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) 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(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 assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
@ -275,7 +276,7 @@ class RESTTest (BitcoinTestFramework):
self.sync_all() self.sync_all()
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) 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) 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) json_obj = json.loads(response_header_json_str)
assert_equal(len(json_obj), 5) #now we should have 5 header objects assert_equal(len(json_obj), 5) #now we should have 5 header objects
@ -291,7 +292,6 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response.getheader('content-length')), 10) assert_greater_than(int(response.getheader('content-length')), 10)
# check block tx details # check block tx details
# let's make 3 tx and mine them on node 1 # let's make 3 tx and mine them on node 1
txs = [] txs = []

View File

@ -105,7 +105,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]]) print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
delta = 1.0e-6 # account for rounding error delta = 1.0e-6 # account for rounding error
last_e = max(fees_seen) 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: # 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): if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
raise AssertionError("Estimated fee (%f) out of range (%f,%f)" raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
@ -219,7 +219,7 @@ class EstimateFeeTest(BitcoinTestFramework):
from_index = random.randint(1,2) from_index = random.randint(1,2)
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo, (txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
self.memutxo, Decimal("0.005"), min_fee, min_fee) 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) self.fees_per_kb.append(float(fee)/tx_kbytes)
sync_mempools(self.nodes[0:3],.1) sync_mempools(self.nodes[0:3],.1)
mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"] mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]

View File

@ -3,8 +3,9 @@
# and for constructing a getheaders message # and for constructing a getheaders message
# #
from mininode import * from .mininode import *
import dbm import dbm
from io import BytesIO
class BlockStore(object): class BlockStore(object):
def __init__(self, datadir): def __init__(self, datadir):
@ -21,7 +22,7 @@ class BlockStore(object):
serialized_block = self.blockDB[repr(blockhash)] serialized_block = self.blockDB[repr(blockhash)]
except KeyError: except KeyError:
return None return None
f = cStringIO.StringIO(serialized_block) f = BytesIO(serialized_block)
ret = CBlock() ret = CBlock()
ret.deserialize(f) ret.deserialize(f)
ret.calc_sha256() ret.calc_sha256()
@ -115,7 +116,7 @@ class TxStore(object):
serialized_tx = self.txDB[repr(txhash)] serialized_tx = self.txDB[repr(txhash)]
except KeyError: except KeyError:
return None return None
f = cStringIO.StringIO(serialized_tx) f = BytesIO(serialized_tx)
ret = CTransaction() ret = CTransaction()
ret.deserialize(f) ret.deserialize(f)
ret.calc_sha256() ret.calc_sha256()

View File

@ -4,8 +4,8 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
# #
from mininode import * from .mininode import *
from script import CScript, OP_TRUE, OP_CHECKSIG from .script import CScript, OP_TRUE, OP_CHECKSIG
# Create a block (with regtest difficulty) # Create a block (with regtest difficulty)
def create_block(hashprev, coinbase, nTime=None): def create_block(hashprev, coinbase, nTime=None):
@ -29,7 +29,7 @@ def serialize_script_num(value):
neg = value < 0 neg = value < 0
absvalue = -value if neg else value absvalue = -value if neg else value
while (absvalue): while (absvalue):
r.append(chr(absvalue & 0xff)) r.append(int(absvalue & 0xff))
absvalue >>= 8 absvalue >>= 8
if r[-1] & 0x80: if r[-1] & 0x80:
r.append(0x80 if neg else 0) r.append(0x80 if neg else 0)
@ -45,7 +45,7 @@ def create_coinbase(height, pubkey = None):
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
ser_string(serialize_script_num(height)), 0xffffffff)) ser_string(serialize_script_num(height)), 0xffffffff))
coinbaseoutput = CTxOut() coinbaseoutput = CTxOut()
coinbaseoutput.nValue = 50*100000000 coinbaseoutput.nValue = 50 * COIN
halvings = int(height/150) # regtest halvings = int(height/150) # regtest
coinbaseoutput.nValue >>= halvings coinbaseoutput.nValue >>= halvings
if (pubkey != None): if (pubkey != None):
@ -62,6 +62,6 @@ def create_transaction(prevtx, n, sig, value):
tx = CTransaction() tx = CTransaction()
assert(n < len(prevtx.vout)) assert(n < len(prevtx.vout))
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
tx.vout.append(CTxOut(value, "")) tx.vout.append(CTxOut(value, b""))
tx.calc_sha256() tx.calc_sha256()
return tx return tx

View File

@ -4,9 +4,9 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
# #
from mininode import * from .mininode import *
from blockstore import BlockStore, TxStore from .blockstore import BlockStore, TxStore
from util import p2p_port from .util import p2p_port
''' '''
This is a tool for comparing two or more bitcoinds to each other 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. Outcome that expects rejection of a transaction or block.
''' '''
def __init__(self, code, reason=''): def __init__(self, code, reason=b''):
self.code = code self.code = code
self.reason = reason self.reason = reason
def match(self, other): def match(self, other):
@ -111,9 +111,9 @@ class TestNode(NodeConnCB):
raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) raise AssertionError("Got pong for unknown ping [%s]" % repr(message))
def on_reject(self, conn, 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) 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) self.block_reject_map[message.data] = RejectResult(message.code, message.reason)
def send_inv(self, obj): def send_inv(self, obj):

View File

@ -20,11 +20,12 @@
import struct import struct
import socket import socket
import asyncore import asyncore
import binascii
import time import time
import sys import sys
import random import random
import cStringIO from binascii import hexlify, unhexlify
from io import BytesIO
from codecs import encode
import hashlib import hashlib
from threading import RLock from threading import RLock
from threading import Thread from threading import Thread
@ -33,11 +34,13 @@ import copy
BIP0031_VERSION = 60000 BIP0031_VERSION = 60000
MY_VERSION = 60001 # past bip-31 for ping/pong 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_INV_SZ = 50000
MAX_BLOCK_SIZE = 1000000 MAX_BLOCK_SIZE = 1000000
COIN = 100000000L # 1 btc in satoshis
# Keep our own socket map for asyncore, so that we can track disconnects # Keep our own socket map for asyncore, so that we can track disconnects
# ourselves (to workaround an issue with closing an asyncore socket when # ourselves (to workaround an issue with closing an asyncore socket when
# using select) # using select)
@ -73,12 +76,12 @@ def deser_string(f):
def ser_string(s): def ser_string(s):
if len(s) < 253: if len(s) < 253:
return chr(len(s)) + s return struct.pack("B", len(s)) + s
elif len(s) < 0x10000: 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: elif len(s) < 0x100000000L:
return chr(254) + struct.pack("<I", len(s)) + s return struct.pack("<BI", 254, len(s)) + s
return chr(255) + struct.pack("<Q", len(s)) + s return struct.pack("<BQ", 255, len(s)) + s
def deser_uint256(f): def deser_uint256(f):
@ -128,15 +131,15 @@ def deser_vector(f, c):
def ser_vector(l): def ser_vector(l):
r = "" r = b""
if len(l) < 253: if len(l) < 253:
r = chr(len(l)) r = struct.pack("B", len(l))
elif len(l) < 0x10000: elif len(l) < 0x10000:
r = chr(253) + struct.pack("<H", len(l)) r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000L: elif len(l) < 0x100000000L:
r = chr(254) + struct.pack("<I", len(l)) r = struct.pack("<BI", 254, len(l))
else: else:
r = chr(255) + struct.pack("<Q", len(l)) r = struct.pack("<BQ", 255, len(l))
for i in l: for i in l:
r += i.serialize() r += i.serialize()
return r return r
@ -158,15 +161,15 @@ def deser_uint256_vector(f):
def ser_uint256_vector(l): def ser_uint256_vector(l):
r = "" r = b""
if len(l) < 253: if len(l) < 253:
r = chr(len(l)) r = struct.pack("B", len(l))
elif len(l) < 0x10000: elif len(l) < 0x10000:
r = chr(253) + struct.pack("<H", len(l)) r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000L: elif len(l) < 0x100000000L:
r = chr(254) + struct.pack("<I", len(l)) r = struct.pack("<BI", 254, len(l))
else: else:
r = chr(255) + struct.pack("<Q", len(l)) r = struct.pack("<BQ", 255, len(l))
for i in l: for i in l:
r += ser_uint256(i) r += ser_uint256(i)
return r return r
@ -190,13 +193,13 @@ def deser_string_vector(f):
def ser_string_vector(l): def ser_string_vector(l):
r = "" r = ""
if len(l) < 253: if len(l) < 253:
r = chr(len(l)) r = struct.pack("B", len(l))
elif len(l) < 0x10000: elif len(l) < 0x10000:
r = chr(253) + struct.pack("<H", len(l)) r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000L: elif len(l) < 0x100000000L:
r = chr(254) + struct.pack("<I", len(l)) r = struct.pack("<BI", 254, len(l))
else: else:
r = chr(255) + struct.pack("<Q", len(l)) r = struct.pack("<BQ", 255, len(l))
for sv in l: for sv in l:
r += ser_string(sv) r += ser_string(sv)
return r return r
@ -218,34 +221,34 @@ def deser_int_vector(f):
def ser_int_vector(l): def ser_int_vector(l):
r = "" r = b""
if len(l) < 253: if len(l) < 253:
r = chr(len(l)) r = struct.pack("B", len(l))
elif len(l) < 0x10000: elif len(l) < 0x10000:
r = chr(253) + struct.pack("<H", len(l)) r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000L: elif len(l) < 0x100000000L:
r = chr(254) + struct.pack("<I", len(l)) r = struct.pack("<BI", 254, len(l))
else: else:
r = chr(255) + struct.pack("<Q", len(l)) r = struct.pack("<BQ", 255, len(l))
for i in l: for i in l:
r += struct.pack("<i", i) r += struct.pack("<i", i)
return r return r
# Deserialize from a hex string representation (eg from RPC) # Deserialize from a hex string representation (eg from RPC)
def FromHex(obj, hex_string): def FromHex(obj, hex_string):
obj.deserialize(cStringIO.StringIO(binascii.unhexlify(hex_string))) obj.deserialize(BytesIO(unhexlify(hex_string.encode('ascii'))))
return obj return obj
# Convert a binary-serializable object to hex (eg for submission via RPC) # Convert a binary-serializable object to hex (eg for submission via RPC)
def ToHex(obj): 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 # Objects that map to bitcoind objects, which can be serialized/deserialized
class CAddress(object): class CAddress(object):
def __init__(self): def __init__(self):
self.nServices = 1 self.nServices = 1
self.pchReserved = "\x00" * 10 + "\xff" * 2 self.pchReserved = b"\x00" * 10 + b"\xff" * 2
self.ip = "0.0.0.0" self.ip = "0.0.0.0"
self.port = 0 self.port = 0
@ -256,7 +259,7 @@ class CAddress(object):
self.port = struct.unpack(">H", f.read(2))[0] self.port = struct.unpack(">H", f.read(2))[0]
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<Q", self.nServices) r += struct.pack("<Q", self.nServices)
r += self.pchReserved r += self.pchReserved
r += socket.inet_aton(self.ip) r += socket.inet_aton(self.ip)
@ -283,7 +286,7 @@ class CInv(object):
self.hash = deser_uint256(f) self.hash = deser_uint256(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.type) r += struct.pack("<i", self.type)
r += ser_uint256(self.hash) r += ser_uint256(self.hash)
return r return r
@ -303,7 +306,7 @@ class CBlockLocator(object):
self.vHave = deser_uint256_vector(f) self.vHave = deser_uint256_vector(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += ser_uint256_vector(self.vHave) r += ser_uint256_vector(self.vHave)
return r return r
@ -323,7 +326,7 @@ class COutPoint(object):
self.n = struct.unpack("<I", f.read(4))[0] self.n = struct.unpack("<I", f.read(4))[0]
def serialize(self): def serialize(self):
r = "" r = b""
r += ser_uint256(self.hash) r += ser_uint256(self.hash)
r += struct.pack("<I", self.n) r += struct.pack("<I", self.n)
return r return r
@ -333,7 +336,7 @@ class COutPoint(object):
class CTxIn(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: if outpoint is None:
self.prevout = COutPoint() self.prevout = COutPoint()
else: else:
@ -348,7 +351,7 @@ class CTxIn(object):
self.nSequence = struct.unpack("<I", f.read(4))[0] self.nSequence = struct.unpack("<I", f.read(4))[0]
def serialize(self): def serialize(self):
r = "" r = b""
r += self.prevout.serialize() r += self.prevout.serialize()
r += ser_string(self.scriptSig) r += ser_string(self.scriptSig)
r += struct.pack("<I", self.nSequence) r += struct.pack("<I", self.nSequence)
@ -356,12 +359,12 @@ class CTxIn(object):
def __repr__(self): def __repr__(self):
return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \ return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \
% (repr(self.prevout), binascii.hexlify(self.scriptSig), % (repr(self.prevout), hexlify(self.scriptSig),
self.nSequence) self.nSequence)
class CTxOut(object): class CTxOut(object):
def __init__(self, nValue=0, scriptPubKey=""): def __init__(self, nValue=0, scriptPubKey=b""):
self.nValue = nValue self.nValue = nValue
self.scriptPubKey = scriptPubKey self.scriptPubKey = scriptPubKey
@ -370,15 +373,15 @@ class CTxOut(object):
self.scriptPubKey = deser_string(f) self.scriptPubKey = deser_string(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<q", self.nValue) r += struct.pack("<q", self.nValue)
r += ser_string(self.scriptPubKey) r += ser_string(self.scriptPubKey)
return r return r
def __repr__(self): def __repr__(self):
return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \
% (self.nValue // 100000000, self.nValue % 100000000, % (self.nValue // COIN, self.nValue % COIN,
binascii.hexlify(self.scriptPubKey)) hexlify(self.scriptPubKey))
class CTransaction(object): class CTransaction(object):
@ -407,7 +410,7 @@ class CTransaction(object):
self.hash = None self.hash = None
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += ser_vector(self.vin) r += ser_vector(self.vin)
r += ser_vector(self.vout) r += ser_vector(self.vout)
@ -421,12 +424,12 @@ class CTransaction(object):
def calc_sha256(self): def calc_sha256(self):
if self.sha256 is None: if self.sha256 is None:
self.sha256 = uint256_from_str(hash256(self.serialize())) 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): def is_valid(self):
self.calc_sha256() self.calc_sha256()
for tout in self.vout: 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 False
return True return True
@ -471,7 +474,7 @@ class CBlockHeader(object):
self.hash = None self.hash = None
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += ser_uint256(self.hashPrevBlock) r += ser_uint256(self.hashPrevBlock)
r += ser_uint256(self.hashMerkleRoot) r += ser_uint256(self.hashMerkleRoot)
@ -482,7 +485,7 @@ class CBlockHeader(object):
def calc_sha256(self): def calc_sha256(self):
if self.sha256 is None: if self.sha256 is None:
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += ser_uint256(self.hashPrevBlock) r += ser_uint256(self.hashPrevBlock)
r += ser_uint256(self.hashMerkleRoot) r += ser_uint256(self.hashMerkleRoot)
@ -490,7 +493,7 @@ class CBlockHeader(object):
r += struct.pack("<I", self.nBits) r += struct.pack("<I", self.nBits)
r += struct.pack("<I", self.nNonce) r += struct.pack("<I", self.nNonce)
self.sha256 = uint256_from_str(hash256(r)) 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): def rehash(self):
self.sha256 = None self.sha256 = None
@ -513,7 +516,7 @@ class CBlock(CBlockHeader):
self.vtx = deser_vector(f, CTransaction) self.vtx = deser_vector(f, CTransaction)
def serialize(self): def serialize(self):
r = "" r = b""
r += super(CBlock, self).serialize() r += super(CBlock, self).serialize()
r += ser_vector(self.vtx) r += ser_vector(self.vtx)
return r return r
@ -568,9 +571,9 @@ class CUnsignedAlert(object):
self.nMaxVer = 0 self.nMaxVer = 0
self.setSubVer = [] self.setSubVer = []
self.nPriority = 0 self.nPriority = 0
self.strComment = "" self.strComment = b""
self.strStatusBar = "" self.strStatusBar = b""
self.strReserved = "" self.strReserved = b""
def deserialize(self, f): def deserialize(self, f):
self.nVersion = struct.unpack("<i", f.read(4))[0] self.nVersion = struct.unpack("<i", f.read(4))[0]
@ -588,7 +591,7 @@ class CUnsignedAlert(object):
self.strReserved = deser_string(f) self.strReserved = deser_string(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += struct.pack("<q", self.nRelayUntil) r += struct.pack("<q", self.nRelayUntil)
r += struct.pack("<q", self.nExpiration) r += struct.pack("<q", self.nExpiration)
@ -613,8 +616,8 @@ class CUnsignedAlert(object):
class CAlert(object): class CAlert(object):
def __init__(self): def __init__(self):
self.vchMsg = "" self.vchMsg = b""
self.vchSig = "" self.vchSig = b""
def deserialize(self, f): def deserialize(self, f):
self.vchMsg = deser_string(f) self.vchMsg = deser_string(f)
@ -633,12 +636,12 @@ class CAlert(object):
# Objects that correspond to messages on the wire # Objects that correspond to messages on the wire
class msg_version(object): class msg_version(object):
command = "version" command = b"version"
def __init__(self): def __init__(self):
self.nVersion = MY_VERSION self.nVersion = MY_VERSION
self.nServices = 1 self.nServices = 1
self.nTime = time.time() self.nTime = int(time.time())
self.addrTo = CAddress() self.addrTo = CAddress()
self.addrFrom = CAddress() self.addrFrom = CAddress()
self.nNonce = random.getrandbits(64) self.nNonce = random.getrandbits(64)
@ -669,7 +672,7 @@ class msg_version(object):
self.nStartingHeight = None self.nStartingHeight = None
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<i", self.nVersion) r += struct.pack("<i", self.nVersion)
r += struct.pack("<Q", self.nServices) r += struct.pack("<Q", self.nServices)
r += struct.pack("<q", self.nTime) r += struct.pack("<q", self.nTime)
@ -688,7 +691,7 @@ class msg_version(object):
class msg_verack(object): class msg_verack(object):
command = "verack" command = b"verack"
def __init__(self): def __init__(self):
pass pass
@ -697,14 +700,14 @@ class msg_verack(object):
pass pass
def serialize(self): def serialize(self):
return "" return b""
def __repr__(self): def __repr__(self):
return "msg_verack()" return "msg_verack()"
class msg_addr(object): class msg_addr(object):
command = "addr" command = b"addr"
def __init__(self): def __init__(self):
self.addrs = [] self.addrs = []
@ -720,7 +723,7 @@ class msg_addr(object):
class msg_alert(object): class msg_alert(object):
command = "alert" command = b"alert"
def __init__(self): def __init__(self):
self.alert = CAlert() self.alert = CAlert()
@ -730,7 +733,7 @@ class msg_alert(object):
self.alert.deserialize(f) self.alert.deserialize(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += self.alert.serialize() r += self.alert.serialize()
return r return r
@ -739,7 +742,7 @@ class msg_alert(object):
class msg_inv(object): class msg_inv(object):
command = "inv" command = b"inv"
def __init__(self, inv=None): def __init__(self, inv=None):
if inv is None: if inv is None:
@ -758,7 +761,7 @@ class msg_inv(object):
class msg_getdata(object): class msg_getdata(object):
command = "getdata" command = b"getdata"
def __init__(self, inv=None): def __init__(self, inv=None):
self.inv = inv if inv != None else [] self.inv = inv if inv != None else []
@ -774,7 +777,7 @@ class msg_getdata(object):
class msg_getblocks(object): class msg_getblocks(object):
command = "getblocks" command = b"getblocks"
def __init__(self): def __init__(self):
self.locator = CBlockLocator() self.locator = CBlockLocator()
@ -786,7 +789,7 @@ class msg_getblocks(object):
self.hashstop = deser_uint256(f) self.hashstop = deser_uint256(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += self.locator.serialize() r += self.locator.serialize()
r += ser_uint256(self.hashstop) r += ser_uint256(self.hashstop)
return r return r
@ -797,7 +800,7 @@ class msg_getblocks(object):
class msg_tx(object): class msg_tx(object):
command = "tx" command = b"tx"
def __init__(self, tx=CTransaction()): def __init__(self, tx=CTransaction()):
self.tx = tx self.tx = tx
@ -813,7 +816,7 @@ class msg_tx(object):
class msg_block(object): class msg_block(object):
command = "block" command = b"block"
def __init__(self, block=None): def __init__(self, block=None):
if block is None: if block is None:
@ -832,7 +835,7 @@ class msg_block(object):
class msg_getaddr(object): class msg_getaddr(object):
command = "getaddr" command = b"getaddr"
def __init__(self): def __init__(self):
pass pass
@ -841,14 +844,14 @@ class msg_getaddr(object):
pass pass
def serialize(self): def serialize(self):
return "" return b""
def __repr__(self): def __repr__(self):
return "msg_getaddr()" return "msg_getaddr()"
class msg_ping_prebip31(object): class msg_ping_prebip31(object):
command = "ping" command = b"ping"
def __init__(self): def __init__(self):
pass pass
@ -857,14 +860,14 @@ class msg_ping_prebip31(object):
pass pass
def serialize(self): def serialize(self):
return "" return b""
def __repr__(self): def __repr__(self):
return "msg_ping() (pre-bip31)" return "msg_ping() (pre-bip31)"
class msg_ping(object): class msg_ping(object):
command = "ping" command = b"ping"
def __init__(self, nonce=0L): def __init__(self, nonce=0L):
self.nonce = nonce self.nonce = nonce
@ -873,7 +876,7 @@ class msg_ping(object):
self.nonce = struct.unpack("<Q", f.read(8))[0] self.nonce = struct.unpack("<Q", f.read(8))[0]
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<Q", self.nonce) r += struct.pack("<Q", self.nonce)
return r return r
@ -882,16 +885,16 @@ class msg_ping(object):
class msg_pong(object): class msg_pong(object):
command = "pong" command = b"pong"
def __init__(self, nonce=0L): def __init__(self, nonce=0):
self.nonce = nonce self.nonce = nonce
def deserialize(self, f): def deserialize(self, f):
self.nonce = struct.unpack("<Q", f.read(8))[0] self.nonce = struct.unpack("<Q", f.read(8))[0]
def serialize(self): def serialize(self):
r = "" r = b""
r += struct.pack("<Q", self.nonce) r += struct.pack("<Q", self.nonce)
return r return r
@ -900,7 +903,7 @@ class msg_pong(object):
class msg_mempool(object): class msg_mempool(object):
command = "mempool" command = b"mempool"
def __init__(self): def __init__(self):
pass pass
@ -909,13 +912,13 @@ class msg_mempool(object):
pass pass
def serialize(self): def serialize(self):
return "" return b""
def __repr__(self): def __repr__(self):
return "msg_mempool()" return "msg_mempool()"
class msg_sendheaders(object): class msg_sendheaders(object):
command = "sendheaders" command = b"sendheaders"
def __init__(self): def __init__(self):
pass pass
@ -924,7 +927,7 @@ class msg_sendheaders(object):
pass pass
def serialize(self): def serialize(self):
return "" return b""
def __repr__(self): def __repr__(self):
return "msg_sendheaders()" return "msg_sendheaders()"
@ -934,7 +937,7 @@ class msg_sendheaders(object):
# vector of hashes # vector of hashes
# hash_stop (hash of last desired block header, 0 to get as many as possible) # hash_stop (hash of last desired block header, 0 to get as many as possible)
class msg_getheaders(object): class msg_getheaders(object):
command = "getheaders" command = b"getheaders"
def __init__(self): def __init__(self):
self.locator = CBlockLocator() self.locator = CBlockLocator()
@ -946,7 +949,7 @@ class msg_getheaders(object):
self.hashstop = deser_uint256(f) self.hashstop = deser_uint256(f)
def serialize(self): def serialize(self):
r = "" r = b""
r += self.locator.serialize() r += self.locator.serialize()
r += ser_uint256(self.hashstop) r += ser_uint256(self.hashstop)
return r return r
@ -959,7 +962,7 @@ class msg_getheaders(object):
# headers message has # headers message has
# <count> <vector of block headers> # <count> <vector of block headers>
class msg_headers(object): class msg_headers(object):
command = "headers" command = b"headers"
def __init__(self): def __init__(self):
self.headers = [] self.headers = []
@ -979,11 +982,11 @@ class msg_headers(object):
class msg_reject(object): class msg_reject(object):
command = "reject" command = b"reject"
def __init__(self): def __init__(self):
self.message = "" self.message = b""
self.code = "" self.code = 0
self.reason = "" self.reason = ""
self.data = 0L self.data = 0L
@ -1006,7 +1009,6 @@ class msg_reject(object):
return "msg_reject: %s %d %s [%064x]" \ return "msg_reject: %s %d %s [%064x]" \
% (self.message, self.code, self.reason, self.data) % (self.message, self.code, self.reason, self.data)
# This is what a callback should look like for NodeConn # This is what a callback should look like for NodeConn
# Reimplement the on_* functions to provide handling for events # Reimplement the on_* functions to provide handling for events
class NodeConnCB(object): class NodeConnCB(object):
@ -1088,27 +1090,27 @@ class NodeConnCB(object):
# This class provides an interface for a p2p connection to a specified node # This class provides an interface for a p2p connection to a specified node
class NodeConn(asyncore.dispatcher): class NodeConn(asyncore.dispatcher):
messagemap = { messagemap = {
"version": msg_version, b"version": msg_version,
"verack": msg_verack, b"verack": msg_verack,
"addr": msg_addr, b"addr": msg_addr,
"alert": msg_alert, b"alert": msg_alert,
"inv": msg_inv, b"inv": msg_inv,
"getdata": msg_getdata, b"getdata": msg_getdata,
"getblocks": msg_getblocks, b"getblocks": msg_getblocks,
"tx": msg_tx, b"tx": msg_tx,
"block": msg_block, b"block": msg_block,
"getaddr": msg_getaddr, b"getaddr": msg_getaddr,
"ping": msg_ping, b"ping": msg_ping,
"pong": msg_pong, b"pong": msg_pong,
"headers": msg_headers, b"headers": msg_headers,
"getheaders": msg_getheaders, b"getheaders": msg_getheaders,
"reject": msg_reject, b"reject": msg_reject,
"mempool": msg_mempool b"mempool": msg_mempool,
} }
MAGIC_BYTES = { MAGIC_BYTES = {
"mainnet": "\xf9\xbe\xb4\xd9", # mainnet "mainnet": b"\xf9\xbe\xb4\xd9", # mainnet
"testnet3": "\x0b\x11\x09\x07", # testnet3 "testnet3": b"\x0b\x11\x09\x07", # testnet3
"regtest": "\xfa\xbf\xb5\xda" # regtest "regtest": b"\xfa\xbf\xb5\xda" # regtest
} }
def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1): def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1):
@ -1117,8 +1119,8 @@ class NodeConn(asyncore.dispatcher):
self.dstaddr = dstaddr self.dstaddr = dstaddr
self.dstport = dstport self.dstport = dstport
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.sendbuf = "" self.sendbuf = b""
self.recvbuf = "" self.recvbuf = b""
self.ver_send = 209 self.ver_send = 209
self.ver_recv = 209 self.ver_recv = 209
self.last_sent = 0 self.last_sent = 0
@ -1155,8 +1157,8 @@ class NodeConn(asyncore.dispatcher):
self.show_debug_msg("MiniNode: Closing Connection to %s:%d... " self.show_debug_msg("MiniNode: Closing Connection to %s:%d... "
% (self.dstaddr, self.dstport)) % (self.dstaddr, self.dstport))
self.state = "closed" self.state = "closed"
self.recvbuf = "" self.recvbuf = b""
self.sendbuf = "" self.sendbuf = b""
try: try:
self.close() self.close()
except: except:
@ -1190,43 +1192,46 @@ class NodeConn(asyncore.dispatcher):
self.sendbuf = self.sendbuf[sent:] self.sendbuf = self.sendbuf[sent:]
def got_data(self): def got_data(self):
while True: try:
if len(self.recvbuf) < 4: while True:
return if len(self.recvbuf) < 4:
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 return
command = self.recvbuf[4:4+12].split("\x00", 1)[0] if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]:
msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0] raise ValueError("got garbage %s" % repr(self.recvbuf))
checksum = None if self.ver_recv < 209:
if len(self.recvbuf) < 4 + 12 + 4 + msglen: if len(self.recvbuf) < 4 + 12 + 4:
return return
msg = self.recvbuf[4+12+4:4+12+4+msglen] command = self.recvbuf[4:4+12].split(b"\x00", 1)[0]
self.recvbuf = self.recvbuf[4+12+4+msglen:] msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
else: checksum = None
if len(self.recvbuf) < 4 + 12 + 4 + 4: if len(self.recvbuf) < 4 + 12 + 4 + msglen:
return return
command = self.recvbuf[4:4+12].split("\x00", 1)[0] msg = self.recvbuf[4+12+4:4+12+4+msglen]
msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0] self.recvbuf = self.recvbuf[4+12+4+msglen:]
checksum = self.recvbuf[4+12+4:4+12+4+4] else:
if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen: if len(self.recvbuf) < 4 + 12 + 4 + 4:
return return
msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen] command = self.recvbuf[4:4+12].split(b"\x00", 1)[0]
th = sha256(msg) msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
h = sha256(th) checksum = self.recvbuf[4+12+4:4+12+4+4]
if checksum != h[:4]: if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
raise ValueError("got bad checksum " + repr(self.recvbuf)) return
self.recvbuf = self.recvbuf[4+12+4+4+msglen:] msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
if command in self.messagemap: th = sha256(msg)
f = cStringIO.StringIO(msg) h = sha256(th)
t = self.messagemap[command]() if checksum != h[:4]:
t.deserialize(f) raise ValueError("got bad checksum " + repr(self.recvbuf))
self.got_message(t) self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
else: if command in self.messagemap:
self.show_debug_msg("Unknown command: '" + command + "' " + f = BytesIO(msg)
repr(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): def send_message(self, message, pushbuf=False):
if self.state != "connected" and not pushbuf: if self.state != "connected" and not pushbuf:
@ -1236,7 +1241,7 @@ class NodeConn(asyncore.dispatcher):
data = message.serialize() data = message.serialize()
tmsg = self.MAGIC_BYTES[self.network] tmsg = self.MAGIC_BYTES[self.network]
tmsg += command tmsg += command
tmsg += "\x00" * (12 - len(command)) tmsg += b"\x00" * (12 - len(command))
tmsg += struct.pack("<I", len(data)) tmsg += struct.pack("<I", len(data))
if self.ver_send >= 209: if self.ver_send >= 209:
th = sha256(data) th = sha256(data)
@ -1248,11 +1253,11 @@ class NodeConn(asyncore.dispatcher):
self.last_sent = time.time() self.last_sent = time.time()
def got_message(self, message): def got_message(self, message):
if message.command == "version": if message.command == b"version":
if message.nVersion <= BIP0031_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(): 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.show_debug_msg("Recv %s" % repr(message))
self.cb.deliver(self, message) self.cb.deliver(self, message)

View File

@ -4,13 +4,14 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Linux network utilities # Linux network utilities
import sys import sys
import socket import socket
import fcntl import fcntl
import struct import struct
import array import array
import os 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 # Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
STATE_ESTABLISHED = '01' STATE_ESTABLISHED = '01'
@ -43,9 +44,9 @@ def _remove_empty(array):
def _convert_ip_port(array): def _convert_ip_port(array):
host,port = array.split(':') host,port = array.split(':')
# convert host from mangled-per-four-bytes form as used by kernel # convert host from mangled-per-four-bytes form as used by kernel
host = binascii.unhexlify(host) host = unhexlify(host)
host_out = '' 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]) (val,) = struct.unpack('=I', host[x*4:(x+1)*4])
host_out += '%08x' % val host_out += '%08x' % val
@ -94,7 +95,7 @@ def all_interfaces():
max_possible = 8 # initial value max_possible = 8 # initial value
while True: while True:
bytes = max_possible * struct_size bytes = max_possible * struct_size
names = array.array('B', '\0' * bytes) names = array.array('B', b'\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl( outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(), s.fileno(),
0x8912, # SIOCGIFCONF 0x8912, # SIOCGIFCONF
@ -105,7 +106,7 @@ def all_interfaces():
else: else:
break break
namestr = names.tostring() 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])) socket.inet_ntoa(namestr[i+20:i+24]))
for i in range(0, outbytes, struct_size)] for i in range(0, outbytes, struct_size)]
@ -136,4 +137,4 @@ def addr_to_hex(addr):
addr = sub[0] + ([0] * nullbytes) + sub[1] addr = sub[0] + ([0] * nullbytes) + sub[1]
else: else:
raise ValueError('Could not parse address %s' % addr) 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 neg = obj.value < 0
absvalue = -obj.value if neg else obj.value absvalue = -obj.value if neg else obj.value
while (absvalue): while (absvalue):
r.append(chr(absvalue & 0xff)) r.append(absvalue & 0xff)
absvalue >>= 8 absvalue >>= 8
if r[-1] & 0x80: if r[-1] & 0x80:
r.append(0x80 if neg else 0) r.append(0x80 if neg else 0)
@ -777,7 +777,7 @@ class CScript(bytes):
# need to change # need to change
def _repr(o): def _repr(o):
if isinstance(o, bytes): if isinstance(o, bytes):
return "x('%s')" % hexlify(o).decode('utf8') return b"x('%s')" % hexlify(o).decode('ascii')
else: else:
return repr(o) return repr(o)

View File

@ -102,7 +102,7 @@ class Socks5Connection(object):
addr = recvall(self.conn, 4) addr = recvall(self.conn, 4)
elif atyp == AddressType.DOMAINNAME: elif atyp == AddressType.DOMAINNAME:
n = recvall(self.conn, 1)[0] n = recvall(self.conn, 1)[0]
addr = str(recvall(self.conn, n)) addr = recvall(self.conn, n)
elif atyp == AddressType.IPV6: elif atyp == AddressType.IPV6:
addr = recvall(self.conn, 16) addr = recvall(self.conn, 16)
else: else:
@ -117,7 +117,7 @@ class Socks5Connection(object):
self.serv.queue.put(cmdin) self.serv.queue.put(cmdin)
print('Proxy: ', cmdin) print('Proxy: ', cmdin)
# Fall through to disconnect # Fall through to disconnect
except Exception,e: except Exception as e:
traceback.print_exc(file=sys.stderr) traceback.print_exc(file=sys.stderr)
self.serv.queue.put(e) self.serv.queue.put(e)
finally: finally:

View File

@ -26,7 +26,7 @@ from .util import (
check_json_precision, check_json_precision,
initialize_chain_clean, initialize_chain_clean,
) )
from authproxy import AuthServiceProxy, JSONRPCException from .authproxy import AuthServiceProxy, JSONRPCException
class BitcoinTestFramework(object): class BitcoinTestFramework(object):
@ -140,7 +140,7 @@ class BitcoinTestFramework(object):
print("JSONRPC error: "+e.error['message']) print("JSONRPC error: "+e.error['message'])
traceback.print_tb(sys.exc_info()[2]) traceback.print_tb(sys.exc_info()[2])
except AssertionError as e: except AssertionError as e:
print("Assertion failed: "+e.message) print("Assertion failed: "+ str(e))
traceback.print_tb(sys.exc_info()[2]) traceback.print_tb(sys.exc_info()[2])
except Exception as e: except Exception as e:
print("Unexpected exception caught during testing: "+str(e)) print("Unexpected exception caught during testing: "+str(e))

View File

@ -1,6 +1,8 @@
# Copyright (c) 2014-2015 The Bitcoin Core developers # Copyright (c) 2014-2015 The Bitcoin Core developers
# Distributed under the MIT 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. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
# #
# Helpful routines for regression testing # Helpful routines for regression testing
# #
@ -9,6 +11,8 @@
import os import os
import sys import sys
from binascii import hexlify, unhexlify
from base64 import b64encode
from decimal import Decimal, ROUND_DOWN from decimal import Decimal, ROUND_DOWN
import json import json
import random import random
@ -70,6 +74,15 @@ def check_json_precision():
def count_bytes(hex_string): def count_bytes(hex_string):
return len(bytearray.fromhex(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): def sync_blocks(rpc_connections, wait=1):
""" """
Wait until everybody has the same block count Wait until everybody has the same block count
@ -424,9 +437,40 @@ def assert_is_hash_string(string, length=64):
raise AssertionError( raise AssertionError(
"String %r contains invalid characters for a hash." % string) "String %r contains invalid characters for a hash." % string)
def satoshi_round(amount): def assert_array_result(object_array, to_match, expected, should_not_find = False):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) """
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): def create_confirmed_utxos(fee, node, count):
node.generate(int(0.5*count)+101) node.generate(int(0.5*count)+101)
utxos = node.listunspent() utxos = node.listunspent()
@ -454,6 +498,8 @@ def create_confirmed_utxos(fee, node, count):
assert(len(utxos) >= count) assert(len(utxos) >= count)
return utxos 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(): def gen_return_txouts():
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create # 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) # 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 txouts = txouts + script_pubkey
return txouts 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): def create_lots_of_big_transactions(node, txouts, utxos, fee):
addr = node.getnewaddress() addr = node.getnewaddress()
txids = [] txids = []

View File

@ -3,7 +3,6 @@
# Distributed under the MIT 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. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
@ -33,6 +32,12 @@ class WalletTest (BitcoinTestFramework):
self.sync_all() self.sync_all()
def run_test (self): def run_test (self):
# 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..." print "Mining blocks..."
self.nodes[0].generate(1) self.nodes[0].generate(1)
@ -49,6 +54,11 @@ class WalletTest (BitcoinTestFramework):
assert_equal(self.nodes[1].getbalance(), 50) assert_equal(self.nodes[1].getbalance(), 50)
assert_equal(self.nodes[2].getbalance(), 0) 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. # Send 21 BTC from 0 to 2 using sendtoaddress call.
# Second transaction will be child of first, and will require a fee # Second transaction will be child of first, and will require a fee
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
@ -61,6 +71,15 @@ class WalletTest (BitcoinTestFramework):
self.nodes[0].generate(1) self.nodes[0].generate(1)
self.sync_all() 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) # Have node1 generate 100 blocks (so node0 can recover the fee)
self.nodes[1].generate(100) self.nodes[1].generate(100)
self.sync_all() self.sync_all()
@ -150,6 +169,10 @@ class WalletTest (BitcoinTestFramework):
assert(txid1 in self.nodes[3].getrawmempool()) 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 #check if we can list zero value tx as available coins
#1. create rawtx #1. create rawtx
#2. hex-changed one output to 0.0 #2. hex-changed one output to 0.0
@ -234,28 +257,53 @@ class WalletTest (BitcoinTestFramework):
txObj = self.nodes[0].gettransaction(txId) txObj = self.nodes[0].gettransaction(txId)
assert_equal(txObj['amount'], Decimal('-0.0001')) assert_equal(txObj['amount'], Decimal('-0.0001'))
#this should fail
errorString = ""
try: try:
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4")
except JSONRPCException,e: except JSONRPCException as e:
errorString = e.error['message'] assert("Invalid amount" in e.error['message'])
else:
raise AssertionError("Must not parse invalid amounts")
assert_equal("Invalid amount" in errorString, True)
errorString = ""
try: try:
self.nodes[0].generate("2") #use a string to as block amount parameter must fail because it's not interpreted as amount self.nodes[0].generate("2")
except JSONRPCException,e: raise AssertionError("Must not accept strings as numeric")
errorString = e.error['message'] except JSONRPCException as e:
assert("not an integer" in e.error['message'])
assert_equal("not an integer" in errorString, True) # 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)
# 3. Validate that the imported address is watch-only on node1
assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"])
# 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})
#check if wallet or blochchain maintenance changes the balance #check if wallet or blochchain maintenance changes the balance
self.sync_all() self.sync_all()
self.nodes[0].generate(1) blocks = self.nodes[0].generate(2)
self.sync_all() self.sync_all()
balance_nodes = [self.nodes[i].getbalance() for i in range(3)] balance_nodes = [self.nodes[i].getbalance() for i in range(3)]
block_count = self.nodes[0].getblockcount()
maintenance = [ maintenance = [
'-rescan', '-rescan',
@ -265,15 +313,21 @@ class WalletTest (BitcoinTestFramework):
'-salvagewallet', '-salvagewallet',
] ]
for m in maintenance: for m in maintenance:
print "check " + m
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds() wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3)
connect_nodes_bi(self.nodes,0,1) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]:
connect_nodes_bi(self.nodes,1,2) # reindex will leave rpc warm up "early"; Wait for it to finish
connect_nodes_bi(self.nodes,0,2) time.sleep(0.1)
self.sync_all()
assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) 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__': if __name__ == '__main__':
WalletTest ().main () WalletTest ().main ()

View File

@ -65,14 +65,8 @@ class ZapWalletTXesTest (BitcoinTestFramework):
#restart bitcoind with zapwallettxes #restart bitcoind with zapwallettxes
self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
aException = False assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3])
try: #there must be a expection because the unconfirmed wallettx0 must be gone by now
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
tx0 = self.nodes[0].gettransaction(txid0) tx0 = self.nodes[0].gettransaction(txid0)
assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed

View File

@ -28,8 +28,8 @@ class ZMQTest (BitcoinTestFramework):
def setup_nodes(self): def setup_nodes(self):
self.zmqContext = zmq.Context() self.zmqContext = zmq.Context()
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock")
self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx")
self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port)
return start_nodes(4, self.options.tmpdir, extra_args=[ return start_nodes(4, self.options.tmpdir, extra_args=[
['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)],
@ -46,13 +46,13 @@ class ZMQTest (BitcoinTestFramework):
print "listen..." print "listen..."
msg = self.zmqSubSocket.recv_multipart() msg = self.zmqSubSocket.recv_multipart()
topic = str(msg[0]) topic = msg[0]
body = msg[1] body = msg[1]
msg = self.zmqSubSocket.recv_multipart() msg = self.zmqSubSocket.recv_multipart()
topic = str(msg[0]) topic = msg[0]
body = msg[1] body = msg[1]
blkhash = binascii.hexlify(body) blkhash = bytes_to_hex_str(body)
assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq
@ -63,10 +63,10 @@ class ZMQTest (BitcoinTestFramework):
zmqHashes = [] zmqHashes = []
for x in range(0,n*2): for x in range(0,n*2):
msg = self.zmqSubSocket.recv_multipart() msg = self.zmqSubSocket.recv_multipart()
topic = str(msg[0]) topic = msg[0]
body = msg[1] body = msg[1]
if topic == "hashblock": if topic == b"hashblock":
zmqHashes.append(binascii.hexlify(body)) zmqHashes.append(bytes_to_hex_str(body))
for x in range(0,n): for x in range(0,n):
assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq
@ -77,11 +77,11 @@ class ZMQTest (BitcoinTestFramework):
# now we should receive a zmq msg because the tx was broadcast # now we should receive a zmq msg because the tx was broadcast
msg = self.zmqSubSocket.recv_multipart() msg = self.zmqSubSocket.recv_multipart()
topic = str(msg[0]) topic = msg[0]
body = msg[1] body = msg[1]
hashZMQ = "" hashZMQ = ""
if topic == "hashtx": if topic == b"hashtx":
hashZMQ = binascii.hexlify(body) hashZMQ = bytes_to_hex_str(body)
assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq

View File

@ -2,6 +2,7 @@
# Distributed under the MIT 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. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from __future__ import division,print_function,unicode_literals
import subprocess import subprocess
import os import os
import json import json

View File

@ -196,6 +196,8 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
BOOST_CHECK_EQUAL(ret, COIN*10); BOOST_CHECK_EQUAL(ret, COIN*10);
BOOST_CHECK(ParseMoney("1.00", ret)); BOOST_CHECK(ParseMoney("1.00", ret));
BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("1", ret));
BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("0.1", ret)); BOOST_CHECK(ParseMoney("0.1", ret));
BOOST_CHECK_EQUAL(ret, COIN/10); BOOST_CHECK_EQUAL(ret, COIN/10);
BOOST_CHECK(ParseMoney("0.01", ret)); BOOST_CHECK(ParseMoney("0.01", ret));
@ -215,6 +217,9 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
// Attempted 63 bit overflow should fail // Attempted 63 bit overflow should fail
BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
// Parsing negative amounts must fail
BOOST_CHECK(!ParseMoney("-1", ret));
} }
BOOST_AUTO_TEST_CASE(util_IsHex) BOOST_AUTO_TEST_CASE(util_IsHex)