From 941eb609ba38c6997fda6e0c795ea950eb316776 Mon Sep 17 00:00:00 2001 From: tersec Date: Tue, 9 Nov 2021 16:17:57 +0000 Subject: [PATCH] update statediffs to work with Altair (#3061) * update statediffs to work with Altair --- beacon_chain/spec/datatypes/altair.nim | 56 ++++++++++++++++++++++++++ beacon_chain/spec/datatypes/base.nim | 46 --------------------- beacon_chain/statediff.nim | 28 ++++++++----- tests/test_statediff.nim | 10 ++--- 4 files changed, 80 insertions(+), 60 deletions(-) diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index e884af046..f5e4b9a90 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -434,6 +434,62 @@ type SyncSubcommitteeIndex* = distinct uint8 ValidatorIndexInSyncCommittee* = distinct uint16 + BeaconStateDiff* = object + # Small and/or static; always include + slot*: Slot + latest_block_header*: BeaconBlockHeader + + # Mod-increment/circular + block_roots*: array[SLOTS_PER_EPOCH, Eth2Digest] + state_roots*: array[SLOTS_PER_EPOCH, Eth2Digest] + + # Append-only; either 0 or 1 per epoch + historical_root_added*: bool + historical_root*: Eth2Digest + + # Replace + eth1_data*: Eth1Data + + eth1_data_votes_replaced*: bool + eth1_data_votes*: + List[Eth1Data, Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)] + + # Replace + eth1_deposit_index*: uint64 + + # Validators come in two parts, the immutable public key and mutable + # entrance/exit/slashed information about that validator. + validator_statuses*: + List[ValidatorStatus, Limit VALIDATOR_REGISTRY_LIMIT] + + # Represent in full + balances*: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + + # Mod-increment + randao_mix*: Eth2Digest + slashing*: uint64 + + # Represent in full; for the next epoch, current_epoch_participation in + # epoch n is previous_epoch_participation in epoch n+1 but this doesn't + # generalize. + previous_epoch_participation*: + List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] + current_epoch_participation*: + List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT] + + justification_bits*: uint8 + previous_justified_checkpoint*: Checkpoint + current_justified_checkpoint*: Checkpoint + finalized_checkpoint*: Checkpoint + + # Represent in full + inactivity_scores*: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT] + + # Represent in full; for the next epoch, next_sync_committee is + # current_sync_committee, but this doesn't generalize. + current_sync_committee*: SyncCommittee + next_sync_committee*: SyncCommittee + chronicles.formatIt BeaconBlock: it.shortLog chronicles.formatIt SyncSubcommitteeIndex: uint8(it) diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index 4f0baa0ae..ad9d04d4a 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -424,52 +424,6 @@ type next_fork_version*: Version next_fork_epoch*: Epoch - BeaconStateDiff* = object - # Small and/or static; always include - slot*: Slot - latest_block_header*: BeaconBlockHeader - - # Mod-increment/circular - block_roots*: array[SLOTS_PER_EPOCH, Eth2Digest] - state_roots*: array[SLOTS_PER_EPOCH, Eth2Digest] - - # Append only; either 0 or 1 per epoch - historical_root_added*: bool - historical_root*: Eth2Digest - - # Replace - eth1_data*: Eth1Data - - eth1_data_votes_replaced*: bool - eth1_data_votes*: - List[Eth1Data, Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)] - - # Replace - eth1_deposit_index*: uint64 - - # Validators come in two parts, the immutable public key and mutable - # entrance/exit/slashed information about that validator. - validator_statuses*: - List[ValidatorStatus, Limit VALIDATOR_REGISTRY_LIMIT] - - # Represent in full - balances*: List[uint64, Limit VALIDATOR_REGISTRY_LIMIT] - - # Mod-increment - randao_mix*: Eth2Digest - slashing*: uint64 - - # To start with, always overwrite, not append - previous_epoch_attestations*: - List[PendingAttestation, Limit(MAX_ATTESTATIONS * SLOTS_PER_EPOCH)] - current_epoch_attestations*: - List[PendingAttestation, Limit(MAX_ATTESTATIONS * SLOTS_PER_EPOCH)] - - justification_bits*: uint8 - previous_justified_checkpoint*: Checkpoint - current_justified_checkpoint*: Checkpoint - finalized_checkpoint*: Checkpoint - BeaconBlockExits* = object # Collection of exits that are suitable for block production proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS] diff --git a/beacon_chain/statediff.nim b/beacon_chain/statediff.nim index 81fc229b6..8852c6756 100644 --- a/beacon_chain/statediff.nim +++ b/beacon_chain/statediff.nim @@ -9,7 +9,7 @@ import stew/assign2, - ./spec/datatypes/phase0, + ./spec/datatypes/altair, ./spec/helpers func diffModIncEpoch[T, U](hl: HashArray[U, T], startSlot: uint64): @@ -81,7 +81,7 @@ func replaceOrAddDecodeEth1Votes[T, U]( if not votes0.add item: raiseAssert "same limit" -func getMutableValidatorStatuses(state: phase0.BeaconState): +func getMutableValidatorStatuses(state: altair.BeaconState): List[ValidatorStatus, Limit VALIDATOR_REGISTRY_LIMIT] = if not result.setLen(state.validators.len): raiseAssert "same limt as validators" @@ -96,7 +96,7 @@ func getMutableValidatorStatuses(state: phase0.BeaconState): assign(result[i].exit_epoch, validator.exit_epoch) assign(result[i].withdrawable_epoch, validator.withdrawable_epoch) -func diffStates*(state0, state1: phase0.BeaconState): BeaconStateDiff = +func diffStates*(state0, state1: altair.BeaconState): BeaconStateDiff = doAssert state1.slot > state0.slot doAssert state0.slot.isEpoch doAssert state1.slot == state0.slot + SLOTS_PER_EPOCH @@ -139,17 +139,22 @@ func diffStates*(state0, state1: phase0.BeaconState): BeaconStateDiff = slashing: state1.slashings[state0.slot.compute_epoch_at_slot.uint64 mod EPOCHS_PER_HISTORICAL_VECTOR.uint64], - previous_epoch_attestations: state1.previous_epoch_attestations.data, - current_epoch_attestations: state1.current_epoch_attestations.data, + previous_epoch_participation: state1.previous_epoch_participation.data, + current_epoch_participation: state1.current_epoch_participation.data, justification_bits: state1.justification_bits, previous_justified_checkpoint: state1.previous_justified_checkpoint, current_justified_checkpoint: state1.current_justified_checkpoint, - finalized_checkpoint: state1.finalized_checkpoint + finalized_checkpoint: state1.finalized_checkpoint, + + inactivity_scores: state1.inactivity_scores.data, + + current_sync_committee: state1.current_sync_committee, + next_sync_committee: state1.next_sync_committee ) func applyDiff*( - state: var phase0.BeaconState, + state: var altair.BeaconState, immutableValidators: openArray[ImmutableValidatorData2], stateDiff: BeaconStateDiff) = template assign[T, U](tgt: var HashList[T, U], src: List[T, U]) = @@ -183,9 +188,9 @@ func applyDiff*( assign(state.slashings[epochIndex], stateDiff.slashing) assign( - state.previous_epoch_attestations, stateDiff.previous_epoch_attestations) + state.previous_epoch_participation, stateDiff.previous_epoch_participation) assign( - state.current_epoch_attestations, stateDiff.current_epoch_attestations) + state.current_epoch_participation, stateDiff.current_epoch_participation) state.justification_bits = stateDiff.justification_bits assign( @@ -194,5 +199,10 @@ func applyDiff*( state.current_justified_checkpoint, stateDiff.current_justified_checkpoint) assign(state.finalized_checkpoint, stateDiff.finalized_checkpoint) + assign(state.inactivity_scores, stateDiff.inactivity_scores) + + assign(state.current_sync_committee, stateDiff.current_sync_committee) + assign(state.next_sync_committee, stateDiff.next_sync_committee) + # Don't update slot until the end, because various other updates depend on it state.slot = stateDiff.slot diff --git a/tests/test_statediff.nim b/tests/test_statediff.nim index 09ed5463a..5516aa4d0 100644 --- a/tests/test_statediff.nim +++ b/tests/test_statediff.nim @@ -11,7 +11,7 @@ import options, sequtils, unittest2, ./testutil, ./testdbutil, ./teststateutil, - ../beacon_chain/spec/datatypes/phase0, + ../beacon_chain/spec/datatypes/altair, ../beacon_chain/spec/[forks, helpers], ../beacon_chain/statediff, ../beacon_chain/consensus_object_pools/[blockchain_dag, block_quarantine] @@ -26,7 +26,7 @@ suite "state diff tests" & preset(): dag = init(ChainDAGRef, defaultRuntimeConfig, db, {}) test "random slot differences" & preset(): - let testStates = getTestStates(dag.headState.data, BeaconStateFork.Phase0) + let testStates = getTestStates(dag.headState.data, BeaconStateFork.Altair) for i in 0 ..< testStates.len: for j in (i+1) ..< testStates.len: @@ -34,9 +34,9 @@ suite "state diff tests" & preset(): getStateField(testStates[j][], slot) if getStateField(testStates[i][], slot) + SLOTS_PER_EPOCH != getStateField(testStates[j][], slot): continue - var tmpStateApplyBase = assignClone(testStates[i].phase0Data.data) + var tmpStateApplyBase = assignClone(testStates[i].altairData.data) let diff = diffStates( - testStates[i].phase0Data.data, testStates[j].phase0Data.data) + testStates[i].altairData.data, testStates[j].altairData.data) # Immutable parts of validators stored separately, so aren't part of # the state diff. Synthesize required portion here for testing. applyDiff( @@ -47,5 +47,5 @@ suite "state diff tests" & preset(): getStateField(testStates[j][], validators).len - 1], it.getImmutableValidatorData), diff) - check hash_tree_root(testStates[j][].phase0Data.data) == + check hash_tree_root(testStates[j][].altairData.data) == hash_tree_root(tmpStateApplyBase[])