示例#1
0
def test_root(data, sedes_and_values):
    sedes, values = sedes_and_values
    value = data.draw(values)

    serializable_value = to_serializable_value(value, sedes)
    serializable_root = ssz.get_hash_tree_root(serializable_value, sedes)

    hashable_value = to_hashable_value(value, sedes)
    hashable_root = ssz.get_hash_tree_root(hashable_value, sedes)

    assert serializable_root == hashable_root
示例#2
0
    async def _validate_local_advertisement(
            self, advertisement: Advertisement) -> None:
        if not advertisement.node_id == self.local_node_id:
            raise Exception(
                "Must be called with an advertisement signed by the local node"
            )

        try:
            try:
                # First query "pinned" storage
                content = self._network.pinned_content_storage.get_content(
                    advertisement.content_key)
            except ContentNotFound:
                # Fall back to "commons" storage
                content = self._network.commons_content_storage.get_content(
                    advertisement.content_key)
        except ContentNotFound as err:
            raise ValidationError(
                f"Content not found: advertisement={advertisement}") from err

        hash_tree_root = ssz.get_hash_tree_root(content, sedes=content_sedes)

        if hash_tree_root != advertisement.hash_tree_root:
            raise ValidationError(
                f"Mismatched roots: local={hash_tree_root.hex()}  "
                f"advertisement={advertisement.hash_tree_root.hex}")
示例#3
0
def get_compact_committees_root(state: BeaconState, epoch: Epoch,
                                config: CommitteeConfig) -> Hash32:
    shard_count = config.SHARD_COUNT

    committees = (CompactCommittee(), ) * shard_count
    start_shard = get_start_shard(state, epoch, config)
    active_validator_indices = get_active_validator_indices(
        state.validators,
        epoch,
    )
    committee_count = get_committee_count(
        len(active_validator_indices),
        config.SHARD_COUNT,
        config.SLOTS_PER_EPOCH,
        config.TARGET_COMMITTEE_SIZE,
    )
    for committee_number in range(committee_count):
        shard = Shard((start_shard + committee_number) % shard_count)
        compact_committee = _compute_compact_committee_for_shard_in_epoch(
            state,
            epoch,
            shard,
            config,
        )
        committees = update_tuple_item(
            committees,
            shard,
            compact_committee,
        )
    return ssz.get_hash_tree_root(committees,
                                  sedes=ssz.sedes.Vector(
                                      CompactCommittee, shard_count))
示例#4
0
 def _randao_provider_of_epoch_signature(public_key: BLSPubkey,
                                         epoch: Epoch) -> BLSSignature:
     private_key = private_key_provider(public_key)
     # TODO: fix how we get the signing root
     message = ssz.get_hash_tree_root(epoch, sedes=ssz.sedes.uint64)
     domain = compute_domain(SignatureDomain.DOMAIN_RANDAO)
     sig = bls.sign(message, private_key, domain)
     return sig
示例#5
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)
示例#6
0
def get_slot_signature(state: BeaconState, slot: Slot, privkey: int,
                       config: Eth2Config) -> BLSSignature:
    """
    Sign on ``slot`` and return the signature.
    """
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        config.SLOTS_PER_EPOCH,
        message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH),
    )
    return bls.sign(get_hash_tree_root(slot, sedes=uint64), privkey, domain)
示例#7
0
def _compute_next_active_index_roots(state: BeaconState,
                                     config: Eth2Config) -> Tuple[Hash32, ...]:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    index_root_position = (next_epoch + config.ACTIVATION_EXIT_DELAY
                           ) % config.EPOCHS_PER_HISTORICAL_VECTOR
    validator_indices_for_new_active_index_root = get_active_validator_indices(
        state.validators, Epoch(next_epoch + config.ACTIVATION_EXIT_DELAY))
    new_active_index_root = ssz.get_hash_tree_root(
        validator_indices_for_new_active_index_root,
        ssz.sedes.List(ssz.uint64, config.VALIDATOR_REGISTRY_LIMIT),
    )
    return update_tuple_item(state.active_index_roots, index_root_position,
                             new_active_index_root)
示例#8
0
def deposit(w3, deposit_contract) -> int:
    deposit_data = DepositDataFactory()
    deposit_input = (
        deposit_data.pubkey,
        deposit_data.withdrawal_credentials,
        deposit_data.signature,
        ssz.get_hash_tree_root(deposit_data),
    )
    tx_hash = deposit_contract.functions.deposit(*deposit_input).transact(
        {"value": deposit_data.amount * eth_utils.denoms.gwei})
    tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    assert tx_receipt["status"]
    return deposit_data.amount
示例#9
0
    async def process_content(self, content_key: ContentKey,
                              content: bytes) -> None:
        if self.content_storage.has_content(content_key):
            local_content = self.content_storage.get_content(content_key)
            if local_content == content:
                self.logger.debug(
                    "Ignoring content we already have: content_key=%s",
                    content_key.hex(),
                )
                return

        self.logger.debug(
            "Processing content: content_key=%s  content=%s",
            content_key.hex(),
            content.hex(),
        )
        content_id = content_key_to_content_id(content_key)

        # TODO: computationally expensive
        hash_tree_root = ssz.get_hash_tree_root(content, sedes=content_sedes)

        known_hash_tree_roots = set(
            self._local_advertisement_db.get_hash_tree_roots_for_content_id(
                content_id, ))

        # We should avoid "polution" of our content database with mismatching
        # roots.  This is a stop gap right now because we will need a mechanism
        # for inserting our own "correct" content into the system even in the
        # case where the existing "network" content doesn't agree on the hash
        # tree root.
        if known_hash_tree_roots and hash_tree_root not in known_hash_tree_roots:
            known_roots_display = "|".join(
                (root.hex() for root in known_hash_tree_roots))
            raise NotImplementedError(
                f"Content hash tree root mismatch: "
                f"content_key={content_key.hex()}  root={hash_tree_root.hex()}  "
                f"known={known_roots_display}")

        self.content_storage.set_content(content_key, content, exists_ok=True)

        advertisement = self._get_or_create_advertisement(
            content_key, hash_tree_root)
        await self._network.broadcast(advertisement)

        self.logger.debug(
            "Processed content: content_key=%s  content=%s",
            content_key.hex(),
            content.hex(),
        )
示例#10
0
 def run_with(cls, inputs: InputType,
              config: Optional[Eth2Config]) -> OutputType:
     serialized_ssz_object, ssz_object_from_yaml = inputs
     deserialized_object = _deserialize_object_from_bytes(
         serialized_ssz_object, cls.object_type)
     return (
         ssz.encode(ssz_object_from_yaml, cls.object_type),
         deserialized_object,
         ssz.encode(deserialized_object, cls.object_type),
         (
             ssz.get_hash_tree_root(ssz_object_from_yaml),
             ssz_object_from_yaml.signing_root if isinstance(
                 ssz_object_from_yaml, SignedHashableContainer) else None,
         ),
     )
示例#11
0
文件: genesis.py 项目: voith/trinity
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,
    )
示例#12
0
def test_ssz_full_proofs(content):
    expected_hash_tree_root = get_hash_tree_root(content, sedes=content_sedes)
    proof = compute_proof(content, sedes=content_sedes)

    validate_proof(proof)
    assert is_proof_valid(proof)
    assert proof.get_hash_tree_root() == expected_hash_tree_root

    proven_data_segments = proof.get_proven_data_segments()

    assert len(proven_data_segments) == 1
    start_index, proven_data = proven_data_segments[0]
    assert start_index == 0
    assert proven_data == content

    proven_data = proof.get_proven_data()
    assert proven_data[0:len(content)] == content
示例#13
0
    async def _broadcast_worker(
            self,
            receive_channel: trio.abc.ReceiveChannel[ContentKey]) -> None:
        while self.manager.is_running:
            content_key = await receive_channel.receive()
            try:
                content = self.content_storage.get_content(content_key)
            except ContentNotFound:
                continue

            # TODO: computationally expensive
            hash_tree_root = ssz.get_hash_tree_root(content,
                                                    sedes=content_sedes)
            advertisement = self._get_or_create_advertisement(
                content_key=content_key,
                hash_tree_root=hash_tree_root,
            )
            await self._network.broadcast(advertisement)
示例#14
0
def test_update_active_index_roots(genesis_state, config, state_slot,
                                   slots_per_epoch,
                                   epochs_per_historical_vector,
                                   activation_exit_delay):
    state = genesis_state.copy(slot=state_slot, )

    result = _compute_next_active_index_roots(state, config)

    index_root = ssz.get_hash_tree_root(
        get_active_validator_indices(
            state.validators,
            compute_epoch_of_slot(state.slot, slots_per_epoch),
        ),
        ssz.sedes.List(ssz.uint64, config.VALIDATOR_REGISTRY_LIMIT),
    )

    target_epoch = state.next_epoch(slots_per_epoch) + activation_exit_delay
    assert result[target_epoch % epochs_per_historical_vector] == index_root
示例#15
0
def deposit(w3, deposit_contract) -> int:
    amount = get_random_valid_deposit_amount()
    deposit_input = (
        SAMPLE_PUBKEY,
        SAMPLE_WITHDRAWAL_CREDENTIALS,
        SAMPLE_VALID_SIGNATURE,
        ssz.get_hash_tree_root(
            DepositData(
                pubkey=SAMPLE_PUBKEY,
                withdrawal_credentials=SAMPLE_WITHDRAWAL_CREDENTIALS,
                amount=amount,
                signature=SAMPLE_VALID_SIGNATURE,
            )),
    )
    tx_hash = deposit_contract.functions.deposit(*deposit_input).transact(
        {"value": amount * eth_utils.denoms.gwei})
    tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    assert tx_receipt["status"]
    return amount
示例#16
0
def validate_aggregator_proof(state: BeaconState,
                              aggregate_and_proof: AggregateAndProof,
                              config: Eth2Config) -> None:
    slot = aggregate_and_proof.aggregate.data.slot
    pubkey = state.validators[aggregate_and_proof.aggregator_index].pubkey
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        config.SLOTS_PER_EPOCH,
        message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH),
    )
    message_hash = get_hash_tree_root(slot, sedes=uint64)

    bls.validate(
        message_hash=message_hash,
        pubkey=pubkey,
        signature=aggregate_and_proof.selection_proof,
        domain=domain,
    )
示例#17
0
def _generate_randao_reveal(privkey: int, slot: Slot, state: BeaconState,
                            config: Eth2Config) -> BLSSignature:
    """
    Return the RANDAO reveal for the validator represented by ``privkey``.
    The current implementation requires a validator to provide the BLS signature
    over the SSZ-serialized epoch in which they are proposing a block.
    """
    epoch = compute_epoch_of_slot(slot, config.SLOTS_PER_EPOCH)

    message_hash = ssz.get_hash_tree_root(epoch, sedes=ssz.sedes.uint64)

    randao_reveal = sign_transaction(
        message_hash=message_hash,
        privkey=privkey,
        state=state,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_RANDAO,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    return randao_reveal
示例#18
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
示例#19
0
def validate_randao_reveal(
    state: BeaconState,
    proposer_index: int,
    epoch: Epoch,
    randao_reveal: Hash32,
    slots_per_epoch: int,
) -> None:
    proposer = state.validators[proposer_index]
    proposer_pubkey = proposer.pubkey
    message_hash = ssz.get_hash_tree_root(epoch, sedes=ssz.sedes.uint64)
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch)

    try:
        bls.validate(
            pubkey=proposer_pubkey,
            message_hash=message_hash,
            signature=cast(BLSSignature, randao_reveal),
            domain=domain,
        )
    except SignatureError as error:
        raise ValidationError("RANDAO reveal is invalid", error)
示例#20
0
 def signing_root(self):
     return ssz.get_hash_tree_root(self, self._meta.signed_container_sedes)
示例#21
0
def test_vector_of_composite(bytes16_vector, result):
    sedes = Vector(ByteVector(16), len(bytes16_vector))
    assert ssz.get_hash_tree_root(bytes16_vector, sedes) == result
示例#22
0
def test_list_of_basic(serialized_uints128, max_length, result):
    # item_length = 128 / 8 = 16
    int_values = tuple(ssz.decode(value, uint128) for value in serialized_uints128)
    assert ssz.get_hash_tree_root(int_values, List(uint128, max_length)) == result
示例#23
0
def test_vector_of_basics(serialized_uints128, result):
    sedes = Vector(uint128, len(serialized_uints128))
    int_values = tuple(ssz.decode(value, uint128) for value in serialized_uints128)
    assert ssz.get_hash_tree_root(int_values, sedes) == result
示例#24
0
def test_bitlist(size, value, result):
    foo = Bitlist(size)
    assert ssz.get_hash_tree_root(value, foo) == result
示例#25
0
def test_container(bytes16_fields, result):
    sedes = Container(tuple(itertools.repeat(bytes16, len(bytes16_fields))))
    assert ssz.get_hash_tree_root(bytes16_fields, sedes) == result
示例#26
0
def test_list_of_composite(bytes16_list, max_length, result):
    # item_length = 32
    sedes = List(bytes16, max_length)
    assert ssz.get_hash_tree_root(bytes16_list, sedes) == result
示例#27
0
def test_root():
    class Test(ssz.Serializable):
        fields = (("field1", uint8), ("field2", uint8))

    test = Test(1, 2)
    assert test.hash_tree_root == ssz.get_hash_tree_root(test, Test)
示例#28
0
def test_uint(uint_and_value):
    uint, value = uint_and_value
    assert ssz.get_hash_tree_root(value,
                                  uint) == ssz.encode(value, uint).ljust(
                                      CHUNK_SIZE, b"\x00")
示例#29
0
def test_boolean(value, expected):
    assert ssz.get_hash_tree_root(value, boolean) == expected
示例#30
0
def execute_tree_hash_test_case(test_case):
    sedes = parse_type_definition(test_case["type"])
    value = from_formatted_dict(test_case["value"], sedes, CustomCodec)
    expected_root = decode_hex(test_case["root"])
    calculated_root = ssz.get_hash_tree_root(value, sedes)
    assert calculated_root == expected_root