Merge branch 'dev' into more_gossip_validations
This commit is contained in:
commit
8948f92def
|
@ -27,6 +27,8 @@ HYSTERESIS_QUOTIENT: 4
|
||||||
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
||||||
# 5 (plus 1.25)
|
# 5 (plus 1.25)
|
||||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
|
# 3
|
||||||
|
PROPORTIONAL_SLASHING_MULTIPLIER: 3
|
||||||
|
|
||||||
|
|
||||||
# Fork Choice
|
# Fork Choice
|
||||||
|
|
|
@ -26,7 +26,8 @@ HYSTERESIS_QUOTIENT: 4
|
||||||
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
||||||
# 5 (plus 1.25)
|
# 5 (plus 1.25)
|
||||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
|
# 3
|
||||||
|
PROPORTIONAL_SLASHING_MULTIPLIER: 3
|
||||||
|
|
||||||
|
|
||||||
# Fork Choice
|
# Fork Choice
|
||||||
|
|
7
setup.py
7
setup.py
|
@ -125,6 +125,7 @@ from eth2spec.config.config_util import apply_constants_config
|
||||||
from typing import (
|
from typing import (
|
||||||
Any, Dict, Set, Sequence, NewType, Tuple, TypeVar, Callable, Optional
|
Any, Dict, Set, Sequence, NewType, Tuple, TypeVar, Callable, Optional
|
||||||
)
|
)
|
||||||
|
from typing import List as PyList
|
||||||
|
|
||||||
from dataclasses import (
|
from dataclasses import (
|
||||||
dataclass,
|
dataclass,
|
||||||
|
@ -152,8 +153,10 @@ GeneralizedIndex = NewType('GeneralizedIndex', int)
|
||||||
SSZObject = TypeVar('SSZObject', bound=View)
|
SSZObject = TypeVar('SSZObject', bound=View)
|
||||||
'''
|
'''
|
||||||
SUNDRY_CONSTANTS_FUNCTIONS = '''
|
SUNDRY_CONSTANTS_FUNCTIONS = '''
|
||||||
def ceillog2(x: uint64) -> int:
|
def ceillog2(x: int) -> uint64:
|
||||||
return (x - 1).bit_length()
|
if x < 1:
|
||||||
|
raise ValueError(f"ceillog2 accepts only positive values, x={x}")
|
||||||
|
return uint64((x - 1).bit_length())
|
||||||
'''
|
'''
|
||||||
PHASE0_SUNDRY_FUNCTIONS = '''
|
PHASE0_SUNDRY_FUNCTIONS = '''
|
||||||
def get_eth1_data(block: Eth1Block) -> Eth1Data:
|
def get_eth1_data(block: Eth1Block) -> Eth1Data:
|
||||||
|
|
|
@ -195,6 +195,7 @@ The following values are (non-configurable) constants used throughout the specif
|
||||||
| `HYSTERESIS_QUOTIENT` | `uint64(4)` |
|
| `HYSTERESIS_QUOTIENT` | `uint64(4)` |
|
||||||
| `HYSTERESIS_DOWNWARD_MULTIPLIER` | `uint64(1)` |
|
| `HYSTERESIS_DOWNWARD_MULTIPLIER` | `uint64(1)` |
|
||||||
| `HYSTERESIS_UPWARD_MULTIPLIER` | `uint64(5)` |
|
| `HYSTERESIS_UPWARD_MULTIPLIER` | `uint64(5)` |
|
||||||
|
| `PROPORTIONAL_SLASHING_MULTIPLIER` | `uint64(3)` |
|
||||||
|
|
||||||
- For the safety of committees, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](http://web.archive.org/web/20190504131341/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.)
|
- For the safety of committees, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](http://web.archive.org/web/20190504131341/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.)
|
||||||
|
|
||||||
|
@ -773,7 +774,7 @@ def compute_committee(indices: Sequence[ValidatorIndex],
|
||||||
Return the committee corresponding to ``indices``, ``seed``, ``index``, and committee ``count``.
|
Return the committee corresponding to ``indices``, ``seed``, ``index``, and committee ``count``.
|
||||||
"""
|
"""
|
||||||
start = (len(indices) * index) // count
|
start = (len(indices) * index) // count
|
||||||
end = (len(indices) * (index + 1)) // count
|
end = (len(indices) * uint64(index + 1)) // count
|
||||||
return [indices[compute_shuffled_index(uint64(i), uint64(len(indices)), seed)] for i in range(start, end)]
|
return [indices[compute_shuffled_index(uint64(i), uint64(len(indices)), seed)] for i in range(start, end)]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1454,7 +1455,7 @@ def get_inclusion_delay_deltas(state: BeaconState) -> Tuple[Sequence[Gwei], Sequ
|
||||||
if index in get_attesting_indices(state, a.data, a.aggregation_bits)
|
if index in get_attesting_indices(state, a.data, a.aggregation_bits)
|
||||||
], key=lambda a: a.inclusion_delay)
|
], key=lambda a: a.inclusion_delay)
|
||||||
rewards[attestation.proposer_index] += get_proposer_reward(state, index)
|
rewards[attestation.proposer_index] += get_proposer_reward(state, index)
|
||||||
max_attester_reward = get_base_reward(state, index) - get_proposer_reward(state, index)
|
max_attester_reward = Gwei(get_base_reward(state, index) - get_proposer_reward(state, index))
|
||||||
rewards[index] += Gwei(max_attester_reward // attestation.inclusion_delay)
|
rewards[index] += Gwei(max_attester_reward // attestation.inclusion_delay)
|
||||||
|
|
||||||
# No penalties associated with inclusion delay
|
# No penalties associated with inclusion delay
|
||||||
|
@ -1554,10 +1555,11 @@ def process_registry_updates(state: BeaconState) -> None:
|
||||||
def process_slashings(state: BeaconState) -> None:
|
def process_slashings(state: BeaconState) -> None:
|
||||||
epoch = get_current_epoch(state)
|
epoch = get_current_epoch(state)
|
||||||
total_balance = get_total_active_balance(state)
|
total_balance = get_total_active_balance(state)
|
||||||
|
adjusted_total_slashing_balance = min(sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER, total_balance)
|
||||||
for index, validator in enumerate(state.validators):
|
for index, validator in enumerate(state.validators):
|
||||||
if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
|
if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
|
||||||
increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow
|
increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow
|
||||||
penalty_numerator = validator.effective_balance // increment * min(sum(state.slashings) * 3, total_balance)
|
penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance
|
||||||
penalty = penalty_numerator // total_balance * increment
|
penalty = penalty_numerator // total_balance * increment
|
||||||
decrease_balance(state, ValidatorIndex(index), penalty)
|
decrease_balance(state, ValidatorIndex(index), penalty)
|
||||||
```
|
```
|
||||||
|
@ -1574,7 +1576,7 @@ def process_final_updates(state: BeaconState) -> None:
|
||||||
# Update effective balances with hysteresis
|
# Update effective balances with hysteresis
|
||||||
for index, validator in enumerate(state.validators):
|
for index, validator in enumerate(state.validators):
|
||||||
balance = state.balances[index]
|
balance = state.balances[index]
|
||||||
HYSTERESIS_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT
|
HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT)
|
||||||
DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
|
DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER
|
||||||
UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -395,9 +395,9 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||||
- _[REJECT]_ The attestation's epoch matches its target -- i.e. `attestation.data.target.epoch ==
|
- _[REJECT]_ The attestation's epoch matches its target -- i.e. `attestation.data.target.epoch ==
|
||||||
compute_epoch_at_slot(attestation.data.slot)`
|
compute_epoch_at_slot(attestation.data.slot)`
|
||||||
- _[REJECT]_ The attestation is unaggregated --
|
- _[REJECT]_ The attestation is unaggregated --
|
||||||
that is, it has exactly one participating validator (`len([bit in bit attestation.aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set).
|
that is, it has exactly one participating validator (`len([bit for bit in attestation.aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set).
|
||||||
- _[REJECT]_ The number of aggregation bits matches the committee size -- i.e.
|
- _[REJECT]_ The number of aggregation bits matches the committee size -- i.e.
|
||||||
`len(attestation.aggregation_bits) == len(get_beacon_committee(state, data.slot, data.index))`
|
`len(attestation.aggregation_bits) == len(get_beacon_committee(state, data.slot, data.index))`.
|
||||||
- _[IGNORE]_ There has been no other valid attestation seen on an attestation subnet
|
- _[IGNORE]_ There has been no other valid attestation seen on an attestation subnet
|
||||||
that has an identical `attestation.data.target.epoch` and participating validator index.
|
that has an identical `attestation.data.target.epoch` and participating validator index.
|
||||||
- _[REJECT]_ The signature of `attestation` is valid.
|
- _[REJECT]_ The signature of `attestation` is valid.
|
||||||
|
@ -413,7 +413,6 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Attestations and Aggregation
|
#### Attestations and Aggregation
|
||||||
|
|
||||||
Attestation broadcasting is grouped into subnets defined by a topic.
|
Attestation broadcasting is grouped into subnets defined by a topic.
|
||||||
|
|
|
@ -168,7 +168,7 @@ def get_committee_assignment(state: BeaconState,
|
||||||
* ``assignment[2]`` is the slot at which the committee is assigned
|
* ``assignment[2]`` is the slot at which the committee is assigned
|
||||||
Return None if no assignment.
|
Return None if no assignment.
|
||||||
"""
|
"""
|
||||||
next_epoch = get_current_epoch(state) + 1
|
next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||||
assert epoch <= next_epoch
|
assert epoch <= next_epoch
|
||||||
|
|
||||||
start_slot = compute_start_slot_at_epoch(epoch)
|
start_slot = compute_start_slot_at_epoch(epoch)
|
||||||
|
@ -460,7 +460,7 @@ def compute_subnet_for_attestation(committees_per_slot: uint64, slot: Slot, comm
|
||||||
Compute the correct subnet for an attestation for Phase 0.
|
Compute the correct subnet for an attestation for Phase 0.
|
||||||
Note, this mimics expected Phase 1 behavior where attestations will be mapped to their shard subnet.
|
Note, this mimics expected Phase 1 behavior where attestations will be mapped to their shard subnet.
|
||||||
"""
|
"""
|
||||||
slots_since_epoch_start = slot % SLOTS_PER_EPOCH
|
slots_since_epoch_start = uint64(slot % SLOTS_PER_EPOCH)
|
||||||
committees_since_epoch_start = committees_per_slot * slots_since_epoch_start
|
committees_since_epoch_start = committees_per_slot * slots_since_epoch_start
|
||||||
|
|
||||||
return uint64((committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT)
|
return uint64((committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT)
|
||||||
|
|
|
@ -105,20 +105,20 @@ Configuration is not namespaced. Instead it is strictly an extension;
|
||||||
|
|
||||||
| Name | Value |
|
| Name | Value |
|
||||||
| - | - |
|
| - | - |
|
||||||
| `MAX_SHARDS` | `2**10` (= 1024) |
|
| `MAX_SHARDS` | `uint64(2**10)` (= 1024) |
|
||||||
| `INITIAL_ACTIVE_SHARDS` | `2**6` (= 64) |
|
| `INITIAL_ACTIVE_SHARDS` | `uint64(2**6)` (= 64) |
|
||||||
| `LIGHT_CLIENT_COMMITTEE_SIZE` | `2**7` (= 128) |
|
| `LIGHT_CLIENT_COMMITTEE_SIZE` | `uint64(2**7)` (= 128) |
|
||||||
| `GASPRICE_ADJUSTMENT_COEFFICIENT` | `2**3` (= 8) |
|
| `GASPRICE_ADJUSTMENT_COEFFICIENT` | `uint64(2**3)` (= 8) |
|
||||||
|
|
||||||
### Shard block configs
|
### Shard block configs
|
||||||
|
|
||||||
| Name | Value | Unit |
|
| Name | Value | Unit |
|
||||||
| - | - | - |
|
| - | - | - |
|
||||||
| `MAX_SHARD_BLOCK_SIZE` | `2**20` (= 1,048,576) | bytes |
|
| `MAX_SHARD_BLOCK_SIZE` | `uint64(2**20)` (= 1,048,576) | bytes |
|
||||||
| `TARGET_SHARD_BLOCK_SIZE` | `2**18` (= 262,144) | bytes |
|
| `TARGET_SHARD_BLOCK_SIZE` | `uint64(2**18)` (= 262,144) | bytes |
|
||||||
| `SHARD_BLOCK_OFFSETS` | `[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]` | - |
|
| `SHARD_BLOCK_OFFSETS` | `List[uint64, 12]([1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233])` | - |
|
||||||
| `MAX_SHARD_BLOCKS_PER_ATTESTATION` | `len(SHARD_BLOCK_OFFSETS)` | - |
|
| `MAX_SHARD_BLOCKS_PER_ATTESTATION` | `len(SHARD_BLOCK_OFFSETS)` | - |
|
||||||
| `BYTES_PER_CUSTODY_CHUNK` | `2**12` (= 4,096) | bytes |
|
| `BYTES_PER_CUSTODY_CHUNK` | `uint64(2**12)` (= 4,096) | bytes |
|
||||||
| `CUSTODY_RESPONSE_DEPTH` | `ceillog2(MAX_SHARD_BLOCK_SIZE // BYTES_PER_CUSTODY_CHUNK)` | - |
|
| `CUSTODY_RESPONSE_DEPTH` | `ceillog2(MAX_SHARD_BLOCK_SIZE // BYTES_PER_CUSTODY_CHUNK)` | - |
|
||||||
|
|
||||||
### Gwei values
|
### Gwei values
|
||||||
|
@ -504,7 +504,7 @@ def compute_committee_source_epoch(epoch: Epoch, period: uint64) -> Epoch:
|
||||||
"""
|
"""
|
||||||
Return the source epoch for computing the committee.
|
Return the source epoch for computing the committee.
|
||||||
"""
|
"""
|
||||||
source_epoch = epoch - epoch % period
|
source_epoch = Epoch(epoch - epoch % period)
|
||||||
if source_epoch >= period:
|
if source_epoch >= period:
|
||||||
source_epoch -= period # `period` epochs lookahead
|
source_epoch -= period # `period` epochs lookahead
|
||||||
return source_epoch
|
return source_epoch
|
||||||
|
@ -575,7 +575,7 @@ def get_light_client_committee(beacon_state: BeaconState, epoch: Epoch) -> Seque
|
||||||
return compute_committee(
|
return compute_committee(
|
||||||
indices=active_validator_indices,
|
indices=active_validator_indices,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
index=0,
|
index=uint64(0),
|
||||||
count=get_active_shard_count(beacon_state),
|
count=get_active_shard_count(beacon_state),
|
||||||
)[:LIGHT_CLIENT_COMMITTEE_SIZE]
|
)[:LIGHT_CLIENT_COMMITTEE_SIZE]
|
||||||
```
|
```
|
||||||
|
@ -601,10 +601,10 @@ def get_committee_count_delta(state: BeaconState, start_slot: Slot, stop_slot: S
|
||||||
"""
|
"""
|
||||||
Return the sum of committee counts in range ``[start_slot, stop_slot)``.
|
Return the sum of committee counts in range ``[start_slot, stop_slot)``.
|
||||||
"""
|
"""
|
||||||
return sum(
|
return uint64(sum(
|
||||||
get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot)))
|
get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot)))
|
||||||
for slot in range(start_slot, stop_slot)
|
for slot in range(start_slot, stop_slot)
|
||||||
)
|
))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_start_shard`
|
#### `get_start_shard`
|
||||||
|
|
|
@ -56,10 +56,10 @@ This document details the beacon chain additions and changes in Phase 1 of Ether
|
||||||
|
|
||||||
| Name | Value | Unit |
|
| Name | Value | Unit |
|
||||||
| - | - | - |
|
| - | - | - |
|
||||||
| `CUSTODY_PRIME` | `2 ** 256 - 189` | - |
|
| `CUSTODY_PRIME` | `int(2 ** 256 - 189)` | - |
|
||||||
| `CUSTODY_SECRETS` | `3` | - |
|
| `CUSTODY_SECRETS` | `uint64(3)` | - |
|
||||||
| `BYTES_PER_CUSTODY_ATOM` | `32` | bytes |
|
| `BYTES_PER_CUSTODY_ATOM` | `uint64(32)` | bytes |
|
||||||
| `CUSTODY_PROBABILITY_EXPONENT` | `10` | - |
|
| `CUSTODY_PROBABILITY_EXPONENT` | `uint64(10)` | - |
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
@ -67,29 +67,29 @@ This document details the beacon chain additions and changes in Phase 1 of Ether
|
||||||
|
|
||||||
| Name | Value | Unit | Duration |
|
| Name | Value | Unit | Duration |
|
||||||
| - | - | :-: | :-: |
|
| - | - | :-: | :-: |
|
||||||
| `RANDAO_PENALTY_EPOCHS` | `2**1` (= 2) | epochs | 12.8 minutes |
|
| `RANDAO_PENALTY_EPOCHS` | `uint64(2**1)` (= 2) | epochs | 12.8 minutes |
|
||||||
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `2**15` (= 32,768) | epochs | ~146 days |
|
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||||
| `EPOCHS_PER_CUSTODY_PERIOD` | `2**14` (= 16,384) | epochs | ~73 days |
|
| `EPOCHS_PER_CUSTODY_PERIOD` | `uint64(2**14)` (= 16,384) | epochs | ~73 days |
|
||||||
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `2**11` (= 2,048) | epochs | ~9 days |
|
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `uint64(2**11)` (= 2,048) | epochs | ~9 days |
|
||||||
| `MAX_CHUNK_CHALLENGE_DELAY` | `2**15` (= 32,768) | epochs | ~146 days |
|
| `MAX_CHUNK_CHALLENGE_DELAY` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||||
|
|
||||||
### Max operations per block
|
### Max operations per block
|
||||||
|
|
||||||
| Name | Value |
|
| Name | Value |
|
||||||
| - | - |
|
| - | - |
|
||||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `2**20` (= 1,048,576) |
|
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `uint64(2**20)` (= 1,048,576) |
|
||||||
| `MAX_CUSTODY_KEY_REVEALS` | `2**8` (= 256) |
|
| `MAX_CUSTODY_KEY_REVEALS` | `uint64(2**8)` (= 256) |
|
||||||
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `2**0` (= 1) |
|
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `uint64(2**0)` (= 1) |
|
||||||
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `2**2` (= 4) |
|
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `uint64(2**2)` (= 4) |
|
||||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `2**4` (= 16) |
|
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `uint64(2**4)` (= 16) |
|
||||||
| `MAX_CUSTODY_SLASHINGS` | `2**0` (= 1) |
|
| `MAX_CUSTODY_SLASHINGS` | `uint64(2**0)` (= 1) |
|
||||||
|
|
||||||
### Reward and penalty quotients
|
### Reward and penalty quotients
|
||||||
|
|
||||||
| Name | Value |
|
| Name | Value |
|
||||||
| - | - |
|
| - | - |
|
||||||
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `2**1` (= 2) |
|
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `uint64(2**1)` (= 2) |
|
||||||
| `MINOR_REWARD_QUOTIENT` | `2**8` (= 256) |
|
| `MINOR_REWARD_QUOTIENT` | `uint64(2**8)` (= 256) |
|
||||||
|
|
||||||
## Data structures
|
## Data structures
|
||||||
|
|
||||||
|
@ -265,12 +265,12 @@ def universal_hash_function(data_chunks: Sequence[bytes], secrets: Sequence[int]
|
||||||
### `compute_custody_bit`
|
### `compute_custody_bit`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def compute_custody_bit(key: BLSSignature, data: ByteList[MAX_SHARD_BLOCK_SIZE]) -> bit:
|
def compute_custody_bit(key: BLSSignature, data: ByteList) -> bit:
|
||||||
custody_atoms = get_custody_atoms(data)
|
custody_atoms = get_custody_atoms(data)
|
||||||
secrets = get_custody_secrets(key)
|
secrets = get_custody_secrets(key)
|
||||||
uhf = universal_hash_function(custody_atoms, secrets)
|
uhf = universal_hash_function(custody_atoms, secrets)
|
||||||
legendre_bits = [legendre_bit(uhf + secrets[0] + i, CUSTODY_PRIME) for i in range(CUSTODY_PROBABILITY_EXPONENT)]
|
legendre_bits = [legendre_bit(uhf + secrets[0] + i, CUSTODY_PRIME) for i in range(CUSTODY_PROBABILITY_EXPONENT)]
|
||||||
return all(legendre_bits)
|
return bit(all(legendre_bits))
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_randao_epoch_for_custody_period`
|
### `get_randao_epoch_for_custody_period`
|
||||||
|
@ -316,7 +316,7 @@ def process_chunk_challenge(state: BeaconState, challenge: CustodyChunkChallenge
|
||||||
# Verify the attestation
|
# Verify the attestation
|
||||||
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, challenge.attestation))
|
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, challenge.attestation))
|
||||||
# Verify it is not too late to challenge the attestation
|
# Verify it is not too late to challenge the attestation
|
||||||
max_attestation_challenge_epoch = challenge.attestation.data.target.epoch + MAX_CHUNK_CHALLENGE_DELAY
|
max_attestation_challenge_epoch = Epoch(challenge.attestation.data.target.epoch + MAX_CHUNK_CHALLENGE_DELAY)
|
||||||
assert get_current_epoch(state) <= max_attestation_challenge_epoch
|
assert get_current_epoch(state) <= max_attestation_challenge_epoch
|
||||||
# Verify it is not too late to challenge the responder
|
# Verify it is not too late to challenge the responder
|
||||||
responder = state.validators[challenge.responder_index]
|
responder = state.validators[challenge.responder_index]
|
||||||
|
@ -438,7 +438,7 @@ def process_early_derived_secret_reveal(state: BeaconState, reveal: EarlyDerived
|
||||||
Note that this function mutates ``state``.
|
Note that this function mutates ``state``.
|
||||||
"""
|
"""
|
||||||
revealed_validator = state.validators[reveal.revealed_index]
|
revealed_validator = state.validators[reveal.revealed_index]
|
||||||
derived_secret_location = reveal.epoch % EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS
|
derived_secret_location = uint64(reveal.epoch % EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS)
|
||||||
|
|
||||||
assert reveal.epoch >= get_current_epoch(state) + RANDAO_PENALTY_EPOCHS
|
assert reveal.epoch >= get_current_epoch(state) + RANDAO_PENALTY_EPOCHS
|
||||||
assert reveal.epoch < get_current_epoch(state) + EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS
|
assert reveal.epoch < get_current_epoch(state) + EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS
|
||||||
|
|
|
@ -281,9 +281,9 @@ def get_shard_transition_fields(
|
||||||
shard: Shard,
|
shard: Shard,
|
||||||
shard_blocks: Sequence[SignedShardBlock],
|
shard_blocks: Sequence[SignedShardBlock],
|
||||||
) -> Tuple[Sequence[uint64], Sequence[Root], Sequence[ShardState]]:
|
) -> Tuple[Sequence[uint64], Sequence[Root], Sequence[ShardState]]:
|
||||||
shard_states = []
|
shard_block_lengths = [] # type: PyList[uint64]
|
||||||
shard_data_roots = []
|
shard_data_roots = [] # type: PyList[Root]
|
||||||
shard_block_lengths = []
|
shard_states = [] # type: PyList[ShardState]
|
||||||
|
|
||||||
shard_state = beacon_state.shard_states[shard]
|
shard_state = beacon_state.shard_states[shard]
|
||||||
shard_block_slots = [shard_block.message.slot for shard_block in shard_blocks]
|
shard_block_slots = [shard_block.message.slot for shard_block in shard_blocks]
|
||||||
|
@ -301,7 +301,7 @@ def get_shard_transition_fields(
|
||||||
shard_state = shard_state.copy()
|
shard_state = shard_state.copy()
|
||||||
process_shard_block(shard_state, shard_block.message)
|
process_shard_block(shard_state, shard_block.message)
|
||||||
shard_states.append(shard_state)
|
shard_states.append(shard_state)
|
||||||
shard_block_lengths.append(len(shard_block.message.body))
|
shard_block_lengths.append(uint64(len(shard_block.message.body)))
|
||||||
|
|
||||||
return shard_block_lengths, shard_data_roots, shard_states
|
return shard_block_lengths, shard_data_roots, shard_states
|
||||||
```
|
```
|
||||||
|
|
|
@ -165,7 +165,7 @@ variable_lengths = [len(part) for part in variable_parts]
|
||||||
assert sum(fixed_lengths + variable_lengths) < 2**(BYTES_PER_LENGTH_OFFSET * BITS_PER_BYTE)
|
assert sum(fixed_lengths + variable_lengths) < 2**(BYTES_PER_LENGTH_OFFSET * BITS_PER_BYTE)
|
||||||
|
|
||||||
# Interleave offsets of variable-size parts with fixed-size parts
|
# Interleave offsets of variable-size parts with fixed-size parts
|
||||||
variable_offsets = [serialize(sum(fixed_lengths + variable_lengths[:i])) for i in range(len(value))]
|
variable_offsets = [serialize(uint32(sum(fixed_lengths + variable_lengths[:i]))) for i in range(len(value))]
|
||||||
fixed_parts = [part if part != None else variable_offsets[i] for i, part in enumerate(fixed_parts)]
|
fixed_parts = [part if part != None else variable_offsets[i] for i, part in enumerate(fixed_parts)]
|
||||||
|
|
||||||
# Return the concatenation of the fixed-size parts (offsets interleaved) with the variable-size parts
|
# Return the concatenation of the fixed-size parts (offsets interleaved) with the variable-size parts
|
||||||
|
|
Loading…
Reference in New Issue