Whisk: complete TODO items in fork logic (#3427)
* Complete TODO items in fork logic * Simpler underflow protection * Add saturating_sub
This commit is contained in:
parent
12512ef818
commit
cc4c810b8f
|
@ -177,17 +177,24 @@ class BeaconState(Container):
|
|||
```
|
||||
|
||||
```python
|
||||
def select_whisk_trackers(state: BeaconState, epoch: Epoch) -> None:
|
||||
def select_whisk_proposer_trackers(state: BeaconState, epoch: Epoch) -> None:
|
||||
# Select proposer trackers from candidate trackers
|
||||
proposer_seed = get_seed(state, epoch - WHISK_PROPOSER_SELECTION_GAP, DOMAIN_WHISK_PROPOSER_SELECTION)
|
||||
proposer_seed = get_seed(
|
||||
state,
|
||||
Epoch(saturating_sub(epoch, WHISK_PROPOSER_SELECTION_GAP)),
|
||||
DOMAIN_WHISK_PROPOSER_SELECTION
|
||||
)
|
||||
for i in range(WHISK_PROPOSER_TRACKERS_COUNT):
|
||||
index = compute_shuffled_index(uint64(i), uint64(len(state.whisk_candidate_trackers)), proposer_seed)
|
||||
state.whisk_proposer_trackers[i] = state.whisk_candidate_trackers[index]
|
||||
```
|
||||
|
||||
```python
|
||||
def select_whisk_candidate_trackers(state: BeaconState, epoch: Epoch) -> None:
|
||||
# Select candidate trackers from active validator trackers
|
||||
active_validator_indices = get_active_validator_indices(state, epoch)
|
||||
for i in range(WHISK_CANDIDATE_TRACKERS_COUNT):
|
||||
seed = hash(get_seed(state, epoch, DOMAIN_WHISK_CANDIDATE_SELECTION) + uint_to_bytes(i))
|
||||
seed = hash(get_seed(state, epoch, DOMAIN_WHISK_CANDIDATE_SELECTION) + uint_to_bytes(uint64(i)))
|
||||
candidate_index = compute_proposer_index(state, active_validator_indices, seed) # sample by effective balance
|
||||
state.whisk_candidate_trackers[i] = state.whisk_trackers[candidate_index]
|
||||
```
|
||||
|
@ -196,7 +203,8 @@ def select_whisk_trackers(state: BeaconState, epoch: Epoch) -> None:
|
|||
def process_whisk_updates(state: BeaconState) -> None:
|
||||
next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
if next_epoch % WHISK_EPOCHS_PER_SHUFFLING_PHASE == 0: # select trackers at the start of shuffling phases
|
||||
select_whisk_trackers(state, next_epoch)
|
||||
select_whisk_proposer_trackers(state, next_epoch)
|
||||
select_whisk_candidate_trackers(state, next_epoch)
|
||||
```
|
||||
|
||||
```python
|
||||
|
|
|
@ -53,27 +53,13 @@ The upgrade occurs after the completion of the inner loop of `process_slots` tha
|
|||
This ensures that we drop right into the beginning of the shuffling phase but without `process_whisk_epoch()` triggering for this Whisk run. Hence we handle all the setup ourselves in `upgrade_to_whisk()` below.
|
||||
|
||||
```python
|
||||
def whisk_candidate_selection(state: BeaconState, epoch: Epoch) -> None:
|
||||
# TODO
|
||||
# pylint: disable=unused-argument
|
||||
pass
|
||||
```
|
||||
|
||||
```python
|
||||
def whisk_proposer_selection(state: BeaconState, epoch: Epoch) -> None:
|
||||
# TODO
|
||||
# pylint: disable=unused-argument
|
||||
pass
|
||||
```
|
||||
|
||||
```python
|
||||
def upgrade_to_whisk(pre: bellatrix.BeaconState) -> BeaconState:
|
||||
def upgrade_to_whisk(pre: capella.BeaconState) -> BeaconState:
|
||||
# Compute initial unsafe trackers for all validators
|
||||
ks = [get_initial_whisk_k(ValidatorIndex(validator_index), 0) for validator_index in range(len(pre.validators))]
|
||||
whisk_k_commitments = [get_k_commitment(k) for k in ks]
|
||||
whisk_trackers = [get_initial_tracker(k) for k in ks]
|
||||
|
||||
epoch = bellatrix.get_current_epoch(pre)
|
||||
epoch = get_current_epoch(pre)
|
||||
post = BeaconState(
|
||||
# Versioning
|
||||
genesis_time=pre.genesis_time,
|
||||
|
@ -115,6 +101,11 @@ def upgrade_to_whisk(pre: bellatrix.BeaconState) -> BeaconState:
|
|||
next_sync_committee=pre.next_sync_committee,
|
||||
# Execution-layer
|
||||
latest_execution_payload_header=pre.latest_execution_payload_header,
|
||||
# Withdrawals
|
||||
next_withdrawal_index=pre.next_withdrawal_index,
|
||||
next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
|
||||
# Deep history valid from Capella onwards
|
||||
historical_summaries=pre.historical_summaries,
|
||||
# Whisk
|
||||
whisk_proposer_trackers=[WhiskTracker() for _ in range(WHISK_PROPOSER_TRACKERS_COUNT)], # [New in Whisk]
|
||||
whisk_candidate_trackers=[WhiskTracker() for _ in range(WHISK_CANDIDATE_TRACKERS_COUNT)], # [New in Whisk]
|
||||
|
@ -124,12 +115,12 @@ def upgrade_to_whisk(pre: bellatrix.BeaconState) -> BeaconState:
|
|||
|
||||
# Do a candidate selection followed by a proposer selection so that we have proposers for the upcoming day
|
||||
# Use an old epoch when selecting candidates so that we don't get the same seed as in the next candidate selection
|
||||
whisk_candidate_selection(post, epoch - WHISK_PROPOSER_SELECTION_GAP - 1)
|
||||
whisk_proposer_selection(post, epoch)
|
||||
select_whisk_candidate_trackers(post, Epoch(saturating_sub(epoch, WHISK_PROPOSER_SELECTION_GAP + 1)))
|
||||
select_whisk_proposer_trackers(post, epoch)
|
||||
|
||||
# Do a final round of candidate selection.
|
||||
# We need it so that we have something to shuffle over the upcoming shuffling phase.
|
||||
whisk_candidate_selection(post, epoch)
|
||||
select_whisk_candidate_trackers(post, epoch)
|
||||
|
||||
return post
|
||||
```
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
- [`xor`](#xor)
|
||||
- [`uint_to_bytes`](#uint_to_bytes)
|
||||
- [`bytes_to_uint64`](#bytes_to_uint64)
|
||||
- [`saturating_sub`](#saturating_sub)
|
||||
- [Crypto](#crypto)
|
||||
- [`hash`](#hash)
|
||||
- [`hash_tree_root`](#hash_tree_root)
|
||||
|
@ -630,6 +631,16 @@ def bytes_to_uint64(data: bytes) -> uint64:
|
|||
return uint64(int.from_bytes(data, ENDIANNESS))
|
||||
```
|
||||
|
||||
#### `saturating_sub`
|
||||
|
||||
```python
|
||||
def saturating_sub(a: int, b: int) -> int:
|
||||
"""
|
||||
Computes a - b, saturating at numeric bounds.
|
||||
"""
|
||||
return a - b if a > b else 0
|
||||
```
|
||||
|
||||
### Crypto
|
||||
|
||||
#### `hash`
|
||||
|
|
Loading…
Reference in New Issue