mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-20 06:18:15 +00:00
Address Danny's comments
This commit is contained in:
parent
81ee59bca8
commit
f2d885f0d8
@ -66,8 +66,8 @@
|
|||||||
- [`get_shard_delta`](#get_shard_delta)
|
- [`get_shard_delta`](#get_shard_delta)
|
||||||
- [`compute_committee`](#compute_committee)
|
- [`compute_committee`](#compute_committee)
|
||||||
- [`get_crosslink_committees_at_slot`](#get_crosslink_committees_at_slot)
|
- [`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_block_root`](#get_block_root)
|
||||||
- [`get_state_root`](#get_state_root)
|
|
||||||
- [`get_randao_mix`](#get_randao_mix)
|
- [`get_randao_mix`](#get_randao_mix)
|
||||||
- [`get_active_index_root`](#get_active_index_root)
|
- [`get_active_index_root`](#get_active_index_root)
|
||||||
- [`generate_seed`](#generate_seed)
|
- [`generate_seed`](#generate_seed)
|
||||||
@ -416,6 +416,8 @@ The types are defined topologically to aid in facilitating an executable version
|
|||||||
'data': AttestationData,
|
'data': AttestationData,
|
||||||
# Inclusion slot
|
# Inclusion slot
|
||||||
'inclusion_slot': 'uint64',
|
'inclusion_slot': 'uint64',
|
||||||
|
# Proposer index
|
||||||
|
'proposer_index': 'uint64',
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -678,6 +680,7 @@ def get_epoch_start_slot(epoch: Epoch) -> Slot:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### `is_active_validator`
|
### `is_active_validator`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def is_active_validator(validator: Validator, epoch: Epoch) -> bool:
|
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`
|
### `is_slashable_validator`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def is_slashable_validator(validator: Validator, epoch: Epoch) -> bool:
|
def is_slashable_validator(validator: Validator, epoch: Epoch) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if ``validator`` is slashable.
|
Check if ``validator`` is slashable.
|
||||||
"""
|
"""
|
||||||
return (
|
return validator.slashed is False and (validator.activation_epoch <= epoch < validator.withdrawable_epoch)
|
||||||
validator.activation_epoch <= epoch < validator.withdrawable_epoch and
|
|
||||||
validator.slashed is False
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_active_validator_indices`
|
### `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.
|
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(
|
return max(
|
||||||
1,
|
1,
|
||||||
min(
|
min(
|
||||||
SHARD_COUNT // SLOTS_PER_EPOCH,
|
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
|
) * SLOTS_PER_EPOCH
|
||||||
```
|
```
|
||||||
@ -850,10 +852,10 @@ def get_crosslink_committees_at_slot(state: BeaconState,
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_block_root`
|
### `get_block_root_at_slot`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_block_root(state: BeaconState,
|
def get_block_root_at_slot(state: BeaconState,
|
||||||
slot: Slot) -> Bytes32:
|
slot: Slot) -> Bytes32:
|
||||||
"""
|
"""
|
||||||
Return the block root at a recent ``slot``.
|
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]
|
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_block_root`
|
||||||
|
|
||||||
### `get_state_root`
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_state_root(state: BeaconState,
|
def get_block_root(state: BeaconState,
|
||||||
slot: Slot) -> Bytes32:
|
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 get_block_root_at_slot(state, get_epoch_start_slot(epoch))
|
||||||
return state.latest_state_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_randao_mix`
|
### `get_randao_mix`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -917,17 +917,17 @@ def generate_seed(state: BeaconState,
|
|||||||
### `get_beacon_proposer_index`
|
### `get_beacon_proposer_index`
|
||||||
|
|
||||||
```python
|
```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``.
|
Return the beacon proposer index at ``slot``.
|
||||||
"""
|
"""
|
||||||
epoch = slot_to_epoch(slot if slot != None else state.slot)
|
epoch = slot_to_epoch(state.slot)
|
||||||
first_committee, _ = get_crosslink_committees_at_slot(state, slot if slot != None else state.slot)[0]
|
first_committee, _ = get_crosslink_committees_at_slot(state, state.slot)[0]
|
||||||
|
MAX_RANDOM_BYTE = 2**8 - 1
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
candidate_index = first_committee[(epoch + i) % len(first_committee)]
|
candidate_index = first_committee[(epoch + i) % len(first_committee)]
|
||||||
random_byte = hash(generate_seed(state, epoch) + int_to_bytes8(i // 32))[i % 32]
|
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
|
effective_balance = state.validator_registry[candidate_index].effective_balance
|
||||||
if effective_balance * MAX_RANDOM_BYTE >= MAX_DEPOSIT_AMOUNT * random_byte:
|
if effective_balance * MAX_RANDOM_BYTE >= MAX_DEPOSIT_AMOUNT * random_byte:
|
||||||
return candidate_index
|
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]:
|
def get_matching_target_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
|
||||||
return [
|
return [
|
||||||
a for a in get_matching_source_attestations(state, epoch)
|
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]:
|
def get_matching_head_attestations(state: BeaconState, epoch: Epoch) -> List[PendingAttestation]:
|
||||||
return [
|
return [
|
||||||
a for a in get_matching_source_attestations(state, epoch)
|
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
|
```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)
|
attestations = get_matching_source_attestations(state, epoch)
|
||||||
shard_attestations = [a for a in attestations if a.data.shard == shard]
|
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]
|
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))
|
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:
|
if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||||
state.current_justified_epoch = get_previous_epoch(state)
|
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)
|
state.justification_bitfield |= (1 << 1)
|
||||||
current_epoch_matching_target_balance = get_attesting_balance(state, get_matching_target_attestations(state, current_epoch))
|
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:
|
if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||||
state.current_justified_epoch = get_current_epoch(state)
|
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)
|
state.justification_bitfield |= (1 << 0)
|
||||||
|
|
||||||
# Process finalizations
|
# 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
|
# 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:
|
if (bitfield >> 1) % 8 == 0b111 and old_previous_justified_epoch == current_epoch - 3:
|
||||||
state.finalized_epoch = old_previous_justified_epoch
|
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
|
# 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:
|
if (bitfield >> 1) % 4 == 0b11 and old_previous_justified_epoch == current_epoch - 2:
|
||||||
state.finalized_epoch = old_previous_justified_epoch
|
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
|
# 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:
|
if (bitfield >> 0) % 8 == 0b111 and old_current_justified_epoch == current_epoch - 2:
|
||||||
state.finalized_epoch = old_current_justified_epoch
|
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
|
# 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:
|
if (bitfield >> 0) % 4 == 0b11 and old_current_justified_epoch == current_epoch - 1:
|
||||||
state.finalized_epoch = old_current_justified_epoch
|
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
|
#### 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)):
|
for slot in range(get_epoch_start_slot(previous_epoch), get_epoch_start_slot(next_epoch)):
|
||||||
epoch = slot_to_epoch(slot)
|
epoch = slot_to_epoch(slot)
|
||||||
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, 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):
|
if 3 * get_total_balance(state, attesting_indices) >= 2 * get_total_balance(state, crosslink_committee):
|
||||||
state.current_crosslinks[shard] = winning_crosslink
|
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]]:
|
def get_attestation_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
|
||||||
previous_epoch = get_previous_epoch(state)
|
previous_epoch = get_previous_epoch(state)
|
||||||
total_balance = get_total_active_balance(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))]
|
rewards = [0 for index in range(len(state.validator_registry))]
|
||||||
penalties = [0 for index in range(len(state.validator_registry))]
|
penalties = [0 for index in range(len(state.validator_registry))]
|
||||||
|
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 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:
|
for index in eligible_validator_indices:
|
||||||
base_reward = get_base_reward(state, index)
|
if index in unslashed_attesting_indices:
|
||||||
|
rewards[index] += get_base_reward(state, index) * attesting_balance // total_balance
|
||||||
# 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
|
|
||||||
else:
|
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)):
|
# Proposer and inclusion delay micro-rewards
|
||||||
earliest_attestation = get_earliest_attestation(state, get_matching_source_attestations(state, previous_epoch), index)
|
if index in get_unslashed_attesting_indices(state, matching_source_attestations):
|
||||||
# Proposer micro-rewards
|
earliest_attestation = get_earliest_attestation(state, matching_source_attestations, index)
|
||||||
proposer_index = get_beacon_proposer_index(state, earliest_attestation.inclusion_slot)
|
rewards[earliest_attestation.proposer_index] += get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT
|
||||||
rewards[proposer_index] += base_reward // PROPOSER_REWARD_QUOTIENT
|
|
||||||
# Inclusion delay micro-rewards
|
|
||||||
inclusion_delay = earliest_attestation.inclusion_slot - earliest_attestation.data.slot
|
inclusion_delay = earliest_attestation.inclusion_slot - earliest_attestation.data.slot
|
||||||
rewards[index] += base_reward * MIN_ATTESTATION_INCLUSION_DELAY // inclusion_delay
|
rewards[index] += get_base_reward(state, index) * MIN_ATTESTATION_INCLUSION_DELAY // inclusion_delay
|
||||||
|
|
||||||
# Inactivity penalty
|
# Inactivity penalty
|
||||||
finality_delay = previous_epoch - state.finalized_epoch
|
finality_delay = previous_epoch - state.finalized_epoch
|
||||||
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
|
if finality_delay > MIN_EPOCHS_TO_INACTIVITY_PENALTY:
|
||||||
penalties[index] += BASE_REWARDS_PER_EPOCH * base_reward
|
matching_target_attesting_indices = get_unslashed_attesting_indices(state, matching_target_attestations)
|
||||||
if index not in get_unslashed_attesting_indices(state, get_matching_target_attestations(state, previous_epoch)):
|
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
|
penalties[index] += state.validator_registry[index].effective_balance * finality_delay // INACTIVITY_PENALTY_QUOTIENT
|
||||||
|
|
||||||
return [rewards, penalties]
|
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))):
|
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)
|
epoch = slot_to_epoch(slot)
|
||||||
for crosslink_committee, shard in get_crosslink_committees_at_slot(state, 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)
|
attesting_balance = get_total_balance(state, attesting_indices)
|
||||||
committee_balance = get_total_balance(state, crosslink_committee)
|
committee_balance = get_total_balance(state, crosslink_committee)
|
||||||
for index in crosslink_committee:
|
for index in crosslink_committee:
|
||||||
@ -1915,7 +1915,8 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
|||||||
pending_attestation = PendingAttestation(
|
pending_attestation = PendingAttestation(
|
||||||
data=data,
|
data=data,
|
||||||
aggregation_bitfield=attestation.aggregation_bitfield,
|
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):
|
if target_epoch == get_current_epoch(state):
|
||||||
state.current_epoch_attestations.append(pending_attestation)
|
state.current_epoch_attestations.append(pending_attestation)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user