mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 13:28:01 -05:00
Implement get_expected_withdrawals (#11618)
* Implement get_expected_withdrawals * Fix config test and export method * Radek's review * start from a different index in a test Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -103,6 +103,7 @@ func TestGetSpec(t *testing.T) {
|
||||
config.TerminalBlockHashActivationEpoch = 72
|
||||
config.TerminalTotalDifficulty = "73"
|
||||
config.DefaultFeeRecipient = common.HexToAddress("DefaultFeeRecipient")
|
||||
config.MaxWithdrawalsPerPayload = 74
|
||||
|
||||
var dbp [4]byte
|
||||
copy(dbp[:], []byte{'0', '0', '0', '1'})
|
||||
@@ -135,7 +136,7 @@ func TestGetSpec(t *testing.T) {
|
||||
resp, err := server.GetSpec(context.Background(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 102, len(resp.Data))
|
||||
assert.Equal(t, 103, len(resp.Data))
|
||||
for k, v := range resp.Data {
|
||||
switch k {
|
||||
case "CONFIG_NAME":
|
||||
@@ -355,6 +356,8 @@ func TestGetSpec(t *testing.T) {
|
||||
case "INTERVALS_PER_SLOT":
|
||||
assert.Equal(t, "3", v)
|
||||
case "SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY":
|
||||
case "MAX_WITHDRAWALS_PER_PAYLOAD":
|
||||
assert.Equal(t, "74", v)
|
||||
default:
|
||||
t.Errorf("Incorrect key: %s", k)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ go_library(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -63,6 +64,7 @@ type ReadOnlyBeaconState interface {
|
||||
Version() int
|
||||
LatestExecutionPayloadHeader() (interfaces.ExecutionData, error)
|
||||
LastWithdrawalValidatorIndex() (types.ValidatorIndex, error)
|
||||
ExpectedWithdrawals() ([]*enginev1.Withdrawal, error)
|
||||
}
|
||||
|
||||
// WriteOnlyBeaconState defines a struct which only has write access to beacon state methods.
|
||||
|
||||
@@ -62,6 +62,7 @@ go_library(
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/time/slots"
|
||||
)
|
||||
|
||||
const ETH1AddressOffset = 12
|
||||
|
||||
// NextWithdrawalIndex returns the index that will be assigned to the next withdrawal.
|
||||
func (b *BeaconState) NextWithdrawalIndex() (uint64, error) {
|
||||
if b.version < version.Capella {
|
||||
@@ -29,3 +35,80 @@ func (b *BeaconState) LastWithdrawalValidatorIndex() (types.ValidatorIndex, erro
|
||||
|
||||
return b.lastWithdrawalValidatorIndex, nil
|
||||
}
|
||||
|
||||
// ExpectedWithdrawals returns the withdrawals that a proposer will need to pack in the next block
|
||||
// applied to the current state. It is also used by validators to check that the execution payload carried
|
||||
// the right number of withdrawals
|
||||
func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
|
||||
if b.version < version.Capella {
|
||||
return nil, errNotSupported("ExpectedWithdrawals", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
withdrawals := make([]*enginev1.Withdrawal, 0, params.BeaconConfig().MaxWithdrawalsPerPayload)
|
||||
validatorIndex := b.lastWithdrawalValidatorIndex
|
||||
withdrawalIndex := b.nextWithdrawalIndex
|
||||
epoch := slots.ToEpoch(b.slot)
|
||||
for range b.validators {
|
||||
validatorIndex += 1
|
||||
if uint64(validatorIndex) == uint64(len(b.validators)) {
|
||||
validatorIndex = types.ValidatorIndex(0)
|
||||
}
|
||||
val := b.validators[validatorIndex]
|
||||
balance := b.balances[validatorIndex]
|
||||
if isFullyWithdrawableValidator(val, epoch) {
|
||||
withdrawals = append(withdrawals, &enginev1.Withdrawal{
|
||||
WithdrawalIndex: withdrawalIndex,
|
||||
ValidatorIndex: validatorIndex,
|
||||
ExecutionAddress: val.WithdrawalCredentials[ETH1AddressOffset:],
|
||||
Amount: balance,
|
||||
})
|
||||
withdrawalIndex++
|
||||
} else if isPartiallyWithdrawableValidator(val, balance) {
|
||||
withdrawals = append(withdrawals, &enginev1.Withdrawal{
|
||||
WithdrawalIndex: withdrawalIndex,
|
||||
ValidatorIndex: validatorIndex,
|
||||
ExecutionAddress: val.WithdrawalCredentials[ETH1AddressOffset:],
|
||||
Amount: balance - params.BeaconConfig().MaxEffectiveBalance,
|
||||
})
|
||||
withdrawalIndex++
|
||||
}
|
||||
if uint64(len(withdrawals)) == params.BeaconConfig().MaxWithdrawalsPerPayload {
|
||||
break
|
||||
}
|
||||
}
|
||||
return withdrawals, nil
|
||||
}
|
||||
|
||||
// hasETH1WithdrawalCredential returns whether the validator has an ETH1
|
||||
// Withdrawal prefix. It assumes that the caller has a lock on the state
|
||||
func hasETH1WithdrawalCredential(val *ethpb.Validator) bool {
|
||||
if val == nil {
|
||||
return false
|
||||
}
|
||||
cred := val.WithdrawalCredentials
|
||||
return len(cred) > 0 && cred[0] == params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
}
|
||||
|
||||
// isFullyWithdrawableValidator returns whether the validator is able to perform a full
|
||||
// withdrawal. This differ from the spec helper in that the balance > 0 is not
|
||||
// checked. This function assumes that the caller holds a lock on the state
|
||||
func isFullyWithdrawableValidator(val *ethpb.Validator, epoch types.Epoch) bool {
|
||||
if val == nil {
|
||||
return false
|
||||
}
|
||||
return hasETH1WithdrawalCredential(val) && val.WithdrawableEpoch <= epoch
|
||||
}
|
||||
|
||||
// isPartiallyWithdrawable returns whether the validator is able to perform a
|
||||
// partial withdrawal. This function assumes that the caller has a lock on the state
|
||||
func isPartiallyWithdrawableValidator(val *ethpb.Validator, balance uint64) bool {
|
||||
if val == nil {
|
||||
return false
|
||||
}
|
||||
hasMaxBalance := val.EffectiveBalance == params.BeaconConfig().MaxEffectiveBalance
|
||||
hasExcessBalance := balance > params.BeaconConfig().MaxEffectiveBalance
|
||||
return hasETH1WithdrawalCredential(val) && hasExcessBalance && hasMaxBalance
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package state_native
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
@@ -36,3 +39,271 @@ func TestLastWithdrawalValidatorIndex(t *testing.T) {
|
||||
assert.ErrorContains(t, "LastWithdrawalValidatorIndex is not supported", err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHasETH1WithdrawalCredentials(t *testing.T) {
|
||||
creds := []byte{0xFA, 0xCC}
|
||||
v := ðpb.Validator{WithdrawalCredentials: creds}
|
||||
require.Equal(t, false, hasETH1WithdrawalCredential(v))
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v = ðpb.Validator{WithdrawalCredentials: creds}
|
||||
require.Equal(t, true, hasETH1WithdrawalCredential(v))
|
||||
// No Withdrawal cred
|
||||
v = ðpb.Validator{}
|
||||
require.Equal(t, false, hasETH1WithdrawalCredential(v))
|
||||
}
|
||||
|
||||
func TestIsFullyWithdrawableValidator(t *testing.T) {
|
||||
// No ETH1 prefix
|
||||
creds := []byte{0xFA, 0xCC}
|
||||
v := ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
WithdrawableEpoch: 2,
|
||||
}
|
||||
require.Equal(t, false, isFullyWithdrawableValidator(v, 3))
|
||||
// Wrong withdrawable epoch
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v = ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
WithdrawableEpoch: 2,
|
||||
}
|
||||
require.Equal(t, false, isFullyWithdrawableValidator(v, 1))
|
||||
// Fully withdrawable
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v = ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
WithdrawableEpoch: 2,
|
||||
}
|
||||
require.Equal(t, true, isFullyWithdrawableValidator(v, 3))
|
||||
}
|
||||
|
||||
func TestIsPartiallyWithdrawableValidator(t *testing.T) {
|
||||
// No ETH1 prefix
|
||||
creds := []byte{0xFA, 0xCC}
|
||||
v, err := NewValidator(ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, v.IsPartiallyWithdrawable(params.BeaconConfig().MaxEffectiveBalance+1))
|
||||
// Not the right effective balance
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v, err = NewValidator(ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance - 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, v.IsPartiallyWithdrawable(params.BeaconConfig().MaxEffectiveBalance+1))
|
||||
// Not enough balance
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v, err = NewValidator(ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, false, v.IsPartiallyWithdrawable(params.BeaconConfig().MaxEffectiveBalance))
|
||||
// Partially Withdrawable
|
||||
creds = []byte{params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, 0xCC}
|
||||
v, err = NewValidator(ðpb.Validator{
|
||||
WithdrawalCredentials: creds,
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, v.IsPartiallyWithdrawable(params.BeaconConfig().MaxEffectiveBalance+1))
|
||||
}
|
||||
|
||||
func TestExpectedWithdrawals(t *testing.T) {
|
||||
t.Run("no withdrawals", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(1),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(expected))
|
||||
})
|
||||
t.Run("one fully withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
lastWithdrawalValidatorIndex: 20,
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(1),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
s.validators[3].WithdrawableEpoch = types.Epoch(0)
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(expected))
|
||||
withdrawal := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 3,
|
||||
ExecutionAddress: s.validators[3].WithdrawalCredentials[12:],
|
||||
Amount: s.balances[3],
|
||||
}
|
||||
require.DeepEqual(t, withdrawal, expected[0])
|
||||
})
|
||||
t.Run("one partially withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(1),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
s.balances[3] += params.BeaconConfig().MinDepositAmount
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(expected))
|
||||
withdrawal := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 3,
|
||||
ExecutionAddress: s.validators[3].WithdrawalCredentials[12:],
|
||||
Amount: params.BeaconConfig().MinDepositAmount,
|
||||
}
|
||||
require.DeepEqual(t, withdrawal, expected[0])
|
||||
})
|
||||
t.Run("one partially and one fully withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(1),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
s.balances[3] += params.BeaconConfig().MinDepositAmount
|
||||
s.validators[7].WithdrawableEpoch = types.Epoch(0)
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(expected))
|
||||
|
||||
withdrawalFull := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 1,
|
||||
ValidatorIndex: 7,
|
||||
ExecutionAddress: s.validators[7].WithdrawalCredentials[12:],
|
||||
Amount: s.balances[7],
|
||||
}
|
||||
withdrawalPartial := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 3,
|
||||
ExecutionAddress: s.validators[3].WithdrawalCredentials[12:],
|
||||
Amount: params.BeaconConfig().MinDepositAmount,
|
||||
}
|
||||
require.DeepEqual(t, withdrawalPartial, expected[0])
|
||||
require.DeepEqual(t, withdrawalFull, expected[1])
|
||||
})
|
||||
t.Run("all partially withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance + 1
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(1),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, params.BeaconConfig().MaxWithdrawalsPerPayload, uint64(len(expected)))
|
||||
withdrawal := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 1,
|
||||
ExecutionAddress: s.validators[0].WithdrawalCredentials[12:],
|
||||
Amount: 1,
|
||||
}
|
||||
require.DeepEqual(t, withdrawal, expected[0])
|
||||
})
|
||||
t.Run("all fully withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(0),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, params.BeaconConfig().MaxWithdrawalsPerPayload, uint64(len(expected)))
|
||||
withdrawal := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 1,
|
||||
ExecutionAddress: s.validators[0].WithdrawalCredentials[12:],
|
||||
Amount: params.BeaconConfig().MaxEffectiveBalance,
|
||||
}
|
||||
require.DeepEqual(t, withdrawal, expected[0])
|
||||
})
|
||||
t.Run("all fully and partially withdrawable", func(t *testing.T) {
|
||||
s := BeaconState{
|
||||
version: version.Capella,
|
||||
validators: make([]*ethpb.Validator, 100),
|
||||
balances: make([]uint64, 100),
|
||||
}
|
||||
for i := range s.validators {
|
||||
s.balances[i] = params.BeaconConfig().MaxEffectiveBalance + 1
|
||||
val := ðpb.Validator{
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
WithdrawableEpoch: types.Epoch(0),
|
||||
}
|
||||
val.WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
|
||||
s.validators[i] = val
|
||||
}
|
||||
expected, err := s.ExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, params.BeaconConfig().MaxWithdrawalsPerPayload, uint64(len(expected)))
|
||||
withdrawal := &enginev1.Withdrawal{
|
||||
WithdrawalIndex: 0,
|
||||
ValidatorIndex: 1,
|
||||
ExecutionAddress: s.validators[0].WithdrawalCredentials[12:],
|
||||
Amount: params.BeaconConfig().MaxEffectiveBalance + 1,
|
||||
}
|
||||
require.DeepEqual(t, withdrawal, expected[0])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -94,11 +94,12 @@ type BeaconChainConfig struct {
|
||||
ProportionalSlashingMultiplier uint64 `yaml:"PROPORTIONAL_SLASHING_MULTIPLIER" spec:"true"` // ProportionalSlashingMultiplier is used as a multiplier on slashed penalties.
|
||||
|
||||
// Max operations per block constants.
|
||||
MaxProposerSlashings uint64 `yaml:"MAX_PROPOSER_SLASHINGS" spec:"true"` // MaxProposerSlashings defines the maximum number of slashings of proposers possible in a block.
|
||||
MaxAttesterSlashings uint64 `yaml:"MAX_ATTESTER_SLASHINGS" spec:"true"` // MaxAttesterSlashings defines the maximum number of casper FFG slashings possible in a block.
|
||||
MaxAttestations uint64 `yaml:"MAX_ATTESTATIONS" spec:"true"` // MaxAttestations defines the maximum allowed attestations in a beacon block.
|
||||
MaxDeposits uint64 `yaml:"MAX_DEPOSITS" spec:"true"` // MaxDeposits defines the maximum number of validator deposits in a block.
|
||||
MaxVoluntaryExits uint64 `yaml:"MAX_VOLUNTARY_EXITS" spec:"true"` // MaxVoluntaryExits defines the maximum number of validator exits in a block.
|
||||
MaxProposerSlashings uint64 `yaml:"MAX_PROPOSER_SLASHINGS" spec:"true"` // MaxProposerSlashings defines the maximum number of slashings of proposers possible in a block.
|
||||
MaxAttesterSlashings uint64 `yaml:"MAX_ATTESTER_SLASHINGS" spec:"true"` // MaxAttesterSlashings defines the maximum number of casper FFG slashings possible in a block.
|
||||
MaxAttestations uint64 `yaml:"MAX_ATTESTATIONS" spec:"true"` // MaxAttestations defines the maximum allowed attestations in a beacon block.
|
||||
MaxDeposits uint64 `yaml:"MAX_DEPOSITS" spec:"true"` // MaxDeposits defines the maximum number of validator deposits in a block.
|
||||
MaxVoluntaryExits uint64 `yaml:"MAX_VOLUNTARY_EXITS" spec:"true"` // MaxVoluntaryExits defines the maximum number of validator exits in a block.
|
||||
MaxWithdrawalsPerPayload uint64 `yaml:"MAX_WITHDRAWALS_PER_PAYLOAD" spec:"true"` // MaxWithdrawalsPerPayload defines the maximum number of withdrawals in a block.
|
||||
|
||||
// BLS domain values.
|
||||
DomainBeaconProposer [4]byte `yaml:"DOMAIN_BEACON_PROPOSER" spec:"true"` // DomainBeaconProposer defines the BLS signature domain for beacon proposal verification.
|
||||
|
||||
@@ -149,11 +149,12 @@ var mainnetBeaconConfig = &BeaconChainConfig{
|
||||
ProportionalSlashingMultiplier: 1,
|
||||
|
||||
// Max operations per block constants.
|
||||
MaxProposerSlashings: 16,
|
||||
MaxAttesterSlashings: 2,
|
||||
MaxAttestations: 128,
|
||||
MaxDeposits: 16,
|
||||
MaxVoluntaryExits: 16,
|
||||
MaxProposerSlashings: 16,
|
||||
MaxAttesterSlashings: 2,
|
||||
MaxAttestations: 128,
|
||||
MaxDeposits: 16,
|
||||
MaxVoluntaryExits: 16,
|
||||
MaxWithdrawalsPerPayload: 16,
|
||||
|
||||
// BLS domain values.
|
||||
DomainBeaconProposer: bytesutil.Uint32ToBytes4(0x00000000),
|
||||
|
||||
@@ -67,6 +67,7 @@ func MinimalSpecConfig() *BeaconChainConfig {
|
||||
minimalConfig.MaxAttestations = 128
|
||||
minimalConfig.MaxDeposits = 16
|
||||
minimalConfig.MaxVoluntaryExits = 16
|
||||
minimalConfig.MaxWithdrawalsPerPayload = 4
|
||||
|
||||
// Signature domains
|
||||
minimalConfig.DomainBeaconProposer = bytesutil.ToBytes4(bytesutil.Bytes4(0))
|
||||
|
||||
@@ -100,6 +100,7 @@ func compareConfigs(t *testing.T, expected, actual *params.BeaconChainConfig) {
|
||||
require.DeepEqual(t, expected.MaxAttestations, actual.MaxAttestations)
|
||||
require.DeepEqual(t, expected.MaxDeposits, actual.MaxDeposits)
|
||||
require.DeepEqual(t, expected.MaxVoluntaryExits, actual.MaxVoluntaryExits)
|
||||
require.DeepEqual(t, expected.MaxWithdrawalsPerPayload, actual.MaxWithdrawalsPerPayload)
|
||||
require.DeepEqual(t, expected.DomainBeaconProposer, actual.DomainBeaconProposer)
|
||||
require.DeepEqual(t, expected.DomainRandao, actual.DomainRandao)
|
||||
require.DeepEqual(t, expected.DomainBeaconAttester, actual.DomainBeaconAttester)
|
||||
|
||||
Reference in New Issue
Block a user