3.3 KiB
Ethereum 2.0 Phase 1 -- Crosslinks and Shard Data
Notice: This document is a work-in-progress for researchers and implementers.
Table of contents
TODO
Introduction
This document describes the shard transition function (data layer only) and the shard fork choice rule as part of Phase 1 of Ethereum 2.0.
Fraud proofs
TODO. The intent is to have a single universal fraud proof type, which contains the following parts:
- An on-time attestation on some
shard
signing aShardTransition
- An index
i
of a particular position to focus on - The
ShardTransition
itself - The full body of the block
- A Merkle proof to the
shard_states
in the parent block the attestation is referencing
The proof verifies that one of the two conditions is false:
custody_bits[i][j] != generate_custody_bit(subkey, block_contents)
for anyj
execute_state_transition(shard, slot, transition.shard_states[i-1].data, hash_tree_root(parent), get_shard_proposer_index(state, shard, slot), block_contents) != transition.shard_states[i].data
(ifi=0
then instead useparent.shard_states[shard][-1].data
)
Shard state transition function
def shard_state_transition(shard: Shard, slot: Slot, pre_state: Hash, previous_beacon_root: Hash, proposer_pubkey: BLSPubkey, block_data: BytesN[MAX_SHARD_BLOCK_CHUNKS * SHARD_BLOCK_CHUNK_SIZE]) -> Hash:
# We will add something more substantive in phase 2
return hash(pre_state + hash_tree_root(previous_beacon_root) + hash_tree_root(block_data))
Honest committee member behavior
Suppose you are a committee member on shard shard
at slot current_slot
. Let state
be the head beacon state you are building on, and let QUARTER_PERIOD = SECONDS_PER_SLOT // 4
. 2 * QUARTER_PERIOD
seconds into slot slot
, run the following procedure:
- Initialize
proposals = []
,shard_states = []
,shard_state = state.shard_states[shard][-1]
,start_slot = shard_state.slot
. - For
slot in get_offset_slots(state, start_slot)
, do the following:- Look for all valid proposals for
slot
; that is, a Bytesproposal
whereshard_state_transition(shard, slot, shard_state, get_block_root_at_slot(state, state.slot - 1), get_shard_proposer_index(state, shard, slot), proposal)
returns a result and does not throw an exception. Letchoices
be the set of non-empty valid proposals you discover. - If
len(choices) == 0
, doproposals.append(make_empty_proposal(shard_state, slot))
- If
len(choices) == 1
, doproposals.append(choices[0])
- If
len(choices) > 1
, letwinning_proposal
be the proposal with the largest number of total attestations from slots instate.shard_next_slots[shard]....slot-1
supporting it or any of its descendants, breaking ties by choosing the first proposal locally seen. Doproposals.append(winning_proposal)
. - If
proposals[-1]
is NOT an empty proposal, setshard_state = shard_state_transition(shard, slot, shard_state, get_block_root_at_slot(state, state.slot - 1), get_shard_proposer_index(state, shard, slot), proposals[-1])
and doshard_states.append(shard_state)
. If it is an empty proposal, leaveshard_state
unchanged.
- Look for all valid proposals for
Make an attestation using shard_data_roots = [hash_tree_root(proposal) for proposal in proposals]
and shard_state_roots = shard_states
.