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

chore(boonet): Fork 3 handling #2250

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
7 changes: 6 additions & 1 deletion beacon/validator/block_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,12 @@ func convertAttestationData[
for i, d := range data {
val, ok := any(d).(AttestationDataT)
if !ok {
panic(fmt.Sprintf("failed to convert attestation data at index %d", i))
panic(
fmt.Sprintf(
"failed to convert attestation data at index %d",
i,
),
)
}
converted[i] = val
}
Expand Down
23 changes: 10 additions & 13 deletions chain-spec/chain/chain_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Spec[

// MaxEffectiveBalance returns the maximum balance counted in rewards
// calculations in Gwei.
MaxEffectiveBalance() uint64
MaxEffectiveBalance(isPostUpgrade bool) uint64

// EjectionBalance returns the balance below which a validator is ejected.
EjectionBalance() uint64
Expand Down Expand Up @@ -155,11 +155,7 @@ type Spec[

// MaxValidatorsPerWithdrawalsSweep returns the maximum number of validators
// per withdrawal sweep.
MaxValidatorsPerWithdrawalsSweep(
isPostUpgrade func(uint64, SlotT) bool,
chainID uint64,
slot SlotT,
) uint64
MaxValidatorsPerWithdrawalsSweep(isPostUpgrade bool) uint64

// Deneb Values

Expand Down Expand Up @@ -278,8 +274,12 @@ func (c chainSpec[
// MaxEffectiveBalance returns the maximum effective balance.
func (c chainSpec[
DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT,
]) MaxEffectiveBalance() uint64 {
return c.Data.MaxEffectiveBalance
]) MaxEffectiveBalance(isPostUpgrade bool) uint64 {
if isPostUpgrade {
return c.Data.MaxEffectiveBalancePostUpgrade
}

return c.Data.MaxEffectiveBalancePreUpgrade
}

// EjectionBalance returns the balance below which a validator is ejected.
Expand Down Expand Up @@ -497,11 +497,8 @@ func (c chainSpec[
// withdrawals sweep.
func (c chainSpec[
DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT,
]) MaxValidatorsPerWithdrawalsSweep(
isPostUpgrade func(uint64, SlotT) bool,
chainID uint64, slot SlotT,
) uint64 {
if isPostUpgrade(chainID, slot) {
]) MaxValidatorsPerWithdrawalsSweep(isPostUpgrade bool) uint64 {
if isPostUpgrade {
return c.Data.MaxValidatorsPerWithdrawalsSweepPostUpgrade
}

Expand Down
7 changes: 5 additions & 2 deletions chain-spec/chain/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ type SpecData[
// transaction.
MinDepositAmount uint64 `mapstructure:"min-deposit-amount"`
// MaxEffectiveBalance is the maximum effective balance allowed for a
// validator.
MaxEffectiveBalance uint64 `mapstructure:"max-effective-balance"`
// validator before the upgrade.
MaxEffectiveBalancePreUpgrade uint64 `mapstructure:"max-effective-balance-pre-upgrade"`
// MaxEffectiveBalancePostUpgrade is the maximum effective balance allowed
// for a validator after the upgrade.
MaxEffectiveBalancePostUpgrade uint64 `mapstructure:"max-effective-balance-post-upgrade"`
// EjectionBalance is the balance at which a validator is ejected.
EjectionBalance uint64 `mapstructure:"ejection-balance"`
// EffectiveBalanceIncrement is the effective balance increment.
Expand Down
2 changes: 1 addition & 1 deletion cli/commands/genesis/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func GetGenesisValidatorRootCmd(cs common.ChainSpec) *cobra.Command {
types.WithdrawalCredentials(deposit.Credentials),
deposit.Amount,
math.Gwei(cs.EffectiveBalanceIncrement()),
math.Gwei(cs.MaxEffectiveBalance()),
math.Gwei(cs.MaxEffectiveBalance(false)),
)
}

Expand Down
9 changes: 5 additions & 4 deletions config/spec/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ func BaseSpec() chain.SpecData[
any,
]{
// Gwei value constants.
MinDepositAmount: 1e9,
MaxEffectiveBalance: 32e9,
EjectionBalance: 16e9,
EffectiveBalanceIncrement: 1e9,
MinDepositAmount: 1e9,
MaxEffectiveBalancePreUpgrade: 32e9,
MaxEffectiveBalancePostUpgrade: 32e9,
EjectionBalance: 16e9,
EffectiveBalanceIncrement: 1e9,

HysteresisQuotient: 4,
HysteresisDownwardMultiplier: 1,
Expand Down
12 changes: 6 additions & 6 deletions config/spec/boonet.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ func BoonetChainSpec() (chain.Spec[
)

// BERA per block minting.
//
// TODO: Determine correct value for boonet upgrade.
boonetSpec.EVMInflationPerBlock = 2.5e9

// ValidatorSetCap is 256 on the Boonet chain.
//
// TODO: Determine correct value for boonet upgrade.
boonetSpec.ValidatorSetCap = 256

// MaxValidatorsPerWithdrawalsSweep is 43 because we expect at least 46
// validators in the total validators set. We choose a prime number smaller
// than the minimum amount of total validators possible.
//
// TODO: Determine correct value for boonet upgrade.
boonetSpec.MaxValidatorsPerWithdrawalsSweepPostUpgrade = 43

// MaxEffectiveBalancePostUpgrade is 5 million BERA after the boonet
// upgrade.
//
//nolint:mnd // ok.
boonetSpec.MaxEffectiveBalancePostUpgrade = 5_000_000 * 1e9

return chain.NewChainSpec(boonetSpec)
}
4 changes: 1 addition & 3 deletions config/spec/special_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

package spec

import "math"

// Special cased Bartio for some ad-hoc handling due to the way
// some bugs were handled on Bartio. To be removed.
const (
Expand All @@ -36,5 +34,5 @@ const (

BoonetFork2Height uint64 = 1722000

BoonetFork3Height uint64 = math.MaxUint64
BoonetFork3Height uint64 = 2235000
)
10 changes: 7 additions & 3 deletions state-transition/core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (s *StateDB[

bound := min(
totalValidators, s.cs.MaxValidatorsPerWithdrawalsSweep(
IsPostUpgrade, s.cs.DepositEth1ChainID(), slot,
IsPostFork2(s.cs.DepositEth1ChainID(), slot),
),
)

Expand Down Expand Up @@ -281,7 +281,9 @@ func (s *StateDB[
// Increment the withdrawal index to process the next withdrawal.
withdrawalIndex++
} else if validator.IsPartiallyWithdrawable(
balance, math.Gwei(s.cs.MaxEffectiveBalance()),
balance, math.Gwei(s.cs.MaxEffectiveBalance(
IsPostFork3(s.cs.DepositEth1ChainID(), slot),
)),
) {
withdrawalAddress, err = validator.
GetWithdrawalCredentials().ToExecutionAddress()
Expand All @@ -293,7 +295,9 @@ func (s *StateDB[
math.U64(withdrawalIndex),
validatorIndex,
withdrawalAddress,
balance-math.Gwei(s.cs.MaxEffectiveBalance()),
balance-math.Gwei(s.cs.MaxEffectiveBalance(
IsPostFork3(s.cs.DepositEth1ChainID(), slot),
)),
))

// Increment the withdrawal index to process the next withdrawal.
Expand Down
22 changes: 20 additions & 2 deletions state-transition/core/state/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ import (
"github.com/berachain/beacon-kit/primitives/math"
)

// IsPostUpgrade returns true if the chain is post-upgrade (Fork2 on Boonet).
// IsPostFork2 returns true if the chain is post-upgrade (Fork2 on Boonet).
//
// TODO: Jank. Refactor into better fork version management.
func IsPostUpgrade(chainID uint64, slot math.Slot) bool {
func IsPostFork2(chainID uint64, slot math.Slot) bool {
switch chainID {
case spec.BartioChainID:
return false
Expand All @@ -42,3 +42,21 @@ func IsPostUpgrade(chainID uint64, slot math.Slot) bool {
return true
}
}

// IsPostFork3 returns true if the chain is post-upgrade (Fork3 on Boonet).
//
// TODO: Jank. Refactor into better fork version management.
func IsPostFork3(chainID uint64, slot math.Slot) bool {
switch chainID {
case spec.BartioChainID:
return false
case spec.BoonetEth1ChainID:
if slot < math.U64(spec.BoonetFork3Height) {
return false
}

return true
default:
return true
}
}
8 changes: 6 additions & 2 deletions state-transition/core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/berachain/beacon-kit/primitives/crypto"
"github.com/berachain/beacon-kit/primitives/math"
"github.com/berachain/beacon-kit/primitives/transition"
"github.com/berachain/beacon-kit/state-transition/core/state"
)

// StateProcessor is a basic Processor, which takes care of the
Expand Down Expand Up @@ -376,7 +377,7 @@ func (sp *StateProcessor[
if err = sp.processRegistryUpdates(st); err != nil {
return nil, err
}
if err = sp.processEffectiveBalanceUpdates(st); err != nil {
if err = sp.processEffectiveBalanceUpdates(st, slot); err != nil {
return nil, err
}
if err = sp.processSlashingsReset(st); err != nil {
Expand Down Expand Up @@ -490,6 +491,7 @@ func (sp *StateProcessor[
_, _, BeaconStateT, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) processEffectiveBalanceUpdates(
st BeaconStateT,
slot math.Slot,
) error {
// Update effective balances with hysteresis
validators, err := st.GetValidators()
Expand Down Expand Up @@ -526,7 +528,9 @@ func (sp *StateProcessor[
updatedBalance := ctypes.ComputeEffectiveBalance(
balance,
math.U64(sp.cs.EffectiveBalanceIncrement()),
math.U64(sp.cs.MaxEffectiveBalance()),
math.U64(sp.cs.MaxEffectiveBalance(
state.IsPostFork3(sp.cs.DepositEth1ChainID(), slot),
)),
)
val.SetEffectiveBalance(updatedBalance)
if err = st.UpdateValidatorAtIndex(idx, val); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions state-transition/core/state_processor_genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestInitialize(t *testing.T) {
sp, st, _, _ := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
increment = math.Gwei(cs.EffectiveBalanceIncrement())
minBalance = math.Gwei(cs.EjectionBalance())
)
Expand Down Expand Up @@ -193,7 +193,7 @@ func TestInitializeBartio(t *testing.T) {
sp, st, _, _ := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
increment = math.Gwei(cs.EffectiveBalanceIncrement())
minBalance = math.Gwei(cs.EjectionBalance())
)
Expand Down Expand Up @@ -366,7 +366,7 @@ func commonChecksValidators(
require.Equal(t, dep.Pubkey, val.Pubkey)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
increment = math.Gwei(cs.EffectiveBalanceIncrement())
minBalance = math.Gwei(cs.EjectionBalance())
)
Expand Down
8 changes: 6 additions & 2 deletions state-transition/core/state_processor_staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
"github.com/berachain/beacon-kit/primitives/version"
"github.com/berachain/beacon-kit/state-transition/core/state"
)

// processOperations processes the operations and ensures they match the
Expand Down Expand Up @@ -188,7 +189,7 @@ func (sp *StateProcessor[
}

// Add the validator to the registry.
return sp.addValidatorToRegistry(st, dep)
return sp.addValidatorToRegistry(st, dep, slot)
}

// addValidatorToRegistry adds a validator to the registry.
Expand All @@ -197,14 +198,17 @@ func (sp *StateProcessor[
]) addValidatorToRegistry(
st BeaconStateT,
dep DepositT,
slot math.Slot,
) error {
var val ValidatorT
val = val.New(
dep.GetPubkey(),
dep.GetWithdrawalCredentials(),
dep.GetAmount(),
math.Gwei(sp.cs.EffectiveBalanceIncrement()),
math.Gwei(sp.cs.MaxEffectiveBalance()),
math.Gwei(sp.cs.MaxEffectiveBalance(
state.IsPostFork3(sp.cs.DepositEth1ChainID(), slot),
)),
)

// TODO: This is a bug that lives on bArtio. Delete this eventually.
Expand Down
12 changes: 6 additions & 6 deletions state-transition/core/state_processor_staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestTransitionUpdateValidators(t *testing.T) {
sp, st, ds, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
increment = math.Gwei(cs.EffectiveBalanceIncrement())
minBalance = math.Gwei(cs.EjectionBalance())
emptyCredentials = types.NewCredentialsFromExecutionAddress(
Expand Down Expand Up @@ -194,7 +194,7 @@ func TestTransitionCreateValidator(t *testing.T) {
sp, st, ds, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
increment = math.Gwei(cs.EffectiveBalanceIncrement())
minBalance = math.Gwei(cs.EjectionBalance())
emptyAddress = common.ExecutionAddress{}
Expand Down Expand Up @@ -389,7 +389,7 @@ func TestTransitionWithdrawals(t *testing.T) {
sp, st, _, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
minBalance = math.Gwei(cs.EffectiveBalanceIncrement())
credentials0 = types.NewCredentialsFromExecutionAddress(
common.ExecutionAddress{},
Expand Down Expand Up @@ -482,7 +482,7 @@ func TestTransitionMaxWithdrawals(t *testing.T) {
sp, st, _, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
minBalance = math.Gwei(cs.EffectiveBalanceIncrement())
address0 = common.ExecutionAddress{}
credentials0 = types.NewCredentialsFromExecutionAddress(address0)
Expand Down Expand Up @@ -620,7 +620,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {
sp, st, ds, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
ejectionBalance = math.Gwei(cs.EjectionBalance())
minBalance = ejectionBalance + math.Gwei(
cs.EffectiveBalanceIncrement(),
Expand Down Expand Up @@ -848,7 +848,7 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {
sp, st, ds, ctx := setupState(t, cs)

var (
maxBalance = math.Gwei(cs.MaxEffectiveBalance())
maxBalance = math.Gwei(cs.MaxEffectiveBalance(false))
ejectionBalance = math.Gwei(cs.EjectionBalance())
minBalance = ejectionBalance + math.Gwei(
cs.EffectiveBalanceIncrement(),
Expand Down
7 changes: 4 additions & 3 deletions state-transition/core/state_processor_withdrawals.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import (
// NOTE: Modified from the Ethereum 2.0 specification to support EVM inflation:
// 1. The first withdrawal MUST be a fixed EVM inflation withdrawal
// 2. Subsequent withdrawals (if any) are processed as validator withdrawals
// 3. This modification reduces the maximum validator withdrawals per block by one.
// 3. This modification reduces the maximum validator withdrawals per block by
// one.
func (sp *StateProcessor[
BeaconBlockT, _, BeaconStateT, _, _, _, _, _, _, _, _, _, _, _, _, _,
]) processWithdrawals(
Expand Down Expand Up @@ -188,7 +189,7 @@ func (sp *StateProcessor[
}
nextValidatorIndex += math.ValidatorIndex(
sp.cs.MaxValidatorsPerWithdrawalsSweep(
state.IsPostUpgrade, sp.cs.DepositEth1ChainID(), slot,
state.IsPostFork2(sp.cs.DepositEth1ChainID(), slot),
))
nextValidatorIndex %= math.ValidatorIndex(totalValidators)
}
Expand Down Expand Up @@ -265,7 +266,7 @@ func (sp *StateProcessor[
}
nextValidatorIndex += math.ValidatorIndex(
sp.cs.MaxValidatorsPerWithdrawalsSweep(
state.IsPostUpgrade, sp.cs.DepositEth1ChainID(), slot,
state.IsPostFork2(sp.cs.DepositEth1ChainID(), slot),
))
nextValidatorIndex %= math.ValidatorIndex(totalValidators)
}
Expand Down
Loading