You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
defget_shard_committee(beacon_state: BeaconState, shard: Shard, epoch: Epoch) ->Sequence[ValidatorIndex]:
older_committee=get_period_committee(beacon_state, shard, compute_shard_period_start_epoch(epoch, 2))
newer_committee=get_period_committee(beacon_state, shard, compute_shard_period_start_epoch(epoch, 1))
# Every epoch cycle out validators from the older committee and cycle in validators from the newer committeeolder_subcommittee= [iforiinolder_committeeifi%EPOCHS_PER_SHARD_PERIOD>epoch%EPOCHS_PER_SHARD_PERIOD]
newer_subcommittee= [iforiinnewer_committeeifi%EPOCHS_PER_SHARD_PERIOD<=epoch%EPOCHS_PER_SHARD_PERIOD]
returnolder_subcommittee+newer_subcommittee
defshard_state_transition(beacon_state: BeaconState,
shard_state: ShardState,
block: ShardBlock,
validate_state_root: bool=False) ->ShardState:
# Process slots (including those with no blocks) since blockprocess_shard_slots(shard_state, block.slot)
# Process blockprocess_shard_block(beacon_state, shard_state, block)
# Validate state root (`validate_state_root == True` in production)ifvalidate_state_root:
assertblock.state_root==hash_tree_root(shard_state)
# Return post-statereturnshard_state
defprocess_shard_slots(shard_state: ShardState, slot: ShardSlot) ->None:
assertshard_state.slot<=slotwhileshard_state.slot<slot:
process_shard_slot(shard_state)
# Process shard period on the start slot of the next shard periodif (shard_state.slot+1) % (SHARD_SLOTS_PER_EPOCH*EPOCHS_PER_SHARD_PERIOD) ==0:
process_shard_period(shard_state)
shard_state.slot+=ShardSlot(1)
defprocess_shard_slot(shard_state: ShardState) ->None:
# Cache state rootprevious_state_root=hash_tree_root(shard_state)
ifshard_state.latest_block_header.state_root==Bytes32():
shard_state.latest_block_header.state_root=previous_state_root# Cache state root in history accumulatordepth=0whileshard_state.slot%2**depth==0anddepth<HISTORY_ACCUMULATOR_DEPTH:
shard_state.history_accumulator[depth] =previous_state_rootdepth+=1
defprocess_shard_block_header(beacon_state: BeaconState, shard_state: ShardState, block: ShardBlock) ->None:
# Verify the shard numberassertblock.shard==shard_state.shard# Verify the slot numberassertblock.slot==shard_state.slot# Verify the beacon chain rootepoch=compute_epoch_of_shard_slot(shard_state.slot)
assertepoch*SLOTS_PER_EPOCH==beacon_state.slotbeacon_block_header=BeaconBlockHeader(
slot=beacon_state.latest_block_header.slot,
parent_root=beacon_state.latest_block_header.parent_root,
state_root=beacon_state.latest_block_header.state_root,
body_root=beacon_state.latest_block_header.body_root,
)
ifbeacon_block_header.state_root==Bytes32():
beacon_block_header.state_root=hash_tree_root(beacon_state)
assertblock.beacon_block_root==signing_root(beacon_block_header)
# Verify the parent rootassertblock.parent_root==signing_root(shard_state.latest_block_header)
# Save current block as the new latest blockshard_state.latest_block_header=ShardBlockHeader(
shard=block.shard,
slot=block.slot,
beacon_block_root=block.beacon_block_root,
parent_root=block.parent_root,
# `state_root` is zeroed and overwritten in the next `process_shard_slot` callbody_root=hash_tree_root(block.body),
block_size_sum=block.block_size_sum,
aggregation_bits=block.aggregation_bits,
attestations=block.attestations,
# `signature` is zeroed
)
# Verify the sum of the block sizes since genesisshard_state.block_size_sum+=SHARD_HEADER_SIZE+len(block.body)
assertblock.block_size_sum==shard_state.block_size_sum# Verify proposer is not slashedproposer_index=get_shard_proposer_index(beacon_state, shard_state.shard, block.slot)
proposer=beacon_state.validators[proposer_index]
assertnotproposer.slashed# Verify proposer signaturedomain=get_domain(beacon_state, DOMAIN_SHARD_PROPOSER, compute_epoch_of_shard_slot(block.slot))
assertbls_verify(proposer.pubkey, signing_root(block), block.signature, domain)
defprocess_shard_block_body(beacon_state: BeaconState, shard_state: ShardState, block: ShardBlock) ->None:
# Verify block body size is a multiple of the header sizeassertlen(block.body) %SHARD_HEADER_SIZE==0# Apply proposer block body feeblock_body_fee=shard_state.block_body_price*len(block.body) //MAX_SHARD_BLOCK_SIZEproposer_index=get_shard_proposer_index(beacon_state, shard_state.shard, block.slot)
process_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee), positive=False) # Burnprocess_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee//PROPOSER_REWARD_QUOTIENT)) # Reward# Calculate new block body priceblock_size=SHARD_HEADER_SIZE+len(block.body)
QUOTIENT=MAX_SHARD_BLOCK_SIZE*BLOCK_BODY_PRICE_QUOTIENTifblock_size>SHARD_BLOCK_SIZE_TARGET:
price_delta=Gwei(shard_state.block_body_price* (block_size-SHARD_BLOCK_SIZE_TARGET) //QUOTIENT)
# The maximum block body price caps the amount burnt on fees within a shard periodMAX_BLOCK_BODY_PRICE=MAX_EFFECTIVE_BALANCE//EPOCHS_PER_SHARD_PERIOD//SHARD_SLOTS_PER_EPOCHshard_state.block_body_price=Gwei(min(MAX_BLOCK_BODY_PRICE, shard_state.block_body_price+price_delta))
else:
price_delta=Gwei(shard_state.block_body_price* (SHARD_BLOCK_SIZE_TARGET-block_size) //QUOTIENT)
shard_state.block_body_price=Gwei(max(MIN_BLOCK_BODY_PRICE, shard_state.block_body_price+price_delta))
Shard fork choice rule
The fork choice rule for any shard is LMD GHOST using the shard attestations of the shard committee and the beacon chain attestations of the crosslink committee currently assigned to that shard, but instead of being rooted in the genesis it is rooted in the block referenced in the most recent accepted crosslink (i.e. beacon_state.crosslinks[shard].shard_block_root). Only blocks whose beacon_block_root is the block in the main beacon chain at the specified slot should be considered. (If the beacon chain skips a slot, then the block at that slot is considered to be the block in the beacon chain at the highest slot lower than that slot.)