Merge pull request #1878 from ethereum/hwwhww/remove_digest

Remove `ShardState.transition_digest`
This commit is contained in:
Danny Ryan 2020-06-16 16:14:22 -06:00
commit a21f93646c
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
6 changed files with 21 additions and 43 deletions

View File

@ -379,7 +379,6 @@ class ShardBlockHeader(Container):
class ShardState(Container):
slot: Slot
gasprice: Gwei
transition_digest: Bytes32
latest_block_root: Root
```

View File

@ -104,7 +104,6 @@ def upgrade_to_phase1(pre: phase0.BeaconState) -> BeaconState:
ShardState(
slot=pre.slot,
gasprice=MIN_GASPRICE,
transition_digest=Root(),
latest_block_root=Root(),
) for i in range(INITIAL_ACTIVE_SHARDS)
),

View File

@ -124,7 +124,7 @@ def get_pending_shard_blocks(store: Store, shard_store: ShardStore) -> Sequence[
beacon_head_state = store.block_states[beacon_head_root]
latest_shard_block_root = beacon_head_state.shard_states[shard].latest_block_root
shard_head_root = tget_shard_head(store, shard_store)
shard_head_root = get_shard_head(store, shard_store)
root = shard_head_root
shard_blocks = []
while root != latest_shard_block_root:
@ -172,7 +172,7 @@ def on_shard_block(store: Store, shard_store: ShardStore, signed_shard_block: Si
assert verify_shard_block_message(beacon_parent_state, shard_parent_state, shard_block)
assert verify_shard_block_signature(beacon_parent_state, signed_shard_block)
post_state = get_post_shard_state(beacon_parent_state, shard_parent_state, shard_block)
post_state = get_post_shard_state(shard_parent_state, shard_block)
# Add new block to the store
shard_store.blocks[hash_tree_root(shard_block)] = shard_block

View File

@ -10,7 +10,6 @@
- [Introduction](#introduction)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [Shard block verification functions](#shard-block-verification-functions)
- [Shard state transition](#shard-state-transition)
- [Fraud proofs](#fraud-proofs)
@ -24,19 +23,6 @@ This document describes the shard transition function and fraud proofs as part o
## Helper functions
### Misc
```python
def compute_shard_transition_digest(beacon_parent_state: BeaconState,
shard_state: ShardState,
beacon_parent_root: Root,
shard_body_root: Root) -> Bytes32:
# TODO: use SSZ hash tree root
return hash(
hash_tree_root(shard_state) + beacon_parent_root + shard_body_root
)
```
### Shard block verification functions
```python
@ -77,11 +63,10 @@ def verify_shard_block_signature(beacon_state: BeaconState,
## Shard state transition
```python
def shard_state_transition(beacon_state: BeaconState,
shard_state: ShardState,
def shard_state_transition(shard_state: ShardState,
block: ShardBlock) -> None:
"""
Update ``shard_state`` with shard ``block`` and ``beacon_state`.
Update ``shard_state`` with shard ``block``.
"""
shard_state.slot = block.slot
prev_gasprice = shard_state.gasprice
@ -91,25 +76,18 @@ def shard_state_transition(beacon_state: BeaconState,
else:
latest_block_root = hash_tree_root(block)
shard_state.latest_block_root = latest_block_root
shard_state.transition_digest = compute_shard_transition_digest(
beacon_state,
shard_state,
block.beacon_parent_root,
hash_tree_root(block.body),
)
```
We have a pure function `get_post_shard_state` for describing the fraud proof verification and honest validator behavior.
```python
def get_post_shard_state(beacon_state: BeaconState,
shard_state: ShardState,
def get_post_shard_state(shard_state: ShardState,
block: ShardBlock) -> ShardState:
"""
A pure function that returns a new post ShardState instead of modifying the given `shard_state`.
"""
post_state = shard_state.copy()
shard_state_transition(beacon_state, post_state, block)
shard_state_transition(post_state, block)
return post_state
```
@ -151,8 +129,8 @@ def is_valid_fraud_proof(beacon_state: BeaconState,
else:
shard_state = transition.shard_states[offset_index - 1] # Not doing the actual state updates here.
shard_state = get_post_shard_state(beacon_state, shard_state, block)
if shard_state.transition_digest != transition.shard_states[offset_index].transition_digest:
shard_state = get_post_shard_state(shard_state, block)
if shard_state != transition.shard_states[offset_index]:
return True
return False

View File

@ -296,7 +296,7 @@ def get_shard_transition_fields(
else:
shard_block = SignedShardBlock(message=ShardBlock(slot=slot, shard=shard))
shard_data_roots.append(Root())
shard_state = get_post_shard_state(beacon_state, shard_state, shard_block.message)
shard_state = get_post_shard_state(shard_state, shard_block.message)
shard_states.append(shard_state)
shard_block_lengths.append(len(shard_block.message.body))
@ -419,8 +419,6 @@ If the validator is in the next light client committee, they must join the `ligh
```python
def is_in_next_light_client_committee(state: BeaconState, index: ValidatorIndex) -> bool:
current_source_epoch = compute_committee_source_epoch(get_current_epoch(state), LIGHT_CLIENT_COMMITTEE_PERIOD)
next_source_epoch = current_source_epoch + LIGHT_CLIENT_COMMITTEE_PERIOD
next_committee = get_light_client_committee(state, get_current_epoch(state) + LIGHT_CLIENT_COMMITTEE_PERIOD)
return index in next_committee
```
@ -578,13 +576,17 @@ Proposer and Attester slashings described in Phase 0 remain in place with the
To avoid custody slashings, the attester must never sign any shard transition for which the custody bit is one. The custody bit is computed using the custody secret:
```python
def get_custody_secret(spec, state, validator_index, epoch=None):
period = spec.get_custody_period_for_validator(validator_index, epoch if epoch is not None
else spec.get_current_epoch(state))
epoch_to_sign = spec.get_randao_epoch_for_custody_period(period, validator_index)
domain = spec.get_domain(state, spec.DOMAIN_RANDAO, epoch_to_sign)
signing_root = spec.compute_signing_root(spec.Epoch(epoch_to_sign), domain)
return bls.Sign(privkeys[validator_index], signing_root)
def get_custody_secret(state: BeaconState,
validator_index: ValidatorIndex,
privkey: int,
epoch: Epoch=None) -> BLSSignature:
if epoch is None:
epoch = get_current_epoch(state)
period = get_custody_period_for_validator(validator_index, epoch)
epoch_to_sign = get_randao_epoch_for_custody_period(period, validator_index)
domain = get_domain(state, DOMAIN_RANDAO, epoch_to_sign)
signing_root = compute_signing_root(Epoch(epoch_to_sign), domain)
return bls.Sign(privkey, signing_root)
```
Note that the valid custody secret is always the one for the **attestation target epoch**, not to be confused with the epoch in which the shard block was generated. While they are the same most of the time, getting this wrong at custody epoch boundaries would result in a custody slashing.

View File

@ -91,7 +91,7 @@ def build_attestation_data(spec, state, slot, index, shard_transition=None, on_t
attestation_data.shard_head_root = shard_transition.shard_data_roots[lastest_shard_data_root_index]
attestation_data.shard_transition_root = shard_transition.hash_tree_root()
else:
attestation_data.shard_head_root = state.shard_states[shard].transition_digest
attestation_data.shard_head_root = state.shard_states[shard].latest_block_root
attestation_data.shard_transition_root = spec.Root()
return attestation_data