7 from .mininode
import *
8 from .blockstore
import BlockStore, TxStore
9 from .util
import p2p_port
12 This is a tool for comparing two or more dashds to each other 13 using a script provided. 15 To use, create a class that implements get_tests(), and pass it in 16 as the test generator to TestManager. get_tests() should be a python 17 generator that returns TestInstance objects. See below for definition. 32 Outcome that expects rejection of a transaction or block. 38 if self.
code != other.code:
40 return other.reason.startswith(self.
reason)
42 return '%i:%s' % (self.
code,self.
reason or '*')
47 NodeConnCB.__init__(self)
70 if len(message.headers) > 0:
71 best_header = message.headers[-1]
72 best_header.calc_sha256()
76 response = self.
block_store.headers_for(message.locator, message.hashstop)
77 if response
is not None:
78 conn.send_message(response)
81 [conn.send_message(r)
for r
in self.
block_store.get_blocks(message.inv)]
82 [conn.send_message(r)
for r
in self.
tx_store.get_transactions(message.inv)]
91 self.
lastInv = [x.hash
for x
in message.inv]
97 raise AssertionError(
"Got pong for unknown ping [%s]" % repr(message))
100 if message.message == b
'tx':
102 if message.message == b
'block':
106 mtype = 2
if isinstance(obj, CBlock)
else 1
113 self.
conn.send_message(m)
121 return nonce
not in self.
pingMap 157 def __init__(self, objects=None, sync_every_block=True, sync_every_tx=False):
173 for i
in range(len(nodes)):
188 return all(node.closed
for node
in self.
test_nodes)
193 return all(node.verack_received
for node
in self.
test_nodes)
197 def received_pongs():
198 return all(node.received_ping_response(counter)
for node
in self.
test_nodes)
205 def blocks_requested():
207 blockhash
in node.block_request_map
and node.block_request_map[blockhash]
212 if not wait_until(blocks_requested, attempts=20*num_blocks):
214 raise AssertionError(
"Not all nodes requested block")
217 [ c.cb.send_getheaders()
for c
in self.
connections ]
227 def transaction_requested():
229 txhash
in node.tx_request_map
and node.tx_request_map[txhash]
234 if not wait_until(transaction_requested, attempts=20*num_events):
236 raise AssertionError(
"Not all nodes requested transaction")
256 if c.cb.bestblockhash != self.
connections[0].cb.bestblockhash:
258 elif isinstance(outcome, RejectResult):
259 if c.cb.bestblockhash == blockhash:
261 if blockhash
not in c.cb.block_reject_map:
262 print 'Block not in reject map: %064x' % (blockhash)
264 if not outcome.match(c.cb.block_reject_map[blockhash]):
265 print 'Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash)
267 elif ((c.cb.bestblockhash == blockhash) != outcome):
286 elif isinstance(outcome, RejectResult):
287 if txhash
in c.cb.lastInv:
289 if txhash
not in c.cb.tx_reject_map:
290 print 'Tx not in reject map: %064x' % (txhash)
292 if not outcome.match(c.cb.tx_reject_map[txhash]):
293 print 'Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash)
295 elif ((txhash
in c.cb.lastInv) != outcome):
309 [ block, block_outcome, tip ] = [
None,
None,
None ]
310 [ tx, tx_outcome ] = [
None,
None ]
313 for test_obj
in test_instance.blocks_and_transactions:
315 outcome = test_obj[1]
317 if isinstance(b_or_t, CBlock):
319 block_outcome = outcome
324 if len(test_obj) >= 3:
333 first_block_with_hash =
True 335 first_block_with_hash =
False 339 if first_block_with_hash
and block.sha256
in c.cb.block_request_map
and c.cb.block_request_map[block.sha256] ==
True:
345 c.cb.block_request_map[block.sha256] =
False 348 if (test_instance.sync_every_block):
352 raise AssertionError(
"Test failed at test %d" % test_number)
354 invqueue.append(
CInv(2, block.sha256))
355 elif isinstance(b_or_t, CBlockHeader):
356 block_header = b_or_t
359 assert(isinstance(b_or_t, CTransaction))
366 c.cb.tx_request_map[tx.sha256] =
False 368 if (test_instance.sync_every_tx):
372 raise AssertionError(
"Test failed at test %d" % test_number)
374 invqueue.append(
CInv(1, tx.sha256))
376 if len(invqueue) == MAX_INV_SZ:
381 if (
not test_instance.sync_every_block
and block
is not None):
382 if len(invqueue) > 0:
385 self.
sync_blocks(block.sha256, len(test_instance.blocks_and_transactions))
387 raise AssertionError(
"Block test failed at test %d" % test_number)
388 if (
not test_instance.sync_every_tx
and tx
is not None):
389 if len(invqueue) > 0:
392 self.
sync_transaction(tx.sha256, len(test_instance.blocks_and_transactions))
394 raise AssertionError(
"Mempool test failed at test %d" % test_number)
396 print "Test %d: PASS" % test_number, [ c.rpc.getblockcount()
for c
in self.
connections ]
def wait_until(predicate, attempts=float('inf'), timeout=float('inf'))