Ejemplo n.º 1
0
async def test_sending_collations(request, event_loop):
    sender, receiver = await get_directly_linked_peers(
        request,
        event_loop,
        ShardingPeer,
        None,
        ShardingPeer,
        None,
    )

    c1 = Collation(CollationHeader(0, b"\x11" * 32, 2, b"\x33" * 20),
                   b"\x44" * COLLATION_SIZE)
    c2 = Collation(CollationHeader(1, b"\x11" * 32, 2, b"\x33" * 20),
                   b"\x44" * COLLATION_SIZE)
    c3 = Collation(CollationHeader(2, b"\x11" * 32, 2, b"\x33" * 20),
                   b"\x44" * COLLATION_SIZE)

    sender.sub_proto.send_collations([c1])
    received_c1 = await asyncio.wait_for(
        receiver.incoming_collation_queue.get(), timeout=1)
    assert received_c1 == c1
    assert receiver.known_collation_hashes == set([c1.hash])

    sender.sub_proto.send_collations([c2, c3])
    received_c2 = await asyncio.wait_for(
        receiver.incoming_collation_queue.get(), timeout=1)
    received_c3 = await asyncio.wait_for(
        receiver.incoming_collation_queue.get(), timeout=1)
    assert set([received_c2, received_c3]) == set([c2, c3])
    assert receiver.known_collation_hashes == set([c1.hash, c2.hash, c3.hash])
Ejemplo n.º 2
0
def test_body_fields(collation_header):
    assert len(CollationHeader.fields) == 4  # if not this test is outdated
    collation = Collation(header=collation_header, body=b"")
    assert collation.shard_id == collation_header.shard_id
    assert collation.chunk_root == collation_header.chunk_root
    assert collation.period == collation_header.period
    assert collation.proposer_address == collation_header.proposer_address
Ejemplo n.º 3
0
def random_collation(shard_id, period):
    body = zpad_right(int_to_big_endian(random.getrandbits(8 * 32)),
                      COLLATION_SIZE)
    header = CollationHeader(
        shard_id=shard_id,
        period=period,
        chunk_root=calc_chunk_root(body),
        proposer_address=b"\xff" * 20,
    )
    return Collation(header, body)
Ejemplo n.º 4
0
    def propose(self) -> Collation:
        """Broadcast a new collation to the network, add it to the local shard, and return it."""
        # create collation for current period
        period = self.get_current_period()
        body = zpad_right(str(self).encode("utf-8"), COLLATION_SIZE)
        header = CollationHeader(self.shard.shard_id, calc_chunk_root(body), period, b"\x11" * 20)
        collation = Collation(header, body)

        self.logger.debug("Proposing collation {}".format(collation))

        # add collation to local chain
        self.shard.add_collation(collation)

        # broadcast collation
        for peer in self.peer_pool.peers:
            cast(ShardingPeer, peer).send_collations([collation])

        return collation
Ejemplo n.º 5
0
def generate_collations():
    explicit_params = {}
    for period in itertools.count():
        default_params = {
            "shard_id": 0,
            "period": period,
            "body": zpad_right(b"body%d" % period, COLLATION_SIZE),
            "proposer_address": zpad_right(b"proposer%d" % period, 20),
        }
        # only calculate chunk root if it wouldn't be replaced anyway
        if "chunk_root" not in explicit_params:
            default_params["chunk_root"] = calc_chunk_root(default_params["body"])

        params = merge(default_params, explicit_params)
        header = CollationHeader(
            shard_id=params["shard_id"],
            chunk_root=params["chunk_root"],
            period=params["period"],
            proposer_address=params["proposer_address"],
        )
        collation = Collation(header, params["body"])
        explicit_params = (yield collation) or {}
Ejemplo n.º 6
0
def collation(collation_header):
    body = b"\x00" * COLLATION_SIZE
    return Collation(collation_header, body)
Ejemplo n.º 7
0
 def get_collation(self, shard_id: int, period: int) -> Collation:
     header = self.get_header(shard_id, period)
     body = self.get_body(shard_id, period)
     return Collation(header, body)
Ejemplo n.º 8
0
async def test_collation_requests(request, event_loop):
    # setup two peers
    sender, receiver = await get_directly_linked_sharding_peers(request, event_loop)
    receiver_peer_pool = MockPeerPoolWithConnectedPeers([receiver])

    # setup shard db for request receiving node
    receiver_db = ShardDB(MemoryDB())
    receiver_shard = Shard(receiver_db, 0)

    # create three collations and add two to the shard of the receiver
    # body is shared to avoid unnecessary chunk root calculation
    body = zpad_right(b"body", COLLATION_SIZE)
    chunk_root = calc_chunk_root(body)
    c1 = Collation(CollationHeader(0, chunk_root, 0, zpad_right(b"proposer1", 20)), body)
    c2 = Collation(CollationHeader(0, chunk_root, 1, zpad_right(b"proposer2", 20)), body)
    c3 = Collation(CollationHeader(0, chunk_root, 2, zpad_right(b"proposer3", 20)), body)
    for collation in [c1, c2]:
        receiver_shard.add_collation(collation)

    # start shard syncer
    receiver_syncer = ShardSyncer(receiver_shard, receiver_peer_pool)
    asyncio.ensure_future(receiver_syncer.run())

    def finalizer():
        event_loop.run_until_complete(receiver_syncer.cancel())
    request.addfinalizer(finalizer)

    cancel_token = CancelToken("test")

    # request single collation
    received_collations = await asyncio.wait_for(
        sender.get_collations([c1.hash], cancel_token),
        timeout=1,
    )
    assert received_collations == set([c1])

    # request multiple collations
    received_collations = await asyncio.wait_for(
        sender.get_collations([c1.hash, c2.hash], cancel_token),
        timeout=1,
    )
    assert received_collations == set([c1, c2])

    # request no collations
    received_collations = await asyncio.wait_for(
        sender.get_collations([], cancel_token),
        timeout=1,
    )
    assert received_collations == set()

    # request unknown collation
    received_collations = await asyncio.wait_for(
        sender.get_collations([c3.hash], cancel_token),
        timeout=1,
    )
    assert received_collations == set()

    # request multiple collations, including unknown one
    received_collations = await asyncio.wait_for(
        sender.get_collations([c1.hash, c2.hash, c3.hash], cancel_token),
        timeout=1,
    )
    assert received_collations == set([c1, c2])
Ejemplo n.º 9
0
 def get_collation_by_hash(self, collation_hash: Hash32) -> Collation:
     header = self.get_header_by_hash(collation_hash)
     body = self.get_body_by_chunk_root(header.chunk_root)
     return Collation(header, body)
Ejemplo n.º 10
0
def collation(header, body):
    return Collation(header, body)