Skip to content

Commit

Permalink
Merge pull request #1488 from ethereum/v09x
Browse files Browse the repository at this point in the history
Release v0.9.2 to master
  • Loading branch information
djrtwo authored Nov 21, 2019
2 parents 03fb097 + 3e96b43 commit aafbe1f
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 110 deletions.
16 changes: 14 additions & 2 deletions configs/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ MIN_PER_EPOCH_CHURN_LIMIT: 4
CHURN_LIMIT_QUOTIENT: 65536
# See issue 563
SHUFFLE_ROUND_COUNT: 90
# `2**16` (= 65,536)
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 65536
# `2**14` (= 16,384)
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
# Jan 3, 2020
MIN_GENESIS_TIME: 1578009600

Expand All @@ -29,6 +29,18 @@ MIN_GENESIS_TIME: 1578009600
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8


# Validator
# ---------------------------------------------------------------
# 2**10 (= 1,024)
ETH1_FOLLOW_DISTANCE: 1024
# 2**4 (= 16)
TARGET_AGGREGATORS_PER_COMMITTEE: 16
# 2**0 (= 1)
RANDOM_SUBNETS_PER_VALIDATOR: 1
# 2**8 (= 256)
EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION: 256


# Deposit contract
# ---------------------------------------------------------------
# **TBD**
Expand Down
12 changes: 12 additions & 0 deletions configs/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ MIN_GENESIS_TIME: 1578009600
# 2**1 (= 1)
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 2

#
# Validator
# ---------------------------------------------------------------
# [customized] process deposits more quickly, but insecure
ETH1_FOLLOW_DISTANCE: 16
# 2**4 (= 16)
TARGET_AGGREGATORS_PER_COMMITTEE: 16
# 2**0 (= 1)
RANDOM_SUBNETS_PER_VALIDATOR: 1
# 2**8 (= 256)
EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION: 256


# Deposit contract
# ---------------------------------------------------------------
Expand Down
14 changes: 7 additions & 7 deletions scripts/build_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,26 @@ def ceillog2(x: uint64) -> int:
SUNDRY_FUNCTIONS = '''
# Monkey patch hash cache
_hash = hash
hash_cache: Dict[bytes, Hash] = {}
hash_cache: Dict[bytes, Bytes32] = {}
def get_eth1_data(distance: uint64) -> Hash:
def get_eth1_data(distance: uint64) -> Bytes32:
return hash(distance)
def hash(x: bytes) -> Hash:
def hash(x: bytes) -> Bytes32:
if x not in hash_cache:
hash_cache[x] = Hash(_hash(x))
hash_cache[x] = Bytes32(_hash(x))
return hash_cache[x]
# Monkey patch validator compute committee code
_compute_committee = compute_committee
committee_cache: Dict[Tuple[Hash, Hash, int, int], Sequence[ValidatorIndex]] = {}
committee_cache: Dict[Tuple[Bytes32, Bytes32, int, int], Sequence[ValidatorIndex]] = {}
def compute_committee(indices: Sequence[ValidatorIndex], # type: ignore
seed: Hash,
seed: Bytes32,
index: int,
count: int) -> Sequence[ValidatorIndex]:
param_hash = (hash(b''.join(index.to_bytes(length=4, byteorder='little') for index in indices)), seed, index, count)
Expand Down Expand Up @@ -210,7 +210,7 @@ def combine_constants(old_constants: Dict[str, str], new_constants: Dict[str, st


ignored_dependencies = [
'bit', 'boolean', 'Vector', 'List', 'Container', 'Hash', 'BLSPubkey', 'BLSSignature', 'Bytes', 'BytesN'
'bit', 'boolean', 'Vector', 'List', 'Container', 'Root', 'BLSPubkey', 'BLSSignature', 'Bytes', 'BytesN'
'Bytes1', 'Bytes4', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector',
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256',
'bytes', 'byte', 'BytesN' # to be removed after updating spec doc
Expand Down
64 changes: 32 additions & 32 deletions specs/core/0_beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ We define the following Python custom types for type hinting and readability:
| `CommitteeIndex` | `uint64` | a committee index at a slot |
| `ValidatorIndex` | `uint64` | a validator registry index |
| `Gwei` | `uint64` | an amount in Gwei |
| `Hash` | `Bytes32` | a hash |
| `Root` | `Bytes32` | a Merkle root |
| `Version` | `Bytes4` | a fork version number |
| `DomainType` | `Bytes4` | a domain type |
| `Domain` | `Bytes8` | a signature domain |
Expand Down Expand Up @@ -171,7 +171,7 @@ The following values are (non-configurable) constants used throughout the specif
| `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) |
| `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) |
| `SHUFFLE_ROUND_COUNT` | `90` |
| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) |
| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**14` (= 16,384) |
| `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) |

- For the safety of committees, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.)
Expand Down Expand Up @@ -275,15 +275,15 @@ class Fork(Container):
```python
class Checkpoint(Container):
epoch: Epoch
root: Hash
root: Root
```

#### `Validator`

```python
class Validator(Container):
pubkey: BLSPubkey
withdrawal_credentials: Hash # Commitment to pubkey for withdrawals
withdrawal_credentials: Bytes32 # Commitment to pubkey for withdrawals
effective_balance: Gwei # Balance at stake
slashed: boolean
# Status epochs
Expand All @@ -300,7 +300,7 @@ class AttestationData(Container):
slot: Slot
index: CommitteeIndex
# LMD GHOST vote
beacon_block_root: Hash
beacon_block_root: Root
# FFG vote
source: Checkpoint
target: Checkpoint
Expand Down Expand Up @@ -329,25 +329,25 @@ class PendingAttestation(Container):

```python
class Eth1Data(Container):
deposit_root: Hash
deposit_root: Root
deposit_count: uint64
block_hash: Hash
block_hash: Bytes32
```

#### `HistoricalBatch`

```python
class HistoricalBatch(Container):
block_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT]
state_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT]
block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
```

#### `DepositData`

```python
class DepositData(Container):
pubkey: BLSPubkey
withdrawal_credentials: Hash
withdrawal_credentials: Bytes32
amount: Gwei
signature: BLSSignature
```
Expand All @@ -357,9 +357,9 @@ class DepositData(Container):
```python
class BeaconBlockHeader(Container):
slot: Slot
parent_root: Hash
state_root: Hash
body_root: Hash
parent_root: Root
state_root: Root
body_root: Root
signature: BLSSignature
```

Expand Down Expand Up @@ -395,7 +395,7 @@ class Attestation(Container):

```python
class Deposit(Container):
proof: Vector[Hash, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to deposit data list root
proof: Vector[Bytes32, DEPOSIT_CONTRACT_TREE_DEPTH + 1] # Merkle path to deposit data list root
data: DepositData
```

Expand Down Expand Up @@ -430,8 +430,8 @@ class BeaconBlockBody(Container):
```python
class BeaconBlock(Container):
slot: Slot
parent_root: Hash
state_root: Hash
parent_root: Root
state_root: Root
body: BeaconBlockBody
signature: BLSSignature
```
Expand All @@ -448,9 +448,9 @@ class BeaconState(Container):
fork: Fork
# History
latest_block_header: BeaconBlockHeader
block_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT]
state_roots: Vector[Hash, SLOTS_PER_HISTORICAL_ROOT]
historical_roots: List[Hash, HISTORICAL_ROOTS_LIMIT]
block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
# Eth1
eth1_data: Eth1Data
eth1_data_votes: List[Eth1Data, SLOTS_PER_ETH1_VOTING_PERIOD]
Expand All @@ -459,7 +459,7 @@ class BeaconState(Container):
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT]
# Randomness
randao_mixes: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR]
randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR]
# Slashings
slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] # Per-epoch sums of slashed effective balances
# Attestations
Expand Down Expand Up @@ -527,15 +527,15 @@ def bytes_to_int(data: bytes) -> uint64:

#### `hash`

`def hash(data: bytes) -> Hash` is SHA256.
`def hash(data: bytes) -> Bytes32` is SHA256.

#### `hash_tree_root`

`def hash_tree_root(object: SSZSerializable) -> Hash` is a function for hashing objects into a single root by utilizing a hash tree structure, as defined in the [SSZ spec](../simple-serialize.md#merkleization).
`def hash_tree_root(object: SSZSerializable) -> Root` is a function for hashing objects into a single root by utilizing a hash tree structure, as defined in the [SSZ spec](../simple-serialize.md#merkleization).

#### `signing_root`

`def signing_root(object: Container) -> Hash` is a function for computing signing messages, as defined in the [SSZ spec](../simple-serialize.md#self-signed-containers).
`def signing_root(object: Container) -> Root` is a function for computing signing messages, as defined in the [SSZ spec](../simple-serialize.md#self-signed-containers).

#### `bls_verify`

Expand Down Expand Up @@ -611,7 +611,7 @@ def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: Indexe
#### `is_valid_merkle_branch`

```python
def is_valid_merkle_branch(leaf: Hash, branch: Sequence[Hash], depth: uint64, index: uint64, root: Hash) -> bool:
def is_valid_merkle_branch(leaf: Bytes32, branch: Sequence[Bytes32], depth: uint64, index: uint64, root: Root) -> bool:
"""
Check if ``leaf`` at ``index`` verifies against the Merkle ``root`` and ``branch``.
"""
Expand All @@ -629,7 +629,7 @@ def is_valid_merkle_branch(leaf: Hash, branch: Sequence[Hash], depth: uint64, in
#### `compute_shuffled_index`

```python
def compute_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Hash) -> ValidatorIndex:
def compute_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Bytes32) -> ValidatorIndex:
"""
Return the shuffled validator index corresponding to ``seed`` (and ``index_count``).
"""
Expand All @@ -652,7 +652,7 @@ def compute_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Has
#### `compute_proposer_index`

```python
def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Hash) -> ValidatorIndex:
def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex:
"""
Return from ``indices`` a random index sampled by effective balance.
"""
Expand All @@ -672,7 +672,7 @@ def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex]

```python
def compute_committee(indices: Sequence[ValidatorIndex],
seed: Hash,
seed: Bytes32,
index: uint64,
count: uint64) -> Sequence[ValidatorIndex]:
"""
Expand Down Expand Up @@ -749,7 +749,7 @@ def get_previous_epoch(state: BeaconState) -> Epoch:
#### `get_block_root`

```python
def get_block_root(state: BeaconState, epoch: Epoch) -> Hash:
def get_block_root(state: BeaconState, epoch: Epoch) -> Root:
"""
Return the block root at the start of a recent ``epoch``.
"""
Expand All @@ -759,7 +759,7 @@ def get_block_root(state: BeaconState, epoch: Epoch) -> Hash:
#### `get_block_root_at_slot`

```python
def get_block_root_at_slot(state: BeaconState, slot: Slot) -> Hash:
def get_block_root_at_slot(state: BeaconState, slot: Slot) -> Root:
"""
Return the block root at a recent ``slot``.
"""
Expand All @@ -770,7 +770,7 @@ def get_block_root_at_slot(state: BeaconState, slot: Slot) -> Hash:
#### `get_randao_mix`

```python
def get_randao_mix(state: BeaconState, epoch: Epoch) -> Hash:
def get_randao_mix(state: BeaconState, epoch: Epoch) -> Bytes32:
"""
Return the randao mix at a recent ``epoch``.
"""
Expand Down Expand Up @@ -801,7 +801,7 @@ def get_validator_churn_limit(state: BeaconState) -> uint64:
#### `get_seed`

```python
def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Hash:
def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Bytes32:
"""
Return the seed at ``epoch``.
"""
Expand Down Expand Up @@ -996,7 +996,7 @@ Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 b
- `deposits` is the sequence of all deposits, ordered chronologically, up to (and including) the block with hash `eth1_block_hash`

```python
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash,
def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
eth1_timestamp: uint64,
deposits: Sequence[Deposit]) -> BeaconState:
state = BeaconState(
Expand Down
25 changes: 19 additions & 6 deletions specs/core/0_fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ The head block root associated with a `store` is defined as `get_head(store)`. A
@dataclass(eq=True, frozen=True)
class LatestMessage(object):
epoch: Epoch
root: Hash
root: Root
```

#### `Store`
Expand All @@ -70,8 +70,8 @@ class Store(object):
justified_checkpoint: Checkpoint
finalized_checkpoint: Checkpoint
best_justified_checkpoint: Checkpoint
blocks: Dict[Hash, BeaconBlock] = field(default_factory=dict)
block_states: Dict[Hash, BeaconState] = field(default_factory=dict)
blocks: Dict[Root, BeaconBlock] = field(default_factory=dict)
block_states: Dict[Root, BeaconState] = field(default_factory=dict)
checkpoint_states: Dict[Checkpoint, BeaconState] = field(default_factory=dict)
latest_messages: Dict[ValidatorIndex, LatestMessage] = field(default_factory=dict)
```
Expand Down Expand Up @@ -113,7 +113,7 @@ def compute_slots_since_epoch_start(slot: Slot) -> int:
#### `get_ancestor`

```python
def get_ancestor(store: Store, root: Hash, slot: Slot) -> Hash:
def get_ancestor(store: Store, root: Root, slot: Slot) -> Root:
block = store.blocks[root]
if block.slot > slot:
return get_ancestor(store, block.parent_root, slot)
Expand All @@ -126,7 +126,7 @@ def get_ancestor(store: Store, root: Hash, slot: Slot) -> Hash:
#### `get_latest_attesting_balance`

```python
def get_latest_attesting_balance(store: Store, root: Hash) -> Gwei:
def get_latest_attesting_balance(store: Store, root: Root) -> Gwei:
state = store.checkpoint_states[store.justified_checkpoint]
active_indices = get_active_validator_indices(state, get_current_epoch(state))
return Gwei(sum(
Expand All @@ -139,7 +139,7 @@ def get_latest_attesting_balance(store: Store, root: Hash) -> Gwei:
#### `get_head`

```python
def get_head(store: Store) -> Hash:
def get_head(store: Store) -> Root:
# Execute the LMD-GHOST fork choice
head = store.justified_checkpoint.root
justified_slot = compute_start_slot_at_epoch(store.justified_checkpoint.epoch)
Expand Down Expand Up @@ -238,6 +238,12 @@ def on_block(store: Store, block: BeaconBlock) -> None:

```python
def on_attestation(store: Store, attestation: Attestation) -> None:
"""
Run ``on_attestation`` upon receiving a new ``attestation`` from either within a block or directly on the wire.
An ``attestation`` that is asserted as invalid may be valid at a later time,
consider scheduling it for later processing in such case.
"""
target = attestation.data.target

# Attestations must be from the current or previous epoch
Expand All @@ -248,10 +254,17 @@ def on_attestation(store: Store, attestation: Attestation) -> None:
# Cannot calculate the current shuffling if have not seen the target
assert target.root in store.blocks

# Attestations target be for a known block. If target block is unknown, delay consideration until the block is found
assert target.root in store.blocks
# Attestations cannot be from future epochs. If they are, delay consideration until the epoch arrives
base_state = store.block_states[target.root].copy()
assert store.time >= base_state.genesis_time + compute_start_slot_at_epoch(target.epoch) * SECONDS_PER_SLOT

# Attestations must be for a known block. If block is unknown, delay consideration until the block is found
assert attestation.data.beacon_block_root in store.blocks
# Attestations must not be for blocks in the future. If not, the attestation should not be considered
assert store.blocks[attestation.data.beacon_block_root].slot <= attestation.data.slot

# Store target checkpoint state if not yet seen
if target not in store.checkpoint_states:
process_slots(base_state, compute_start_slot_at_epoch(target.epoch))
Expand Down
Loading

0 comments on commit aafbe1f

Please sign in to comment.