def test_bitvector_round_trip_no_sedes(size, value):
    foo = Bitvector(size)
    assert decode(encode(value, foo), foo) == value

    @pytest.mark.parametrize(("sedes", "id"),
                             ((Bitvector(64), "Bitvector64"), ))
    def test_get_sedes_id(sedes, id):
        assert sedes.get_sedes_id() == id
Esempio n. 2
0
 def _write_state_justification_bits(self, state_root: Root,
                                     justification_bits: Bitfield) -> None:
     key = SchemaV1.state_root_to_justification_bitfield(state_root)
     encoding = ssz.encode(justification_bits,
                           Bitvector(JUSTIFICATION_BITS_LENGTH))
     self._state_bytes_written += len(encoding)
     self.db[key] = encoding
Esempio n. 3
0
def bitvector_sedes_and_values_st(draw):
    size = draw(
        st.one_of(
            st.integers(1, 10),
            st.just(300),  # choose at least one sample exceeding one chunk
        ))
    return Bitvector(size), bitvector_value_st(size)
Esempio n. 4
0
class ClockInRecords(SignedHashableContainer):
    fields = [
        ("epoch", uint64),
        ("bio_id_scan", bytes32),
        ("poo_log_bits", Bitlist(32)),
        ("wash_log_bits", Bitvector(32)),
        ("signature", bytes96),
    ]
Esempio n. 5
0
class MetaData(HashableContainer):
    fields = [("seq_number", uint64),
              ("attnets", Bitvector(ATTESTATION_SUBNET_COUNT))]

    @classmethod
    def create(
        cls: Type[TMetaData],
        *,
        seq_number: SeqNumber = default_seq_number,
        attnets: Tuple[bool, ...] = default_attnets_tuple,
    ) -> TMetaData:
        return super().create(seq_number=seq_number, attnets=attnets)

    def __str__(self) -> str:
        attnets = map(lambda elem: "1" if elem else "0", self.attnets)
        return f"seq_number={self.seq_number}, attnets=0b{''.join(attnets)}"
def test_bitvector_instantiation_bound():
    with pytest.raises(TypeError):
        bit_count = 0
        Bitvector(bit_count)
Esempio n. 7
0
class BeaconState(HashableContainer):

    fields = [
        # Versioning
        ("genesis_time", uint64),
        ("slot", uint64),
        ("fork", Fork),
        # History
        ("latest_block_header", BeaconBlockHeader),
        (
            "block_roots",
            Vector(bytes32, 1),
        ),  # Needed to process attestations, older to newer  # noqa: E501
        ("state_roots", Vector(bytes32, 1)),
        (
            "historical_roots",
            List(bytes32, 1),
        ),  # allow for a log-sized Merkle proof from any block to any historical block root  # noqa: E501
        # Ethereum 1.0 chain
        ("eth1_data", Eth1Data),
        ("eth1_data_votes", List(Eth1Data, 1)),
        ("eth1_deposit_index", uint64),
        # Validator registry
        ("validators", List(Validator, 1)),
        ("balances", List(uint64, 1)),
        # Shuffling
        ("randao_mixes", Vector(bytes32, 1)),
        # Slashings
        (
            "slashings",
            Vector(uint64, 1),
        ),  # Balances slashed at every withdrawal period  # noqa: E501
        # Attestations
        ("previous_epoch_attestations", List(PendingAttestation, 1)),
        ("current_epoch_attestations", List(PendingAttestation, 1)),
        # Justification
        ("justification_bits", Bitvector(JUSTIFICATION_BITS_LENGTH)),
        ("previous_justified_checkpoint", Checkpoint),
        ("current_justified_checkpoint", Checkpoint),
        # Finality
        ("finalized_checkpoint", Checkpoint),
    ]

    @classmethod
    def create(
        cls: Type[TBeaconState],
        *,
        genesis_time: Timestamp = default_timestamp,
        slot: Slot = default_slot,
        fork: Fork = default_fork,
        latest_block_header: BeaconBlockHeader = default_beacon_block_header,
        block_roots: Sequence[SigningRoot] = default_block_roots,
        state_roots: Sequence[Hash32] = default_state_roots,
        historical_roots: Sequence[Hash32] = default_tuple,
        eth1_data: Eth1Data = default_eth1_data,
        eth1_data_votes: Sequence[Eth1Data] = default_tuple,
        eth1_deposit_index: int = 0,
        validators: Sequence[Validator] = default_tuple,
        balances: Sequence[Gwei] = default_tuple,
        randao_mixes: Sequence[Hash32] = default_randao_mixes,
        slashings: Sequence[Gwei] = default_slashings,
        previous_epoch_attestations: Sequence[
            PendingAttestation] = default_tuple,
        current_epoch_attestations: Sequence[
            PendingAttestation] = default_tuple,
        justification_bits: Bitfield = default_justification_bits,
        previous_justified_checkpoint: Checkpoint = default_checkpoint,
        current_justified_checkpoint: Checkpoint = default_checkpoint,
        finalized_checkpoint: Checkpoint = default_checkpoint,
        config: Eth2Config = None,
        validator_and_balance_length_check: bool = True,
    ) -> TBeaconState:
        # We usually want to check that the lengths of each list are the same
        # In some cases, e.g. SSZ fuzzing, they are not and we still want to instantiate an object.
        if validator_and_balance_length_check:
            if len(validators) != len(balances):
                raise ValueError(
                    f"The length of validators ({len(validators)}) and balances ({len(balances)}) "
                    "lists should be the same.")

        if config:
            # try to provide sane defaults
            if block_roots == default_tuple:
                block_roots = default_tuple_of_size(
                    config.SLOTS_PER_HISTORICAL_ROOT, ZERO_SIGNING_ROOT)
            if state_roots == default_tuple:
                state_roots = default_tuple_of_size(
                    config.SLOTS_PER_HISTORICAL_ROOT, ZERO_HASH32)
            if randao_mixes == default_tuple:
                randao_mixes = default_tuple_of_size(
                    config.EPOCHS_PER_HISTORICAL_VECTOR, ZERO_HASH32)
            if slashings == default_tuple:
                slashings = default_tuple_of_size(
                    config.EPOCHS_PER_SLASHINGS_VECTOR, Gwei(0))

        return super().create(
            genesis_time=genesis_time,
            slot=slot,
            fork=fork,
            latest_block_header=latest_block_header,
            block_roots=block_roots,
            state_roots=state_roots,
            historical_roots=historical_roots,
            eth1_data=eth1_data,
            eth1_data_votes=eth1_data_votes,
            eth1_deposit_index=eth1_deposit_index,
            validators=validators,
            balances=balances,
            randao_mixes=randao_mixes,
            slashings=slashings,
            previous_epoch_attestations=previous_epoch_attestations,
            current_epoch_attestations=current_epoch_attestations,
            justification_bits=justification_bits,
            previous_justified_checkpoint=previous_justified_checkpoint,
            current_justified_checkpoint=current_justified_checkpoint,
            finalized_checkpoint=finalized_checkpoint,
        )

    def __str__(self) -> str:
        return (
            f"[hash_tree_root]={humanize_hash(self.hash_tree_root)}, slot={self.slot}"
        )

    @property
    def validator_count(self) -> int:
        return len(self.validators)

    def current_epoch(self, slots_per_epoch: int) -> Epoch:
        return compute_epoch_at_slot(self.slot, slots_per_epoch)

    def previous_epoch(self, slots_per_epoch: int,
                       genesis_epoch: Epoch) -> Epoch:
        current_epoch = self.current_epoch(slots_per_epoch)
        if current_epoch == genesis_epoch:
            return genesis_epoch
        else:
            return Epoch(current_epoch - 1)

    def next_epoch(self, slots_per_epoch: int) -> Epoch:
        return Epoch(self.current_epoch(slots_per_epoch) + 1)
Esempio n. 8
0
def test_bitvector(size, value, result):
    foo = Bitvector(size)
    assert ssz.get_hash_tree_root(value, foo) == result
Esempio n. 9
0
                                         (16, (True, ) + (False, ) * 15)))
def test_bitlist_round_trip_no_sedes(size, value):
    foo = Bitlist(size)
    assert decode(encode(value, foo), foo) == value


@pytest.mark.parametrize(("sedes", "id"), ((Bitlist(64), "Bitlist64"), ))
def test_get_sedes_id(sedes, id):
    assert sedes.get_sedes_id() == id


@pytest.mark.parametrize(("sedes1", "sedes2"), ((Bitlist(2), Bitlist(2)), ))
def test_eq(sedes1, sedes2):
    assert sedes1 == sedes1
    assert sedes2 == sedes2
    assert sedes1 == sedes2
    assert hash(sedes1) == hash(sedes2)


@pytest.mark.parametrize(
    ("sedes1", "sedes2"),
    (
        (Bitlist(2), Bitlist(3)),
        (Bitlist(2), Bitvector(2)),
        (Bitlist(2), List(boolean, 2)),
    ),
)
def test_neq(sedes1, sedes2):
    assert sedes1 != sedes2
    assert hash(sedes1) != hash(sedes2)
def test_bitvector_deserialize_values(size, value, expected):
    foo = Bitvector(size)
    assert foo.deserialize(value) == expected
def test_bitvector_serialize_values(size, value, expected):
    foo = Bitvector(size)
    assert encode(value, foo) == expected
    assert foo.serialize(bytearray(value)) == expected
    assert foo.deserialize(value) == expected


@pytest.mark.parametrize("size, value", ((16, (True, ) + (False, ) * 15), ))
def test_bitvector_round_trip_no_sedes(size, value):
    foo = Bitvector(size)
    assert decode(encode(value, foo), foo) == value

    @pytest.mark.parametrize(("sedes", "id"),
                             ((Bitvector(64), "Bitvector64"), ))
    def test_get_sedes_id(sedes, id):
        assert sedes.get_sedes_id() == id


@pytest.mark.parametrize(("sedes1", "sedes2"),
                         ((Bitvector(2), Bitvector(2)), ))
def test_eq(sedes1, sedes2):
    assert sedes1 == sedes1
    assert sedes2 == sedes2
    assert sedes1 == sedes2
    assert hash(sedes1) == hash(sedes2)


@pytest.mark.parametrize(
    ("sedes1", "sedes2"),
    (
        (Bitvector(2), Bitvector(3)),
        (Bitvector(2), Bitlist(2)),
        (Bitvector(2), Vector(boolean, 2)),
    ),
)
Esempio n. 13
0
# License for the specific language governing permissions and limitations
# under the License.

from typing import Sequence

from ssz.hashable_container import HashableContainer, SignedHashableContainer
from ssz.sedes import (
    Bitlist,
    Bitvector,
    List,
    Vector,
    boolean,
    bytes32,
    bytes48,
    bytes96,
    uint64,
)

import sys
import argparse

if __name__ == "__main__":
    # Binary read from stdin
    bv = sys.stdin.buffer.read()

    # Execute function/method to test
    hash = Bitvector(len(bv)).get_hash_tree_root(bv)

    # Write result to stdout in binary
    sys.stdout.buffer.write(hash)
Esempio n. 14
0
class BeaconState(ssz.Serializable):

    fields = [
        # Versioning
        ("genesis_time", uint64),
        ("slot", uint64),
        ("fork", Fork),
        # History
        ("latest_block_header", BeaconBlockHeader),
        (
            "block_roots",
            Vector(bytes32, 1),
        ),  # Needed to process attestations, older to newer  # noqa: E501
        ("state_roots", Vector(bytes32, 1)),
        (
            "historical_roots",
            List(bytes32, 1),
        ),  # allow for a log-sized Merkle proof from any block to any historical block root  # noqa: E501
        # Ethereum 1.0 chain
        ("eth1_data", Eth1Data),
        ("eth1_data_votes", List(Eth1Data, 1)),
        ("eth1_deposit_index", uint64),
        # Validator registry
        ("validators", List(Validator, 1)),
        ("balances", List(uint64, 1)),
        # Shuffling
        ("start_shard", uint64),
        ("randao_mixes", Vector(bytes32, 1)),
        ("active_index_roots", Vector(bytes32, 1)),
        ("compact_committees_roots", Vector(bytes32, 1)),
        # Slashings
        (
            "slashings",
            Vector(uint64, 1),
        ),  # Balances slashed at every withdrawal period  # noqa: E501
        # Attestations
        ("previous_epoch_attestations", List(PendingAttestation, 1)),
        ("current_epoch_attestations", List(PendingAttestation, 1)),
        # Crosslinks
        ("previous_crosslinks", Vector(Crosslink, 1)),
        ("current_crosslinks", Vector(Crosslink, 1)),
        # Justification
        ("justification_bits", Bitvector(JUSTIFICATION_BITS_LENGTH)),
        ("previous_justified_checkpoint", Checkpoint),
        ("current_justified_checkpoint", Checkpoint),
        # Finality
        ("finalized_checkpoint", Checkpoint),
    ]

    def __init__(
        self,
        *,
        genesis_time: Timestamp = default_timestamp,
        slot: Slot = default_slot,
        fork: Fork = default_fork,
        latest_block_header: BeaconBlockHeader = default_beacon_block_header,
        block_roots: Sequence[Hash32] = default_tuple,
        state_roots: Sequence[Hash32] = default_tuple,
        historical_roots: Sequence[Hash32] = default_tuple,
        eth1_data: Eth1Data = default_eth1_data,
        eth1_data_votes: Sequence[Eth1Data] = default_tuple,
        eth1_deposit_index: int = 0,
        validators: Sequence[Validator] = default_tuple,
        balances: Sequence[Gwei] = default_tuple,
        start_shard: Shard = default_shard,
        randao_mixes: Sequence[Hash32] = default_tuple,
        active_index_roots: Sequence[Hash32] = default_tuple,
        compact_committees_roots: Sequence[Hash32] = default_tuple,
        slashings: Sequence[Gwei] = default_tuple,
        previous_epoch_attestations: Sequence[
            PendingAttestation] = default_tuple,
        current_epoch_attestations: Sequence[
            PendingAttestation] = default_tuple,
        previous_crosslinks: Sequence[Crosslink] = default_tuple,
        current_crosslinks: Sequence[Crosslink] = default_tuple,
        justification_bits: Bitfield = default_justification_bits,
        previous_justified_checkpoint: Checkpoint = default_checkpoint,
        current_justified_checkpoint: Checkpoint = default_checkpoint,
        finalized_checkpoint: Checkpoint = default_checkpoint,
        config: Eth2Config = None,
    ) -> None:
        if len(validators) != len(balances):
            raise ValueError(
                "The length of validators and balances lists should be the same."
            )

        if config:
            # try to provide sane defaults
            if block_roots == default_tuple:
                block_roots = default_tuple_of_size(
                    config.SLOTS_PER_HISTORICAL_ROOT, ZERO_HASH32)
            if state_roots == default_tuple:
                state_roots = default_tuple_of_size(
                    config.SLOTS_PER_HISTORICAL_ROOT, ZERO_HASH32)
            if randao_mixes == default_tuple:
                randao_mixes = default_tuple_of_size(
                    config.EPOCHS_PER_HISTORICAL_VECTOR, ZERO_HASH32)
            if active_index_roots == default_tuple:
                active_index_roots = default_tuple_of_size(
                    config.EPOCHS_PER_HISTORICAL_VECTOR, ZERO_HASH32)
            if compact_committees_roots == default_tuple:
                compact_committees_roots = default_tuple_of_size(
                    config.EPOCHS_PER_HISTORICAL_VECTOR, ZERO_HASH32)
            if slashings == default_tuple:
                slashings = default_tuple_of_size(
                    config.EPOCHS_PER_SLASHINGS_VECTOR, Gwei(0))
            if previous_crosslinks == default_tuple:
                previous_crosslinks = default_tuple_of_size(
                    config.SHARD_COUNT, default_crosslink)
            if current_crosslinks == default_tuple:
                current_crosslinks = default_tuple_of_size(
                    config.SHARD_COUNT, default_crosslink)

        super().__init__(
            genesis_time=genesis_time,
            slot=slot,
            fork=fork,
            latest_block_header=latest_block_header,
            block_roots=block_roots,
            state_roots=state_roots,
            historical_roots=historical_roots,
            eth1_data=eth1_data,
            eth1_data_votes=eth1_data_votes,
            eth1_deposit_index=eth1_deposit_index,
            validators=validators,
            balances=balances,
            start_shard=start_shard,
            randao_mixes=randao_mixes,
            active_index_roots=active_index_roots,
            compact_committees_roots=compact_committees_roots,
            slashings=slashings,
            previous_epoch_attestations=previous_epoch_attestations,
            current_epoch_attestations=current_epoch_attestations,
            previous_crosslinks=previous_crosslinks,
            current_crosslinks=current_crosslinks,
            justification_bits=justification_bits,
            previous_justified_checkpoint=previous_justified_checkpoint,
            current_justified_checkpoint=current_justified_checkpoint,
            finalized_checkpoint=finalized_checkpoint,
        )

    def __repr__(self) -> str:
        return f"<BeaconState #{self.slot} {encode_hex(self.hash_tree_root)[2:10]}>"

    @property
    def validator_count(self) -> int:
        return len(self.validators)

    def update_validator(
        self,
        validator_index: ValidatorIndex,
        validator: Validator,
        balance: Gwei = None,
    ) -> "BeaconState":
        """
        Replace ``self.validators[validator_index]`` with ``validator``.

        Callers can optionally provide a ``balance`` which will replace
        ``self.balances[validator_index] with ``balance``.
        """
        if (validator_index >= len(self.validators)
                or validator_index >= len(self.balances)
                or validator_index < 0):
            raise IndexError("Incorrect validator index")

        state = self.update_validator_with_fn(validator_index,
                                              lambda *_: validator)
        if balance:
            return state._update_validator_balance(validator_index, balance)
        else:
            return state

    def update_validator_with_fn(
        self,
        validator_index: ValidatorIndex,
        fn: Callable[[Validator, Any], Validator],
        *args: Any,
    ) -> "BeaconState":
        """
        Replace ``self.validators[validator_index]`` with
        the result of calling ``fn`` on the existing ``validator``.
        Any auxillary args passed in ``args`` are provided to ``fn`` along with the
        ``validator``.
        """
        if validator_index >= len(self.validators) or validator_index < 0:
            raise IndexError("Incorrect validator index")

        return self.copy(validators=update_tuple_item_with_fn(
            self.validators, validator_index, fn, *args))

    def _update_validator_balance(self, validator_index: ValidatorIndex,
                                  balance: Gwei) -> "BeaconState":
        """
        Update the balance of validator of the given ``validator_index``.
        """
        if validator_index >= len(self.balances) or validator_index < 0:
            raise IndexError("Incorrect validator index")

        return self.copy(balances=update_tuple_item(self.balances,
                                                    validator_index, balance))

    def current_epoch(self, slots_per_epoch: int) -> Epoch:
        return compute_epoch_of_slot(self.slot, slots_per_epoch)

    def previous_epoch(self, slots_per_epoch: int,
                       genesis_epoch: Epoch) -> Epoch:
        current_epoch = self.current_epoch(slots_per_epoch)
        if current_epoch == genesis_epoch:
            return genesis_epoch
        else:
            return Epoch(current_epoch - 1)

    def next_epoch(self, slots_per_epoch: int) -> Epoch:
        return Epoch(self.current_epoch(slots_per_epoch) + 1)
Esempio n. 15
0
 def _read_state_justification_bits(self, state_root: Root) -> Bitfield:
     key = SchemaV1.state_root_to_justification_bitfield(state_root)
     return ssz.decode(self.db[key], Bitvector(JUSTIFICATION_BITS_LENGTH))