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

Updates for almost v0.8 #714

Merged
merged 192 commits into from
Jul 9, 2019

Conversation

ralexstokes
Copy link
Member

@ralexstokes ralexstokes commented Jun 11, 2019

What was wrong?

This PR contains the updates for almost v0.8. Given that we are skipping over v0.6 and v0.7, there are quite a few changes here.

This PR targets the spec repo as of this commit: ethereum/consensus-specs@b007d5a

I'll complete the work on this branch and then think about about how to make it more digestible for review.

How was it fixed?

Updating all the code according to the latest spec.

To-Do

  • Update code
  • remove dead code
  • update tests

Cute Animal Picture

put a cute animal picture link inside the parentheses

@ralexstokes ralexstokes changed the title Validator spec updates Updates for v0.7 -- Validator type Jun 11, 2019
@ralexstokes
Copy link
Member Author

ralexstokes commented Jun 12, 2019

the linter failures here are temporary to the multi-PR v0.7 update.

and the fixture failures may also not get fixed until all of the spec updates land.

So consider this PR ready for review in lieu of the failing tests... I suppose the way to work around this is to go ahead w/ a multi-PR approach but then once the final PR is together just have one big merge of the final stuff...

@ralexstokes ralexstokes changed the title Updates for v0.7 -- Validator type [wip] Updates for v0.7 Jun 13, 2019
@ralexstokes ralexstokes changed the title [wip] Updates for v0.7 [wip] Updates for v0.7.1 Jun 21, 2019
@ralexstokes ralexstokes force-pushed the validator-spec-updates branch 3 times, most recently from faf19b2 to e0fbe7d Compare June 26, 2019 19:35
@ralexstokes ralexstokes changed the title [wip] Updates for v0.7.1 [wip] Updates for almost v0.8 Jun 29, 2019
@ralexstokes ralexstokes changed the title [wip] Updates for almost v0.8 Updates for almost v0.8 Jul 1, 2019
Copy link
Contributor

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first pass. Left some comments but feel free to ignore all of them 😹

)

if config:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Not in this PR]: What do you think creating a classmethod that takes config as argument? So we can keep the init function clean

@classmethod
def from_config(config, **kwargs):
    ...
    return cls(**kwargs) 

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my view is that an instance of BeaconState is not valid until this __init__ function returns w/ these defaults as given.

the only reason this is done this way is because the linter complains if we have a function call in a kwargs argument.

the thing consistent w/ what you are suggesting is to remove all default arguments but that goes against the broader intention to have valuable default objects.

i'll send notes soon about the rationale here on the "default objects"

eth2/beacon/types/deposit_data.py Outdated Show resolved Hide resolved
from typing import Any # noqa: F401


default_bls_pubkey = BLSPubkey(b'\x00' * 48)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think moving this to eth2/beacon/constants.py and next to EMPTY_SIGNATURE = BLSSignature(b'\x00' * 96)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intention is to have these default_type types live internal to the types package so that the only thing a user of this package sees is an abstract type Type()

the pattern to achieve this is that for any default type in types/defaults, it should not escape that package.... i think i have done this succeessfully :)

if you see something that falls outside of this pattern or what to change it, lets talk :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is using both default_* and constants.ZERO_HASH32/constants.EMPTY_SIGNATURE. If being nitpicky, it's better to make them all in default_* - but I think it's not necessary for now. 😄

# This can be done by providing either a ``block`` *or* a ``future_slot``.
# We enforce this invariant with the assertion on ``target_slot``.
target_slot = block.slot if block else future_slot
assert target_slot is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Not in this PR] It looks like the interface requires some checks to ensure the input has exactly a block or a future slot. Maybe make it two functions like the old apply_state_transition and apply_state_transition_without_block?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we could go either way on this -- the spec functions handle either so i think it makes sense to have a unified implementation.

the question then becomes: is the interface unified or not?
in this PR, the interface is the union, but we could roll it back how we had it....

i changed it this way bc as a user of this method i like just having to remember one symbol apply_state_transition and then i can feed it whichever data i need to accomplish that goal -- it seems to always be clear from context which one i need to do

this all being said, i'm not opposed to having two distinct interfaces -- they would just both call the existing implementation w/ the appropriate target_slot (and optional block)

Copy link
Contributor

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything else looks good. Great work 😓🙏

@ralexstokes ralexstokes force-pushed the validator-spec-updates branch from ecaa160 to 3ea9081 Compare July 2, 2019 19:05
Copy link
Contributor

@hwwhww hwwhww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first pass - eth2/beacon/types/ files.
Mostly just some TODO notes. (I didn't note the TODOs that we need py-ssz update, that would be another round after we update py-ssz.)

Goooood job!

block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock:
return block_class.create_empty_block(genesis_slot).copy(
state_root=genesis_state_root,
def is_genesis_trigger(deposits: Sequence[Deposit], timestamp: int, config: Eth2Config) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the procedure has been updated: https://github.com/ethereum/eth2.0-specs/blob/dev/specs/core/0_beacon-chain.md#genesis-state
The main difference is now we use SSZ List hash tree root of deposit_data_list as the deposit_root.


class AttestationData(ssz.Serializable):

fields = [
# LMD GHOST vote
('slot', uint64),
('beacon_block_root', bytes32),

# FFG vote
('source_epoch', uint64),
('source_root', bytes32),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Add Checkpoint


class Attestation(ssz.Serializable):

fields = [
# Attester aggregation bitfield
('aggregation_bitfield', byte_list),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: rename to aggregation_bits and use Bitlist (aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE])

('data', AttestationData),
# Proof of custody bitfield
('custody_bitfield', byte_list),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: custody_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE]

default_gwei = Gwei(0)
default_timestamp = Timestamp(0)
default_second = Second(0)
default_bitfield = Bitfield(b'')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it makes sense to rename all these default_* variable to capital DEFAULT_*? (not strongly opinion :) )

('active_index_roots', Vector(bytes32, 1)),

# Slashings
('slashed_balances', Vector(uint64, 1)), # Balances slashed at every withdrawal period # noqa: E501
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to slashings.

Suggested change
('slashed_balances', Vector(uint64, 1)), # Balances slashed at every withdrawal period # noqa: E501
('slashings', Vector(uint64, 1)), # Balances slashed at every withdrawal period # noqa: E501

('previous_justified_root', bytes32),
('current_justified_epoch', uint64),
('current_justified_root', bytes32),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: use Checkpoint

('current_justified_root', bytes32),
# Note: justification_bitfield is meant to be defined as an integer type,
# so its bit operation is in Python and is easier to specify and implement.
('justification_bitfield', uint64),

# Finality
('finalized_epoch', uint64),
('finalized_root', bytes32),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

previous_justified_root=previous_justified_root,
current_justified_epoch=current_justified_epoch,
current_justified_root=current_justified_root,
justification_bitfield=justification_bitfield,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO:
justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH]

)


def _round_down_to_previous_multiple(amount: int, increment: int) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def _round_down_to_previous_multiple(amount: int, increment: int) -> int:
def _round_down_to_previous_multiple(amount: Gwei, increment: Gwei) -> Gwei:

Copy link
Contributor

@hwwhww hwwhww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second pass - configs.py part

('MAX_BALANCE_CHURN_QUOTIENT', int),
('MAX_INDICES_PER_SLASHABLE_VOTE', int),
('MAX_EXIT_DEQUEUES_PER_EPOCH', int),
('MAX_INDICES_PER_ATTESTATION', int),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to MAX_VALIDATORS_PER_COMMITTEE.

Suggested change
('MAX_INDICES_PER_ATTESTATION', int),
('MAX_VALIDATORS_PER_COMMITTEE', int),


def validate_indexed_attestation(state: BeaconState,
indexed_attestation: IndexedAttestation,
max_indices_per_attestation: int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to MAX_VALIDATORS_PER_COMMITTEE.

Suggested change
max_indices_per_attestation: int,
max_validators_per_committee: int,

f"Expected no custody bit 1 validators (cf. {bit_1_indices})."
)

if len(bit_0_indices) + len(bit_1_indices) > max_indices_per_attestation:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if len(bit_0_indices) + len(bit_1_indices) > max_indices_per_attestation:
if len(bit_0_indices) + len(bit_1_indices) > max_validators_per_committee:


if len(bit_0_indices) + len(bit_1_indices) > max_indices_per_attestation:
raise ValidationError(
f"Require no more than {max_indices_per_attestation} validators per attestation,"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"Require no more than {max_indices_per_attestation} validators per attestation,"
f"Require no more than {max_validators_per_committee} validators per attestation,"

MAX_BALANCE_CHURN_QUOTIENT=2**5, # (= 32)
MAX_INDICES_PER_SLASHABLE_VOTE=2**12, # (= 4,096) votes
MAX_EXIT_DEQUEUES_PER_EPOCH=2**2, # (= 4)
MAX_INDICES_PER_ATTESTATION=2**12, # (= 4,096) votes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MAX_INDICES_PER_ATTESTATION=2**12, # (= 4,096) votes
MAX_VALIDATORS_PER_COMMITTEE =2**12, # (= 4,096) votes

# Max operations per block
('MAX_PROPOSER_SLASHINGS', int),
('MAX_ATTESTER_SLASHINGS', int),
('MAX_ATTESTATIONS', int),
('MAX_DEPOSITS', int),
('MAX_VOLUNTARY_EXITS', int),
('MAX_TRANSFERS', int),
# Genesis
('GENESIS_ACTIVE_VALIDATOR_COUNT', int),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing:

Suggested change
('GENESIS_ACTIVE_VALIDATOR_COUNT', int),
('MIN_GENESIS_TIME', int),

('WHISTLEBLOWER_REWARD_QUOTIENT', int),
('ATTESTATION_INCLUSION_REWARD_QUOTIENT', int),
('EPOCHS_PER_HISTORICAL_VECTOR', int),
('EPOCHS_PER_SLASHED_BALANCES_VECTOR', int),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing: HISTORICAL_ROOTS_LIMIT and VALIDATOR_REGISTRY_LIMIT

self.LATEST_RANDAO_MIXES_LENGTH = config.LATEST_RANDAO_MIXES_LENGTH
self.EPOCHS_PER_HISTORICAL_VECTOR = config.EPOCHS_PER_HISTORICAL_VECTOR
self.EPOCHS_PER_HISTORICAL_VECTOR = config.EPOCHS_PER_HISTORICAL_VECTOR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

BLS_WITHDRAWAL_PREFIX_BYTE=b'\x00',
GENESIS_SLOT=Slot(0),
GENESIS_EPOCH=Epoch(0),
BLS_WITHDRAWAL_PREFIX=0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now in byte (again).

Suggested change
BLS_WITHDRAWAL_PREFIX=0,
BLS_WITHDRAWAL_PREFIX=b'\x00',

# `FAR_FUTURE_EPOCH`, `EMPTY_SIGNATURE` `ZERO_HASH (ZERO_HASH32)`
# are defined in constants.py
('BLS_WITHDRAWAL_PREFIX_BYTE', bytes),
('BLS_WITHDRAWAL_PREFIX', int),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now in byte (again).

Suggested change
('BLS_WITHDRAWAL_PREFIX', int),
('BLS_WITHDRAWAL_PREFIX', bytes),

Copy link
Contributor

@hwwhww hwwhww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming (spec sync) nitpicks of eth2/beacon/committee_helpers.py

shuffling_epoch=state.previous_shuffling_epoch,
shuffling_start_shard=state.previous_shuffling_start_shard,
)
def get_epoch_start_shard(state: BeaconState,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to get_start_shard.

committee_config: CommitteeConfig,
registry_change: bool=False) -> Iterable[Tuple[Sequence[ValidatorIndex], Shard]]:
def get_beacon_proposer_index(state: BeaconState,
committee_config: CommitteeConfig) -> ValidatorIndex:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
committee_config: CommitteeConfig) -> ValidatorIndex:
config: CommitteeConfig) -> ValidatorIndex:

state: 'BeaconState',
attestation_data: 'AttestationData',
committee_config: CommitteeConfig) -> Iterable[ValidatorIndex]:
def _get_shuffled_index(index: int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to compute_shuffled_index?

state: 'BeaconState',
attestation_data: 'AttestationData',
committee_config: CommitteeConfig) -> Iterable[ValidatorIndex]:
def _get_shuffled_index(index: int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def _get_shuffled_index(index: int,
def _get_shuffled_index(index: ValidatorIndex,

attestation_data.shard,
)
f"The given `index_count` ({index_count}) should be equal to or less than "
f"`MAX_INDEX_COUNT` ({MAX_INDEX_COUNT}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion has been removed from the spec.

)
byte = h[(hash_pos % 256) // 8]
bit = (byte >> (hash_pos % 8)) % 2
new_index = flip if bit else new_index
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some spec renames nitpick:

  1. hash_pos -> position
  2. h -> source

@hwwhww
Copy link
Contributor

hwwhww commented Jul 5, 2019

@ralexstokes

I made a list of PRs after ethereum/consensus-specs@b007d5a:

@ralexstokes ralexstokes force-pushed the validator-spec-updates branch from 6400927 to 8f45a0d Compare July 9, 2019 15:56
@ralexstokes ralexstokes force-pushed the validator-spec-updates branch from 8f45a0d to 5750a2e Compare July 9, 2019 16:22
@ralexstokes ralexstokes merged commit 2644c23 into ethereum:master Jul 9, 2019
@ralexstokes ralexstokes deleted the validator-spec-updates branch July 9, 2019 17:02
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants