mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-20 22:38:11 +00:00
Merge branch 'dev' into testgenphase1
This commit is contained in:
commit
5374890da0
@ -1,6 +1,6 @@
|
||||
# Ethereum 2.0 Specifications
|
||||
|
||||
[](https://discord.gg/hpFs23p) [](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://discord.gg/qGpsxSA) [](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
To learn more about sharding and Ethereum 2.0 (Serenity), see the [sharding FAQ](https://eth.wiki/sharding/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/s/H1PGqDhpm).
|
||||
|
||||
|
@ -102,8 +102,6 @@ SLOTS_PER_HISTORICAL_ROOT: 8192
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||
# 2**8 (= 256) epochs ~27 hours
|
||||
SHARD_COMMITTEE_PERIOD: 256
|
||||
# 2**6 (= 64) epochs ~7 hours
|
||||
MAX_EPOCHS_PER_CROSSLINK: 64
|
||||
# 2**2 (= 4) epochs 25.6 minutes
|
||||
MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
|
||||
|
||||
|
@ -101,8 +101,6 @@ SLOTS_PER_HISTORICAL_ROOT: 64
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||
# [customized] higher frequency of committee turnover and faster time to acceptable voluntary exit
|
||||
SHARD_COMMITTEE_PERIOD: 64
|
||||
# [customized] fast catchup crosslinks
|
||||
MAX_EPOCHS_PER_CROSSLINK: 4
|
||||
# 2**2 (= 4) epochs
|
||||
MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
|
||||
|
||||
|
1
setup.py
1
setup.py
@ -127,6 +127,7 @@ from eth2spec.config.config_util import apply_constants_config
|
||||
from typing import (
|
||||
Any, Dict, Set, Sequence, NewType, Tuple, TypeVar, Callable, Optional
|
||||
)
|
||||
from typing import List as PyList
|
||||
|
||||
from dataclasses import (
|
||||
dataclass,
|
||||
|
@ -11,6 +11,24 @@ See this [blog post](https://blog.ethereum.org/2020/06/23/eth2-quick-update-no-1
|
||||
|
||||
In August 2020, version `r2` was released with metadata modifications and relicensed to CC0-1.0. Afterward, this contract has been ported back to from [`axic/eth2-deposit-contract`](https://github.com/axic/eth2-deposit-contract) to this repository and replaced the Vyper deposit contract.
|
||||
|
||||
## Compiling solidity deposit contract
|
||||
|
||||
In the `eth2.0-specs` directory run:
|
||||
```sh
|
||||
make compile_deposit_contract
|
||||
```
|
||||
|
||||
The following parameters were used to generate the bytecode for the `DepositContract` available in this repository:
|
||||
|
||||
* Contract Name: `DepositContract`
|
||||
* Compiler Version: Solidity `v0.6.11+commit.5ef660b1`
|
||||
* Optimization Enabled: `Yes` with `5000000` runs
|
||||
* Metadata Options: `--metadata-literal` (to verify metadata hash)
|
||||
|
||||
```sh
|
||||
solc --optimize --optimize-runs 5000000 --metadata-literal --bin deposit_contract.sol
|
||||
```
|
||||
|
||||
## Running web3 tests
|
||||
|
||||
1. In the `eth2.0-specs` directory run `make install_deposit_contract_web3_tester` to install the tools needed (make sure to have Python 3.7 and pip installed).
|
||||
|
@ -603,7 +603,7 @@ def bytes_to_uint64(data: bytes) -> uint64:
|
||||
|
||||
#### BLS Signatures
|
||||
|
||||
Eth2 makes use of BLS signatures as specified in the [IETF draft BLS specification draft-irtf-cfrg-bls-signature-02](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02) but uses [Hashing to Elliptic Curves - draft-irtf-cfrg-hash-to-curve-07](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07) instead of draft-irtf-cfrg-hash-to-curve-06. Specifically, eth2 uses the `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` ciphersuite which implements the following interfaces:
|
||||
Eth2 makes use of BLS signatures as specified in the [IETF draft BLS specification draft-irtf-cfrg-bls-signature-03](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03). Specifically, eth2 uses the `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` ciphersuite which implements the following interfaces:
|
||||
|
||||
- `def Sign(SK: int, message: Bytes) -> BLSSignature`
|
||||
- `def Verify(PK: BLSPubkey, message: Bytes, signature: BLSSignature) -> bool`
|
||||
@ -613,8 +613,6 @@ Eth2 makes use of BLS signatures as specified in the [IETF draft BLS specificati
|
||||
|
||||
Within these specifications, BLS signatures are treated as a module for notational clarity, thus to verify a signature `bls.Verify(...)` is used.
|
||||
|
||||
*Note*: The non-standard configuration of the BLS and hash to curve specs is temporary and will be resolved once IETF releases BLS spec draft 3.
|
||||
|
||||
### Predicates
|
||||
|
||||
#### `is_active_validator`
|
||||
@ -774,7 +772,7 @@ def compute_committee(indices: Sequence[ValidatorIndex],
|
||||
Return the committee corresponding to ``indices``, ``seed``, ``index``, and committee ``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)]
|
||||
```
|
||||
|
||||
@ -1455,7 +1453,7 @@ def get_inclusion_delay_deltas(state: BeaconState) -> Tuple[Sequence[Gwei], Sequ
|
||||
if index in get_attesting_indices(state, a.data, a.aggregation_bits)
|
||||
], key=lambda a: a.inclusion_delay)
|
||||
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)
|
||||
|
||||
# No penalties associated with inclusion delay
|
||||
@ -1576,7 +1574,7 @@ def process_final_updates(state: BeaconState) -> None:
|
||||
# Update effective balances with hysteresis
|
||||
for index, validator in enumerate(state.validators):
|
||||
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
|
||||
UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER
|
||||
if (
|
||||
|
@ -98,14 +98,10 @@ This should be the genesis state for a full client.
|
||||
|
||||
*Note* With regards to fork choice, block headers are interchangeable with blocks. The spec is likely to move to headers for reduced overhead in test vectors and better encapsulation. Full implementations store blocks as part of their database and will often use full blocks when dealing with production fork choice.
|
||||
|
||||
_The block for `anchor_root` is incorrectly initialized to the block header, rather than the full block. This does not affect functionality but will be cleaned up in subsequent releases._
|
||||
|
||||
```python
|
||||
def get_forkchoice_store(anchor_state: BeaconState) -> Store:
|
||||
anchor_block_header = copy(anchor_state.latest_block_header)
|
||||
if anchor_block_header.state_root == Bytes32():
|
||||
anchor_block_header.state_root = hash_tree_root(anchor_state)
|
||||
anchor_root = hash_tree_root(anchor_block_header)
|
||||
def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -> Store:
|
||||
assert anchor_block.state_root == hash_tree_root(anchor_state)
|
||||
anchor_root = hash_tree_root(anchor_block)
|
||||
anchor_epoch = get_current_epoch(anchor_state)
|
||||
justified_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
|
||||
finalized_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
|
||||
@ -115,7 +111,7 @@ def get_forkchoice_store(anchor_state: BeaconState) -> Store:
|
||||
justified_checkpoint=justified_checkpoint,
|
||||
finalized_checkpoint=finalized_checkpoint,
|
||||
best_justified_checkpoint=justified_checkpoint,
|
||||
blocks={anchor_root: anchor_block_header},
|
||||
blocks={anchor_root: copy(anchor_block)},
|
||||
block_states={anchor_root: copy(anchor_state)},
|
||||
checkpoint_states={justified_checkpoint: copy(anchor_state)},
|
||||
)
|
||||
|
@ -243,12 +243,11 @@ Each gossipsub [message](https://github.com/libp2p/go-libp2p-pubsub/blob/master/
|
||||
Clients MUST reject (fail validation) messages that are over this size limit.
|
||||
Likewise, clients MUST NOT emit or propagate messages larger than this limit.
|
||||
|
||||
The `message-id` of a gossipsub message MUST be:
|
||||
The `message-id` of a gossipsub message MUST be the first 8 bytes of the SHA-256 hash of the message data, i.e.:
|
||||
|
||||
```python
|
||||
message-id: base64(SHA256(message.data))
|
||||
message-id: SHA256(message.data)[0:8]
|
||||
```
|
||||
where `base64` is the [URL-safe base64 alphabet](https://tools.ietf.org/html/rfc4648#section-3.2) with padding characters omitted.
|
||||
|
||||
The payload is carried in the `data` field of a gossipsub message, and varies depending on the topic:
|
||||
|
||||
@ -383,6 +382,7 @@ The `beacon_attestation_{subnet_id}` topics are used to propagate unaggregated a
|
||||
to the subnet `subnet_id` (typically beacon and persistent committees) to be aggregated before being gossiped to `beacon_aggregate_and_proof`.
|
||||
|
||||
The following validations MUST pass before forwarding the `attestation` on the subnet.
|
||||
- _[REJECT]_ The committee index is within the expected range -- i.e. `data.index < get_committee_count_per_slot(state, data.target.epoch)`.
|
||||
- _[REJECT]_ The attestation is for the correct subnet --
|
||||
i.e. `compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.index) == subnet_id`,
|
||||
where `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)`,
|
||||
@ -395,6 +395,8 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||
compute_epoch_at_slot(attestation.data.slot)`
|
||||
- _[REJECT]_ The attestation is unaggregated --
|
||||
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.
|
||||
`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
|
||||
that has an identical `attestation.data.target.epoch` and participating validator index.
|
||||
- _[REJECT]_ The signature of `attestation` is valid.
|
||||
@ -410,7 +412,6 @@ The following validations MUST pass before forwarding the `attestation` on the s
|
||||
|
||||
|
||||
|
||||
|
||||
#### Attestations and Aggregation
|
||||
|
||||
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
|
||||
Return None if no assignment.
|
||||
"""
|
||||
next_epoch = get_current_epoch(state) + 1
|
||||
next_epoch = Epoch(get_current_epoch(state) + 1)
|
||||
assert epoch <= next_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.
|
||||
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
|
||||
|
||||
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 |
|
||||
| - | - |
|
||||
| `MAX_SHARDS` | `2**10` (= 1024) |
|
||||
| `INITIAL_ACTIVE_SHARDS` | `2**6` (= 64) |
|
||||
| `LIGHT_CLIENT_COMMITTEE_SIZE` | `2**7` (= 128) |
|
||||
| `GASPRICE_ADJUSTMENT_COEFFICIENT` | `2**3` (= 8) |
|
||||
| `MAX_SHARDS` | `uint64(2**10)` (= 1024) |
|
||||
| `INITIAL_ACTIVE_SHARDS` | `uint64(2**6)` (= 64) |
|
||||
| `LIGHT_CLIENT_COMMITTEE_SIZE` | `uint64(2**7)` (= 128) |
|
||||
| `GASPRICE_ADJUSTMENT_COEFFICIENT` | `uint64(2**3)` (= 8) |
|
||||
|
||||
### Shard block configs
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | - |
|
||||
| `MAX_SHARD_BLOCK_SIZE` | `2**20` (= 1,048,576) | bytes |
|
||||
| `TARGET_SHARD_BLOCK_SIZE` | `2**18` (= 262,144) | bytes |
|
||||
| `SHARD_BLOCK_OFFSETS` | `[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]` | - |
|
||||
| `MAX_SHARD_BLOCK_SIZE` | `uint64(2**20)` (= 1,048,576) | bytes |
|
||||
| `TARGET_SHARD_BLOCK_SIZE` | `uint64(2**18)` (= 262,144) | bytes |
|
||||
| `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)` | - |
|
||||
| `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)` | - |
|
||||
|
||||
### Gwei values
|
||||
@ -504,7 +504,7 @@ def compute_committee_source_epoch(epoch: Epoch, period: uint64) -> Epoch:
|
||||
"""
|
||||
Return the source epoch for computing the committee.
|
||||
"""
|
||||
source_epoch = epoch - epoch % period
|
||||
source_epoch = Epoch(epoch - epoch % period)
|
||||
if source_epoch >= period:
|
||||
source_epoch -= period # `period` epochs lookahead
|
||||
return source_epoch
|
||||
@ -575,7 +575,7 @@ def get_light_client_committee(beacon_state: BeaconState, epoch: Epoch) -> Seque
|
||||
return compute_committee(
|
||||
indices=active_validator_indices,
|
||||
seed=seed,
|
||||
index=0,
|
||||
index=uint64(0),
|
||||
count=get_active_shard_count(beacon_state),
|
||||
)[: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 sum(
|
||||
return uint64(sum(
|
||||
get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot)))
|
||||
for slot in range(start_slot, stop_slot)
|
||||
)
|
||||
))
|
||||
```
|
||||
|
||||
#### `get_start_shard`
|
||||
|
@ -56,10 +56,10 @@ This document details the beacon chain additions and changes in Phase 1 of Ether
|
||||
|
||||
| Name | Value | Unit |
|
||||
| - | - | - |
|
||||
| `CUSTODY_PRIME` | `2 ** 256 - 189` | - |
|
||||
| `CUSTODY_SECRETS` | `3` | - |
|
||||
| `BYTES_PER_CUSTODY_ATOM` | `32` | bytes |
|
||||
| `CUSTODY_PROBABILITY_EXPONENT` | `10` | - |
|
||||
| `CUSTODY_PRIME` | `int(2 ** 256 - 189)` | - |
|
||||
| `CUSTODY_SECRETS` | `uint64(3)` | - |
|
||||
| `BYTES_PER_CUSTODY_ATOM` | `uint64(32)` | bytes |
|
||||
| `CUSTODY_PROBABILITY_EXPONENT` | `uint64(10)` | - |
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -67,29 +67,29 @@ This document details the beacon chain additions and changes in Phase 1 of Ether
|
||||
|
||||
| Name | Value | Unit | Duration |
|
||||
| - | - | :-: | :-: |
|
||||
| `RANDAO_PENALTY_EPOCHS` | `2**1` (= 2) | epochs | 12.8 minutes |
|
||||
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `2**15` (= 32,768) | epochs | ~146 days |
|
||||
| `EPOCHS_PER_CUSTODY_PERIOD` | `2**14` (= 16,384) | epochs | ~73 days |
|
||||
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `2**11` (= 2,048) | epochs | ~9 days |
|
||||
| `MAX_CHUNK_CHALLENGE_DELAY` | `2**15` (= 32,768) | epochs | ~146 days |
|
||||
| `RANDAO_PENALTY_EPOCHS` | `uint64(2**1)` (= 2) | epochs | 12.8 minutes |
|
||||
| `EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
| `EPOCHS_PER_CUSTODY_PERIOD` | `uint64(2**14)` (= 16,384) | epochs | ~73 days |
|
||||
| `CUSTODY_PERIOD_TO_RANDAO_PADDING` | `uint64(2**11)` (= 2,048) | epochs | ~9 days |
|
||||
| `MAX_CHUNK_CHALLENGE_DELAY` | `uint64(2**15)` (= 32,768) | epochs | ~146 days |
|
||||
|
||||
### Max operations per block
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `2**20` (= 1,048,576) |
|
||||
| `MAX_CUSTODY_KEY_REVEALS` | `2**8` (= 256) |
|
||||
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `2**0` (= 1) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `2**2` (= 4) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `2**4` (= 16) |
|
||||
| `MAX_CUSTODY_SLASHINGS` | `2**0` (= 1) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RECORDS` | `uint64(2**20)` (= 1,048,576) |
|
||||
| `MAX_CUSTODY_KEY_REVEALS` | `uint64(2**8)` (= 256) |
|
||||
| `MAX_EARLY_DERIVED_SECRET_REVEALS` | `uint64(2**0)` (= 1) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGES` | `uint64(2**2)` (= 4) |
|
||||
| `MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES` | `uint64(2**4)` (= 16) |
|
||||
| `MAX_CUSTODY_SLASHINGS` | `uint64(2**0)` (= 1) |
|
||||
|
||||
### Reward and penalty quotients
|
||||
|
||||
| Name | Value |
|
||||
| - | - |
|
||||
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `2**1` (= 2) |
|
||||
| `MINOR_REWARD_QUOTIENT` | `2**8` (= 256) |
|
||||
| `EARLY_DERIVED_SECRET_REVEAL_SLOT_REWARD_MULTIPLE` | `uint64(2**1)` (= 2) |
|
||||
| `MINOR_REWARD_QUOTIENT` | `uint64(2**8)` (= 256) |
|
||||
|
||||
## Data structures
|
||||
|
||||
@ -265,12 +265,12 @@ def universal_hash_function(data_chunks: Sequence[bytes], secrets: Sequence[int]
|
||||
### `compute_custody_bit`
|
||||
|
||||
```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)
|
||||
secrets = get_custody_secrets(key)
|
||||
uhf = universal_hash_function(custody_atoms, secrets)
|
||||
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`
|
||||
@ -316,7 +316,7 @@ def process_chunk_challenge(state: BeaconState, challenge: CustodyChunkChallenge
|
||||
# Verify the attestation
|
||||
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, challenge.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
|
||||
# Verify it is not too late to challenge the responder
|
||||
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``.
|
||||
"""
|
||||
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) + EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS
|
||||
|
@ -71,11 +71,9 @@ class ShardStore:
|
||||
#### Updated `get_forkchoice_store`
|
||||
|
||||
```python
|
||||
def get_forkchoice_store(anchor_state: BeaconState) -> Store:
|
||||
anchor_block_header = anchor_state.latest_block_header.copy()
|
||||
if anchor_block_header.state_root == Bytes32():
|
||||
anchor_block_header.state_root = hash_tree_root(anchor_state)
|
||||
anchor_root = hash_tree_root(anchor_block_header)
|
||||
def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -> Store:
|
||||
assert anchor_block.state_root == hash_tree_root(anchor_state)
|
||||
anchor_root = hash_tree_root(anchor_block)
|
||||
anchor_epoch = get_current_epoch(anchor_state)
|
||||
justified_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
|
||||
finalized_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
|
||||
@ -85,7 +83,7 @@ def get_forkchoice_store(anchor_state: BeaconState) -> Store:
|
||||
justified_checkpoint=justified_checkpoint,
|
||||
finalized_checkpoint=finalized_checkpoint,
|
||||
best_justified_checkpoint=justified_checkpoint,
|
||||
blocks={anchor_root: anchor_block_header},
|
||||
blocks={anchor_root: copy(anchor_block)},
|
||||
block_states={anchor_root: anchor_state.copy()},
|
||||
checkpoint_states={justified_checkpoint: anchor_state.copy()},
|
||||
shard_stores={
|
||||
|
@ -281,9 +281,9 @@ def get_shard_transition_fields(
|
||||
shard: Shard,
|
||||
shard_blocks: Sequence[SignedShardBlock],
|
||||
) -> Tuple[Sequence[uint64], Sequence[Root], Sequence[ShardState]]:
|
||||
shard_states = []
|
||||
shard_data_roots = []
|
||||
shard_block_lengths = []
|
||||
shard_block_lengths = [] # type: PyList[uint64]
|
||||
shard_data_roots = [] # type: PyList[Root]
|
||||
shard_states = [] # type: PyList[ShardState]
|
||||
|
||||
shard_state = beacon_state.shard_states[shard]
|
||||
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()
|
||||
process_shard_block(shard_state, shard_block.message)
|
||||
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
|
||||
```
|
||||
|
@ -1,3 +1,6 @@
|
||||
from eth2spec.phase0 import spec as phase0_spec
|
||||
|
||||
|
||||
def get_anchor_root(spec, state):
|
||||
anchor_block_header = state.latest_block_header.copy()
|
||||
if anchor_block_header.state_root == spec.Bytes32():
|
||||
@ -25,3 +28,10 @@ def add_attestation_to_store(spec, store, attestation):
|
||||
spec.on_tick(store, next_epoch_time)
|
||||
|
||||
spec.on_attestation(store, attestation)
|
||||
|
||||
|
||||
def get_genesis_forkchoice_store(spec, genesis_state):
|
||||
assert genesis_state.slot == spec.GENESIS_SLOT
|
||||
# The genesis block must be a Phase 0 `BeaconBlock`
|
||||
genesis_block = phase0_spec.BeaconBlock(state_root=genesis_state.hash_tree_root())
|
||||
return spec.get_forkchoice_store(genesis_state, genesis_block)
|
||||
|
@ -79,6 +79,20 @@ def test_invalid_sig_1_and_2(spec, state):
|
||||
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_invalid_sig_1_and_2_swap(spec, state):
|
||||
# Get valid signatures for the slashings
|
||||
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
|
||||
|
||||
# But swap them
|
||||
signature_1 = proposer_slashing.signed_header_1.signature
|
||||
proposer_slashing.signed_header_1.signature = proposer_slashing.signed_header_2.signature
|
||||
proposer_slashing.signed_header_2.signature = signature_1
|
||||
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_invalid_proposer_index(spec, state):
|
||||
@ -122,11 +136,26 @@ def test_epochs_are_different(spec, state):
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_headers_are_same(spec, state):
|
||||
def test_headers_are_same_sigs_are_same(spec, state):
|
||||
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
|
||||
|
||||
# set headers to be the same
|
||||
proposer_slashing.signed_header_2 = proposer_slashing.signed_header_1
|
||||
proposer_slashing.signed_header_2 = proposer_slashing.signed_header_1.copy()
|
||||
|
||||
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_headers_are_same_sigs_are_different(spec, state):
|
||||
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=False)
|
||||
|
||||
# set headers to be the same
|
||||
proposer_slashing.signed_header_2 = proposer_slashing.signed_header_1.copy()
|
||||
# but signatures to be different
|
||||
proposer_slashing.signed_header_2.signature = proposer_slashing.signed_header_2.signature[:-1] + b'\x00'
|
||||
|
||||
assert proposer_slashing.signed_header_1.signature != proposer_slashing.signed_header_2.signature
|
||||
|
||||
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
from eth2spec.test.context import with_all_phases, spec_state_test
|
||||
from eth2spec.test.helpers.attestations import get_valid_attestation, next_epoch_with_attestations
|
||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot
|
||||
from eth2spec.test.helpers.fork_choice import add_attestation_to_store, add_block_to_store, get_anchor_root
|
||||
from eth2spec.test.helpers.fork_choice import (
|
||||
add_attestation_to_store,
|
||||
add_block_to_store, get_anchor_root,
|
||||
get_genesis_forkchoice_store,
|
||||
)
|
||||
from eth2spec.test.helpers.state import (
|
||||
next_epoch,
|
||||
state_transition_and_sign_block,
|
||||
@ -12,7 +16,7 @@ from eth2spec.test.helpers.state import (
|
||||
@spec_state_test
|
||||
def test_genesis(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
assert spec.get_head(store) == anchor_root
|
||||
|
||||
@ -21,7 +25,7 @@ def test_genesis(spec, state):
|
||||
@spec_state_test
|
||||
def test_chain_no_attestations(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
assert spec.get_head(store) == anchor_root
|
||||
|
||||
@ -44,7 +48,7 @@ def test_split_tie_breaker_no_attestations(spec, state):
|
||||
genesis_state = state.copy()
|
||||
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
assert spec.get_head(store) == anchor_root
|
||||
|
||||
@ -72,13 +76,13 @@ def test_shorter_chain_but_heavier_weight(spec, state):
|
||||
genesis_state = state.copy()
|
||||
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
assert spec.get_head(store) == anchor_root
|
||||
|
||||
# build longer tree
|
||||
long_state = genesis_state.copy()
|
||||
for i in range(3):
|
||||
for _ in range(3):
|
||||
long_block = build_empty_block_for_next_slot(spec, long_state)
|
||||
signed_long_block = state_transition_and_sign_block(spec, long_state, long_block)
|
||||
add_block_to_store(spec, store, signed_long_block)
|
||||
@ -100,7 +104,7 @@ def test_shorter_chain_but_heavier_weight(spec, state):
|
||||
@spec_state_test
|
||||
def test_filtered_block_tree(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
|
||||
# transition state past initial couple of epochs
|
||||
|
@ -2,6 +2,7 @@ from eth2spec.test.context import PHASE0, with_all_phases, spec_state_test
|
||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot
|
||||
from eth2spec.test.helpers.attestations import get_valid_attestation, sign_attestation
|
||||
from eth2spec.test.helpers.state import transition_to, state_transition_and_sign_block, next_epoch, next_slot
|
||||
from eth2spec.test.helpers.fork_choice import get_genesis_forkchoice_store
|
||||
|
||||
|
||||
def run_on_attestation(spec, state, store, attestation, valid=True):
|
||||
@ -41,7 +42,7 @@ def run_on_attestation(spec, state, store, attestation, valid=True):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_current_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
spec.on_tick(store, store.time + spec.SECONDS_PER_SLOT * 2)
|
||||
|
||||
block = build_empty_block_for_next_slot(spec, state)
|
||||
@ -60,7 +61,7 @@ def test_on_attestation_current_epoch(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_previous_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
spec.on_tick(store, store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH)
|
||||
|
||||
block = build_empty_block_for_next_slot(spec, state)
|
||||
@ -79,7 +80,7 @@ def test_on_attestation_previous_epoch(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_past_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
|
||||
# move time forward 2 epochs
|
||||
time = store.time + 2 * spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||
@ -101,7 +102,7 @@ def test_on_attestation_past_epoch(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_mismatched_target_and_slot(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
spec.on_tick(store, store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH)
|
||||
|
||||
block = build_empty_block_for_next_slot(spec, state)
|
||||
@ -124,7 +125,7 @@ def test_on_attestation_mismatched_target_and_slot(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_inconsistent_target_and_head(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
spec.on_tick(store, store.time + 2 * spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH)
|
||||
|
||||
# Create chain 1 as empty chain between genesis and start of 1st epoch
|
||||
@ -162,7 +163,7 @@ def test_on_attestation_inconsistent_target_and_head(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_target_block_not_in_store(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1)
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -184,7 +185,7 @@ def test_on_attestation_target_block_not_in_store(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_target_checkpoint_not_in_store(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1)
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -209,7 +210,7 @@ def test_on_attestation_target_checkpoint_not_in_store(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_target_checkpoint_not_in_store_diff_slot(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1)
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -236,7 +237,7 @@ def test_on_attestation_target_checkpoint_not_in_store_diff_slot(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_beacon_block_not_in_store(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1)
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -265,7 +266,7 @@ def test_on_attestation_beacon_block_not_in_store(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_future_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + 3 * spec.SECONDS_PER_SLOT
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -285,7 +286,7 @@ def test_on_attestation_future_epoch(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_future_block(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT * 5
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -305,7 +306,7 @@ def test_on_attestation_future_block(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_same_slot(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + spec.SECONDS_PER_SLOT
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -321,7 +322,7 @@ def test_on_attestation_same_slot(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_on_attestation_invalid_attestation(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = store.time + 3 * spec.SECONDS_PER_SLOT
|
||||
spec.on_tick(store, time)
|
||||
|
||||
|
@ -2,10 +2,11 @@ from copy import deepcopy
|
||||
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
||||
|
||||
from eth2spec.test.context import with_all_phases, spec_state_test
|
||||
from eth2spec.test.helpers.attestations import next_epoch_with_attestations
|
||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block, transition_unsigned_block, \
|
||||
build_empty_block
|
||||
from eth2spec.test.helpers.attestations import next_epoch_with_attestations
|
||||
from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block
|
||||
from eth2spec.test.helpers.fork_choice import get_genesis_forkchoice_store
|
||||
from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block, transition_to
|
||||
|
||||
|
||||
def run_on_block(spec, store, signed_block, valid=True):
|
||||
@ -37,7 +38,7 @@ def apply_next_epoch_with_attestations(spec, state, store):
|
||||
@spec_state_test
|
||||
def test_basic(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
assert store.time == time
|
||||
@ -61,7 +62,7 @@ def test_basic(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_checkpoints(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -87,7 +88,7 @@ def test_on_block_checkpoints(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_future_block(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
|
||||
# do not tick time
|
||||
|
||||
@ -101,7 +102,7 @@ def test_on_block_future_block(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_bad_parent_root(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -121,7 +122,7 @@ def test_on_block_bad_parent_root(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_before_finalized(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -140,7 +141,7 @@ def test_on_block_before_finalized(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_finalized_skip_slots(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -160,16 +161,18 @@ def test_on_block_finalized_skip_slots(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_finalized_skip_slots_not_in_skip_chain(spec, state):
|
||||
# Initialization
|
||||
next_epoch(spec, state)
|
||||
store = spec.get_forkchoice_store(state)
|
||||
|
||||
transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH - 1)
|
||||
block = build_empty_block_for_next_slot(spec, state)
|
||||
transition_unsigned_block(spec, state, block)
|
||||
block.state_root = state.hash_tree_root()
|
||||
store = spec.get_forkchoice_store(state, block)
|
||||
store.finalized_checkpoint = spec.Checkpoint(
|
||||
epoch=store.finalized_checkpoint.epoch + 2,
|
||||
root=store.finalized_checkpoint.root
|
||||
)
|
||||
|
||||
# First transition through the epoch to ensure no skipped slots
|
||||
state, store, last_signed_block = apply_next_epoch_with_attestations(spec, state, store)
|
||||
state, store, _ = apply_next_epoch_with_attestations(spec, state, store)
|
||||
|
||||
# Now build a block at later slot than finalized epoch
|
||||
# Includes finalized block in chain, but not at appropriate skip slot
|
||||
@ -183,7 +186,7 @@ def test_on_block_finalized_skip_slots_not_in_skip_chain(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_update_justified_checkpoint_within_safe_slots(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 0
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -214,7 +217,7 @@ def test_on_block_update_justified_checkpoint_within_safe_slots(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_outside_safe_slots_and_multiple_better_justified(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 0
|
||||
spec.on_tick(store, time)
|
||||
|
||||
@ -264,7 +267,7 @@ def test_on_block_outside_safe_slots_and_multiple_better_justified(spec, state):
|
||||
@spec_state_test
|
||||
def test_on_block_outside_safe_slots_but_finality(spec, state):
|
||||
# Initialization
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
time = 100
|
||||
spec.on_tick(store, time)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
from eth2spec.test.context import with_all_phases, spec_state_test
|
||||
from eth2spec.test.helpers.fork_choice import get_genesis_forkchoice_store
|
||||
|
||||
|
||||
def run_on_tick(spec, store, time, new_justified_checkpoint=False):
|
||||
@ -19,14 +20,14 @@ def run_on_tick(spec, store, time, new_justified_checkpoint=False):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_basic(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
run_on_tick(spec, store, store.time + 1)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_update_justified_single(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
next_epoch = spec.get_current_epoch(state) + 1
|
||||
next_epoch_start_slot = spec.compute_start_slot_at_epoch(next_epoch)
|
||||
seconds_until_next_epoch = next_epoch_start_slot * spec.SECONDS_PER_SLOT - store.time
|
||||
@ -42,7 +43,7 @@ def test_update_justified_single(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_update_same_slot_at_epoch_boundary(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
seconds_per_epoch = spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||
|
||||
store.best_justified_checkpoint = spec.Checkpoint(
|
||||
@ -59,7 +60,7 @@ def test_no_update_same_slot_at_epoch_boundary(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_update_not_epoch_boundary(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
|
||||
store.best_justified_checkpoint = spec.Checkpoint(
|
||||
epoch=store.justified_checkpoint.epoch + 1,
|
||||
@ -72,7 +73,7 @@ def test_no_update_not_epoch_boundary(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_update_new_justified_equal_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
seconds_per_epoch = spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||
|
||||
store.best_justified_checkpoint = spec.Checkpoint(
|
||||
@ -91,7 +92,7 @@ def test_no_update_new_justified_equal_epoch(spec, state):
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_update_new_justified_later_epoch(spec, state):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
seconds_per_epoch = spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||
|
||||
store.best_justified_checkpoint = spec.Checkpoint(
|
||||
|
@ -7,7 +7,7 @@ from eth2spec.test.helpers.shard_block import (
|
||||
get_shard_transitions,
|
||||
get_committee_index_of_shard,
|
||||
)
|
||||
from eth2spec.test.helpers.fork_choice import add_block_to_store, get_anchor_root
|
||||
from eth2spec.test.helpers.fork_choice import add_block_to_store, get_anchor_root, get_genesis_forkchoice_store
|
||||
from eth2spec.test.helpers.state import state_transition_and_sign_block
|
||||
from eth2spec.test.helpers.block import build_empty_block
|
||||
|
||||
@ -28,7 +28,7 @@ def run_on_shard_block(spec, store, signed_block, valid=True):
|
||||
|
||||
|
||||
def initialize_store(spec, state, shards):
|
||||
store = spec.get_forkchoice_store(state)
|
||||
store = get_genesis_forkchoice_store(spec, state)
|
||||
anchor_root = get_anchor_root(spec, state)
|
||||
assert spec.get_head(store) == anchor_root
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user