Esempio n. 1
0
 def __init__(
     self,
     privkey: datatypes.PrivateKey,
     address: Address,
     network_id: int,
     min_peers: int = 0,
     peer_class: Type[BasePeer] = ShardingPeer,
     peer_pool_class: Type[PeerPool] = PeerPool,
     bootstrap_nodes: List[str] = [],
 ) -> None:
     BaseService.__init__(self, CancelToken('ShardingServer'))
     self.privkey = privkey
     self.address = address
     self.network_id = network_id
     self.peer_class = peer_class
     self.discovery = DiscoveryProtocol(self.privkey,
                                        self.address,
                                        bootstrap_nodes=bootstrap_nodes)
     # XXX: This is not supposed to work and causes both the PeerPool and Server to crash, but
     # the tests in test_sharding.py don't seem to care
     self.headerdb = None
     self.peer_pool = peer_pool_class(
         peer_class,
         self.headerdb,
         self.network_id,
         self.privkey,
         self.discovery,
         min_peers=min_peers,
     )
     shard_db = ShardDB(MemoryDB())
     shard = Shard(shard_db, 0)
     self.syncer = ShardSyncer(shard, self.peer_pool,
                               self.cancel_token)  # type: ignore
Esempio n. 2
0
async def test_syncer_requests_new_collations(request, event_loop):
    # setup a-b topology
    peer_a_b, peer_b_a = await get_directly_linked_sharding_peers(
        request, event_loop)
    peer_a_b_subscriber = asyncio.Queue()
    peer_a_b.add_subscriber(peer_a_b_subscriber)
    peer_pool_b = MockPeerPoolWithConnectedPeers([peer_b_a])

    # setup shard dbs at b
    shard_db = ShardDB(MemoryDB())
    shard = Shard(shard_db, 0)

    # start shard syncer
    syncer = ShardSyncer(shard, peer_pool_b)
    asyncio.ensure_future(syncer.run())

    def finalizer():
        event_loop.run_until_complete(syncer.cancel())

    request.addfinalizer(finalizer)

    # notify b about new hashes at a and check that it requests them
    hashes_and_periods = ((b"\xaa" * 32, 0), )
    peer_a_b.sub_proto.send_new_collation_hashes(hashes_and_periods)
    peer, cmd, msg = await asyncio.wait_for(
        peer_a_b_subscriber.get(),
        timeout=1,
    )
    assert peer == peer_a_b
    assert isinstance(cmd, GetCollations)
    assert msg["collation_hashes"] == (hashes_and_periods[0][0], )
Esempio n. 3
0
def shard_chain(shard_chaindb, funded_address,
                funded_address_initial_balance):  # noqa: F811
    genesis_params = {
        "bloom":
        0,
        "coinbase":
        to_canonical_address("8888f1f195afa192cfee860698584c030f4c9db1"),
        "difficulty":
        131072,
        "extra_data":
        b"B",
        "gas_limit":
        3141592,
        "gas_used":
        0,
        "mix_hash":
        decode_hex(
            "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
        ),  # noqa: E501
        "nonce":
        decode_hex("0102030405060708"),
        "block_number":
        0,
        "parent_hash":
        decode_hex(
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),  # noqa: E501
        "transaction_root":
        constants.EMPTY_SHA3,
        "receipt_root":
        constants.EMPTY_SHA3,
        "timestamp":
        1422494849,
        "uncles_hash":
        decode_hex(
            "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
        )  # noqa: E501
    }
    genesis_state = {
        funded_address: {
            "balance": funded_address_initial_balance,
            "nonce": 0,
            "code": b"",
            "storage": {}
        }
    }
    klass = Shard.configure(__name__='TestChain',
                            vm_configuration=((constants.GENESIS_BLOCK_NUMBER,
                                               ShardingVM), ))
    shard = klass.from_genesis(shard_chaindb, genesis_params, genesis_state)

    return shard
Esempio n. 4
0
async def test_new_collations_notification(request, event_loop):
    # setup a-b-c topology
    peer_a_b, peer_b_a = await get_directly_linked_sharding_peers(
        request, event_loop)
    peer_b_c, peer_c_b = await get_directly_linked_sharding_peers(
        request, event_loop)
    peer_c_b_subscriber = asyncio.Queue()
    peer_c_b.add_subscriber(peer_c_b_subscriber)
    peer_pool_b = MockPeerPoolWithConnectedPeers([peer_b_a, peer_b_c])

    # setup shard dbs at b
    shard_db = ShardDB(MemoryDB())
    shard = Shard(shard_db, 0)

    # start shard syncer
    syncer = ShardSyncer(shard, peer_pool_b)
    asyncio.ensure_future(syncer.run())

    def finalizer():
        event_loop.run_until_complete(syncer.cancel())

    request.addfinalizer(finalizer)

    # send collation from a to b and check that c gets notified
    c1 = next(collations)
    peer_a_b.sub_proto.send_collations(0, [c1])
    peer, cmd, msg = await asyncio.wait_for(
        peer_c_b_subscriber.get(),
        timeout=1,
    )
    assert peer == peer_c_b
    assert isinstance(cmd, NewCollationHashes)
    assert msg["collation_hashes_and_periods"] == ((c1.hash, c1.period), )

    # check that c won't be notified about c1 again
    c2 = next(collations)
    peer_a_b.sub_proto.send_collations(0, [c1, c2])
    peer, cmd, msg = await asyncio.wait_for(
        peer_c_b_subscriber.get(),
        timeout=1,
    )
    assert peer == peer_c_b
    assert isinstance(cmd, NewCollationHashes)
    assert msg["collation_hashes_and_periods"] == ((c2.hash, c2.period), )
Esempio n. 5
0
def shard_chain_without_block_validation(shard_chaindb):  # noqa: F811
    shard_chaindb = shard_chaindb
    """
    Return a Chain object containing just the genesis block.

    This Chain does not perform any validation when importing new blocks.

    The Chain's state includes one funded account which is where the simple transfer

    contract will be deployed at.
    """
    overrides = {
        'import_block': import_block_without_validation,
        'validate_block': lambda self, block: None,
    }
    klass = Shard.configure(
        __name__='TestShardChainWithoutBlockValidation',
        vm_configuration=((constants.GENESIS_BLOCK_NUMBER, ShardingVM), ),
        **overrides,
    )
    genesis_params = {
        'block_number': constants.GENESIS_BLOCK_NUMBER,
        'difficulty': constants.GENESIS_DIFFICULTY,
        'gas_limit': constants.GENESIS_GAS_LIMIT,
        'parent_hash': constants.GENESIS_PARENT_HASH,
        'coinbase': constants.GENESIS_COINBASE,
        'nonce': constants.GENESIS_NONCE,
        'mix_hash': constants.GENESIS_MIX_HASH,
        'extra_data': constants.GENESIS_EXTRA_DATA,
        'timestamp': 1501851927,
        'transaction_root': constants.EMPTY_SHA3,
        'receipt_root': constants.EMPTY_SHA3,
    }
    genesis_state = {
        decode_hex(SHARD_CHAIN_CONTRACTS_FIXTURES[i]["deployed_address"]): {
            'balance': SHARD_CHAIN_CONTRACTS_FIXTURES[i]["initial_balance"],
            'code': b'',
            'storage': {},
        }
        for i in range(len(SHARD_CHAIN_CONTRACTS_FIXTURES))
    }
    shard = klass.from_genesis(shard_chaindb, genesis_params, genesis_state)
    return shard
Esempio n. 6
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])
Esempio n. 7
0
def shard(shard_db):
    return Shard(shard_db, shard_id=0)
Esempio n. 8
0
 def _make_syncer(self, peer_pool: PeerPool) -> BaseService:
     shard_db = ShardDB(MemoryDB())
     shard = Shard(shard_db, 0)
     return ShardSyncer(shard, peer_pool, self.cancel_token)