Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fork-choice graph oriented implementation #7212

Merged
merged 6 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/ef-tests-cl/consensus_tests/sanity.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ func testSanityFunction(context testContext) error {
if err != nil {
break
}
changes = append(changes, testState.StopCollectingReverseChangeSet())
}
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ type ReverseBeaconStateChangeSet struct {
ExitEpochChange *ListChangeSet[uint64]
WithdrawalEpochChange *ListChangeSet[uint64]
// Efficient unwinding on reset (only applicable at epoch boundaries)
PreviousEpochParticipationAtReset cltypes.ParticipationFlagsList
CurrentEpochParticipationAtReset cltypes.ParticipationFlagsList
Eth1DataVotesAtReset []*cltypes.Eth1Data
previousEpochParticipationAtReset cltypes.ParticipationFlagsList
currentEpochParticipationAtReset cltypes.ParticipationFlagsList
eth1DataVotesAtReset []*cltypes.Eth1Data
wasEth1DataVotesReset bool
wasEpochParticipationReset bool
}

func (r *ReverseBeaconStateChangeSet) OnSlotChange(prevSlot uint64) {
Expand Down Expand Up @@ -176,25 +178,9 @@ func (r *ReverseBeaconStateChangeSet) HasValidatorSetNotChanged(validatorSetLeng
r.EffectiveBalanceChange.Empty() && r.SlashedChange.Empty() && r.ExitEpochChange.Empty() && r.WithdrawalEpochChange.Empty()
}

func (r *ReverseBeaconStateChangeSet) ApplyEth1DataVotesChanges(input []*cltypes.Eth1Data) (output []*cltypes.Eth1Data, changed bool) {
output = input
if r.Eth1DataVotesChanges.Empty() && r.Eth1DataVotesChanges.ListLength() == len(output) {
return
}
changed = true
if r.Eth1DataVotesChanges.ListLength() != len(output) {
output = make([]*cltypes.Eth1Data, r.Eth1DataVotesChanges.ListLength())
copy(output, input)
}
r.Eth1DataVotesChanges.ChangesWithHandler(func(value cltypes.Eth1Data, index int) {
*output[index] = value
})
return
}

func (r *ReverseBeaconStateChangeSet) ApplyHistoricalSummaryChanges(input []*cltypes.HistoricalSummary) (output []*cltypes.HistoricalSummary, changed bool) {
output = input
if r.HistoricalSummaryChange.Empty() && r.Eth1DataVotesChanges.ListLength() == len(output) {
if r.HistoricalSummaryChange.Empty() && r.HistoricalSummaryChange.ListLength() == len(output) {
return
}
changed = true
Expand All @@ -217,12 +203,12 @@ func (r *ReverseBeaconStateChangeSet) CompactChanges() {
r.SlashingsChanges.CompactChangesReverse()
r.RandaoMixesChanges.CompactChangesReverse()
r.BalancesChanges.CompactChangesReverse()
if len(r.Eth1DataVotesAtReset) > 0 {
if len(r.eth1DataVotesAtReset) > 0 {
r.Eth1DataVotesChanges = nil
} else {
r.Eth1DataVotesChanges.CompactChangesReverse()
}
if len(r.PreviousEpochParticipationAtReset) > 0 {
if len(r.previousEpochParticipationAtReset) > 0 {
r.PreviousEpochParticipationChanges = nil
r.CurrentEpochParticipationChanges = nil
} else {
Expand All @@ -239,3 +225,55 @@ func (r *ReverseBeaconStateChangeSet) CompactChanges() {
r.SlashedChange.CompactChangesReverse()
r.WithdrawalEpochChange.CompactChangesReverse()
}

func (r *ReverseBeaconStateChangeSet) ReportVotesReset(previousVotes []*cltypes.Eth1Data) {
if r.wasEth1DataVotesReset {
return
}
// Copy the slice over
for _, vote := range previousVotes {
copyVote := *vote
r.eth1DataVotesAtReset = append(r.eth1DataVotesAtReset, &copyVote)
}
r.wasEth1DataVotesReset = true
}

func (r *ReverseBeaconStateChangeSet) ReportEpochParticipationReset(prevParticipation, currParticpation cltypes.ParticipationFlagsList) {
if r.wasEpochParticipationReset {
return
}
r.previousEpochParticipationAtReset = prevParticipation.Copy()
r.currentEpochParticipationAtReset = currParticpation.Copy()
r.wasEpochParticipationReset = true
}

func (r *ReverseBeaconStateChangeSet) ApplyEth1DataVotesChanges(initialVotes []*cltypes.Eth1Data) (output []*cltypes.Eth1Data, changed bool) {
if r.wasEth1DataVotesReset {
return r.eth1DataVotesAtReset, true
}
output = initialVotes
if r.Eth1DataVotesChanges.Empty() && r.Eth1DataVotesChanges.ListLength() == len(output) {
return
}
changed = true
if r.Eth1DataVotesChanges.ListLength() != len(output) {
output = make([]*cltypes.Eth1Data, r.Eth1DataVotesChanges.ListLength())
copy(output, initialVotes)
}
r.Eth1DataVotesChanges.ChangesWithHandler(func(value cltypes.Eth1Data, index int) {
*output[index] = value
})
return
}

func (r *ReverseBeaconStateChangeSet) ApplyEpochParticipationChanges(
previousEpochParticipation cltypes.ParticipationFlagsList,
currentEpochParticipation cltypes.ParticipationFlagsList) (newPreviousEpochParticipation cltypes.ParticipationFlagsList, newCurrentEpochParticipation cltypes.ParticipationFlagsList,
previousParticipationChanged bool, currentParticipationChanged bool) {
if r.wasEpochParticipationReset {
return r.previousEpochParticipationAtReset, r.currentEpochParticipationAtReset, true, true
}
newPreviousEpochParticipation, previousParticipationChanged = r.PreviousEpochParticipationChanges.ApplyChanges(previousEpochParticipation)
newCurrentEpochParticipation, currentParticipationChanged = r.CurrentEpochParticipationChanges.ApplyChanges(currentEpochParticipation)
return
}
39 changes: 15 additions & 24 deletions cmd/erigon-cl/core/state/changeset.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,37 +138,27 @@ func (b *BeaconState) RevertWithChangeset(changeset *beacon_changeset.ReverseBea
if touched {
b.touchedLeaves[HistoricalRootsLeafIndex] = true
}
// This is a special case, as reset will lead to complete change of votes
if len(changeset.Eth1DataVotesAtReset) == 0 {
b.eth1DataVotes, touched = changeset.ApplyEth1DataVotesChanges(b.eth1DataVotes)
if touched {
b.touchedLeaves[Eth1DataVotesLeafIndex] = true
}
} else {
b.eth1DataVotes = changeset.Eth1DataVotesAtReset
// Process votes changes
b.eth1DataVotes, touched = changeset.ApplyEth1DataVotesChanges(b.eth1DataVotes)
if touched {
b.touchedLeaves[Eth1DataVotesLeafIndex] = true
}
b.balances, touched = changeset.BalancesChanges.ApplyChanges(b.balances)
if touched {
b.touchedLeaves[BalancesLeafIndex] = true
}
// This also a special case, as this is another victim of reset, we use rotation with curr and prev to handle it efficiently
if len(changeset.PreviousEpochParticipationAtReset) == 0 && len(changeset.CurrentEpochParticipationAtReset) == 0 {
b.previousEpochParticipation, touched = changeset.PreviousEpochParticipationChanges.ApplyChanges(b.previousEpochParticipation)
if touched {
b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true
}
b.currentEpochParticipation, touched = changeset.CurrentEpochParticipationChanges.ApplyChanges(b.currentEpochParticipation)
if touched {
b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true
}
} else {
// Process epoch participation changes
var touchedPreviousEpochParticipation, touchedCurrentEpochParticipation bool
b.previousEpochParticipation, b.currentEpochParticipation,
touchedPreviousEpochParticipation,
touchedCurrentEpochParticipation = changeset.ApplyEpochParticipationChanges(b.previousEpochParticipation, b.currentEpochParticipation)
if touchedPreviousEpochParticipation {
b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true
}
if touchedCurrentEpochParticipation {
b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true
b.previousEpochParticipation = changeset.PreviousEpochParticipationAtReset.Copy()
b.currentEpochParticipation = changeset.CurrentEpochParticipationAtReset.Copy()
}

// Process inactivity scores changes.
b.inactivityScores, touched = changeset.InactivityScoresChanges.ApplyChanges(b.inactivityScores)
if touched {
b.touchedLeaves[InactivityScoresLeafIndex] = true
Expand Down Expand Up @@ -243,17 +233,18 @@ func (b *BeaconState) RevertWithChangeset(changeset *beacon_changeset.ReverseBea
}

func (b *BeaconState) revertCachesOnBoundary(beforeSlot uint64) {
b.activeValidatorsCache.Purge()
beforeEpoch := beforeSlot / b.beaconConfig.SlotsPerEpoch
epoch := b.Epoch()
b.committeeCache.Purge()
b.previousStateRoot = libcommon.Hash{}
b.proposerIndex = nil
b.totalActiveBalanceCache = nil
if epoch <= beforeEpoch {
return
}
b.totalActiveBalanceCache = nil
b.committeeCache.Purge()
for epochToBeRemoved := beforeEpoch; epochToBeRemoved < epoch+1; beforeEpoch++ {
b.activeValidatorsCache.Remove(epochToBeRemoved)
b.shuffledSetsCache.Remove(b.GetSeed(epochToBeRemoved, b.beaconConfig.DomainBeaconAttester))
b.activeValidatorsCache.Remove(epochToBeRemoved)
}
Expand Down
8 changes: 3 additions & 5 deletions cmd/erigon-cl/core/state/setters.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (b *BeaconState) AddEth1DataVote(vote *cltypes.Eth1Data) {

func (b *BeaconState) ResetEth1DataVotes() {
if b.reverseChangeset != nil {
b.reverseChangeset.Eth1DataVotesAtReset = b.eth1DataVotes
b.reverseChangeset.ReportVotesReset(b.eth1DataVotes)
}
b.touchedLeaves[Eth1DataVotesLeafIndex] = true
b.eth1DataVotes = nil
Expand Down Expand Up @@ -213,10 +213,8 @@ func (b *BeaconState) SetValidatorAtIndex(index int, validator *cltypes.Validato
}

func (b *BeaconState) ResetEpochParticipation() {
if b.reverseChangeset != nil && len(b.reverseChangeset.CurrentEpochParticipationAtReset) == 0 &&
len(b.reverseChangeset.PreviousEpochParticipationAtReset) == 0 {
b.reverseChangeset.CurrentEpochParticipationAtReset = b.currentEpochParticipation.Copy()
b.reverseChangeset.PreviousEpochParticipationAtReset = b.previousEpochParticipation.Copy()
if b.reverseChangeset != nil {
b.reverseChangeset.ReportEpochParticipationReset(b.previousEpochParticipation, b.currentEpochParticipation)
}
b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true
b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true
Expand Down
Loading