Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Remove custody placeholder from phase 0 #1262

Merged
merged 3 commits into from
Nov 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .circleci/get_eth2_fixtures.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env bash

if [ ! -d "./eth2-fixtures/tests" ]; then
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.0/general.tar.gz
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.0/mainnet.tar.gz
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.0/minimal.tar.gz
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.1/general.tar.gz
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.1/mainnet.tar.gz
wget -c https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.9.1/minimal.tar.gz
mkdir eth2-fixtures
tar zxvf general.tar.gz -C ./eth2-fixtures
tar zxvf mainnet.tar.gz -C ./eth2-fixtures
Expand Down
57 changes: 12 additions & 45 deletions eth2/beacon/attestation_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,28 @@
from eth2.beacon.helpers import get_domain
from eth2.beacon.signature_domain import SignatureDomain
from eth2.beacon.types.attestation_data import AttestationData
from eth2.beacon.types.attestation_data_and_custody_bits import (
AttestationDataAndCustodyBit,
)
from eth2.beacon.types.attestations import IndexedAttestation
from eth2.beacon.types.states import BeaconState


def validate_indexed_attestation_aggregate_signature(
state: BeaconState, indexed_attestation: IndexedAttestation, slots_per_epoch: int
) -> None:
bit_0_indices = indexed_attestation.custody_bit_0_indices
bit_1_indices = indexed_attestation.custody_bit_1_indices

pubkeys = (
bls.aggregate_pubkeys(tuple(state.validators[i].pubkey for i in bit_0_indices)),
bls.aggregate_pubkeys(tuple(state.validators[i].pubkey for i in bit_1_indices)),
)

message_hashes = (
AttestationDataAndCustodyBit(
data=indexed_attestation.data, custody_bit=False
).hash_tree_root,
AttestationDataAndCustodyBit(
data=indexed_attestation.data, custody_bit=True
).hash_tree_root,
attesting_indices = indexed_attestation.attesting_indices
pubkey = bls.aggregate_pubkeys(
tuple(state.validators[i].pubkey for i in attesting_indices)
)

message_hash = indexed_attestation.data.hash_tree_root
domain = get_domain(
state,
SignatureDomain.DOMAIN_BEACON_ATTESTER,
slots_per_epoch,
indexed_attestation.data.target.epoch,
)
bls.validate_multiple(
pubkeys=pubkeys,
message_hashes=message_hashes,
bls.validate(
pubkey=pubkey,
message_hash=message_hash,
signature=indexed_attestation.signature,
domain=domain,
)
Expand All @@ -55,36 +41,17 @@ def validate_indexed_attestation(
"""
Derived from spec: `is_valid_indexed_attestation`.
"""
bit_0_indices = indexed_attestation.custody_bit_0_indices
bit_1_indices = indexed_attestation.custody_bit_1_indices

if len(bit_1_indices) != 0:
raise ValidationError(
f"Expected no custody bit 1 validators (cf. {bit_1_indices})."
)
attesting_indices = indexed_attestation.attesting_indices

if len(bit_0_indices) + len(bit_1_indices) > max_validators_per_committee:
if len(attesting_indices) > max_validators_per_committee:
raise ValidationError(
f"Require no more than {max_validators_per_committee} validators per attestation,"
f" but have {len(bit_0_indices)} 0-bit validators"
f" and {len(bit_1_indices)} 1-bit validators."
)

intersection = set(bit_0_indices).intersection(bit_1_indices)
if len(intersection) != 0:
raise ValidationError(
f"Index sets by custody bits must be disjoint but have the following"
f" indices in common: {intersection}."
)

if bit_0_indices != tuple(sorted(bit_0_indices)):
raise ValidationError(
f"Indices should be sorted; the 0-bit indices are not: {bit_0_indices}."
f" but have {len(attesting_indices)} validators."
)

if bit_1_indices != tuple(sorted(bit_1_indices)):
if attesting_indices != tuple(sorted(attesting_indices)):
raise ValidationError(
f"Indices should be sorted; the 1-bit indices are not: {bit_1_indices}."
f"Indices should be sorted; the attesting indices are not: {attesting_indices}."
)

try:
Expand Down
15 changes: 2 additions & 13 deletions eth2/beacon/epoch_processing_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Iterable, Sequence, Set, Tuple

from eth_utils import ValidationError, to_tuple
from eth_utils import to_tuple

from eth2._utils.bitfield import Bitfield, has_voted
from eth2._utils.numeric import integer_squareroot
Expand Down Expand Up @@ -65,20 +65,9 @@ def get_indexed_attestation(
attesting_indices = get_attesting_indices(
state, attestation.data, attestation.aggregation_bits, config
)
custody_bit_1_indices = get_attesting_indices(
state, attestation.data, attestation.custody_bits, config
)
if not custody_bit_1_indices.issubset(attesting_indices):
raise ValidationError(
f"Attestation {attestation} has custody bit 1 indices ({custody_bit_1_indices})"
f" that are not a subset of the attestation's attesting indices ({attesting_indices})"
f" diff: {custody_bit_1_indices.difference(attesting_indices)}"
)
custody_bit_0_indices = attesting_indices.difference(custody_bit_1_indices)

return IndexedAttestation(
custody_bit_0_indices=sorted(custody_bit_0_indices),
custody_bit_1_indices=sorted(custody_bit_1_indices),
attesting_indices=sorted(attesting_indices),
data=attestation.data,
signature=attestation.signature,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,10 @@ def _validate_aggregation_bits(
) -> None:
data = attestation.data
committee = get_beacon_committee(state, data.slot, data.index, config)
if not (
len(attestation.aggregation_bits)
== len(attestation.custody_bits)
== len(committee)
):
if not (len(attestation.aggregation_bits) == len(committee)):
raise ValidationError(
f"The attestation bit lengths not match:"
f"\tlen(attestation.aggregation_bits)={len(attestation.aggregation_bits)}\n"
f"\tlen(attestation.custody_bits)={len(attestation.custody_bits)}"
f"\tlen(committee)={len(committee)}"
)

Expand Down
15 changes: 5 additions & 10 deletions eth2/beacon/state_machines/forks/serenity/operation_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,12 @@ def process_attester_slashings(
slashed_any = False
attestation_1 = attester_slashing.attestation_1
attestation_2 = attester_slashing.attestation_2
attesting_indices_1 = (
attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices
sorted_attesting_indices = sorted(
set(attestation_1.attesting_indices).intersection(
attestation_2.attesting_indices
)
)
attesting_indices_2 = (
attestation_2.custody_bit_0_indices + attestation_2.custody_bit_1_indices
)

eligible_indices = sorted(
set(attesting_indices_1).intersection(attesting_indices_2)
)
for index in eligible_indices:
for index in sorted_attesting_indices:
validator = state.validators[index]
if validator.is_slashable(current_epoch):
state = slash_validator(state, index, config)
Expand Down
24 changes: 3 additions & 21 deletions eth2/beacon/tools/builder/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
from eth2.beacon.signature_domain import SignatureDomain
from eth2.beacon.state_machines.base import BaseBeaconStateMachine
from eth2.beacon.types.attestation_data import AttestationData
from eth2.beacon.types.attestation_data_and_custody_bits import (
AttestationDataAndCustodyBit,
)
from eth2.beacon.types.attestations import Attestation, IndexedAttestation
from eth2.beacon.types.attester_slashings import AttesterSlashing
from eth2.beacon.types.blocks import BeaconBlockHeader
Expand Down Expand Up @@ -340,7 +337,7 @@ def create_mock_slashable_attestation(
),
)

message_hash = _get_mock_message(attestation_data)
message_hash = attestation_data.hash_tree_root
attesting_indices = _get_mock_attesting_indices(committee, num_voted_attesters=1)

signature = sign_transaction(
Expand All @@ -354,10 +351,7 @@ def create_mock_slashable_attestation(
validator_indices = tuple(committee[i] for i in attesting_indices)

return IndexedAttestation(
custody_bit_0_indices=validator_indices,
custody_bit_1_indices=tuple(),
data=attestation_data,
signature=signature,
attesting_indices=validator_indices, data=attestation_data, signature=signature
)


Expand Down Expand Up @@ -437,17 +431,6 @@ def _get_target_root(
)


def _get_mock_message(attestation_data: AttestationData) -> Hash32:
"""
Get ``message_hash`` of ``attestation_data``.
"""
message_hash = AttestationDataAndCustodyBit(
data=attestation_data, custody_bit=False
).hash_tree_root

return message_hash


def _get_mock_attesting_indices(
committee: Sequence[ValidatorIndex], num_voted_attesters: int
) -> Tuple[CommitteeValidatorIndex, ...]:
Expand Down Expand Up @@ -479,7 +462,7 @@ def _create_mock_signed_attestation(
"""
Create a mocking attestation of the given ``attestation_data`` slot with ``keymap``.
"""
message_hash = _get_mock_message(attestation_data)
message_hash = attestation_data.hash_tree_root

if is_for_simulation:
simulation_attesting_indices = _get_mock_attesting_indices(
Expand Down Expand Up @@ -519,7 +502,6 @@ def _create_mock_signed_attestation(
return Attestation(
aggregation_bits=aggregation_bits,
data=attestation_data,
custody_bits=Bitfield((False,) * len(aggregation_bits)),
signature=aggregate_signature,
)

Expand Down
3 changes: 3 additions & 0 deletions eth2/beacon/tools/fixtures/loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
def generate_config_by_dict(dict_config: Dict[str, Any]) -> Eth2Config:
filtered_keys = (
"DOMAIN_",
# TODO: Fork choice rule
"SAFE_SLOTS_TO_UPDATE_JUSTIFIED",
# Phase 1
"MAX_EPOCHS_PER_CROSSLINK",
"EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS",
"EPOCHS_PER_CUSTODY_PERIOD",
Expand Down
10 changes: 0 additions & 10 deletions eth2/beacon/tools/fixtures/test_types/ssz_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
from eth2.beacon.tools.fixtures.test_handler import TestHandler
from eth2.beacon.tools.fixtures.test_part import TestPart
from eth2.beacon.types.attestation_data import AttestationData
from eth2.beacon.types.attestation_data_and_custody_bits import (
AttestationDataAndCustodyBit,
)
from eth2.beacon.types.attestations import Attestation, IndexedAttestation
from eth2.beacon.types.attester_slashings import AttesterSlashing
from eth2.beacon.types.block_headers import BeaconBlockHeader
Expand Down Expand Up @@ -153,11 +150,6 @@ class AttestationDataHandler(SSZHandler):
object_type = AttestationData


class AttestationDataAndCustodyBitHandler(SSZHandler):
name = "AttestationDataAndCustodyBit"
object_type = AttestationDataAndCustodyBit


class AttesterSlashingHandler(SSZHandler):
name = "AttesterSlashing"
object_type = AttesterSlashing
Expand Down Expand Up @@ -241,7 +233,6 @@ class VoluntaryExitHandler(SSZHandler):
SSZStaticHandlerType = Tuple[
Type[AttestationHandler],
Type[AttestationDataHandler],
Type[AttestationDataAndCustodyBitHandler],
Type[AttesterSlashingHandler],
Type[BeaconBlockHandler],
Type[BeaconBlockBodyHandler],
Expand All @@ -267,7 +258,6 @@ class SSZStaticTestType(TestType[SSZStaticHandlerType]):
handlers = (
AttestationHandler,
AttestationDataHandler,
AttestationDataAndCustodyBitHandler,
AttesterSlashingHandler,
BeaconBlockHandler,
BeaconBlockBodyHandler,
Expand Down
10 changes: 2 additions & 8 deletions eth2/beacon/tools/misc/ssz_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@

def _mk_overrides(config: Eth2Config) -> Dict[ssz.Serializable, Dict[str, int]]:
return {
Attestation: {
"aggregation_bits": config.MAX_VALIDATORS_PER_COMMITTEE,
"custody_bits": config.MAX_VALIDATORS_PER_COMMITTEE,
},
Attestation: {"aggregation_bits": config.MAX_VALIDATORS_PER_COMMITTEE},
BeaconBlockBody: {
"proposer_slashings": config.MAX_PROPOSER_SLASHINGS,
"attester_slashings": config.MAX_ATTESTER_SLASHINGS,
Expand All @@ -42,10 +39,7 @@ def _mk_overrides(config: Eth2Config) -> Dict[ssz.Serializable, Dict[str, int]]:
"block_roots": config.SLOTS_PER_HISTORICAL_ROOT,
"state_roots": config.SLOTS_PER_HISTORICAL_ROOT,
},
IndexedAttestation: {
"custody_bit_0_indices": config.MAX_VALIDATORS_PER_COMMITTEE,
"custody_bit_1_indices": config.MAX_VALIDATORS_PER_COMMITTEE,
},
IndexedAttestation: {"attesting_indices": config.MAX_VALIDATORS_PER_COMMITTEE},
PendingAttestation: {"aggregation_bits": config.MAX_VALIDATORS_PER_COMMITTEE},
}

Expand Down
24 changes: 0 additions & 24 deletions eth2/beacon/types/attestation_data_and_custody_bits.py

This file was deleted.

16 changes: 5 additions & 11 deletions eth2/beacon/types/attestations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,21 @@ class Attestation(ssz.Serializable):
fields = [
("aggregation_bits", Bitlist(1)),
("data", AttestationData),
("custody_bits", Bitlist(1)),
("signature", bytes96),
]

def __init__(
self,
aggregation_bits: Bitfield = default_bitfield,
data: AttestationData = default_attestation_data,
custody_bits: Bitfield = default_bitfield,
signature: BLSSignature = EMPTY_SIGNATURE,
) -> None:
super().__init__(aggregation_bits, data, custody_bits, signature)
super().__init__(aggregation_bits, data, signature)

def __str__(self) -> str:
return (
f"aggregation_bits={self.aggregation_bits},"
f" data=({self.data}),"
f" custody_bits={self.custody_bits},"
f" signature={humanize_hash(self.signature)}"
)

Expand All @@ -43,8 +40,7 @@ class IndexedAttestation(ssz.Serializable):

fields = [
# Validator indices
("custody_bit_0_indices", List(uint64, 1)),
("custody_bit_1_indices", List(uint64, 1)),
("attesting_indices", List(uint64, 1)),
# Attestation data
("data", AttestationData),
# Aggregate signature
Expand All @@ -53,17 +49,15 @@ class IndexedAttestation(ssz.Serializable):

def __init__(
self,
custody_bit_0_indices: Sequence[ValidatorIndex] = default_tuple,
custody_bit_1_indices: Sequence[ValidatorIndex] = default_tuple,
attesting_indices: Sequence[ValidatorIndex] = default_tuple,
data: AttestationData = default_attestation_data,
signature: BLSSignature = EMPTY_SIGNATURE,
) -> None:
super().__init__(custody_bit_0_indices, custody_bit_1_indices, data, signature)
super().__init__(attesting_indices, data, signature)

def __str__(self) -> str:
return (
f"custody_bit_0_indices={self.custody_bit_0_indices},"
f" custody_bit_1_indices={self.custody_bit_1_indices},"
f"attesting_indices={self.attesting_indices},"
f" data=({self.data}),"
f" signature={humanize_hash(self.signature)}"
)
Expand Down
Loading