diff --git a/cl/abstract/beacon_state.go b/cl/abstract/beacon_state.go index be22f118827..67b1e8bb3ba 100644 --- a/cl/abstract/beacon_state.go +++ b/cl/abstract/beacon_state.go @@ -63,6 +63,7 @@ type BeaconStateExtension interface { GetDepositBalanceToConsume() uint64 GetPendingDeposits() *solid.ListSSZ[*solid.PendingDeposit] GetDepositRequestsStartIndex() uint64 + GetPendingConsolidations() *solid.ListSSZ[*solid.PendingConsolidation] } type BeaconStateBasic interface { @@ -131,6 +132,7 @@ type BeaconStateMutator interface { SetPendingPartialWithdrawals(*solid.ListSSZ[*solid.PendingPartialWithdrawal]) SetPendingDeposits(*solid.ListSSZ[*solid.PendingDeposit]) SetDepositBalanceToConsume(uint64) + SetPendingConsolidations(consolidations *solid.ListSSZ[*solid.PendingConsolidation]) AddEth1DataVote(vote *cltypes.Eth1Data) AddValidator(validator solid.Validator, balance uint64) diff --git a/cl/phase1/core/state/raw/setters.go b/cl/phase1/core/state/raw/setters.go index 4c36466871d..e00df933d7e 100644 --- a/cl/phase1/core/state/raw/setters.go +++ b/cl/phase1/core/state/raw/setters.go @@ -541,6 +541,11 @@ func (b *BeaconState) SetPendingDeposits(deposits *solid.ListSSZ[*solid.PendingD b.markLeaf(PendingDepositsLeafIndex) } +func (b *BeaconState) SetPendingConsolidations(consolidations *solid.ListSSZ[*solid.PendingConsolidation]) { + b.pendingConsolidations = consolidations + b.markLeaf(PendingConsolidationsLeafIndex) +} + func (b *BeaconState) SetDepositBalanceToConsume(balance uint64) { b.depositBalanceToConsume = balance b.markLeaf(DepositBalanceToConsumeLeafIndex) diff --git a/cl/phase1/core/state/raw/state.go b/cl/phase1/core/state/raw/state.go index 8f4df4b941b..7ffab7bba25 100644 --- a/cl/phase1/core/state/raw/state.go +++ b/cl/phase1/core/state/raw/state.go @@ -260,3 +260,7 @@ func (b *BeaconState) GetPendingDeposits() *solid.ListSSZ[*solid.PendingDeposit] func (b *BeaconState) GetDepositRequestsStartIndex() uint64 { return b.depositRequestsStartIndex } + +func (b *BeaconState) GetPendingConsolidations() *solid.ListSSZ[*solid.PendingConsolidation] { + return b.pendingConsolidations +} diff --git a/cl/transition/impl/eth2/statechange/process_pending_consolidations.go b/cl/transition/impl/eth2/statechange/process_pending_consolidations.go index f0ef77245f6..aecff774d94 100644 --- a/cl/transition/impl/eth2/statechange/process_pending_consolidations.go +++ b/cl/transition/impl/eth2/statechange/process_pending_consolidations.go @@ -1,11 +1,45 @@ package statechange import ( - "errors" - + "github.com/erigontech/erigon-lib/log/v3" "github.com/erigontech/erigon/cl/abstract" + "github.com/erigontech/erigon/cl/cltypes/solid" + "github.com/erigontech/erigon/cl/phase1/core/state" ) -func ProcessPendingConsolidations(s abstract.BeaconState) error { - return errors.New("not implemented") +func ProcessPendingConsolidations(s abstract.BeaconState) { + nextEpoch := s.Slot()/s.BeaconConfig().SlotsPerEpoch + 1 + nextConsolidationIndex := 0 + s.GetPendingConsolidations().Range(func(i int, c *solid.PendingConsolidation, length int) bool { + sourceValidator, err := s.ValidatorForValidatorIndex(int(c.SourceIndex)) + if err != nil { + log.Warn("Failed to get source validator for consolidation", "index", c.SourceIndex) + nextConsolidationIndex++ + return true + } + if sourceValidator.Slashed() { + nextConsolidationIndex++ + return true + } + if sourceValidator.WithdrawableEpoch() > nextEpoch { + return false // stop processing + } + // Calculate the consolidated balance + maxEffectiveBalance := state.GetMaxEffectiveBalanceByVersion(sourceValidator, s.BeaconConfig(), s.Version()) + vBalance, err := s.ValidatorBalance(int(c.SourceIndex)) + if err != nil { + log.Warn("Failed to get validator balance for consolidation", "index", c.SourceIndex) + nextConsolidationIndex++ + return true + } + sourceEffectiveBalance := min(vBalance, maxEffectiveBalance) + // Move active balance to target. Excess balance is withdrawable. + state.DecreaseBalance(s, c.SourceIndex, sourceEffectiveBalance) + state.IncreaseBalance(s, c.TargetIndex, sourceEffectiveBalance) + nextConsolidationIndex++ + return true + }) + pendingConsolidations := s.GetPendingConsolidations().ShallowCopy() + pendingConsolidations.Cut(nextConsolidationIndex) + s.SetPendingConsolidations(pendingConsolidations) }