Ejemplo n.º 1
0
def translate_typ(typ) -> ssz.BaseSedes:
    """
    Translates a spec type to a Py-SSZ type description (sedes).
    :param typ: The spec type, a class.
    :return: The Py-SSZ equivalent.
    """
    if issubclass(typ, spec_ssz.Container):
        return ssz.Container([
            translate_typ(field_typ)
            for field_name, field_typ in typ.get_fields().items()
        ])
    elif issubclass(typ, spec_ssz.BytesN):
        return ssz.ByteVector(typ.length)
    elif issubclass(typ, spec_ssz.Bytes):
        return ssz.ByteList()
    elif issubclass(typ, spec_ssz.Vector):
        return ssz.Vector(translate_typ(typ.elem_type), typ.length)
    elif issubclass(typ, spec_ssz.List):
        # TODO: Make py-ssz List support the new fixed length list
        return ssz.List(translate_typ(typ.elem_type))
    elif issubclass(typ, spec_ssz.Bitlist):
        # TODO: Once Bitlist implemented in py-ssz, use appropriate type
        return ssz.List(translate_typ(typ.elem_type))
    elif issubclass(typ, spec_ssz.Bitvector):
        # TODO: Once Bitvector implemented in py-ssz, use appropriate type
        return ssz.Vector(translate_typ(typ.elem_type), typ.length)
    elif issubclass(typ, spec_ssz.boolean):
        return ssz.boolean
    elif issubclass(typ, spec_ssz.uint):
        if typ.byte_len == 1:
            return ssz.uint8
        elif typ.byte_len == 2:
            return ssz.uint16
        elif typ.byte_len == 4:
            return ssz.uint32
        elif typ.byte_len == 8:
            return ssz.uint64
        elif typ.byte_len == 16:
            return ssz.uint128
        elif typ.byte_len == 32:
            return ssz.uint256
        else:
            raise TypeError("invalid uint size")
    else:
        raise TypeError("Type not supported: {}".format(typ))
Ejemplo n.º 2
0
 def _read_state_historical_roots(
         self, state_root: Root,
         HISTORICAL_ROOTS_LIMIT: int) -> Tuple[Root]:
     key = SchemaV1.state_root_to_historical_roots_root(state_root)
     historical_roots_root = self.db[key]
     return ssz.decode(
         self.db[historical_roots_root],
         ssz.List(ssz.bytes32, HISTORICAL_ROOTS_LIMIT),
     )
Ejemplo n.º 3
0
 def _read_state_balances(self, state_root: Root,
                          VALIDATOR_REGISTRY_LIMIT: int) -> Tuple[Gwei]:
     state_root_to_balances_root = SchemaV1.state_root_to_balances_root(
         state_root)
     balances_root = Root(Hash32(self.db[state_root_to_balances_root]))
     balances_root_to_balances = SchemaV1.balances_root_to_balances(
         balances_root)
     return ssz.decode(
         self.db[balances_root_to_balances],
         ssz.List(ssz.uint64, VALIDATOR_REGISTRY_LIMIT),
     )
Ejemplo n.º 4
0
def initialize_beacon_state_from_eth1(*, eth1_block_hash: Hash32,
                                      eth1_timestamp: Timestamp,
                                      deposits: Sequence[Deposit],
                                      config: Eth2Config) -> BeaconState:
    fork = Fork.create(
        previous_version=config.GENESIS_FORK_VERSION,
        current_version=config.GENESIS_FORK_VERSION,
        epoch=GENESIS_EPOCH,
    )

    state = BeaconState.create(
        genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp,
                                                       config.GENESIS_DELAY),
        fork=fork,
        eth1_data=Eth1Data.create(block_hash=eth1_block_hash,
                                  deposit_count=len(deposits)),
        latest_block_header=BeaconBlockHeader.create(
            body_root=BeaconBlockBody.create().hash_tree_root),
        block_roots=(ZERO_ROOT, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        state_roots=(ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        randao_mixes=(eth1_block_hash, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        slashings=(Gwei(0), ) * config.EPOCHS_PER_SLASHINGS_VECTOR,
        config=config,
    )

    # Process genesis deposits
    for index, deposit in enumerate(deposits):
        deposit_data_list = tuple(deposit.data
                                  for deposit in deposits[:index + 1])
        deposit_root = ssz.get_hash_tree_root(
            deposit_data_list,
            ssz.List(DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH))
        state = state.transform(("eth1_data", "deposit_root"), deposit_root)
        state = process_deposit(state=state, deposit=deposit, config=config)

    # Process genesis activations
    for validator_index in range(len(state.validators)):
        validator_index = ValidatorIndex(validator_index)
        balance = state.balances[validator_index]
        effective_balance = calculate_effective_balance(balance, config)

        state = state.transform(
            ("validators", validator_index, "effective_balance"),
            effective_balance)

        if effective_balance == config.MAX_EFFECTIVE_BALANCE:
            activated_validator = activate_validator(
                state.validators[validator_index], GENESIS_EPOCH)
            state = state.transform(("validators", validator_index),
                                    activated_validator)

    return state.set("genesis_validators_root",
                     state.validators.hash_tree_root)
Ejemplo n.º 5
0
    async def _recv_beacon_blocks_by_root(self, stream: INetStream) -> None:
        request_data = await _read_request(stream)
        request = _deserialize_ssz(request_data,
                                   ssz.List(ROOT_SEDES, MAX_REQUEST_BLOCKS))

        for root in request:
            block = self._block_provider_by_root(root)

            if not block:
                continue

            response_payload = _serialize_ssz(block, SignedBeaconBlock)

            await _write_success_response_chunk(stream, response_payload)

        await stream.close()
Ejemplo n.º 6
0
def state_with_validator_digests(state: BeaconState,
                                 config: Eth2Config) -> BeaconState:
    active_validator_indices = get_active_validator_indices(
        state.validators, config.GENESIS_EPOCH)
    active_index_root = ssz.get_hash_tree_root(
        active_validator_indices,
        ssz.List(ssz.uint64, config.VALIDATOR_REGISTRY_LIMIT))
    active_index_roots = (
        active_index_root, ) * config.EPOCHS_PER_HISTORICAL_VECTOR
    committee_root = get_compact_committees_root(state, config.GENESIS_EPOCH,
                                                 CommitteeConfig(config))
    compact_committees_roots = (
        committee_root, ) * config.EPOCHS_PER_HISTORICAL_VECTOR
    return state.copy(
        active_index_roots=active_index_roots,
        compact_committees_roots=compact_committees_roots,
    )
Ejemplo n.º 7
0
    async def _recv_beacon_blocks_by_root(self, stream: INetStream) -> None:
        request_data = await _read_request(stream)
        element_sedes = ssz.sedes.bytes32
        list_len = len(request_data) // element_sedes.length
        request = _deserialize_ssz(request_data,
                                   ssz.List(element_sedes, list_len))

        for root in request:
            block = self._block_provider_by_root(root)

            if not block:
                continue

            response_payload = _serialize_ssz(block, SignedBeaconBlock)

            await _write_success_response_chunk(stream, response_payload)

        await stream.close()
Ejemplo n.º 8
0
    async def get_blocks_by_root(
            self, stream: INetStream,
            *roots: Sequence[Root]) -> AsyncIterable[SignedBeaconBlock]:
        if not roots:
            return

        request_payload = _serialize_ssz(
            roots, ssz.List(ssz.sedes.bytes32, len(roots)))

        await _write_request(request_payload, stream)
        await stream.close()

        for _ in range(len(roots)):
            response_data = await _read_response(stream)

            if not response_data:
                break

            block = _deserialize_ssz(response_data, SignedBeaconBlock)
            yield block
Ejemplo n.º 9
0
def initialize_beacon_state_from_eth1(*, eth1_block_hash: Hash32,
                                      eth1_timestamp: Timestamp,
                                      deposits: Sequence[Deposit],
                                      config: Eth2Config) -> BeaconState:
    state = BeaconState(
        genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp),
        eth1_data=Eth1Data(block_hash=eth1_block_hash,
                           deposit_count=len(deposits)),
        latest_block_header=BeaconBlockHeader(
            body_root=BeaconBlockBody().hash_tree_root),
        randao_mixes=(eth1_block_hash, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        config=config,
    )

    # Process genesis deposits
    for index, deposit in enumerate(deposits):
        deposit_data_list = tuple(deposit.data
                                  for deposit in deposits[:index + 1])
        state = state.copy(eth1_data=state.eth1_data.copy(
            deposit_root=ssz.get_hash_tree_root(
                deposit_data_list,
                ssz.List(DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH),
            )))
        state = process_deposit(state=state, deposit=deposit, config=config)

    # Process genesis activations
    for validator_index in range(len(state.validators)):
        validator_index = ValidatorIndex(validator_index)
        balance = state.balances[validator_index]
        effective_balance = calculate_effective_balance(balance, config)

        state = state.update_validator_with_fn(
            validator_index,
            lambda v, *_: v.copy(effective_balance=effective_balance))

        if effective_balance == config.MAX_EFFECTIVE_BALANCE:
            state = state.update_validator_with_fn(validator_index,
                                                   activate_validator,
                                                   config.GENESIS_EPOCH)

    return state
Ejemplo n.º 10
0
    async def get_blocks_by_root(
            self, stream: INetStream,
            *roots: Sequence[Root]) -> AsyncIterable[SignedBeaconBlock]:
        if not roots:
            return

        # TODO ensure ssz error if ``len(roots) > MAX_REQUEST_BLOCKS``
        request_payload = _serialize_ssz(
            roots, ssz.List(ROOT_SEDES, MAX_REQUEST_BLOCKS))

        await _write_request(request_payload, stream)
        await stream.close()

        for _ in range(len(roots)):
            response_data = await _read_response(stream)

            if not response_data:
                break

            block = _deserialize_ssz(response_data, SignedBeaconBlock)
            yield block
Ejemplo n.º 11
0
def translate_typ(typ) -> ssz.BaseSedes:
    """
    Translates a spec type to a Py-SSZ type description (sedes).
    :param typ: The spec type, a class.
    :return: The Py-SSZ equivalent.
    """
    if spec_ssz.is_container_type(typ):
        return ssz.Container([
            translate_typ(field_typ)
            for (field_name, field_typ) in typ.get_fields()
        ])
    elif spec_ssz.is_bytesn_type(typ):
        return ssz.ByteVector(typ.length)
    elif spec_ssz.is_bytes_type(typ):
        return ssz.ByteList()
    elif spec_ssz.is_vector_type(typ):
        return ssz.Vector(translate_typ(spec_ssz.read_vector_elem_type(typ)),
                          typ.length)
    elif spec_ssz.is_list_type(typ):
        return ssz.List(translate_typ(spec_ssz.read_list_elem_type(typ)))
    elif spec_ssz.is_bool_type(typ):
        return ssz.boolean
    elif spec_ssz.is_uint_type(typ):
        size = spec_ssz.uint_byte_size(typ)
        if size == 1:
            return ssz.uint8
        elif size == 2:
            return ssz.uint16
        elif size == 4:
            return ssz.uint32
        elif size == 8:
            return ssz.uint64
        elif size == 16:
            return ssz.uint128
        elif size == 32:
            return ssz.uint256
        else:
            raise TypeError("invalid uint size")
    else:
        raise TypeError("Type not supported: {}".format(typ))