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)
예제 #3
0
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]
예제 #4
0
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]
예제 #6
0
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)
예제 #7
0
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)
예제 #8
0
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)