Address Danny's comments

This commit is contained in:
Justin 2019-04-24 14:23:51 +10:00 committed by GitHub
parent 81ee59bca8
commit f2d885f0d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 63 additions and 62 deletions

View File

@ -66,8 +66,8 @@
- [`get_shard_delta`](#get_shard_delta)
- [`compute_committee`](#compute_committee)
- [`get_crosslink_committees_at_slot`](#get_crosslink_committees_at_slot)
- [`get_block_root_at_slot`](#get_block_root_at_slot)
- [`get_block_root`](#get_block_root)
- [`get_state_root`](#get_state_root)
- [`get_randao_mix`](#get_randao_mix)
- [`get_active_index_root`](#get_active_index_root)
- [`generate_seed`](#generate_seed)
@ -416,6 +416,8 @@ The types are defined topologically to aid in facilitating an executable version
'data': AttestationData,
# Inclusion slot
'inclusion_slot': 'uint64',
# Proposer index
'proposer_index': 'uint64',
}
```
@ -678,6 +680,7 @@ def get_epoch_start_slot(epoch: Epoch) -> Slot:
```
### `is_active_validator`
```python
def is_active_validator(validator: Validator, epoch: Epoch) -> bool:
"""
@ -687,15 +690,14 @@ def is_active_validator(validator: Validator, epoch: Epoch) -> bool:
```
### `is_slashable_validator`
```python
def is_slashable_validator(validator: Validator, epoch: Epoch) -> bool:
"""
Check if ``validator`` is slashable.
"""
return (
validator.activation_epoch <= epoch < validator.withdrawable_epoch and
validator.slashed is False
)
return validator.slashed is False and (validator.activation_epoch <= epoch < validator.withdrawable_epoch)
```
### `get_active_validator_indices`
@ -772,12 +774,12 @@ def get_epoch_committee_count(state: BeaconState, epoch: Epoch) -> int:
"""
Return the number of committees in one epoch.
"""
active_validators = get_active_validator_indices(state, epoch)
active_validator_indices = get_active_validator_indices(state, epoch)
return max(
1,
min(
SHARD_COUNT // SLOTS_PER_EPOCH,
len(active_validators) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
len(active_validator_indices) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
)
) * SLOTS_PER_EPOCH
```
@ -850,11 +852,11 @@ def get_crosslink_committees_at_slot(state: BeaconState,
]
```
### `get_block_root`
### `get_block_root_at_slot`
```python
def get_block_root(state: BeaconState,
slot: Slot) -> Bytes32:
def get_block_root_at_slot(state: BeaconState,
slot: Slot) -> Bytes32:
"""
Return the block root at a recent ``slot``.
"""
@ -862,19 +864,17 @@ def get_block_root(state: BeaconState,
return state.latest_block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
```
`get_block_root(_, s)` should always return `signing_root` of the block in the beacon chain at slot `s`, and `get_crosslink_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
### `get_state_root`
### `get_block_root`
```python
def get_state_root(state: BeaconState,
slot: Slot) -> Bytes32:
def get_block_root(state: BeaconState,
epoch: Epoch) -> Bytes32:
"""
Return the state root at a recent ``slot``.
Return the block root at a recent ``epoch``.
"""
assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
return state.latest_state_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
return get_block_root_at_slot(state, get_epoch_start_slot(epoch))
```
### `get_randao_mix`
```python
@ -917,17 +917,17 @@ def generate_seed(state: BeaconState,
### `get_beacon_proposer_index`
```python
def get_beacon_proposer_index(state: BeaconState, slot: Slot=None) -> ValidatorIndex:
def get_beacon_proposer_index(state: BeaconState) -> ValidatorIndex:
"""
Return the beacon proposer index at ``slot``.
"""
epoch = slot_to_epoch(slot if slot != None else state.slot)
first_committee, _ = get_crosslink_committees_at_slot(state, slot if slot != None else state.slot)[0]
epoch = slot_to_epoch(state.slot)
first_committee, _ = get_crosslink_committees_at_slot(state, state.slot)[0]
MAX_RANDOM_BYTE = 2**8 - 1
i = 0
while True:
candidate_index = first_committee[(epoch + i) % len(first_committee)]
random_byte = hash(generate_seed(state, epoch) + int_to_bytes8(i // 32))[i % 32]
MAX_RANDOM_BYTE = 2**8 - 1
effective_balance = state.validator_registry[candidate_index].effective_balance
if effective_balance * MAX_RANDOM_BYTE >= MAX_DEPOSIT_AMOUNT * random_byte:
return candidate_index
@ -1449,7 +1449,7 @@ def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> List[P
def get_matching_target_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
return [
a for a in get_matching_source_attestations(state, epoch)
if a.data.target_root == get_block_root(state, get_epoch_start_slot(epoch))
if a.data.target_root == get_block_root(state, epoch)
]
```
@ -1457,7 +1457,7 @@ def get_matching_target_attestations(state: BeaconState, epoch: Epoch) -> List[P
def get_matching_head_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
return [
a for a in get_matching_source_attestations(state, epoch)
if a.data.beacon_block_root == get_block_root(state, a.data.slot)
if a.data.beacon_block_root == get_block_root_at_slot(state, a.data.slot)
]
```
@ -1484,7 +1484,7 @@ def get_crosslink_from_attestation_data(state: BeaconState, data: AttestationDat
```
```python
def get_winning_crosslink_and_attesting_indices(state: BeaconState, epoch: Epoch, shard: Shard) -> Tuple[Crosslink, List[ValidatorIndex]]:
def get_winning_crosslink_and_attesting_indices(state: BeaconState, shard: Shard, epoch: Epoch) -> Tuple[Crosslink, List[ValidatorIndex]]:
attestations = get_matching_source_attestations(state, epoch)
shard_attestations = [a for a in attestations if a.data.shard == shard]
shard_crosslinks = [get_crosslink_from_attestation_data(state, a.data) for a in shard_attestations]
@ -1533,12 +1533,12 @@ def process_justification_and_finalization(state: BeaconState) -> None:
previous_epoch_matching_target_balance = get_attesting_balance(state, get_matching_target_attestations(state, previous_epoch))
if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
state.current_justified_epoch = get_previous_epoch(state)
state.current_justified_root = get_block_root(state, get_epoch_start_slot(state.current_justified_epoch))
state.current_justified_root = get_block_root(state, state.current_justified_epoch)
state.justification_bitfield |= (1 << 1)
current_epoch_matching_target_balance = get_attesting_balance(state, get_matching_target_attestations(state, current_epoch))
if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
state.current_justified_epoch = get_current_epoch(state)
state.current_justified_root = get_block_root(state, get_epoch_start_slot(state.current_justified_epoch))
state.current_justified_root = get_block_root(state, state.current_justified_epoch)
state.justification_bitfield |= (1 << 0)
# Process finalizations
@ -1546,19 +1546,19 @@ def process_justification_and_finalization(state: BeaconState) -> None:
# The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
if (bitfield >> 1) % 8 == 0b111 and old_previous_justified_epoch == current_epoch - 3:
state.finalized_epoch = old_previous_justified_epoch
state.finalized_root = get_block_root(state, get_epoch_start_slot(state.finalized_epoch))
state.finalized_root = get_block_root(state, state.finalized_epoch)
# The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
if (bitfield >> 1) % 4 == 0b11 and old_previous_justified_epoch == current_epoch - 2:
state.finalized_epoch = old_previous_justified_epoch
state.finalized_root = get_block_root(state, get_epoch_start_slot(state.finalized_epoch))
state.finalized_root = get_block_root(state, state.finalized_epoch)
# The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
if (bitfield >> 0) % 8 == 0b111 and old_current_justified_epoch == current_epoch - 2:
state.finalized_epoch = old_current_justified_epoch
state.finalized_root = get_block_root(state, get_epoch_start_slot(state.finalized_epoch))
state.finalized_root = get_block_root(state, state.finalized_epoch)
# The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
if (bitfield >> 0) % 4 == 0b11 and old_current_justified_epoch == current_epoch - 1:
state.finalized_epoch = old_current_justified_epoch
state.finalized_root = get_block_root(state, get_epoch_start_slot(state.finalized_epoch))
state.finalized_root = get_block_root(state, state.finalized_epoch)
```
#### Crosslinks
@ -1573,7 +1573,7 @@ def process_crosslinks(state: BeaconState) -> None:
for slot in range(get_epoch_start_slot(previous_epoch), get_epoch_start_slot(next_epoch)):
epoch = slot_to_epoch(slot)
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, slot):
winning_crosslink, attesting_indices = get_winning_crosslink_and_attesting_indices(state, epoch, shard)
winning_crosslink, attesting_indices = get_winning_crosslink_and_attesting_indices(state, shard, epoch)
if 3 * get_total_balance(state, attesting_indices) >= 2 * get_total_balance(state, crosslink_committee):
state.current_crosslinks[shard] = winning_crosslink
```
@ -1595,40 +1595,40 @@ def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
previous_epoch = get_previous_epoch(state)
total_balance = get_total_active_balance(state)
eligible_validator_indices = [
index for index, validator in enumerate(state.validator_registry)
if is_active_validator(validator, previous_epoch) or (validator.slashed and previous_epoch < validator.withdrawable_epoch)
]
rewards = [0 for index in range(len(state.validator_registry))]
penalties = [0 for index in range(len(state.validator_registry))]
for index in eligible_validator_indices:
base_reward = get_base_reward(state, index)
eligible_validator_indices = [
index for index, v in enumerate(state.validator_registry)
if is_active_validator(v, previous_epoch) or (v.slashed and previous_epoch + 1 < v.withdrawable_epoch)
]
# Micro-incentives for attestations matching FFG source, FFG target, and head
for attestations in (
get_matching_source_attestations(state, previous_epoch),
get_matching_target_attestations(state, previous_epoch),
get_matching_source_attestations(state, previous_epoch),
):
if index in get_unslashed_attesting_indices(state, attestations):
rewards[index] += base_reward * get_attesting_balance(state, attestations) // total_balance
# Micro-incentives for matching FFG source, FFG target, and head
matching_source_attestations = get_matching_source_attestations(state, previous_epoch)
matching_target_attestations = get_matching_target_attestations(state, previous_epoch)
matching_head_attestations = get_matching_head_attestations(state, previous_epoch)
for attestations in (matching_source_attestations, matching_target_attestations, matching_head_attestations):
unslashed_attesting_indices = get_unslashed_attesting_indices(state, attestations)
attesting_balance = get_attesting_balance(state, attestations)
for index in eligible_validator_indices:
if index in unslashed_attesting_indices:
rewards[index] += get_base_reward(state, index) * attesting_balance // total_balance
else:
penalties[index] += base_reward
penalties[index] += get_base_reward(state, index)
if index in get_unslashed_attesting_indices(state, get_matching_source_attestations(state, previous_epoch)):
earliest_attestation = get_earliest_attestation(state, get_matching_source_attestations(state, previous_epoch), index)
# Proposer micro-rewards
proposer_index = get_beacon_proposer_index(state, earliest_attestation.inclusion_slot)
rewards[proposer_index] += base_reward // PROPOSER_REWARD_QUOTIENT
# Inclusion delay micro-rewards
inclusion_delay = earliest_attestation.inclusion_slot - earliest_attestation.data.slot
rewards[index] += base_reward * MIN_ATTESTATION_INCLUSION_DELAY // inclusion_delay
# Proposer and inclusion delay micro-rewards
if index in get_unslashed_attesting_indices(state, matching_source_attestations):
earliest_attestation = get_earliest_attestation(state, matching_source_attestations, index)
rewards[earliest_attestation.proposer_index] += get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT
inclusion_delay = earliest_attestation.inclusion_slot - earliest_attestation.data.slot
rewards[index] += get_base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY // inclusion_delay
# Inactivity penalty
finality_delay = previous_epoch - state.finalized_epoch
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
penalties[index] += BASE_REWARDS_PER_EPOCH * base_reward
if index not in get_unslashed_attesting_indices(state, get_matching_target_attestations(state, previous_epoch)):
# Inactivity penalty
finality_delay = previous_epoch - state.finalized_epoch
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
matching_target_attesting_indices = get_unslashed_attesting_indices(state, matching_target_attestations)
for index in eligible_validator_indices:
penalties[index] += BASE_REWARDS_PER_EPOCH * get_base_reward(state, index)
if index not in matching_target_attesting_indices:
penalties[index] += state.validator_registry[index].effective_balance * finality_delay // INACTIVITY_PENALTY_QUOTIENT
return [rewards, penalties]
@ -1641,7 +1641,7 @@ def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
for slot in range(get_epoch_start_slot(get_previous_epoch(state)), get_epoch_start_slot(get_current_epoch(state))):
epoch = slot_to_epoch(slot)
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, slot):
winning_crosslink, attesting_indices = get_winning_crosslink_and_attesting_indices(state, epoch, shard)
winning_crosslink, attesting_indices = get_winning_crosslink_and_attesting_indices(state, shard, epoch)
attesting_balance = get_total_balance(state, attesting_indices)
committee_balance = get_total_balance(state, crosslink_committee)
for index in crosslink_committee:
@ -1915,7 +1915,8 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
pending_attestation = PendingAttestation(
data=data,
aggregation_bitfield=attestation.aggregation_bitfield,
inclusion_slot=state.slot
inclusion_slot=state.slot,
proposer_index=get_beacon_proposer_index(state),
)
if target_epoch == get_current_epoch(state):
state.current_epoch_attestations.append(pending_attestation)