aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/assumevalid.py10
-rwxr-xr-xtest/functional/bumpfee.py1
-rwxr-xr-xtest/functional/fundrawtransaction.py4
-rwxr-xr-xtest/functional/importmulti.py2
-rwxr-xr-xtest/functional/keypool.py41
-rwxr-xr-xtest/functional/maxblocksinflight.py6
-rwxr-xr-xtest/functional/maxuploadtarget.py11
-rwxr-xr-xtest/functional/p2p-acceptblock.py17
-rwxr-xr-xtest/functional/p2p-compactblocks.py27
-rwxr-xr-xtest/functional/p2p-feefilter.py4
-rwxr-xr-xtest/functional/p2p-leaktests.py2
-rwxr-xr-xtest/functional/p2p-mempool.py11
-rwxr-xr-xtest/functional/p2p-segwit.py24
-rwxr-xr-xtest/functional/p2p-timeouts.py4
-rwxr-xr-xtest/functional/p2p-versionbits-warning.py17
-rwxr-xr-xtest/functional/sendheaders.py4
-rwxr-xr-xtest/functional/test_framework/comptool.py2
-rwxr-xr-xtest/functional/test_framework/mininode.py125
-rwxr-xr-xtest/functional/wallet-dump.py6
-rwxr-xr-xtest/functional/wallet-hd.py19
-rw-r--r--test/util/bctest.py12
-rw-r--r--test/util/data/bitcoin-util-test.json36
22 files changed, 217 insertions, 168 deletions
diff --git a/test/functional/assumevalid.py b/test/functional/assumevalid.py
index da680a5d24..8e301c4379 100755
--- a/test/functional/assumevalid.py
+++ b/test/functional/assumevalid.py
@@ -40,17 +40,14 @@ from test_framework.mininode import (CBlockHeader,
CTxOut,
NetworkThread,
NodeConn,
- SingleNodeConnCB,
+ NodeConnCB,
msg_block,
msg_headers)
from test_framework.script import (CScript, OP_TRUE)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (start_node, p2p_port, assert_equal)
-class BaseNode(SingleNodeConnCB):
- def __init__(self):
- super().__init__()
-
+class BaseNode(NodeConnCB):
def send_header_for_blocks(self, new_blocks):
headers_message = msg_headers()
headers_message.headers = [CBlockHeader(b) for b in new_blocks]
@@ -193,7 +190,8 @@ class AssumeValidTest(BitcoinTestFramework):
# Send all blocks to node1. All blocks will be accepted.
for i in range(2202):
node1.send_message(msg_block(self.blocks[i]))
- node1.sync_with_ping() # make sure the most recent block is synced
+ # Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
+ node1.sync_with_ping(120)
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
# Send blocks to node2. Block 102 will be rejected.
diff --git a/test/functional/bumpfee.py b/test/functional/bumpfee.py
index 172e414188..c51a75cc26 100755
--- a/test/functional/bumpfee.py
+++ b/test/functional/bumpfee.py
@@ -196,7 +196,6 @@ def test_dust_to_fee(rbf_node, dest_address):
def test_settxfee(rbf_node, dest_address):
# check that bumpfee reacts correctly to the use of settxfee (paytxfee)
rbfid = spend_one_input(rbf_node, dest_address)
- rbftx = rbf_node.gettransaction(rbfid)
requested_feerate = Decimal("0.00025000")
rbf_node.settxfee(requested_feerate)
bumped_tx = rbf_node.bumpfee(rbfid)
diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py
index 3bfc05d37b..b86ea2d877 100755
--- a/test/functional/fundrawtransaction.py
+++ b/test/functional/fundrawtransaction.py
@@ -467,6 +467,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# drain the keypool
self.nodes[1].getnewaddress()
+ self.nodes[1].getrawchangeaddress()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
@@ -476,6 +477,7 @@ class RawTransactionsTest(BitcoinTestFramework):
#refill the keypool
self.nodes[1].walletpassphrase("test", 100)
+ self.nodes[1].keypoolrefill(8) #need to refill the keypool to get an internal change address
self.nodes[1].walletlock()
assert_raises_jsonrpc(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
@@ -644,7 +646,7 @@ class RawTransactionsTest(BitcoinTestFramework):
if out['value'] > 1.0:
changeaddress += out['scriptPubKey']['addresses'][0]
assert(changeaddress != "")
- nextaddr = self.nodes[3].getnewaddress()
+ nextaddr = self.nodes[3].getrawchangeaddress()
# frt should not have removed the key from the keypool
assert(changeaddress == nextaddr)
diff --git a/test/functional/importmulti.py b/test/functional/importmulti.py
index aa03c6780a..e049302632 100755
--- a/test/functional/importmulti.py
+++ b/test/functional/importmulti.py
@@ -434,7 +434,7 @@ class ImportMultiTest (BitcoinTestFramework):
address_assert = self.nodes[1].validateaddress(watchonly_address)
assert_equal(address_assert['iswatchonly'], True)
assert_equal(address_assert['ismine'], False)
- assert_equal(address_assert['timestamp'], watchonly_timestamp);
+ assert_equal(address_assert['timestamp'], watchonly_timestamp)
# Bad or missing timestamps
self.log.info("Should throw on invalid or missing timestamp values")
diff --git a/test/functional/keypool.py b/test/functional/keypool.py
index cee58563f0..cb9ab688d1 100755
--- a/test/functional/keypool.py
+++ b/test/functional/keypool.py
@@ -27,28 +27,42 @@ class KeyPoolTest(BitcoinTestFramework):
wallet_info = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
-
assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)
- # put three new keys in the keypool
+ # put six (plus 2) new keys in the keypool (100% external-, +100% internal-keys, 1 in min)
nodes[0].walletpassphrase('test', 12000)
- nodes[0].keypoolrefill(3)
+ nodes[0].keypoolrefill(6)
nodes[0].walletlock()
+ wi = nodes[0].getwalletinfo()
+ assert_equal(wi['keypoolsize_hd_internal'], 6)
+ assert_equal(wi['keypoolsize'], 6)
- # drain the keys
+ # drain the internal keys
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
addr = set()
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- # assert that four unique addresses were returned
- assert(len(addr) == 4)
# the next one should fail
assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].getrawchangeaddress)
+ # drain the external keys
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ assert(len(addr) == 6)
+ # the next one should fail
+ assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)
+
# refill keypool with three new addresses
nodes[0].walletpassphrase('test', 1)
nodes[0].keypoolrefill(3)
+
# test walletpassphrase timeout
time.sleep(1.1)
assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)
@@ -57,9 +71,14 @@ class KeyPoolTest(BitcoinTestFramework):
nodes[0].generate(1)
nodes[0].generate(1)
nodes[0].generate(1)
- nodes[0].generate(1)
assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].generate, 1)
+ nodes[0].walletpassphrase('test', 100)
+ nodes[0].keypoolrefill(100)
+ wi = nodes[0].getwalletinfo()
+ assert_equal(wi['keypoolsize_hd_internal'], 100)
+ assert_equal(wi['keypoolsize'], 100)
+
def __init__(self):
super().__init__()
self.setup_clean_chain = False
diff --git a/test/functional/maxblocksinflight.py b/test/functional/maxblocksinflight.py
index 2c3766125a..4ef2a35a44 100755
--- a/test/functional/maxblocksinflight.py
+++ b/test/functional/maxblocksinflight.py
@@ -17,7 +17,6 @@ from test_framework.util import *
MAX_REQUESTS = 128
class TestManager(NodeConnCB):
- # set up NodeConnCB callbacks, overriding base class
def on_getdata(self, conn, message):
self.log.debug("got getdata %s" % repr(message))
# Log the requests
@@ -30,11 +29,8 @@ class TestManager(NodeConnCB):
if not self.disconnectOkay:
raise EarlyDisconnectError(0)
- def __init__(self):
- NodeConnCB.__init__(self)
-
def add_new_connection(self, connection):
- self.connection = connection
+ super().add_connection(connection)
self.blockReqCounts = {}
self.disconnectOkay = False
diff --git a/test/functional/maxuploadtarget.py b/test/functional/maxuploadtarget.py
index 40cd85c9ec..9b42bf276c 100755
--- a/test/functional/maxuploadtarget.py
+++ b/test/functional/maxuploadtarget.py
@@ -20,7 +20,7 @@ import time
# p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB):
def __init__(self):
- NodeConnCB.__init__(self)
+ super().__init__()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -68,15 +68,6 @@ class TestNode(NodeConnCB):
def on_close(self, conn):
self.peer_disconnected = True
- # Sync up with the node after delivery of a block
- def sync_with_ping(self, timeout=30):
- def received_pong():
- return (self.last_pong.nonce == self.ping_counter)
- self.connection.send_message(msg_ping(nonce=self.ping_counter))
- success = wait_until(received_pong, timeout=timeout)
- self.ping_counter += 1
- return success
-
class MaxUploadTest(BitcoinTestFramework):
def __init__(self):
diff --git a/test/functional/p2p-acceptblock.py b/test/functional/p2p-acceptblock.py
index e1111da4ae..c09945baa6 100755
--- a/test/functional/p2p-acceptblock.py
+++ b/test/functional/p2p-acceptblock.py
@@ -58,7 +58,7 @@ from test_framework.blocktools import create_block, create_coinbase
# p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB):
def __init__(self):
- NodeConnCB.__init__(self)
+ super().__init__()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -88,21 +88,6 @@ class TestNode(NodeConnCB):
def on_pong(self, conn, message):
self.last_pong = message
- # Sync up with the node after delivery of a block
- def sync_with_ping(self, timeout=30):
- self.connection.send_message(msg_ping(nonce=self.ping_counter))
- received_pong = False
- sleep_time = 0.05
- while not received_pong and timeout > 0:
- time.sleep(sleep_time)
- timeout -= sleep_time
- with mininode_lock:
- if self.last_pong.nonce == self.ping_counter:
- received_pong = True
- self.ping_counter += 1
- return received_pong
-
-
class AcceptBlockTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
diff --git a/test/functional/p2p-compactblocks.py b/test/functional/p2p-compactblocks.py
index 1fc0312c34..bf8d113767 100755
--- a/test/functional/p2p-compactblocks.py
+++ b/test/functional/p2p-compactblocks.py
@@ -15,9 +15,9 @@ from test_framework.blocktools import create_block, create_coinbase, add_witness
from test_framework.script import CScript, OP_TRUE
# TestNode: A peer we use to send messages to bitcoind, and store responses.
-class TestNode(SingleNodeConnCB):
+class TestNode(NodeConnCB):
def __init__(self):
- SingleNodeConnCB.__init__(self)
+ super().__init__()
self.last_sendcmpct = []
self.last_headers = None
self.last_inv = None
@@ -32,6 +32,13 @@ class TestNode(SingleNodeConnCB):
# This is for synchronizing the p2p message traffic,
# so we can eg wait until a particular block is announced.
self.set_announced_blockhashes = set()
+ self.connected = False
+
+ def on_open(self, conn):
+ self.connected = True
+
+ def on_close(self, conn):
+ self.connected = False
def on_sendcmpct(self, conn, message):
self.last_sendcmpct.append(message)
@@ -107,6 +114,18 @@ class TestNode(SingleNodeConnCB):
return (block_hash in self.set_announced_blockhashes)
return wait_until(received_hash, timeout=timeout)
+ def send_await_disconnect(self, message, timeout=30):
+ """Sends a message to the node and wait for disconnect.
+
+ This is used when we want to send a message into the node that we expect
+ will get us disconnected, eg an invalid block."""
+ self.send_message(message)
+ success = wait_until(lambda: not self.connected, timeout=timeout)
+ if not success:
+ logger.error("send_await_disconnect failed!")
+ raise AssertionError("send_await_disconnect failed!")
+ return success
+
class CompactBlocksTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
@@ -274,8 +293,8 @@ class CompactBlocksTest(BitcoinTestFramework):
# This index will be too high
prefilled_txn = PrefilledTransaction(1, block.vtx[0])
cmpct_block.prefilled_txn = [prefilled_txn]
- self.test_node.send_and_ping(msg_cmpctblock(cmpct_block))
- assert(int(self.nodes[0].getbestblockhash(), 16) == block.hashPrevBlock)
+ self.test_node.send_await_disconnect(msg_cmpctblock(cmpct_block))
+ assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock)
# Compare the generated shortids to what we expect based on BIP 152, given
# bitcoind's choice of nonce.
diff --git a/test/functional/p2p-feefilter.py b/test/functional/p2p-feefilter.py
index d8f07700d0..12539be950 100755
--- a/test/functional/p2p-feefilter.py
+++ b/test/functional/p2p-feefilter.py
@@ -24,9 +24,9 @@ def allInvsMatch(invsExpected, testnode):
# TestNode: bare-bones "peer". Used to track which invs are received from a node
# and to send the node feefilter messages.
-class TestNode(SingleNodeConnCB):
+class TestNode(NodeConnCB):
def __init__(self):
- SingleNodeConnCB.__init__(self)
+ super().__init__()
self.txinvs = []
def on_inv(self, conn, message):
diff --git a/test/functional/p2p-leaktests.py b/test/functional/p2p-leaktests.py
index 3a843197fb..5853ec86f0 100755
--- a/test/functional/p2p-leaktests.py
+++ b/test/functional/p2p-leaktests.py
@@ -19,10 +19,10 @@ banscore = 10
class CLazyNode(NodeConnCB):
def __init__(self):
+ super().__init__()
self.connection = None
self.unexpected_msg = False
self.connected = False
- super().__init__()
def add_connection(self, conn):
self.connection = conn
diff --git a/test/functional/p2p-mempool.py b/test/functional/p2p-mempool.py
index 0aa9c90e8f..5064ce74aa 100755
--- a/test/functional/p2p-mempool.py
+++ b/test/functional/p2p-mempool.py
@@ -14,7 +14,7 @@ from test_framework.util import *
class TestNode(NodeConnCB):
def __init__(self):
- NodeConnCB.__init__(self)
+ super().__init__()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -62,15 +62,6 @@ class TestNode(NodeConnCB):
def on_close(self, conn):
self.peer_disconnected = True
- # Sync up with the node after delivery of a block
- def sync_with_ping(self, timeout=30):
- def received_pong():
- return (self.last_pong.nonce == self.ping_counter)
- self.connection.send_message(msg_ping(nonce=self.ping_counter))
- success = wait_until(received_pong, timeout=timeout)
- self.ping_counter += 1
- return success
-
def send_mempool(self):
self.lastInv = []
self.send_message(msg_mempool())
diff --git a/test/functional/p2p-segwit.py b/test/functional/p2p-segwit.py
index dcf2b9a7de..cd7b788eb4 100755
--- a/test/functional/p2p-segwit.py
+++ b/test/functional/p2p-segwit.py
@@ -32,10 +32,9 @@ def get_virtual_size(witness_block):
vsize = int((3*base_size + total_size + 3)/4)
return vsize
-# Note: we can reduce code by using SingleNodeConnCB (in master, not 0.12)
class TestNode(NodeConnCB):
def __init__(self):
- NodeConnCB.__init__(self)
+ super().__init__()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong(0)
@@ -81,13 +80,6 @@ class TestNode(NodeConnCB):
timeout -= self.sleep_time
raise AssertionError("Sync failed to complete")
- def sync_with_ping(self, timeout=60):
- self.send_message(msg_ping(nonce=self.ping_counter))
- test_function = lambda: self.last_pong.nonce == self.ping_counter
- self.sync(test_function, timeout)
- self.ping_counter += 1
- return
-
def wait_for_block(self, blockhash, timeout=60):
test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash
self.sync(test_function, timeout)
@@ -149,7 +141,7 @@ class TestNode(NodeConnCB):
if with_witness:
tx_message = msg_witness_tx(tx)
self.send_message(tx_message)
- self.sync_with_ping()
+ self.sync_with_ping(60)
assert_equal(tx.hash in self.connection.rpc.getrawmempool(), accepted)
if (reason != None and not accepted):
# Check the rejection reason as well.
@@ -162,7 +154,7 @@ class TestNode(NodeConnCB):
self.send_message(msg_witness_block(block))
else:
self.send_message(msg_block(block))
- self.sync_with_ping()
+ self.sync_with_ping(60)
assert_equal(self.connection.rpc.getbestblockhash() == block.hash, accepted)
@@ -236,7 +228,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block(nVersion=1)
block.solve()
self.test_node.send_message(msg_block(block))
- self.test_node.sync_with_ping() # make sure the block was processed
+ self.test_node.sync_with_ping(60) # make sure the block was processed
txid = block.vtx[0].sha256
self.nodes[0].generate(99) # let the block mature
@@ -252,7 +244,7 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(msg_tx(tx).serialize(), msg_witness_tx(tx).serialize())
self.test_node.send_message(msg_witness_tx(tx))
- self.test_node.sync_with_ping() # make sure the tx was processed
+ self.test_node.sync_with_ping(60) # make sure the tx was processed
assert(tx.hash in self.nodes[0].getrawmempool())
# Save this transaction for later
self.utxo.append(UTXO(tx.sha256, 0, 49*100000000))
@@ -292,7 +284,7 @@ class SegWitTest(BitcoinTestFramework):
# But it should not be permanently marked bad...
# Resend without witness information.
self.test_node.send_message(msg_block(block))
- self.test_node.sync_with_ping()
+ self.test_node.sync_with_ping(60)
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
sync_blocks(self.nodes)
@@ -1258,7 +1250,7 @@ class SegWitTest(BitcoinTestFramework):
# Spending a higher version witness output is not allowed by policy,
# even with fRequireStandard=false.
self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=False)
- self.test_node.sync_with_ping()
+ self.test_node.sync_with_ping(60)
with mininode_lock:
assert(b"reserved for soft-fork upgrades" in self.test_node.last_reject.reason)
@@ -1388,7 +1380,7 @@ class SegWitTest(BitcoinTestFramework):
for i in range(NUM_TESTS):
# Ping regularly to keep the connection alive
if (not i % 100):
- self.test_node.sync_with_ping()
+ self.test_node.sync_with_ping(60)
# Choose random number of inputs to use.
num_inputs = random.randint(1, 10)
# Create a slight bias for producing more utxos
diff --git a/test/functional/p2p-timeouts.py b/test/functional/p2p-timeouts.py
index 498acb23fe..de4edd6800 100755
--- a/test/functional/p2p-timeouts.py
+++ b/test/functional/p2p-timeouts.py
@@ -27,9 +27,9 @@ from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-class TestNode(SingleNodeConnCB):
+class TestNode(NodeConnCB):
def __init__(self):
- SingleNodeConnCB.__init__(self)
+ super().__init__()
self.connected = False
self.received_version = False
diff --git a/test/functional/p2p-versionbits-warning.py b/test/functional/p2p-versionbits-warning.py
index dc714e9a4a..da960e2d80 100755
--- a/test/functional/p2p-versionbits-warning.py
+++ b/test/functional/p2p-versionbits-warning.py
@@ -28,7 +28,7 @@ VB_PATTERN = re.compile("^Warning.*versionbit")
# p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB):
def __init__(self):
- NodeConnCB.__init__(self)
+ super().__init__()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -46,21 +46,6 @@ class TestNode(NodeConnCB):
def on_pong(self, conn, message):
self.last_pong = message
- # Sync up with the node after delivery of a block
- def sync_with_ping(self, timeout=30):
- self.connection.send_message(msg_ping(nonce=self.ping_counter))
- received_pong = False
- sleep_time = 0.05
- while not received_pong and timeout > 0:
- time.sleep(sleep_time)
- timeout -= sleep_time
- with mininode_lock:
- if self.last_pong.nonce == self.ping_counter:
- received_pong = True
- self.ping_counter += 1
- return received_pong
-
-
class VersionBitsWarningTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
diff --git a/test/functional/sendheaders.py b/test/functional/sendheaders.py
index de7f5e0849..1a7475ae84 100755
--- a/test/functional/sendheaders.py
+++ b/test/functional/sendheaders.py
@@ -81,9 +81,9 @@ from test_framework.blocktools import create_block, create_coinbase
direct_fetch_response_time = 0.05
-class BaseNode(SingleNodeConnCB):
+class BaseNode(NodeConnCB):
def __init__(self):
- SingleNodeConnCB.__init__(self)
+ super().__init__()
self.last_inv = None
self.last_headers = None
self.last_block = None
diff --git a/test/functional/test_framework/comptool.py b/test/functional/test_framework/comptool.py
index 70d1d700ef..25c18bda82 100755
--- a/test/functional/test_framework/comptool.py
+++ b/test/functional/test_framework/comptool.py
@@ -42,7 +42,7 @@ class RejectResult(object):
class TestNode(NodeConnCB):
def __init__(self, block_store, tx_store):
- NodeConnCB.__init__(self)
+ super().__init__()
self.conn = None
self.bestblockhash = None
self.block_store = block_store
diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py
index aace17a043..ebb846a237 100755
--- a/test/functional/test_framework/mininode.py
+++ b/test/functional/test_framework/mininode.py
@@ -1476,25 +1476,9 @@ class NodeConnCB(object):
self.deliver_sleep_time = None
# Remember the services our peer has advertised
self.peer_services = None
-
- def set_deliver_sleep_time(self, value):
- with mininode_lock:
- self.deliver_sleep_time = value
-
- def get_deliver_sleep_time(self):
- with mininode_lock:
- return self.deliver_sleep_time
-
- # Spin until verack message is received from the node.
- # Tests may want to use this as a signal that the test can begin.
- # This can be called from the testing thread, so it needs to acquire the
- # global lock.
- def wait_for_verack(self):
- while True:
- with mininode_lock:
- if self.verack_received:
- return
- time.sleep(0.05)
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
def deliver(self, conn, message):
deliver_sleep = self.get_deliver_sleep_time()
@@ -1506,17 +1490,36 @@ class NodeConnCB(object):
except:
logger.exception("ERROR delivering %s" % repr(message))
- def on_version(self, conn, message):
- if message.nVersion >= 209:
- conn.send_message(msg_verack())
- conn.ver_send = min(MY_VERSION, message.nVersion)
- if message.nVersion < 209:
- conn.ver_recv = conn.ver_send
- conn.nServices = message.nServices
+ def set_deliver_sleep_time(self, value):
+ with mininode_lock:
+ self.deliver_sleep_time = value
- def on_verack(self, conn, message):
- conn.ver_recv = conn.ver_send
- self.verack_received = True
+ def get_deliver_sleep_time(self):
+ with mininode_lock:
+ return self.deliver_sleep_time
+
+ # Callbacks which can be overridden by subclasses
+ #################################################
+
+ def on_addr(self, conn, message): pass
+ def on_alert(self, conn, message): pass
+ def on_block(self, conn, message): pass
+ def on_blocktxn(self, conn, message): pass
+ def on_close(self, conn): pass
+ def on_cmpctblock(self, conn, message): pass
+ def on_feefilter(self, conn, message): pass
+ def on_getaddr(self, conn, message): pass
+ def on_getblocks(self, conn, message): pass
+ def on_getblocktxn(self, conn, message): pass
+ def on_getdata(self, conn, message): pass
+ def on_getheaders(self, conn, message): pass
+ def on_headers(self, conn, message): pass
+ def on_mempool(self, conn): pass
+ def on_open(self, conn): pass
+ def on_reject(self, conn, message): pass
+ def on_sendcmpct(self, conn, message): pass
+ def on_sendheaders(self, conn, message): pass
+ def on_tx(self, conn, message): pass
def on_inv(self, conn, message):
want = msg_getdata()
@@ -1526,37 +1529,27 @@ class NodeConnCB(object):
if len(want.inv):
conn.send_message(want)
- def on_addr(self, conn, message): pass
- def on_alert(self, conn, message): pass
- def on_getdata(self, conn, message): pass
- def on_getblocks(self, conn, message): pass
- def on_tx(self, conn, message): pass
- def on_block(self, conn, message): pass
- def on_getaddr(self, conn, message): pass
- def on_headers(self, conn, message): pass
- def on_getheaders(self, conn, message): pass
def on_ping(self, conn, message):
if conn.ver_send > BIP0031_VERSION:
conn.send_message(msg_pong(message.nonce))
- def on_reject(self, conn, message): pass
- def on_open(self, conn): pass
- def on_close(self, conn): pass
- def on_mempool(self, conn): pass
- def on_pong(self, conn, message): pass
- def on_feefilter(self, conn, message): pass
- def on_sendheaders(self, conn, message): pass
- def on_sendcmpct(self, conn, message): pass
- def on_cmpctblock(self, conn, message): pass
- def on_getblocktxn(self, conn, message): pass
- def on_blocktxn(self, conn, message): pass
-# More useful callbacks and functions for NodeConnCB's which have a single NodeConn
-class SingleNodeConnCB(NodeConnCB):
- def __init__(self):
- NodeConnCB.__init__(self)
- self.connection = None
- self.ping_counter = 1
- self.last_pong = msg_pong()
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ def on_verack(self, conn, message):
+ conn.ver_recv = conn.ver_send
+ self.verack_received = True
+
+ def on_version(self, conn, message):
+ if message.nVersion >= 209:
+ conn.send_message(msg_verack())
+ conn.ver_send = min(MY_VERSION, message.nVersion)
+ if message.nVersion < 209:
+ conn.ver_recv = conn.ver_send
+ conn.nServices = message.nServices
+
+ # Helper functions
+ ##################
def add_connection(self, conn):
self.connection = conn
@@ -1569,18 +1562,30 @@ class SingleNodeConnCB(NodeConnCB):
self.send_message(message)
self.sync_with_ping()
- def on_pong(self, conn, message):
- self.last_pong = message
-
# Sync up with the node
- def sync_with_ping(self, timeout=30):
+ def sync_with_ping(self, timeout=60):
def received_pong():
return (self.last_pong.nonce == self.ping_counter)
self.send_message(msg_ping(nonce=self.ping_counter))
success = wait_until(received_pong, timeout=timeout)
+ if not success:
+ logger.error("sync_with_ping failed!")
+ raise AssertionError("sync_with_ping failed!")
self.ping_counter += 1
+
return success
+ # Spin until verack message is received from the node.
+ # Tests may want to use this as a signal that the test can begin.
+ # This can be called from the testing thread, so it needs to acquire the
+ # global lock.
+ def wait_for_verack(self):
+ while True:
+ with mininode_lock:
+ if self.verack_received:
+ return
+ time.sleep(0.05)
+
# The actual NodeConn class
# This class provides an interface for a p2p connection to a specified node
class NodeConn(asyncore.dispatcher):
diff --git a/test/functional/wallet-dump.py b/test/functional/wallet-dump.py
index b819b72b75..8876f935a4 100755
--- a/test/functional/wallet-dump.py
+++ b/test/functional/wallet-dump.py
@@ -88,7 +88,7 @@ class WalletDumpTest(BitcoinTestFramework):
read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, None)
assert_equal(found_addr, test_addr_count) # all keys must be in the dump
assert_equal(found_addr_chg, 50) # 50 blocks where mined
- assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one)
+ assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys
#encrypt wallet, restart, unlock and dump
self.nodes[0].encryptwallet('test')
@@ -102,8 +102,8 @@ class WalletDumpTest(BitcoinTestFramework):
found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_enc = \
read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, hd_master_addr_unenc)
assert_equal(found_addr, test_addr_count)
- assert_equal(found_addr_chg, 90 + 1 + 50) # old reserve keys are marked as change now
- assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one)
+ assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now
+ assert_equal(found_addr_rsv, 90*2)
if __name__ == '__main__':
WalletDumpTest().main ()
diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py
index c40662dc3d..64a6c92782 100755
--- a/test/functional/wallet-hd.py
+++ b/test/functional/wallet-hd.py
@@ -42,6 +42,11 @@ class WalletHDTest(BitcoinTestFramework):
masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid']
assert_equal(len(masterkeyid), 40)
+ # create an internal key
+ change_addr = self.nodes[1].getrawchangeaddress()
+ change_addrV= self.nodes[1].validateaddress(change_addr);
+ assert_equal(change_addrV["hdkeypath"], "m/0'/1'/0'") #first internal child key
+
# Import a non-HD private key in the HD wallet
non_hd_add = self.nodes[0].getnewaddress()
self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add))
@@ -65,6 +70,11 @@ class WalletHDTest(BitcoinTestFramework):
self.nodes[0].sendtoaddress(non_hd_add, 1)
self.nodes[0].generate(1)
+ # create an internal key (again)
+ change_addr = self.nodes[1].getrawchangeaddress()
+ change_addrV= self.nodes[1].validateaddress(change_addr);
+ assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") #second internal child key
+
self.sync_all()
assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
@@ -90,6 +100,15 @@ class WalletHDTest(BitcoinTestFramework):
#connect_nodes_bi(self.nodes, 0, 1)
assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
+ # send a tx and make sure its using the internal chain for the changeoutput
+ txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1)
+ outs = self.nodes[1].decoderawtransaction(self.nodes[1].gettransaction(txid)['hex'])['vout'];
+ keypath = ""
+ for out in outs:
+ if out['value'] != 1:
+ keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath']
+
+ assert_equal(keypath[0:7], "m/0'/1'")
if __name__ == '__main__':
WalletHDTest().main ()
diff --git a/test/util/bctest.py b/test/util/bctest.py
index dfe3a123d1..b17cf77ae3 100644
--- a/test/util/bctest.py
+++ b/test/util/bctest.py
@@ -102,6 +102,18 @@ def bctest(testDir, testObj, buildenv):
logging.error("Return code mismatch for " + outputFn)
raise Exception
+ if "error_txt" in testObj:
+ want_error = testObj["error_txt"]
+ # Compare error text
+ # TODO: ideally, we'd compare the strings exactly and also assert
+ # That stderr is empty if no errors are expected. However, bitcoin-tx
+ # emits DISPLAY errors when running as a windows application on
+ # linux through wine. Just assert that the expected error text appears
+ # somewhere in stderr.
+ if want_error not in outs[1]:
+ logging.error("Error mismatch:\n" + "Expected: " + want_error + "\nReceived: " + outs[1].rstrip())
+ raise Exception
+
def bctester(testDir, input_basename, buildenv):
""" Loads and parses the input file, runs all tests and reports results"""
input_filename = testDir + "/" + input_basename
diff --git a/test/util/data/bitcoin-util-test.json b/test/util/data/bitcoin-util-test.json
index a80ab51901..b61a4f7f8f 100644
--- a/test/util/data/bitcoin-util-test.json
+++ b/test/util/data/bitcoin-util-test.json
@@ -42,6 +42,7 @@
"args": ["-", "delin=31"],
"input": "tx394b54bb.hex",
"return_code": 1,
+ "error_txt": "error: Invalid TX input index '31'",
"description": "Attempts to delete an input with a bad index from a transaction. Expected to fail."
},
{ "exec": "./bitcoin-tx",
@@ -60,6 +61,7 @@
"args": ["-", "delout=2"],
"input": "tx394b54bb.hex",
"return_code": 1,
+ "error_txt": "error: Invalid TX output index '2'",
"description": "Attempts to delete an output with a bad index from a transaction. Expected to fail."
},
{ "exec": "./bitcoin-tx",
@@ -77,6 +79,38 @@
{ "exec": "./bitcoin-tx",
"args":
["-create",
+ "outaddr=1"],
+ "return_code": 1,
+ "error_txt": "error: TX output missing or too many separators",
+ "description": "Malformed outaddr argument (no address specified). Expected to fail."
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "outaddr=1:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o:garbage"],
+ "return_code": 1,
+ "error_txt": "error: TX output missing or too many separators",
+ "description": "Malformed outaddr argument (too many separators). Expected to fail."
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "outpubkey=0"],
+ "return_code": 1,
+ "error_txt": "error: TX output missing or too many separators",
+ "description": "Malformed outpubkey argument (no pubkey specified). Expected to fail."
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:W:non53nse"],
+ "return_code": 1,
+ "error_txt": "error: TX output missing or too many separators",
+ "description": "Malformed outpubkey argument (too many separators). Expected to fail."
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
"in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
@@ -233,6 +267,7 @@
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"outdata=4:badhexdata"],
"return_code": 1,
+ "error_txt": "error: invalid TX output data",
"description": "Attempts to create a new transaction with one input and an output with malformed hex data. Expected to fail"
},
{ "exec": "./bitcoin-tx",
@@ -241,6 +276,7 @@
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"outdata=badhexdata"],
"return_code": 1,
+ "error_txt": "error: invalid TX output data",
"description": "Attempts to create a new transaction with one input and an output with no value and malformed hex data. Expected to fail"
},
{ "exec": "./bitcoin-tx",