Ejemplo n.º 1
0
def test_get_x_coordinate(message, domain):
    x_coordinate = _get_x_coordinate(message, domain)
    domain_in_bytes = domain.to_bytes(8, 'big')
    assert x_coordinate == FQ2([
        big_endian_to_int(hash_eth2(message + domain_in_bytes + b'\x01')),
        big_endian_to_int(hash_eth2(message + domain_in_bytes + b'\x02')),
    ])
Ejemplo n.º 2
0
def _get_x_coordinate(message: bytes, domain: int) -> FQ2:
    domain_in_bytes = domain.to_bytes(8, 'big')

    # Initial candidate x coordinate
    x_re = big_endian_to_int(hash_eth2(message + domain_in_bytes + b'\x01'))
    x_im = big_endian_to_int(hash_eth2(message + domain_in_bytes + b'\x02'))
    x_coordinate = FQ2([x_re, x_im])  # x_re + x_im * i

    return x_coordinate
Ejemplo n.º 3
0
def verify_merkle_branch(leaf: Hash32, proof: Sequence[Hash32], depth: int,
                         index: int, root: Hash32) -> bool:
    """
    Verify that the given ``leaf`` is on the merkle branch ``proof``.
    """
    value = leaf
    for i in range(depth):
        if index // (2**i) % 2:
            value = hash_eth2(proof[i] + value)
        else:
            value = hash_eth2(value + proof[i])
    return value == root
Ejemplo n.º 4
0
def verify_merkle_proof(root: Hash32, leaf: Hash32, index: int,
                        proof: MerkleProof) -> bool:
    """
    Verify that the given ``item`` is on the merkle branch ``proof``
    starting with the given ``root``.
    """
    assert len(proof) == TreeDepth
    value = leaf
    for i in range(TreeDepth):
        if index // (2**i) % 2:
            value = hash_eth2(proof[i] + value)
        else:
            value = hash_eth2(value + proof[i])
    return value == root
def test_update_latest_index_roots(genesis_state,
                                   config,
                                   state_slot,
                                   epoch_length,
                                   latest_index_roots_length):
    state = genesis_state.copy(
        slot=state_slot,
    )

    result_state = _update_latest_index_roots(state, config)

    # TODO: chanege to hash_tree_root
    index_root = hash_eth2(
        b''.join(
            [
                index.to_bytes(32, 'big')
                for index in get_active_validator_indices(
                    state.validator_registry,
                    # TODO: change to `per-epoch` version
                    state.slot,
                )
            ]
        )
    )

    assert result_state.latest_index_roots[
        state.next_epoch(epoch_length) % latest_index_roots_length
    ] == index_root
Ejemplo n.º 6
0
def generate_seed(state: 'BeaconState',
                  epoch: EpochNumber,
                  epoch_length: int,
                  seed_lookahead: int,
                  entry_exit_delay: int,
                  latest_index_roots_length: int,
                  latest_randao_mixes_length: int) -> Hash32:
    """
    Generate a seed for the given ``epoch``.
    """
    randao_mix = get_randao_mix(
        state=state,
        epoch=EpochNumber(epoch - seed_lookahead),
        epoch_length=epoch_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    active_index_root = get_active_index_root(
        state=state,
        epoch=epoch,
        epoch_length=epoch_length,
        entry_exit_delay=entry_exit_delay,
        latest_index_roots_length=latest_index_roots_length,
    )
    epoch_as_bytes = epoch.to_bytes(32, byteorder="little")

    return hash_eth2(randao_mix + active_index_root + epoch_as_bytes)
Ejemplo n.º 7
0
def process_randao(state: BeaconState, block: BaseBeaconBlock,
                   config: Eth2Config) -> BeaconState:
    proposer_index = get_beacon_proposer_index(
        state=state,
        slot=state.slot,
        committee_config=CommitteeConfig(config),
    )
    proposer = state.validator_registry[proposer_index]

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)

    validate_randao_reveal(
        randao_reveal=block.randao_reveal,
        proposer_index=proposer_index,
        proposer_pubkey=proposer.pubkey,
        epoch=epoch,
        fork=state.fork,
    )

    randao_mix_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH
    new_randao_mix = bitwise_xor(
        get_randao_mix(
            state=state,
            epoch=epoch,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
        ),
        hash_eth2(block.randao_reveal),
    )

    return state.copy(latest_randao_mixes=update_tuple_item(
        state.latest_randao_mixes,
        randao_mix_index,
        new_randao_mix,
    ), )
Ejemplo n.º 8
0
def validate_deposit_proof(state: BeaconState, deposit: Deposit,
                           deposit_contract_tree_depth: int) -> None:
    """
    Validate if deposit branch proof is valid.
    """
    # Should equal 8 bytes for deposit_data.amount +
    #              8 bytes for deposit_data.timestamp +
    #              176 bytes for deposit_data.deposit_input
    # It should match the deposit_data in the eth1.0 deposit contract
    serialized_deposit_data = ssz.encode(deposit.deposit_data)

    is_valid_proof = verify_merkle_branch(
        leaf=hash_eth2(serialized_deposit_data),
        proof=deposit.proof,
        depth=deposit_contract_tree_depth,
        index=deposit.index,
        root=state.latest_eth1_data.deposit_root,
    )
    if not is_valid_proof:
        raise ValidationError(
            f"deposit.proof ({deposit.proof}) is invalid against "
            f"leaf={hash_eth2(serialized_deposit_data)}, "
            f"deposit_contract_tree_depth={deposit_contract_tree_depth}, "
            f"deposit.index={deposit.index} "
            f"state.latest_eth1_data.deposit_root={state.latest_eth1_data.deposit_root.hex()}"
        )
Ejemplo n.º 9
0
 def mock_get_active_index_root(state, epoch, slots_per_epoch,
                                activation_exit_delay,
                                latest_active_index_roots_length):
     return hash_eth2(
         state.root + epoch.to_bytes(32, byteorder='little') +
         slots_per_epoch.to_bytes(32, byteorder='little') +
         latest_active_index_roots_length.to_bytes(32, byteorder='little'))
def test_get_previous_epoch_matching_head_attestations(
        random, sample_state, genesis_epoch, slots_per_epoch,
        slots_per_historical_root, sample_attestation_data_params,
        sample_attestation_params):
    previous_epoch = 9
    current_epoch = previous_epoch + 1
    current_slot = get_epoch_start_slot(current_epoch + 1, slots_per_epoch) - 1
    latest_block_roots = [
        hash_eth2(b'block_root' + i.to_bytes(1, 'little'))
        for i in range(slots_per_historical_root)
    ]

    num_previous_epoch_attestation = random.sample(range(slots_per_epoch),
                                                   1)[0]
    previous_epoch_attestion_slots = random.sample(
        range(
            get_epoch_start_slot(previous_epoch, slots_per_epoch),
            get_epoch_start_slot(current_epoch, slots_per_epoch),
        ),
        num_previous_epoch_attestation,
    )
    num_previous_epoch_head_attestation = random.sample(
        range(num_previous_epoch_attestation), 1)[0]
    previous_epoch_head_attestion_slots = random.sample(
        previous_epoch_attestion_slots,
        num_previous_epoch_head_attestation,
    )
    previous_epoch_not_head_attestion_slots = set(
        previous_epoch_attestion_slots).difference(
            set(previous_epoch_head_attestion_slots))

    previous_epoch_head_attestations = []
    for slot in previous_epoch_head_attestion_slots:
        previous_epoch_head_attestations.append(
            Attestation(**sample_attestation_params).copy(
                data=AttestationData(**sample_attestation_data_params).copy(
                    slot=slot,
                    beacon_block_root=latest_block_roots[
                        slot % slots_per_historical_root],
                ), ))
    previous_epoch_not_head_attestations = []
    for slot in previous_epoch_not_head_attestion_slots:
        previous_epoch_not_head_attestations.append(
            Attestation(**sample_attestation_params).copy(data=AttestationData(
                **sample_attestation_data_params).copy(slot=slot, ), ))

    state = sample_state.copy(
        slot=current_slot,
        latest_block_roots=latest_block_roots,
        previous_epoch_attestations=(previous_epoch_head_attestations +
                                     previous_epoch_not_head_attestations),
    )

    result = get_previous_epoch_matching_head_attestations(
        state,
        slots_per_epoch,
        genesis_epoch,
        slots_per_historical_root,
    )
    assert set(previous_epoch_head_attestations) == set(result)
def test_update_latest_active_index_roots(genesis_state,
                                          committee_config,
                                          state_slot,
                                          slots_per_epoch,
                                          latest_active_index_roots_length,
                                          activation_exit_delay):
    state = genesis_state.copy(
        slot=state_slot,
    )

    result_state = _update_latest_active_index_roots(state, committee_config)

    # TODO: chanege to hash_tree_root
    index_root = hash_eth2(
        b''.join(
            [
                index.to_bytes(32, 'little')
                for index in get_active_validator_indices(
                    state.validator_registry,
                    # TODO: change to `per-epoch` version
                    slot_to_epoch(state.slot, slots_per_epoch),
                )
            ]
        )
    )

    target_epoch = state.next_epoch(slots_per_epoch) + activation_exit_delay
    assert result_state.latest_active_index_roots[
        target_epoch % latest_active_index_roots_length
    ] == index_root
Ejemplo n.º 12
0
def _update_latest_index_roots(state: BeaconState,
                               committee_config: CommitteeConfig) -> BeaconState:
    """
    Return the BeaconState with updated `latest_index_roots`.
    """
    next_epoch = state.next_epoch(committee_config.EPOCH_LENGTH)

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        EpochNumber(next_epoch + committee_config.ENTRY_EXIT_DELAY),
    )
    index_root = hash_eth2(
        b''.join(
            [
                index.to_bytes(32, 'big')
                for index in active_validator_indices
            ]
        )
    )

    latest_index_roots = update_tuple_item(
        state.latest_index_roots,
        (
            (next_epoch + committee_config.ENTRY_EXIT_DELAY) %
            committee_config.LATEST_INDEX_ROOTS_LENGTH
        ),
        index_root,
    )

    return state.copy(
        latest_index_roots=latest_index_roots,
    )
Ejemplo n.º 13
0
 def mock_get_active_index_root(state, epoch, epoch_length,
                                entry_exit_delay,
                                latest_index_roots_length):
     return hash_eth2(
         state.root + epoch.to_bytes(32, byteorder='little') +
         epoch_length.to_bytes(32, byteorder='little') +
         latest_index_roots_length.to_bytes(32, byteorder='little'))
Ejemplo n.º 14
0
 def mock_get_randao_mix(state,
                         slot,
                         latest_randao_mixes_length):
     return hash_eth2(
         state.root +
         abs(slot).to_bytes(32, byteorder='big') +
         latest_randao_mixes_length.to_bytes(32, byteorder='big')
     )
Ejemplo n.º 15
0
 def mock_get_randao_mix(state,
                         epoch,
                         slots_per_epoch,
                         latest_randao_mixes_length):
     return hash_eth2(
         state.root +
         epoch.to_bytes(32, byteorder='little') +
         latest_randao_mixes_length.to_bytes(32, byteorder='little')
     )
Ejemplo n.º 16
0
def shuffle(values: Sequence[TItem],
            seed: Hash32) -> Iterable[TItem]:
    """
    Return the shuffled ``values`` with ``seed`` as entropy.
    Mainly for shuffling active validators in-protocol.

    Spec: https://github.com/ethereum/eth2.0-specs/blob/70cef14a08de70e7bd0455d75cf380eb69694bfb/specs/core/0_beacon-chain.md#helper-functions  # noqa: E501
    """
    values_count = len(values)

    # The range of the RNG places an upper-bound on the size of the list that
    # may be shuffled. It is a logic error to supply an oversized list.
    if values_count >= RAND_MAX:
        raise ValueError(
            "values_count (%s) should less than RAND_MAX (%s)." %
            (values_count, RAND_MAX)
        )

    output = [x for x in values]
    source = seed
    index = 0
    while index < values_count - 1:
        # Re-hash the `source` to obtain a new pattern of bytes.
        source = hash_eth2(source)

        # Iterate through the `source` bytes in 3-byte chunks.
        for position in range(0, 32 - (32 % RAND_BYTES), RAND_BYTES):
            # Determine the number of indices remaining in `values` and exit
            # once the last index is reached.
            remaining = values_count - index
            if remaining == 1:
                break

            # Read 3-bytes of `source` as a 24-bit big-endian integer.
            sample_from_source = int.from_bytes(
                source[position:position + RAND_BYTES], 'big'
            )

            # Sample values greater than or equal to `sample_max` will cause
            # modulo bias when mapped into the `remaining` range.
            sample_max = RAND_MAX - RAND_MAX % remaining

            # Perform a swap if the consumed entropy will not cause modulo bias.
            if sample_from_source < sample_max:
                # Select a replacement index for the current index.
                replacement_position = (sample_from_source % remaining) + index
                # Swap the current index with the replacement index.
                (output[index], output[replacement_position]) = (
                    output[replacement_position],
                    output[index]
                )
                index += 1
            else:
                # The sample causes modulo bias. A new sample should be read.
                pass

    return output
Ejemplo n.º 17
0
def hash_to_G2(message: bytes, domain: int) -> Tuple[FQ2, FQ2, FQ2]:
    domain_in_bytes = domain.to_bytes(8, 'big')

    # Initial candidate x coordinate
    x_re = big_endian_to_int(hash_eth2(domain_in_bytes + b'\x01' + message))
    x_im = big_endian_to_int(hash_eth2(domain_in_bytes + b'\x02' + message))
    x_coordinate = FQ2([x_re, x_im])  # x_re + x_im * i

    # Test candidate y coordinates until a one is found
    while 1:
        y_coordinate_squared = x_coordinate**3 + FQ2(
            [4, 4])  # The curve is y^2 = x^3 + 4(i + 1)
        y_coordinate = modular_squareroot(y_coordinate_squared)
        if y_coordinate is not None:  # Check if quadratic residue found
            break
        x_coordinate += FQ2([1, 0])  # Add 1 and try again

    return multiply((x_coordinate, y_coordinate, FQ2([1, 0])), G2_cofactor)
Ejemplo n.º 18
0
 def mock_get_active_index_root(state,
                                slot,
                                epoch_length,
                                latest_index_roots_length):
     return hash_eth2(
         state.root +
         abs(slot).to_bytes(32, byteorder='big') +
         epoch_length.to_bytes(32, byteorder='big') +
         latest_index_roots_length.to_bytes(32, byteorder='big')
     )
Ejemplo n.º 19
0
def shuffle(values: Sequence[TItem],
            seed: Hash32,
            shuffle_round_count: int = 90) -> Iterable[TItem]:
    """
    Return shuffled indices in a pseudorandom permutation `0...list_size-1` with
    ``seed`` as entropy.

    Utilizes 'swap or not' shuffling found in
    https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf
    See the 'generalized domain' algorithm on page 3.
    """
    list_size = len(values)

    if list_size > MAX_LIST_SIZE:
        raise ValidationError(
            f"The `list_size` ({list_size}) should be equal to or less than "
            f"`MAX_LIST_SIZE` ({MAX_LIST_SIZE}")

    indices = list(range(list_size))
    for round in range(shuffle_round_count):
        hash_bytes = b''.join([
            hash_eth2(seed + round.to_bytes(1, 'little') +
                      i.to_bytes(4, 'little'))
            for i in range((list_size + 255) // 256)
        ])

        pivot = int.from_bytes(
            hash_eth2(seed + round.to_bytes(1, 'little'))[:8],
            'little',
        ) % list_size
        for i in range(list_size):
            flip = (pivot - indices[i]) % list_size
            hash_position = indices[i] if indices[i] > flip else flip
            byte = hash_bytes[hash_position // 8]
            mask = POWER_OF_TWO_NUMBERS[hash_position % 8]
            if byte & mask:
                indices[i] = flip
            else:
                # not swap
                pass

    for i in indices:
        yield values[i]
Ejemplo n.º 20
0
def test_get_merkle_root():
    hash_0 = b"0" * 32
    leaves = (hash_0, )
    root = get_merkle_root(leaves)
    assert root == hash_0

    hash_1 = b"1" * 32
    leaves = (hash_0, hash_1)
    root = get_merkle_root(leaves)
    assert root == hash_eth2(hash_0 + hash_1)
Ejemplo n.º 21
0
def test_merkle_root_and_proofs(items, expected_root):
    tree = calc_merkle_tree(items)
    assert get_root(tree) == expected_root
    for index in range(len(items)):
        item = items[index]
        proof = get_merkle_proof(tree, index)
        assert verify_merkle_proof(expected_root, hash_eth2(item), index,
                                   proof)

        assert not verify_merkle_proof(b"\x32" * 32, hash_eth2(item), index,
                                       proof)
        assert not verify_merkle_proof(expected_root, hash_eth2(b"\x32" * 32),
                                       index, proof)
        if len(items) > 1:
            assert not verify_merkle_proof(expected_root, hash_eth2(item),
                                           (index + 1) % len(items), proof)
        for replaced_index in range(len(proof)):
            altered_proof = proof[:replaced_index] + (
                b"\x32" * 32, ) + proof[replaced_index + 1:]
            assert not verify_merkle_proof(expected_root, hash_eth2(item),
                                           index, altered_proof)
Ejemplo n.º 22
0
def test_generate_seed(monkeypatch, genesis_state, slots_per_epoch,
                       min_seed_lookahead, activation_exit_delay,
                       latest_active_index_roots_length,
                       latest_randao_mixes_length):
    from eth2.beacon import helpers

    def mock_get_randao_mix(state, epoch, slots_per_epoch,
                            latest_randao_mixes_length):
        return hash_eth2(
            state.root + epoch.to_bytes(32, byteorder='little') +
            latest_randao_mixes_length.to_bytes(32, byteorder='little'))

    def mock_get_active_index_root(state, epoch, slots_per_epoch,
                                   activation_exit_delay,
                                   latest_active_index_roots_length):
        return hash_eth2(
            state.root + epoch.to_bytes(32, byteorder='little') +
            slots_per_epoch.to_bytes(32, byteorder='little') +
            latest_active_index_roots_length.to_bytes(32, byteorder='little'))

    monkeypatch.setattr(helpers, 'get_randao_mix', mock_get_randao_mix)
    monkeypatch.setattr(helpers, 'get_active_index_root',
                        mock_get_active_index_root)

    state = genesis_state
    epoch = 1

    epoch_as_bytes = epoch.to_bytes(32, 'little')

    seed = generate_seed(
        state=state,
        epoch=epoch,
        slots_per_epoch=slots_per_epoch,
        min_seed_lookahead=min_seed_lookahead,
        activation_exit_delay=activation_exit_delay,
        latest_active_index_roots_length=latest_active_index_roots_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    assert seed == hash_eth2(
        mock_get_randao_mix(
            state=state,
            epoch=(epoch - min_seed_lookahead),
            slots_per_epoch=slots_per_epoch,
            latest_randao_mixes_length=latest_randao_mixes_length,
        ) + mock_get_active_index_root(
            state=state,
            epoch=epoch,
            slots_per_epoch=slots_per_epoch,
            activation_exit_delay=activation_exit_delay,
            latest_active_index_roots_length=latest_active_index_roots_length,
        ) + epoch_as_bytes)
Ejemplo n.º 23
0
def get_permuted_index(index: int, list_size: int, seed: Hash32,
                       shuffle_round_count: int) -> int:
    """
    Return `p(index)` in a pseudorandom permutation `p` of `0...list_size-1`
    with ``seed`` as entropy.

    Utilizes 'swap or not' shuffling found in
    https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf
    See the 'generalized domain' algorithm on page 3.
    """
    if index >= list_size:
        raise ValidationError(
            f"The given `index` ({index}) should be less than `list_size` ({list_size}"
        )

    if list_size > MAX_LIST_SIZE:
        raise ValidationError(
            f"The given `list_size` ({list_size}) should be equal to or less than "
            f"`MAX_LIST_SIZE` ({MAX_LIST_SIZE}")

    new_index = index
    for round in range(shuffle_round_count):
        pivot = int.from_bytes(
            hash_eth2(seed + round.to_bytes(1, 'little'))[0:8],
            'little',
        ) % list_size

        flip = (pivot - new_index) % list_size
        hash_pos = max(new_index, flip)
        h = hash_eth2(seed + round.to_bytes(1, 'little') +
                      (hash_pos // 256).to_bytes(4, 'little'))
        byte = h[(hash_pos % 256) // 8]
        bit = (byte >> (hash_pos % 8)) % 2
        new_index = flip if bit else new_index

    return new_index
Ejemplo n.º 24
0
def test_generate_seed(monkeypatch, genesis_state, epoch_length,
                       seed_lookahead, entry_exit_delay,
                       latest_index_roots_length, latest_randao_mixes_length):
    from eth2.beacon import helpers

    def mock_get_randao_mix(state, epoch, epoch_length,
                            latest_randao_mixes_length):
        return hash_eth2(
            state.root + abs(epoch).to_bytes(32, byteorder='big') +
            latest_randao_mixes_length.to_bytes(32, byteorder='big'))

    def mock_get_active_index_root(state, epoch, epoch_length,
                                   entry_exit_delay,
                                   latest_index_roots_length):
        return hash_eth2(
            state.root + abs(epoch).to_bytes(32, byteorder='big') +
            epoch_length.to_bytes(32, byteorder='big') +
            latest_index_roots_length.to_bytes(32, byteorder='big'))

    monkeypatch.setattr(helpers, 'get_randao_mix', mock_get_randao_mix)
    monkeypatch.setattr(helpers, 'get_active_index_root',
                        mock_get_active_index_root)

    state = genesis_state
    epoch = 1

    seed = generate_seed(
        state=state,
        epoch=epoch,
        epoch_length=epoch_length,
        seed_lookahead=seed_lookahead,
        entry_exit_delay=entry_exit_delay,
        latest_index_roots_length=latest_index_roots_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    assert seed == hash_eth2(
        mock_get_randao_mix(
            state=state,
            epoch=(epoch - seed_lookahead),
            epoch_length=epoch_length,
            latest_randao_mixes_length=latest_randao_mixes_length,
        ) + mock_get_active_index_root(
            state=state,
            epoch=epoch,
            epoch_length=epoch_length,
            entry_exit_delay=entry_exit_delay,
            latest_index_roots_length=latest_index_roots_length,
        ))
Ejemplo n.º 25
0
def verify_merkle_proof(root: Hash32,
                        item: Union[bytes, bytearray],
                        item_index: int,
                        proof: MerkleProof) -> bool:
    """
    Verify a Merkle proof against a root hash.
    """
    leaf = hash_eth2(item)
    branch_indices = get_branch_indices(item_index, len(proof))
    node_orderers = [
        identity if branch_index % 2 == 0 else reversed
        for branch_index in branch_indices
    ]
    proof_root = reduce(
        lambda n1, n2_and_order: _calc_parent_hash(*n2_and_order[1]([n1, n2_and_order[0]])),
        zip(proof, node_orderers),
        leaf,
    )
    return proof_root == root
Ejemplo n.º 26
0
def create_mock_genesis_validator_deposits_and_root(
        num_validators: int,
        config: Eth2Config,
        pubkeys: Sequence[BLSPubkey],
        keymap: Dict[BLSPubkey, int]) -> Tuple[Tuple[Deposit, ...], Hash32]:
    # Mock data
    withdrawal_credentials = Hash32(b'\x22' * 32)
    fork = Fork(
        previous_version=config.GENESIS_FORK_VERSION.to_bytes(4, 'little'),
        current_version=config.GENESIS_FORK_VERSION.to_bytes(4, 'little'),
        epoch=config.GENESIS_EPOCH,
    )

    deposit_data_array = tuple()  # type: Tuple[DepositData, ...]
    deposit_data_leaves = tuple()  # type: Tuple[Hash32, ...]

    for i in range(num_validators):
        deposit_data = create_mock_deposit_data(
            config=config,
            pubkeys=pubkeys,
            keymap=keymap,
            validator_index=ValidatorIndex(i),
            withdrawal_credentials=withdrawal_credentials,
            fork=fork,
        )
        item = hash_eth2(ssz.encode(deposit_data))
        deposit_data_leaves += (item,)
        deposit_data_array += (deposit_data,)

    tree = calc_merkle_tree_from_leaves(deposit_data_leaves)
    root = get_merkle_root(deposit_data_leaves)

    genesis_validator_deposits = tuple(
        Deposit(
            proof=get_merkle_proof(tree, item_index=i),
            index=i,
            deposit_data=deposit_data_array[i],
        )
        for i in range(num_validators)
    )

    return genesis_validator_deposits, root
Ejemplo n.º 27
0
def generate_seed(state: 'BeaconState', slot: SlotNumber, epoch_length: int,
                  seed_lookahead: int, latest_index_roots_length: int,
                  latest_randao_mixes_length: int) -> Hash32:
    """
    Generate a seed for the given ``slot``.

    TODO: it's slot version, will be changed to epoch version.
    """
    randao_mix = get_randao_mix(
        state,
        SlotNumber(slot - seed_lookahead),
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    active_index_root = get_active_index_root(
        state,
        slot,
        epoch_length=epoch_length,
        latest_index_roots_length=latest_index_roots_length,
    )

    return hash_eth2(randao_mix + active_index_root)
Ejemplo n.º 28
0
def validate_serenity_attestation_aggregate_signature(
        state: BeaconState, attestation: Attestation,
        epoch_length: int) -> None:
    """
    Validate ``aggregate_signature`` field of ``attestation``.
    Raise ``ValidationError`` if it's invalid.

    Note: This is the phase 0 version of `aggregate_signature`` validation.
    All proof of custody bits are assumed to be 0 within the signed data.
    This will change to reflect real proof of custody bits in the Phase 1.
    """
    participant_indices = get_attestation_participants(
        state=state,
        slot=attestation.data.slot,
        shard=attestation.data.shard,
        participation_bitfield=attestation.participation_bitfield,
        epoch_length=epoch_length,
    )

    pubkeys = tuple(state.validator_registry[validator_index].pubkey
                    for validator_index in participant_indices)
    group_public_key = bls.aggregate_pubkeys(pubkeys)

    # TODO: change to tree hashing when we have SSZ
    # TODO: Replace with AttestationAndCustodyBit data structure
    message = hash_eth2(rlp.encode(attestation.data) + (0).to_bytes(1, "big"))

    is_valid_signature = bls.verify(
        message=message,
        pubkey=group_public_key,
        signature=attestation.aggregate_signature,
        domain=get_domain(
            fork_data=state.fork_data,
            slot=attestation.data.slot,
            domain_type=SignatureDomain.DOMAIN_ATTESTATION,
        ),
    )
    if not is_valid_signature:
        raise ValidationError(
            "Attestation ``aggregate_signature`` is invalid.")
Ejemplo n.º 29
0
def _update_latest_index_roots(state: BeaconState,
                               config: BeaconConfig) -> BeaconState:
    """
    Return the BeaconState with updated `latest_index_roots`.
    """
    next_epoch = state.next_epoch(config.EPOCH_LENGTH)

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        # TODO: change to `per-epoch` version
        state.slot,
    )
    index_root = hash_eth2(b''.join(
        [index.to_bytes(32, 'big') for index in active_validator_indices]))

    latest_index_roots = update_tuple_item(
        state.latest_index_roots,
        next_epoch % config.LATEST_INDEX_ROOTS_LENGTH,
        index_root,
    )

    return state.copy(latest_index_roots=latest_index_roots, )
Ejemplo n.º 30
0
    def create_mock_signed_attestation(state,
                                       shard_committee,
                                       voting_committee_indices,
                                       attestation_data):
        message = hash_eth2(
            rlp.encode(attestation_data) +
            (0).to_bytes(1, "big")
        )
        # participants sign message
        signatures = [
            bls.sign(
                message,
                privkeys[shard_committee.committee[committee_index]],
                domain=get_domain(
                    fork_data=state.fork_data,
                    slot=attestation_data.slot,
                    domain_type=SignatureDomain.DOMAIN_ATTESTATION,
                )
            )
            for committee_index in voting_committee_indices
        ]

        # aggregate signatures and construct participant bitfield
        participation_bitfield, aggregate_signature = aggregate_votes(
            bitfield=get_empty_bitfield(len(shard_committee.committee)),
            sigs=(),
            voting_sigs=signatures,
            voting_committee_indices=voting_committee_indices,
        )

        # create attestation from attestation_data, particpipant_bitfield, and signature
        return Attestation(
            data=attestation_data,
            participation_bitfield=participation_bitfield,
            custody_bitfield=b'',
            aggregate_signature=aggregate_signature,
        )