diff --git a/cl/abstract/beacon_state.go b/cl/abstract/beacon_state.go index 304a414dd..cc77a2061 100644 --- a/cl/abstract/beacon_state.go +++ b/cl/abstract/beacon_state.go @@ -40,6 +40,7 @@ type BeaconStateExtension interface { ValidatorIndexByPubkey(key [48]byte) (uint64, bool) PreviousStateRoot() common.Hash SetPreviousStateRoot(root common.Hash) + GetValidatorActivationChurnLimit() uint64 } type BeaconStateBasic interface { diff --git a/cl/clparams/config.go b/cl/clparams/config.go index 4d51e918d..8748f7a8f 100644 --- a/cl/clparams/config.go +++ b/cl/clparams/config.go @@ -308,20 +308,21 @@ type BeaconChainConfig struct { JustificationBitsLength uint64 `yaml:"JUSTIFICATION_BITS_LENGTH"` // JustificationBitsLength defines number of epochs to track when implementing k-finality in Casper FFG. // Misc constants. - PresetBase string `yaml:"PRESET_BASE" spec:"true"` // PresetBase represents the underlying spec preset this config is based on. - ConfigName string `yaml:"CONFIG_NAME" spec:"true"` // ConfigName for allowing an easy human-readable way of knowing what chain is being used. - TargetCommitteeSize uint64 `yaml:"TARGET_COMMITTEE_SIZE" spec:"true"` // TargetCommitteeSize is the number of validators in a committee when the chain is healthy. - MaxValidatorsPerCommittee uint64 `yaml:"MAX_VALIDATORS_PER_COMMITTEE" spec:"true"` // MaxValidatorsPerCommittee defines the upper bound of the size of a committee. - MaxCommitteesPerSlot uint64 `yaml:"MAX_COMMITTEES_PER_SLOT" spec:"true"` // MaxCommitteesPerSlot defines the max amount of committee in a single slot. - MinPerEpochChurnLimit uint64 `yaml:"MIN_PER_EPOCH_CHURN_LIMIT" spec:"true"` // MinPerEpochChurnLimit is the minimum amount of churn allotted for validator rotations. - ChurnLimitQuotient uint64 `yaml:"CHURN_LIMIT_QUOTIENT" spec:"true"` // ChurnLimitQuotient is used to determine the limit of how many validators can rotate per epoch. - ShuffleRoundCount uint64 `yaml:"SHUFFLE_ROUND_COUNT" spec:"true"` // ShuffleRoundCount is used for retrieving the permuted index. - MinGenesisActiveValidatorCount uint64 `yaml:"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT" spec:"true"` // MinGenesisActiveValidatorCount defines how many validator deposits needed to kick off beacon chain. - MinGenesisTime uint64 `yaml:"MIN_GENESIS_TIME" spec:"true"` // MinGenesisTime is the time that needed to pass before kicking off beacon chain. - TargetAggregatorsPerCommittee uint64 `yaml:"TARGET_AGGREGATORS_PER_COMMITTEE" spec:"true"` // TargetAggregatorsPerCommittee defines the number of aggregators inside one committee. - HysteresisQuotient uint64 `yaml:"HYSTERESIS_QUOTIENT" spec:"true"` // HysteresisQuotient defines the hysteresis quotient for effective balance calculations. - HysteresisDownwardMultiplier uint64 `yaml:"HYSTERESIS_DOWNWARD_MULTIPLIER" spec:"true"` // HysteresisDownwardMultiplier defines the hysteresis downward multiplier for effective balance calculations. - HysteresisUpwardMultiplier uint64 `yaml:"HYSTERESIS_UPWARD_MULTIPLIER" spec:"true"` // HysteresisUpwardMultiplier defines the hysteresis upward multiplier for effective balance calculations. + PresetBase string `yaml:"PRESET_BASE" spec:"true"` // PresetBase represents the underlying spec preset this config is based on. + ConfigName string `yaml:"CONFIG_NAME" spec:"true"` // ConfigName for allowing an easy human-readable way of knowing what chain is being used. + TargetCommitteeSize uint64 `yaml:"TARGET_COMMITTEE_SIZE" spec:"true"` // TargetCommitteeSize is the number of validators in a committee when the chain is healthy. + MaxValidatorsPerCommittee uint64 `yaml:"MAX_VALIDATORS_PER_COMMITTEE" spec:"true"` // MaxValidatorsPerCommittee defines the upper bound of the size of a committee. + MaxCommitteesPerSlot uint64 `yaml:"MAX_COMMITTEES_PER_SLOT" spec:"true"` // MaxCommitteesPerSlot defines the max amount of committee in a single slot. + MinPerEpochChurnLimit uint64 `yaml:"MIN_PER_EPOCH_CHURN_LIMIT" spec:"true"` // MinPerEpochChurnLimit is the minimum amount of churn allotted for validator rotations. + ChurnLimitQuotient uint64 `yaml:"CHURN_LIMIT_QUOTIENT" spec:"true"` // ChurnLimitQuotient is used to determine the limit of how many validators can rotate per epoch. + MaxPerEpochActivationChurnLimit uint64 `yaml:"MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT" spec:"true"` // MaxPerEpochActivationChurnLimit defines the maximum amount of churn allowed in one epoch from deneb. + ShuffleRoundCount uint64 `yaml:"SHUFFLE_ROUND_COUNT" spec:"true"` // ShuffleRoundCount is used for retrieving the permuted index. + MinGenesisActiveValidatorCount uint64 `yaml:"MIN_GENESIS_ACTIVE_VALIDATOR_COUNT" spec:"true"` // MinGenesisActiveValidatorCount defines how many validator deposits needed to kick off beacon chain. + MinGenesisTime uint64 `yaml:"MIN_GENESIS_TIME" spec:"true"` // MinGenesisTime is the time that needed to pass before kicking off beacon chain. + TargetAggregatorsPerCommittee uint64 `yaml:"TARGET_AGGREGATORS_PER_COMMITTEE" spec:"true"` // TargetAggregatorsPerCommittee defines the number of aggregators inside one committee. + HysteresisQuotient uint64 `yaml:"HYSTERESIS_QUOTIENT" spec:"true"` // HysteresisQuotient defines the hysteresis quotient for effective balance calculations. + HysteresisDownwardMultiplier uint64 `yaml:"HYSTERESIS_DOWNWARD_MULTIPLIER" spec:"true"` // HysteresisDownwardMultiplier defines the hysteresis downward multiplier for effective balance calculations. + HysteresisUpwardMultiplier uint64 `yaml:"HYSTERESIS_UPWARD_MULTIPLIER" spec:"true"` // HysteresisUpwardMultiplier defines the hysteresis upward multiplier for effective balance calculations. // Gwei value constants. MinDepositAmount uint64 `yaml:"MIN_DEPOSIT_AMOUNT" spec:"true"` // MinDepositAmount is the minimum amount of Gwei a validator can send to the deposit contract at once (lower amounts will be reverted). @@ -573,18 +574,19 @@ var MainnetBeaconConfig BeaconChainConfig = BeaconChainConfig{ GenesisDelay: 604800, // 1 week. // Misc constant. - TargetCommitteeSize: 128, - MaxValidatorsPerCommittee: 2048, - MaxCommitteesPerSlot: 64, - MinPerEpochChurnLimit: 4, - ChurnLimitQuotient: 1 << 16, - ShuffleRoundCount: 90, - MinGenesisActiveValidatorCount: 16384, - MinGenesisTime: 1606824000, // Dec 1, 2020, 12pm UTC. - TargetAggregatorsPerCommittee: 16, - HysteresisQuotient: 4, - HysteresisDownwardMultiplier: 1, - HysteresisUpwardMultiplier: 5, + TargetCommitteeSize: 128, + MaxValidatorsPerCommittee: 2048, + MaxCommitteesPerSlot: 64, + MinPerEpochChurnLimit: 4, + ChurnLimitQuotient: 1 << 16, + MaxPerEpochActivationChurnLimit: 8, + ShuffleRoundCount: 90, + MinGenesisActiveValidatorCount: 16384, + MinGenesisTime: 1606824000, // Dec 1, 2020, 12pm UTC. + TargetAggregatorsPerCommittee: 16, + HysteresisQuotient: 4, + HysteresisDownwardMultiplier: 1, + HysteresisUpwardMultiplier: 5, // Gwei value constants. MinDepositAmount: 1 * 1e9, diff --git a/cl/cltypes/eth1_header.go b/cl/cltypes/eth1_header.go index 9eabdfc1a..e74270fc6 100644 --- a/cl/cltypes/eth1_header.go +++ b/cl/cltypes/eth1_header.go @@ -57,7 +57,7 @@ func (e *Eth1Header) Capella() { e.WithdrawalsRoot = libcommon.Hash{} } -// Capella converts the header to capella version. +// Deneb converts the header to deneb version. func (e *Eth1Header) Deneb() { e.version = clparams.DenebVersion e.BlobGasUsed = 0 diff --git a/cl/phase1/core/state/cache_accessors.go b/cl/phase1/core/state/cache_accessors.go index 99f2f17a9..80685ec5a 100644 --- a/cl/phase1/core/state/cache_accessors.go +++ b/cl/phase1/core/state/cache_accessors.go @@ -171,7 +171,10 @@ func (b *CachingBeaconState) GetAttestationParticipationFlagIndicies(data solid. if inclusionDelay <= utils.IntegerSquareRoot(b.BeaconConfig().SlotsPerEpoch) { participationFlagIndicies = append(participationFlagIndicies, b.BeaconConfig().TimelySourceFlagIndex) } - if matchingTarget && inclusionDelay <= b.BeaconConfig().SlotsPerEpoch { + if b.Version() < clparams.DenebVersion && matchingTarget && inclusionDelay <= b.BeaconConfig().SlotsPerEpoch { + participationFlagIndicies = append(participationFlagIndicies, b.BeaconConfig().TimelyTargetFlagIndex) + } + if b.Version() >= clparams.DenebVersion && matchingTarget { participationFlagIndicies = append(participationFlagIndicies, b.BeaconConfig().TimelyTargetFlagIndex) } if matchingHead && inclusionDelay == b.BeaconConfig().MinAttestationInclusionDelay { @@ -295,3 +298,11 @@ func (b *CachingBeaconState) GetValidatorChurnLimit() uint64 { activeIndsCount := uint64(len(b.GetActiveValidatorsIndices(Epoch(b)))) return utils.Max64(activeIndsCount/b.BeaconConfig().ChurnLimitQuotient, b.BeaconConfig().MinPerEpochChurnLimit) } + +// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#new-get_validator_activation_churn_limit +func (b *CachingBeaconState) GetValidatorActivationChurnLimit() uint64 { + if b.Version() >= clparams.DenebVersion { + return utils.Min64(b.BeaconConfig().MaxPerEpochActivationChurnLimit, b.GetValidatorChurnLimit()) + } + return b.GetValidatorChurnLimit() +} diff --git a/cl/phase1/forkchoice/on_operations.go b/cl/phase1/forkchoice/on_operations.go index 8679fb6a9..743995231 100644 --- a/cl/phase1/forkchoice/on_operations.go +++ b/cl/phase1/forkchoice/on_operations.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/Giulio2002/bls" + "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/phase1/core/state" @@ -49,10 +50,18 @@ func (f *ForkChoiceStore) OnVoluntaryExit(signedVoluntaryExit *cltypes.SignedVol pk := val.PublicKey() f.mu.Unlock() - domain, err := s.GetDomain(s.BeaconConfig().DomainVoluntaryExit, voluntaryExit.Epoch) + domainType := f.beaconCfg.DomainVoluntaryExit + var domain []byte + + if s.Version() < clparams.DenebVersion { + domain, err = s.GetDomain(domainType, voluntaryExit.Epoch) + } else if s.Version() >= clparams.DenebVersion { + domain, err = fork.ComputeDomain(domainType[:], utils.Uint32ToBytes4(s.BeaconConfig().CapellaForkVersion), s.GenesisValidatorsRoot()) + } if err != nil { return err } + signingRoot, err := fork.ComputeSigningRoot(voluntaryExit, domain) if err != nil { return err diff --git a/cl/spectest/Makefile b/cl/spectest/Makefile index 42877b2a3..23c6cf4c1 100644 --- a/cl/spectest/Makefile +++ b/cl/spectest/Makefile @@ -3,15 +3,14 @@ tests: GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/ethereum/consensus-spec-tests - cd consensus-spec-tests && git checkout 99549a414c10baa9e69abcb08eb256fc1a8d54f6 && git lfs pull --exclude=tests/general,tests/minimal && cd .. + cd consensus-spec-tests && git checkout 080c96fbbf3be58e75947debfeb9ba3b2b7c9748 && git lfs pull --exclude=tests/general,tests/minimal && cd .. mv consensus-spec-tests/tests . rm -rf consensus-spec-tests rm -rf tests/minimal # not needed for now rm -rf tests/mainnet/eip6110 - # will not implement until i see it on a testnet - rm -rf tests/mainnet/deneb - + # FIXME: Add fork choice coverage for deneb + rm -rf tests/mainnet/deneb/fork_choice clean: rm -rf tests diff --git a/cl/transition/impl/eth2/operations.go b/cl/transition/impl/eth2/operations.go index 0650a1c1c..fd570038f 100644 --- a/cl/transition/impl/eth2/operations.go +++ b/cl/transition/impl/eth2/operations.go @@ -217,7 +217,12 @@ func (I *impl) ProcessVoluntaryExit(s abstract.BeaconState, signedVoluntaryExit // We can skip it in some instances if we want to optimistically sync up. if I.FullValidation { - domain, err := s.GetDomain(s.BeaconConfig().DomainVoluntaryExit, voluntaryExit.Epoch) + var domain []byte + if s.Version() < clparams.DenebVersion { + domain, err = s.GetDomain(s.BeaconConfig().DomainVoluntaryExit, voluntaryExit.Epoch) + } else if s.Version() >= clparams.DenebVersion { + domain, err = fork.ComputeDomain(s.BeaconConfig().DomainVoluntaryExit[:], utils.Uint32ToBytes4(s.BeaconConfig().CapellaForkVersion), s.GenesisValidatorsRoot()) + } if err != nil { return err } @@ -697,7 +702,10 @@ func (I *impl) processAttestation(s abstract.BeaconState, attestation *solid.Att if (data.Target().Epoch() != currentEpoch && data.Target().Epoch() != previousEpoch) || data.Target().Epoch() != state.GetEpochAtSlot(s.BeaconConfig(), data.Slot()) { return nil, errors.New("ProcessAttestation: attestation with invalid epoch") } - if data.Slot()+beaconConfig.MinAttestationInclusionDelay > stateSlot || stateSlot > data.Slot()+beaconConfig.SlotsPerEpoch { + if s.Version() < clparams.DenebVersion && ((data.Slot()+beaconConfig.MinAttestationInclusionDelay > stateSlot) || (stateSlot > data.Slot()+beaconConfig.SlotsPerEpoch)) { + return nil, errors.New("ProcessAttestation: attestation slot not in range") + } + if s.Version() >= clparams.DenebVersion && data.Slot()+beaconConfig.MinAttestationInclusionDelay > stateSlot { return nil, errors.New("ProcessAttestation: attestation slot not in range") } if data.ValidatorIndex() >= s.CommitteeCount(data.Target().Epoch()) { diff --git a/cl/transition/impl/eth2/statechange/process_registry_updates.go b/cl/transition/impl/eth2/statechange/process_registry_updates.go index c22c44226..ee56a2f0e 100644 --- a/cl/transition/impl/eth2/statechange/process_registry_updates.go +++ b/cl/transition/impl/eth2/statechange/process_registry_updates.go @@ -62,7 +62,7 @@ func ProcessRegistryUpdates(s abstract.BeaconState) error { } return activationQueue[i].validatorIndex < activationQueue[j].validatorIndex }) - activationQueueLength := s.GetValidatorChurnLimit() + activationQueueLength := s.GetValidatorActivationChurnLimit() if len(activationQueue) > int(activationQueueLength) { activationQueue = activationQueue[:activationQueueLength] }