Beispiel #1
0
def test_decoder():
    rng = Random(123)

    # check these types only, Block covers a lot of operation types already.
    for typ in [spec.AttestationDataAndCustodyBit, spec.BeaconState, spec.BeaconBlock]:
        # create a random pyspec value
        original = random_value.get_random_ssz_object(rng, typ, 100, 10,
                                                      mode=random_value.RandomizationMode.mode_random,
                                                      chaos=True)
        # serialize it, using pyspec
        pyspec_data = spec_ssz_impl.serialize(original)
        # get the py-ssz type for it
        block_sedes = translate_typ(typ)
        # try decoding using the py-ssz type
        raw_value = block_sedes.deserialize(pyspec_data)

        # serialize it using py-ssz
        pyssz_data = block_sedes.serialize(raw_value)
        # now check if the serialized form is equal. If so, we confirmed decoding and encoding to work.
        assert pyspec_data == pyssz_data

        # now translate the py-ssz value in a pyspec-value
        block = translate_value(raw_value, typ)

        # and see if the hash-tree-root of the original matches the hash-tree-root of the decoded & translated value.
        original_hash_tree_root = spec_ssz_impl.hash_tree_root(original)
        assert original_hash_tree_root == spec_ssz_impl.hash_tree_root(block)
        assert original_hash_tree_root == block_sedes.get_hash_tree_root(raw_value)
Beispiel #2
0
def decode(data: Any, typ):
    if issubclass(typ, (uint, boolean)):
        return typ(data)
    elif issubclass(typ, (List, Vector)):
        return typ(decode(element, typ.element_cls()) for element in data)
    elif issubclass(typ, ByteVector):
        return typ(bytes.fromhex(data[2:]))
    elif issubclass(typ, ByteList):
        return typ(bytes.fromhex(data[2:]))
    elif issubclass(typ, Container):
        temp = {}
        for field_name, field_type in typ.fields().items():
            temp[field_name] = decode(data[field_name], field_type)
            if field_name + "_hash_tree_root" in data:
                assert (data[field_name +
                             "_hash_tree_root"][2:] == hash_tree_root(
                                 temp[field_name]).hex())
        ret = typ(**temp)
        if "hash_tree_root" in data:
            assert (data["hash_tree_root"][2:] == hash_tree_root(ret).hex())
        return ret
    elif issubclass(typ, Union):
        selector = int(data["selector"])
        options = typ.options()
        value_typ = options[selector]
        value: View
        if value_typ is None:  # handle the "nil" type case
            assert data["value"] is None
            value = None
        else:
            value = decode(data["value"], value_typ)
        return typ(selector=selector, value=value)
    else:
        raise Exception(f"Type not recognized: data={data}, typ={typ}")
Beispiel #3
0
def encode(value, include_hash_tree_roots=False):
    if isinstance(value, uint):
        # Larger uints are boxed and the class declares their byte length
        if value.__class__.type_byte_length() > 8:
            return str(int(value))
        return int(value)
    elif isinstance(value, boolean):
        return value == 1
    elif isinstance(value, (Bitlist, Bitvector)):
        return '0x' + serialize(value).hex()
    elif isinstance(value, list):  # normal python lists
        return [encode(element, include_hash_tree_roots) for element in value]
    elif isinstance(value, (List, Vector)):
        return [encode(element, include_hash_tree_roots) for element in value]
    elif isinstance(value, bytes):  # bytes, ByteList, ByteVector
        return '0x' + value.hex()
    elif isinstance(value, Container):
        ret = {}
        for field_name in value.fields().keys():
            field_value = getattr(value, field_name)
            ret[field_name] = encode(field_value, include_hash_tree_roots)
            if include_hash_tree_roots:
                ret[field_name + "_hash_tree_root"] = '0x' + hash_tree_root(
                    field_value).hex()
        if include_hash_tree_roots:
            ret["hash_tree_root"] = '0x' + hash_tree_root(value).hex()
        return ret
    else:
        raise Exception(
            f"Type not recognized: value={value}, typ={type(value)}")
Beispiel #4
0
def decode(data, typ):
    if is_uint_type(typ):
        return data
    elif is_bool_type(typ):
        assert data in (True, False)
        return data
    elif is_list_type(typ):
        elem_typ = read_list_elem_type(typ)
        return [decode(element, elem_typ) for element in data]
    elif is_vector_type(typ):
        elem_typ = read_vector_elem_type(typ)
        return Vector(decode(element, elem_typ) for element in data)
    elif is_bytes_type(typ):
        return bytes.fromhex(data[2:])
    elif is_bytesn_type(typ):
        return BytesN(bytes.fromhex(data[2:]))
    elif is_container_type(typ):
        temp = {}
        for field, subtype in typ.get_fields():
            temp[field] = decode(data[field], subtype)
            if field + "_hash_tree_root" in data:
                assert (data[field + "_hash_tree_root"][2:] == hash_tree_root(
                    temp[field], subtype).hex())
        ret = typ(**temp)
        if "hash_tree_root" in data:
            assert (data["hash_tree_root"][2:] == hash_tree_root(ret,
                                                                 typ).hex())
        return ret
    else:
        raise Exception(f"Type not recognized: data={data}, typ={typ}")
Beispiel #5
0
def create_genesis_state(spec, validator_balances, activation_threshold):
    deposit_root = b'\x42' * 32

    state = spec.BeaconState(
        genesis_time=0,
        eth1_deposit_index=len(validator_balances),
        eth1_data=spec.Eth1Data(
            deposit_root=deposit_root,
            deposit_count=len(validator_balances),
            block_hash=spec.Hash(),
        ),
        latest_block_header=spec.BeaconBlockHeader(body_root=spec.hash_tree_root(spec.BeaconBlockBody())),
    )

    # We "hack" in the initial validators,
    #  as it is much faster than creating and processing genesis deposits for every single test case.
    state.balances = copy.deepcopy(validator_balances)
    state.validators = [build_mock_validator(spec, i, state.balances[i]) for i in range(len(validator_balances))]

    # Process genesis activations
    for validator in state.validators:
        if validator.effective_balance >= activation_threshold:
            validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
            validator.activation_epoch = spec.GENESIS_EPOCH

    genesis_active_index_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT](
        spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)))
    genesis_compact_committees_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT](
        spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)))
    for index in range(spec.EPOCHS_PER_HISTORICAL_VECTOR):
        state.active_index_roots[index] = genesis_active_index_root
        state.compact_committees_roots[index] = genesis_compact_committees_root

    return state
Beispiel #6
0
    def record_block(self, item: specs.SignedBeaconBlock) -> bool:
        # When a validator receives a block from the network, they call `record_block` to see
        # whether they should record it.

        #         print(self.validator_index, "maybe record block", hash_tree_root(item.message))

        # If we already know about the block, do nothing
        if hash_tree_root(item.message) in self.store.blocks:
            return False

        # Sometimes recording the block fails. Examples include:
        # - The block slot is not the current slot (we keep it in memory for later, when we check backlog)
        # - The block parent is not known
        try:
            state = self.process_to_slot(item.message.parent_root,
                                         item.message.slot)
            specs.on_block(self.store, item, state=state)
#             print(self.validator_index, "recorded block", str(hash_tree_root(item.message))[-6:], "->", str(item.message.parent_root)[-6:])
        except AssertionError as e:
            print(self.validator_index, "didn't record block",
                  str(hash_tree_root(item.message))[-6:], "->",
                  str(item.message.parent_root)[-6:])
            print(e.args)
            return False

        # If attestations are included in the block, we want to record them
        for attestation in item.message.body.attestations:
            self.record_attestation(attestation)

        return True
Beispiel #7
0
def process_genesis_block(genesis_state):
    block_proposer = specs.get_beacon_proposer_index(genesis_state)

    genesis_block = specs.SignedBeaconBlock(message=specs.BeaconBlock(
        state_root=hash_tree_root(genesis_state),
        parent_root=hash_tree_root(genesis_state.latest_block_header),
        proposer_index=block_proposer))
    specs.process_block(genesis_state, genesis_block.message)
Beispiel #8
0
def aggregate_attestations(attestations):
    # Take in a set of attestations
    # Output aggregated attestations
    hashes = set([hash_tree_root(att.data) for att in attestations])
    return [
        build_aggregate([
            att for att in attestations if att_hash == hash_tree_root(att.data)
        ]) for att_hash in hashes
    ]
Beispiel #9
0
def build_empty_block(spec, state, slot=None):
    if slot is None:
        slot = state.slot
    empty_block = spec.BeaconBlock()
    empty_block.slot = slot
    empty_block.body.eth1_data.deposit_count = state.eth1_deposit_index
    previous_block_header = state.latest_block_header.copy()
    if previous_block_header.state_root == spec.Root():
        previous_block_header.state_root = hash_tree_root(state)
    empty_block.parent_root = hash_tree_root(previous_block_header)
    apply_randao_reveal(spec, state, empty_block)
    return empty_block
Beispiel #10
0
def get_valid_custody_response(spec,
                               state,
                               bit_challenge,
                               custody_data,
                               challenge_index,
                               invalid_chunk_bit=False):
    chunks = custody_chunkify(spec, custody_data)

    chunk_index = len(chunks) - 1
    chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key,
                                           chunks[chunk_index])

    while chunk_bit == bit_challenge.chunk_bits[
            chunk_index] ^ invalid_chunk_bit:
        chunk_index -= 1
        chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key,
                                               chunks[chunk_index])

    chunks_hash_tree_roots = [
        hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunk))
        for chunk in chunks
    ]
    chunks_hash_tree_roots += [
        hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](
            b"\0" * spec.BYTES_PER_CUSTODY_CHUNK))
        for i in range(2**spec.ceillog2(len(chunks)) - len(chunks))
    ]
    data_tree = get_merkle_tree(chunks_hash_tree_roots)

    data_branch = get_merkle_proof(data_tree, chunk_index)

    bitlist_chunk_index = chunk_index // BYTES_PER_CHUNK
    print(bitlist_chunk_index)
    bitlist_chunk_nodes = pack_bits_to_chunks(bit_challenge.chunk_bits)
    bitlist_tree = subtree_fill_to_contents(bitlist_chunk_nodes,
                                            get_depth(spec.MAX_CUSTODY_CHUNKS))
    print(bitlist_tree)
    bitlist_chunk_branch = None  # TODO; extract proof from merkle tree

    bitlist_chunk_index = chunk_index // 256

    chunk_bits_leaf = Bitvector[256](
        bit_challenge.chunk_bits[bitlist_chunk_index *
                                 256:(bitlist_chunk_index + 1) * 256])

    return spec.CustodyResponse(
        challenge_index=challenge_index,
        chunk_index=chunk_index,
        chunk=ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunks[chunk_index]),
        data_branch=data_branch,
        chunk_bits_branch=bitlist_chunk_branch,
        chunk_bits_leaf=chunk_bits_leaf,
    )
Beispiel #11
0
def get_valid_custody_response(spec,
                               state,
                               bit_challenge,
                               custody_data,
                               challenge_index,
                               invalid_chunk_bit=False):
    chunks = custody_chunkify(spec, custody_data)

    chunk_index = len(chunks) - 1
    chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key,
                                           chunks[chunk_index])

    while chunk_bit == bit_challenge.chunk_bits[
            chunk_index] ^ invalid_chunk_bit:
        chunk_index -= 1
        chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key,
                                               chunks[chunk_index])

    chunks_hash_tree_roots = [
        hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunk))
        for chunk in chunks
    ]
    chunks_hash_tree_roots += [
        hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](
            b"\0" * spec.BYTES_PER_CUSTODY_CHUNK))
        for i in range(2**spec.ceillog2(len(chunks)) - len(chunks))
    ]
    data_tree = get_merkle_tree(chunks_hash_tree_roots)

    data_branch = get_merkle_proof(data_tree, chunk_index)

    bitlist_chunk_index = chunk_index // BYTES_PER_CHUNK
    bitlist_chunks = chunkify(pack(bit_challenge.chunk_bits))
    bitlist_tree = get_merkle_tree(bitlist_chunks,
                                   pad_to=spec.MAX_CUSTODY_CHUNKS // 256)
    bitlist_chunk_branch = get_merkle_proof(bitlist_tree, chunk_index // 256) + \
        [len(bit_challenge.chunk_bits).to_bytes(32, "little")]

    bitlist_chunk_index = chunk_index // 256

    chunk_bits_leaf = Bitvector[256](
        bit_challenge.chunk_bits[bitlist_chunk_index *
                                 256:(bitlist_chunk_index + 1) * 256])

    return spec.CustodyResponse(
        challenge_index=challenge_index,
        chunk_index=chunk_index,
        chunk=ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunks[chunk_index]),
        data_branch=data_branch,
        chunk_bits_branch=bitlist_chunk_branch,
        chunk_bits_leaf=chunk_bits_leaf,
    )
Beispiel #12
0
def get_state_and_beacon_parent_root_at_slot(spec, state, slot):
    if slot < state.slot:
        raise Exception("Cannot build blocks for past slots")
    if slot > state.slot:
        # transition forward in copied state to grab relevant data from state
        state = state.copy()
        spec.process_slots(state, slot)

    previous_block_header = state.latest_block_header.copy()
    if previous_block_header.state_root == spec.Root():
        previous_block_header.state_root = hash_tree_root(state)
    beacon_parent_root = hash_tree_root(previous_block_header)
    return state, beacon_parent_root
Beispiel #13
0
def build_empty_shard_block(spec,
                            beacon_state,
                            shard_state,
                            slot,
                            signed=False,
                            full_attestation=False):
    if slot is None:
        slot = shard_state.slot

    previous_beacon_header = deepcopy(beacon_state.latest_block_header)
    if previous_beacon_header.state_root == spec.Bytes32():
        previous_beacon_header.state_root = beacon_state.hash_tree_root()
    beacon_block_root = hash_tree_root(previous_beacon_header)

    previous_block_header = deepcopy(shard_state.latest_block_header)
    if previous_block_header.state_root == spec.Bytes32():
        previous_block_header.state_root = shard_state.hash_tree_root()
    parent_root = hash_tree_root(previous_block_header)

    block = spec.ShardBlock(
        shard=shard_state.shard,
        slot=slot,
        beacon_block_root=beacon_block_root,
        parent_root=parent_root,
        block_size_sum=shard_state.block_size_sum + spec.SHARD_HEADER_SIZE,
    )

    if full_attestation:
        shard_committee = spec.get_shard_committee(beacon_state,
                                                   shard_state.shard,
                                                   block.slot)
        block.aggregation_bits = list(
            (True, ) * len(shard_committee) + (False, ) *
            (spec.MAX_PERIOD_COMMITTEE_SIZE * 2 - len(shard_committee)))
    else:
        shard_committee = []

    block.attestations = sign_shard_attestation(
        spec,
        beacon_state,
        shard_state,
        block,
        participants=shard_committee,
    )

    if signed:
        sign_shard_block(spec, beacon_state, shard_state, block)

    return block
Beispiel #14
0
def sign_block(spec, state, block, proposer_index=None):
    assert state.slot <= block.slot

    if proposer_index is None:
        if block.slot == state.slot:
            proposer_index = spec.get_beacon_proposer_index(state)
        else:
            if spec.compute_epoch_at_slot(
                    state.slot) + 1 > spec.compute_epoch_at_slot(block.slot):
                print(
                    "warning: block slot far away, and no proposer index manually given."
                    " Signing block is slow due to transition for proposer index calculation."
                )
            # use stub state to get proposer index of future slot
            stub_state = deepcopy(state)
            spec.process_slots(stub_state, block.slot)
            proposer_index = spec.get_beacon_proposer_index(stub_state)

    privkey = privkeys[proposer_index]

    block.body.randao_reveal = bls_sign(
        privkey=privkey,
        message_hash=hash_tree_root(spec.compute_epoch_at_slot(block.slot)),
        domain=spec.get_domain(
            state,
            message_epoch=spec.compute_epoch_at_slot(block.slot),
            domain_type=spec.DOMAIN_RANDAO,
        ))
    block.signature = bls_sign(message_hash=signing_root(block),
                               privkey=privkey,
                               domain=spec.get_domain(
                                   state, spec.DOMAIN_BEACON_PROPOSER,
                                   spec.compute_epoch_at_slot(block.slot)))
Beispiel #15
0
def run_bit_challenge_processing(spec, state, custody_bit_challenge, valid=True):
    """
    Run ``process_bit_challenge``, yielding:
      - pre-state ('pre')
      - CustodyBitChallenge ('custody_bit_challenge')
      - post-state ('post').
    If ``valid == False``, run expecting ``AssertionError``
    """
    yield 'pre', state
    yield 'custody_bit_challenge', custody_bit_challenge

    if not valid:
        expect_assertion_error(lambda: spec.process_bit_challenge(state, custody_bit_challenge))
        yield 'post', None
        return

    spec.process_bit_challenge(state, custody_bit_challenge)

    assert state.custody_bit_challenge_records[state.custody_challenge_index - 1].chunk_bits_merkle_root == \
        hash_tree_root(custody_bit_challenge.chunk_bits)
    assert state.custody_bit_challenge_records[state.custody_challenge_index - 1].challenger_index == \
        custody_bit_challenge.challenger_index
    assert state.custody_bit_challenge_records[state.custody_challenge_index - 1].responder_index == \
        custody_bit_challenge.responder_index

    yield 'post', state
Beispiel #16
0
def build_deposit(spec, state, deposit_data_list, pubkey, privkey, amount,
                  withdrawal_credentials, signed):
    deposit_data = build_deposit_data(spec,
                                      pubkey,
                                      privkey,
                                      amount,
                                      withdrawal_credentials,
                                      state=state,
                                      signed=signed)
    index = len(deposit_data_list)
    deposit_data_list.append(deposit_data)
    root = hash_tree_root(
        List[spec.DepositData,
             2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list))
    tree = calc_merkle_tree_from_leaves(
        tuple([d.hash_tree_root() for d in deposit_data_list]))
    proof = list(get_merkle_proof(
        tree, item_index=index)) + [(index + 1).to_bytes(32, 'little')]
    leaf = deposit_data.hash_tree_root()
    assert spec.is_valid_merkle_branch(leaf, proof,
                                       spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1,
                                       index, root)
    deposit = spec.Deposit(proof=proof, data=deposit_data)

    return deposit, root, deposit_data_list
Beispiel #17
0
def get_valid_custody_key_reveal(spec, state, period=None):
    current_epoch = spec.get_current_epoch(state)
    revealer_index = spec.get_active_validator_indices(state, current_epoch)[0]
    revealer = state.validators[revealer_index]

    if period is None:
        period = revealer.next_custody_secret_to_reveal

    epoch_to_sign = spec.get_randao_epoch_for_custody_period(
        period, revealer_index)

    # Generate the secret that is being revealed
    reveal = bls_sign(
        message_hash=hash_tree_root(spec.Epoch(epoch_to_sign)),
        privkey=privkeys[revealer_index],
        domain=spec.get_domain(
            state=state,
            domain_type=spec.DOMAIN_RANDAO,
            message_epoch=epoch_to_sign,
        ),
    )
    return spec.CustodyKeyReveal(
        revealer_index=revealer_index,
        reveal=reveal,
    )
Beispiel #18
0
def create_genesis_state(spec, num_validators):
    deposit_root = b'\x42' * 32

    state = spec.BeaconState(genesis_time=0,
                             deposit_index=num_validators,
                             latest_eth1_data=spec.Eth1Data(
                                 deposit_root=deposit_root,
                                 deposit_count=num_validators,
                                 block_hash=spec.ZERO_HASH,
                             ))

    # We "hack" in the initial validators,
    #  as it is much faster than creating and processing genesis deposits for every single test case.
    state.balances = [spec.MAX_EFFECTIVE_BALANCE] * num_validators
    state.validator_registry = [
        build_mock_validator(spec, i, state.balances[i])
        for i in range(num_validators)
    ]

    # Process genesis activations
    for validator in state.validator_registry:
        if validator.effective_balance >= spec.MAX_EFFECTIVE_BALANCE:
            validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
            validator.activation_epoch = spec.GENESIS_EPOCH

    genesis_active_index_root = hash_tree_root(
        spec.get_active_validator_indices(state, spec.GENESIS_EPOCH))
    for index in range(spec.LATEST_ACTIVE_INDEX_ROOTS_LENGTH):
        state.latest_active_index_roots[index] = genesis_active_index_root

    return state
def test_deposit_event_log(registration_contract, a0, w3):
    log_filter = registration_contract.events.DepositEvent.createFilter(
        fromBlock='latest', )
    deposit_amount_list = [
        randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(3)
    ]

    for i in range(3):
        deposit_input = (
            SAMPLE_PUBKEY, SAMPLE_WITHDRAWAL_CREDENTIALS,
            SAMPLE_VALID_SIGNATURE,
            hash_tree_root(
                DepositData(
                    pubkey=SAMPLE_PUBKEY,
                    withdrawal_credentials=SAMPLE_WITHDRAWAL_CREDENTIALS,
                    amount=deposit_amount_list[i],
                    signature=SAMPLE_VALID_SIGNATURE,
                ), ))
        registration_contract.functions.deposit(*deposit_input, ).transact(
            {"value": deposit_amount_list[i] * eth_utils.denoms.gwei})

        logs = log_filter.get_new_entries()
        assert len(logs) == 1
        log = logs[0]['args']

        assert log['pubkey'] == deposit_input[0]
        assert log['withdrawal_credentials'] == deposit_input[1]
        assert log['amount'] == deposit_amount_list[i].to_bytes(8, 'little')
        assert log['signature'] == deposit_input[2]
        assert log['index'] == i.to_bytes(8, 'little')
Beispiel #20
0
def test_deposit_tree(registration_contract, w3, assert_tx_failed, deposit_input):
    log_filter = registration_contract.events.DepositEvent.createFilter(
        fromBlock='latest',
    )

    deposit_amount_list = [randint(MIN_DEPOSIT_AMOUNT, FULL_DEPOSIT_AMOUNT * 2) for _ in range(10)]
    deposit_data_list = []
    for i in range(0, 10):
        tx_hash = registration_contract.functions.deposit(
            *deposit_input,
        ).transact({"value": deposit_amount_list[i] * eth_utils.denoms.gwei})
        receipt = w3.eth.getTransactionReceipt(tx_hash)
        print("deposit transaction consumes %d gas" % receipt['gasUsed'])

        logs = log_filter.get_new_entries()
        assert len(logs) == 1
        log = logs[0]['args']

        assert log["index"] == i.to_bytes(8, 'little')

        deposit_data_list.append(DepositData(
            pubkey=deposit_input[0],
            withdrawal_credentials=deposit_input[1],
            amount=deposit_amount_list[i],
            signature=deposit_input[2],
        ))

        root = hash_tree_root(List[DepositData, 2**32](*deposit_data_list))
        assert root == registration_contract.functions.get_hash_tree_root().call()
    def record_block(self, item: SignedBeaconBlock) -> bool:
        """
        When a validator receives a block from the network, they call `record_block` to see
        whether they should record it.
        """

        # If we already know about the block, do nothing
        if hash_tree_root(item.message) in self.store.blocks:
            return False

        # Sometimes recording the block fails. Examples include:
        # - The block slot is not the current slot (we keep it in memory for later, when we check backlog)
        # - The block parent is not known
        try:
            state = self.process_to_slot(item.message.parent_root,
                                         item.message.slot)
            on_block(self.store, item, state=state)
        except AssertionError as e:
            return False

        # If attestations are included in the block, we want to record them
        for attestation in item.message.body.attestations:
            self.record_attestation(attestation)

        return True
    def record_block(self, item: SignedBeaconBlock) -> bool:
        """
        When a validator receives a block from the network, they call `record_block` to see
        whether they should record it.
        """

        # If we already know about the block, do nothing
        if hash_tree_root(item.message) in self.store.blocks:
            return False

        # Sometimes recording the block fails. Examples include:
        # - The block slot is not the current slot (we keep it in memory for later, when we check backlog)
        # - The block parent is not known
        try:
            state = self.process_to_slot(item.message.parent_root,
                                         item.message.slot)
            chunk_challenge_count = state.custody_chunk_challenge_index
            on_block(self.store, item, state=state)
            # if the block chunk challenges you, you put it in your active challenges
            new_chunk_challenge_count = state.custody_chunk_challenge_index
            new_chunk_challenges = state.custody_chunk_challenge_records[
                chunk_challenge_count:]
            for cha in new_chunk_challenges:
                if cha.responder_index == self.validator_index:
                    #                    print(self.validator_index, "is accused")
                    self.data.chunk_challenges_accusations.append(cha)

        except AssertionError as e:
            return False

        # If attestations are included in the block, we want to record them
        for attestation in item.message.body.attestations:
            self.record_attestation(attestation)

        return True
Beispiel #23
0
def test_on_block_update_justified_checkpoint_within_safe_slots(spec, state):
    # Initialization
    store = get_genesis_forkchoice_store(spec, state)
    time = 0
    spec.on_tick(store, time)

    next_epoch(spec, state)
    spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT)
    state, store, last_signed_block = apply_next_epoch_with_attestations(spec, state, store)
    next_epoch(spec, state)
    spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT)
    last_block_root = hash_tree_root(last_signed_block.message)

    # Mock the justified checkpoint
    just_state = store.block_states[last_block_root]
    new_justified = spec.Checkpoint(
        epoch=just_state.current_justified_checkpoint.epoch + 1,
        root=b'\x77' * 32,
    )
    just_state.current_justified_checkpoint = new_justified

    block = build_empty_block_for_next_slot(spec, just_state)
    signed_block = state_transition_and_sign_block(spec, deepcopy(just_state), block)
    assert spec.get_current_slot(store) % spec.SLOTS_PER_EPOCH < spec.SAFE_SLOTS_TO_UPDATE_JUSTIFIED
    run_on_block(spec, store, signed_block)

    assert store.justified_checkpoint == new_justified
Beispiel #24
0
def honest_propose(validator, known_items):
    # Honest block proposal, using the current LMD-GHOST head and all known attestations,
    # aggregated.

    slot = validator.data.slot
    head = validator.data.head_root

    processed_state = validator.process_to_slot(head, slot)

    attestations = [
        att for att in known_items["attestations"]
        if should_process_attestation(processed_state, att.item)
    ]
    attestations = aggregate_attestations([
        att.item for att in attestations
        if slot <= att.item.data.slot + specs.SLOTS_PER_EPOCH
    ])

    beacon_block_body = specs.BeaconBlockBody(attestations=attestations)

    beacon_block = specs.BeaconBlock(slot=slot,
                                     parent_root=head,
                                     body=beacon_block_body,
                                     proposer_index=validator.validator_index)

    specs.process_block(processed_state, beacon_block)
    state_root = hash_tree_root(processed_state)
    beacon_block.state_root = state_root

    signed_beacon_block = specs.SignedBeaconBlock(message=beacon_block)

    print(validator.validator_index, "proposes block for slot", slot)

    return signed_beacon_block
Beispiel #25
0
 def case_fn():
     value = value_fn()
     yield "value", "data", encode(value)
     yield "serialized", "ssz", serialize(value)
     yield "root", "meta", '0x' + hash_tree_root(value).hex()
     if isinstance(value, Container):
         yield "signing_root", "meta", '0x' + signing_root(value).hex()
def test_deposit_inputs(registration_contract, w3, assert_tx_failed, amount,
                        invalid_pubkey, invalid_withdrawal_credentials,
                        invalid_signature, success):
    pubkey = SAMPLE_PUBKEY[2:] if invalid_pubkey else SAMPLE_PUBKEY
    withdrawal_credentials = (SAMPLE_WITHDRAWAL_CREDENTIALS[2:]
                              if invalid_withdrawal_credentials else
                              SAMPLE_WITHDRAWAL_CREDENTIALS)
    signature = SAMPLE_VALID_SIGNATURE[
        2:] if invalid_signature else SAMPLE_VALID_SIGNATURE

    call = registration_contract.functions.deposit(
        pubkey, withdrawal_credentials, signature,
        hash_tree_root(
            DepositData(
                pubkey=SAMPLE_PUBKEY if invalid_pubkey else pubkey,
                withdrawal_credentials=(SAMPLE_WITHDRAWAL_CREDENTIALS
                                        if invalid_withdrawal_credentials else
                                        withdrawal_credentials),
                amount=amount,
                signature=SAMPLE_VALID_SIGNATURE
                if invalid_signature else signature,
            ), ))
    if success:
        assert call.transact({"value": amount * eth_utils.denoms.gwei})
    else:
        assert_tx_failed(
            lambda: call.transact({"value": amount * eth_utils.denoms.gwei}))
Beispiel #27
0
def create_test_case(rng: Random, typ, mode: random_value.RandomizationMode, chaos: bool) -> Iterable[gen_typing.TestCasePart]:
    value = random_value.get_random_ssz_object(rng, typ, MAX_BYTES_LENGTH, MAX_LIST_LENGTH, mode, chaos)
    yield "value", "data", encode.encode(value)
    yield "serialized", "ssz", serialize(value)
    roots_data = {
        "root": '0x' + hash_tree_root(value).hex()
    }
    yield "roots", "data", roots_data
Beispiel #28
0
def deposit_data_root(deposit_message, signature):
    deposit_data = DepositData(
        pubkey=deposit_message.pubkey,
        withdrawal_credentials=deposit_message.withdrawal_credentials,
        amount=deposit_message.amount,
        signature=signature,
    )
    root = hash_tree_root(deposit_data)
    return root
Beispiel #29
0
def apply_next_epoch_with_attestations(spec, state, store):
    _, new_signed_blocks, post_state = next_epoch_with_attestations(spec, state, True, False)
    for signed_block in new_signed_blocks:
        block = signed_block.message
        block_root = hash_tree_root(block)
        store.blocks[block_root] = block
        store.block_states[block_root] = post_state
        last_signed_block = signed_block
    spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT)
    return post_state, store, last_signed_block
Beispiel #30
0
def sign_voluntary_exit(spec, state, voluntary_exit, privkey):
    return spec.SignedVoluntaryExit(
        message=voluntary_exit,
        signature=bls_sign(message_hash=hash_tree_root(voluntary_exit),
                           privkey=privkey,
                           domain=spec.get_domain(
                               state=state,
                               domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
                               message_epoch=voluntary_exit.epoch,
                           )))