Skip to content

Commit

Permalink
get head tests
Browse files Browse the repository at this point in the history
  • Loading branch information
djrtwo committed Jun 25, 2019
1 parent 846ca64 commit 228195d
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 4 deletions.
9 changes: 5 additions & 4 deletions specs/core/0_fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def get_genesis_store(genesis_state: BeaconState) -> Store:
justified_checkpoint=justified_checkpoint,
finalized_checkpoint=finalized_checkpoint,
blocks={root: genesis_block},
block_states={root: genesis_state},
block_states={root: genesis_state.copy()},
checkpoint_states={justified_checkpoint: genesis_state.copy()},
)
```
Expand All @@ -110,10 +110,11 @@ def get_ancestor(store: Store, root: Hash, slot: Slot) -> Hash:
```python
def get_latest_attesting_balance(store: Store, root: Hash) -> Gwei:
state = store.checkpoint_states[store.justified_checkpoint]
active_indices = get_active_validator_indices(state.validator_registry, get_current_epoch(state))
active_indices = get_active_validator_indices(state, get_current_epoch(state))
return Gwei(sum(
state.validator_registry[i].effective_balance for i in active_indices
if get_ancestor(store, store.latest_targets[i].root, store.blocks[root].slot) == root
state.validators[i].effective_balance for i in active_indices
if (i in store.latest_targets and
get_ancestor(store, store.latest_targets[i].root, store.blocks[root].slot) == root)
))
```

Expand Down
118 changes: 118 additions & 0 deletions test_libs/pyspec/eth2spec/test/fork_choice/test_get_head.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from eth2spec.test.context import with_all_phases, with_state, bls_switch
from eth2spec.test.helpers.attestations import get_valid_attestation
from eth2spec.test.helpers.block import build_empty_block_for_next_slot
from eth2spec.test.helpers.state import state_transition_and_sign_block


def add_block_to_store(spec, store, block):
pre_state = store.block_states[block.parent_root]
block_time = pre_state.genesis_time + block.slot * spec.SECONDS_PER_SLOT

if store.time < block_time:
spec.on_tick(store, block_time)

spec.on_block(store, block)


def add_attestation_to_store(spec, store, attestation):
parent_block = store.blocks[attestation.data.beacon_block_root]
pre_state = store.block_states[spec.signing_root(parent_block)]
block_time = pre_state.genesis_time + parent_block.slot * spec.SECONDS_PER_SLOT
next_epoch_time = block_time + spec.SLOTS_PER_EPOCH * spec.SECONDS_PER_SLOT

if store.time < next_epoch_time:
spec.on_tick(store, next_epoch_time)

spec.on_attestation(store, attestation)


@with_all_phases
@with_state
@bls_switch
def test_genesis(spec, state):
# Initialization
store = spec.get_genesis_store(state)
genesis_block = spec.BeaconBlock(state_root=state.hash_tree_root())
assert spec.get_head(store) == spec.signing_root(genesis_block)


@with_all_phases
@with_state
@bls_switch
def test_chain_no_attestations(spec, state):
# Initialization
store = spec.get_genesis_store(state)
genesis_block = spec.BeaconBlock(state_root=state.hash_tree_root())
assert spec.get_head(store) == spec.signing_root(genesis_block)

# On receiving a block of `GENESIS_SLOT + 1` slot
block_1 = build_empty_block_for_next_slot(spec, state)
state_transition_and_sign_block(spec, state, block_1)
add_block_to_store(spec, store, block_1)

# On receiving a block of next epoch
block_2 = build_empty_block_for_next_slot(spec, state)
state_transition_and_sign_block(spec, state, block_2)
add_block_to_store(spec, store, block_2)

assert spec.get_head(store) == spec.signing_root(block_2)


@with_all_phases
@with_state
@bls_switch
def test_split_tie_breaker_no_attestations(spec, state):
genesis_state = state.copy()

# Initialization
store = spec.get_genesis_store(state)
genesis_block = spec.BeaconBlock(state_root=state.hash_tree_root())
assert spec.get_head(store) == spec.signing_root(genesis_block)

# block at slot 1
block_1_state = genesis_state.copy()
block_1 = build_empty_block_for_next_slot(spec, block_1_state)
state_transition_and_sign_block(spec, block_1_state, block_1)
add_block_to_store(spec, store, block_1)

# additional block at slot 1
block_2_state = genesis_state.copy()
block_2 = build_empty_block_for_next_slot(spec, block_2_state)
block_2.body.graffiti = b'\x42' * 32
state_transition_and_sign_block(spec, block_2_state, block_2)
add_block_to_store(spec, store, block_2)

highest_root = max(spec.signing_root(block_1), spec.signing_root(block_2))

assert spec.get_head(store) == highest_root


@with_all_phases
@with_state
@bls_switch
def test_shorter_chain_but_heavier_weight(spec, state):
genesis_state = state.copy()

# Initialization
store = spec.get_genesis_store(state)
genesis_block = spec.BeaconBlock(state_root=state.hash_tree_root())
assert spec.get_head(store) == spec.signing_root(genesis_block)

# build longer tree
long_state = genesis_state.copy()
for i in range(3):
long_block = build_empty_block_for_next_slot(spec, long_state)
state_transition_and_sign_block(spec, long_state, long_block)
add_block_to_store(spec, store, long_block)

# build short tree
short_state = genesis_state.copy()
short_block = build_empty_block_for_next_slot(spec, short_state)
short_block.body.graffiti = b'\x42' * 32
state_transition_and_sign_block(spec, short_state, short_block)
add_block_to_store(spec, store, short_block)

short_attestation = get_valid_attestation(spec, short_state, short_block.slot, signed=True)
add_attestation_to_store(spec, store, short_attestation)

assert spec.get_head(store) == spec.signing_root(short_block)

0 comments on commit 228195d

Please sign in to comment.