def test_BlockHandler_simple(): # create some peers peer1_2, peer2_1 = create_handshaked_peers(ip1="127.0.0.1", ip2="127.0.0.2") peer1_3, peer3_1 = create_handshaked_peers(ip1="127.0.0.1", ip2="127.0.0.3") BLOCK_LIST = make_blocks(2) @asyncio.coroutine def run_client(peer_list, block_list): block_chain = BlockChain() block_store = {} inv_collector = InvCollector() block_handler = BlockHandler(inv_collector, block_chain, block_store) for peer in peer_list: inv_collector.add_peer(peer) block_handler.add_peer(peer) for block in block_list: inv_collector.advertise_item(InvItem(ITEM_TYPE_BLOCK, block.hash())) block_store[block.hash()] = block while len(block_store) < 2: yield from asyncio.sleep(0.1) return block_store f1 = asyncio.Task(run_client([peer1_2, peer1_3], [])) f2 = asyncio.Task(run_client([peer2_1], BLOCK_LIST[0:1])) f3 = asyncio.Task(run_client([peer3_1], BLOCK_LIST[1:2])) done, pending = asyncio.get_event_loop().run_until_complete(asyncio.wait([f1, f2, f3], timeout=5.0)) assert len(done) == 3 assert len(pending) == 0 for i in range(3): r = done.pop().result() assert len(r) == 2
def test_BlockHandler_tcp(): BLOCK_LIST = make_blocks(32) BL1 = BLOCK_LIST[:-8] BL2 = BLOCK_LIST[-8:] block_handler_1, block_chain_1, block_store_1, add_peer_1 = items_for_client(BL1) block_handler_2, block_chain_2, block_store_2, add_peer_2 = items_for_client() peer1, peer2 = create_peers_tcp() handshake_peers(peer1, peer2, dict(local_ip="127.0.0.1", last_block_index=len(BL1)), dict(local_ip="127.0.0.2")) add_peer_1(peer1, 0) add_peer_2(peer2, len(BL1)) assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == 0 def wait_for_change_q(block_chain, count): r = [] done = asyncio.Future() def change_callback(blockchain, ops): r.extend(ops) if len(r) >= count: done.set_result(r) block_chain.add_change_callback(change_callback) try: r = asyncio.get_event_loop().run_until_complete(asyncio.wait_for(done, timeout=5)) except asyncio.TimeoutError: r = [] return r r = wait_for_change_q(block_chain_2, len(BL1)) assert len(r) == len(BL1) assert r == [("add", b.hash(), idx) for idx, b in enumerate(BL1)] assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == len(BL1) for block in BL2: block_handler_1.add_block(block) block_store_1[block.hash()] = block block_chain_1.add_headers(BL2) assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BL1) r = wait_for_change_q(block_chain_2, len(BL2)) peer1.dump() peer2.dump() assert len(r) == len(BL2) assert r == [("add", b.hash(), idx + len(BL1)) for idx, b in enumerate(BL2)] assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BLOCK_LIST)
def test_simple_getheader(): BLOCKS = make_blocks(20) blockchain1 = BlockChain() blockchain1.add_headers(BLOCKS) block_store = dict((b.hash(), b) for b in BLOCKS) peer1, peer2 = create_handshaked_peers() block_store = {} block_chain = BlockChain() inv_collector = InvCollector() block_handler = BlockHandler(inv_collector, block_chain, block_store) for block in BLOCKS: inv_collector.advertise_item(InvItem(ITEM_TYPE_BLOCK, block.hash())) block_store[block.hash()] = block block_chain.add_headers(BLOCKS) inv_collector.add_peer(peer1) block_handler.add_peer(peer1) @asyncio.coroutine def run_peer2(): r = [] headers = yield from standards.get_headers_hashes( peer2, after_block_hash=b'\0' * 32) r.append(headers) return r f2 = asyncio.Task(run_peer2()) asyncio.get_event_loop().run_until_complete(asyncio.wait([f2])) r = f2.result() assert len(r) == 1 assert [b.hash() for b in r[0]] == [b.hash() for b in BLOCKS]
def test_BlockHandler_simple(): # create some peers peer1_2, peer2_1 = create_handshaked_peers(ip1="127.0.0.1", ip2="127.0.0.2") peer1_3, peer3_1 = create_handshaked_peers(ip1="127.0.0.1", ip2="127.0.0.3") BLOCK_LIST = make_blocks(2) @asyncio.coroutine def run_client(peer_list, block_list): block_chain = BlockChain() block_store = {} inv_collector = InvCollector() block_handler = BlockHandler(inv_collector, block_chain, block_store) for peer in peer_list: inv_collector.add_peer(peer) block_handler.add_peer(peer) for block in block_list: inv_collector.advertise_item(InvItem(ITEM_TYPE_BLOCK, block.hash())) block_store[block.hash()] = block while len(block_store) < 2: yield from asyncio.sleep(0.1) return block_store f1 = asyncio.Task(run_client([peer1_2, peer1_3], [])) f2 = asyncio.Task(run_client([peer2_1], BLOCK_LIST[0:1])) f3 = asyncio.Task(run_client([peer3_1], BLOCK_LIST[1:2])) done, pending = asyncio.get_event_loop().run_until_complete( asyncio.wait([f1, f2, f3], timeout=5.0)) assert len(done) == 3 assert len(pending) == 0 for i in range(3): r = done.pop().result() assert len(r) == 2
def test_simple_getheader(): BLOCKS = make_blocks(20) blockchain1 = BlockChain() blockchain1.add_headers(BLOCKS) block_store = dict((b.hash(), b) for b in BLOCKS) peer1, peer2 = create_handshaked_peers() block_store = {} block_chain = BlockChain() inv_collector = InvCollector() block_handler = BlockHandler(inv_collector, block_chain, block_store) for block in BLOCKS: inv_collector.advertise_item(InvItem(ITEM_TYPE_BLOCK, block.hash())) block_store[block.hash()] = block block_chain.add_headers(BLOCKS) inv_collector.add_peer(peer1) block_handler.add_peer(peer1) @asyncio.coroutine def run_peer2(): r = [] headers = yield from standards.get_headers_hashes(peer2, after_block_hash=b"\0" * 32) r.append(headers) return r f2 = asyncio.Task(run_peer2()) asyncio.get_event_loop().run_until_complete(asyncio.wait([f2])) r = f2.result() assert len(r) == 1 assert [b.hash() for b in r[0]] == [b.hash() for b in BLOCKS]
def test_BlockHandler_tcp(): BLOCK_LIST = make_blocks(32) BL1 = BLOCK_LIST[:-8] BL2 = BLOCK_LIST[-8:] block_handler_1, block_chain_1, block_store_1, add_peer_1 = items_for_client( BL1) block_handler_2, block_chain_2, block_store_2, add_peer_2 = items_for_client( ) peer1, peer2 = create_peers_tcp() handshake_peers(peer1, peer2, dict(local_ip="127.0.0.1", last_block_index=len(BL1)), dict(local_ip="127.0.0.2")) add_peer_1(peer1, 0) add_peer_2(peer2, len(BL1)) change_q_1 = block_chain_1.new_change_q() change_q_2 = block_chain_2.new_change_q() assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == 0 def wait_for_change_q(change_q, count): @asyncio.coroutine def async_tests(change_q, count): r = [] while len(r) < count: v = yield from change_q.get() r.append(v) return r try: r = asyncio.get_event_loop().run_until_complete( asyncio.wait_for(async_tests(change_q, count), timeout=5)) except asyncio.TimeoutError: r = [] return r r = wait_for_change_q(change_q_2, len(BL1)) assert len(r) == len(BL1) assert r == [('add', b.hash(), idx) for idx, b in enumerate(BL1)] assert change_q_1.qsize() == 0 assert change_q_2.qsize() == 0 assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == len(BL1) for block in BL2: block_handler_1.add_block(block) block_store_1[block.hash()] = block block_chain_1.add_headers(BL2) assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BL1) r = wait_for_change_q(change_q_2, len(BL2)) peer1.dump() peer2.dump() assert len(r) == len(BL2) assert r == [('add', b.hash(), idx + len(BL1)) for idx, b in enumerate(BL2)] assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BLOCK_LIST)
def test_BlockHandler_tcp(): BLOCK_LIST = make_blocks(32) BL1 = BLOCK_LIST[:-8] BL2 = BLOCK_LIST[-8:] block_handler_1, block_chain_1, block_store_1, add_peer_1 = items_for_client(BL1) block_handler_2, block_chain_2, block_store_2, add_peer_2 = items_for_client() peer1, peer2 = create_peers_tcp() handshake_peers(peer1, peer2, dict(local_ip="127.0.0.1", last_block_index=len(BL1)), dict(local_ip="127.0.0.2")) add_peer_1(peer1, 0) add_peer_2(peer2, len(BL1)) change_q_1 = block_chain_1.new_change_q() change_q_2 = block_chain_2.new_change_q() assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == 0 def wait_for_change_q(change_q, count): @asyncio.coroutine def async_tests(change_q, count): r = [] while len(r) < count: v = yield from change_q.get() r.append(v) return r try: r = asyncio.get_event_loop().run_until_complete(asyncio.wait_for(async_tests(change_q, count), timeout=5)) except asyncio.TimeoutError: r = [] return r r = wait_for_change_q(change_q_2, len(BL1)) assert len(r) == len(BL1) assert r == [('add', b.hash(), idx) for idx, b in enumerate(BL1)] assert change_q_1.qsize() == 0 assert change_q_2.qsize() == 0 assert block_chain_1.length() == len(BL1) assert block_chain_2.length() == len(BL1) for block in BL2: block_handler_1.add_block(block) block_store_1[block.hash()] = block block_chain_1.add_headers(BL2) assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BL1) r = wait_for_change_q(change_q_2, len(BL2)) peer1.dump() peer2.dump() assert len(r) == len(BL2) assert r == [('add', b.hash(), idx+len(BL1)) for idx, b in enumerate(BL2)] assert block_chain_1.length() == len(BLOCK_LIST) assert block_chain_2.length() == len(BLOCK_LIST)
def test_get_mined_block(): # create two clients: A and B # create block chain of length 25 # A connects to B # B has 20 blocks # A has none # A should catch up all 20 blocks # A mines a new block # B should acquire it from A asyncio.tasks._DEBUG = True logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT) logging.getLogger("asyncio").setLevel(logging.INFO) def do_update(blockchain, ops): #import pdb; pdb.set_trace() logging.info("update 1: ops=%s", ops) client_2_has_20_blocks_future = asyncio.Future() client_2_has_25_blocks_future = asyncio.Future() def do_update_2(blockchain, ops): #import pdb; pdb.set_trace() logging.info("update 2: ops=%s", ops) if not client_2_has_20_blocks_future.done() and blockchain.length() >= 20: client_2_has_20_blocks_future.set_result(blockchain.length()) if not client_2_has_25_blocks_future.done() and blockchain.length() >= 25: client_2_has_25_blocks_future.set_result(blockchain.length()) return for op, the_hash, idx in ops: if op == 'add': #block = yield from client_2.get_block(the_hash) logging.debug("got block %s" % block.id()) blocks = helper.make_blocks(25) LOOP = asyncio.get_event_loop() with tempfile.TemporaryDirectory() as state_dir: host_port_q_1 = asyncio.Queue() def should_download_block_f(block_hash, block_index): import pdb; pdb.set_trace() return True block_chain_store_1 = BlockChainStore(os.path.join(state_dir, "1")) client_1 = Client(TESTNET, host_port_q_1, should_download_block_f, block_chain_store_1, do_update, server_port=9110) host_port_q_2 = asyncio.Queue() block_chain_store_2 = BlockChainStore(os.path.join(state_dir, "2")) client_2 = Client(TESTNET, host_port_q_2, should_download_block_f, block_chain_store_2, do_update_2, server_port=9115) def add_blocks_1(): for b in blocks[:20]: client_1.add_block(b) def add_blocks_2(): for b in blocks[20:]: client_1.add_block(b) def wait(): LOOP.run_until_complete(asyncio.sleep(0.05)) LOOP.call_soon(add_blocks_1) wait() host_port_q_2.put_nowait(("127.0.0.1", 9110)) wait() LOOP.run_until_complete(client_2_has_20_blocks_future) wait() LOOP.call_soon(add_blocks_2) wait() LOOP.run_until_complete(client_2_has_25_blocks_future)