Skip to content

Commit 143d472

Browse files
Unit tests for new process_withdrawal logic in electra
1 parent 6852f64 commit 143d472

File tree

1 file changed

+103
-38
lines changed

1 file changed

+103
-38
lines changed

beacon-chain/core/blocks/withdrawals_test.go

Lines changed: 103 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import (
1212
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
1313
"github.com/prysmaticlabs/prysm/v5/config/params"
1414
consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
15+
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
1516
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
1617
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
1718
"github.com/prysmaticlabs/prysm/v5/crypto/bls/common"
1819
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
1920
"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
2021
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
2122
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
23+
"github.com/prysmaticlabs/prysm/v5/runtime/version"
2224
"github.com/prysmaticlabs/prysm/v5/testing/require"
2325
"github.com/prysmaticlabs/prysm/v5/time/slots"
2426
)
@@ -675,6 +677,7 @@ func TestProcessWithdrawals(t *testing.T) {
675677
FullWithdrawalIndices []primitives.ValidatorIndex
676678
PendingPartialWithdrawalIndices []primitives.ValidatorIndex
677679
Withdrawals []*enginev1.Withdrawal
680+
PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal // Electra
678681
}
679682
type control struct {
680683
NextWithdrawalValidatorIndex primitives.ValidatorIndex
@@ -772,7 +775,7 @@ func TestProcessWithdrawals(t *testing.T) {
772775
},
773776
{
774777
Args: args{
775-
Name: "Less than max sweep at end",
778+
Name: "less than max sweep at end",
776779
NextWithdrawalIndex: 22,
777780
NextWithdrawalValidatorIndex: 4,
778781
FullWithdrawalIndices: []primitives.ValidatorIndex{80, 81, 82, 83},
@@ -789,7 +792,7 @@ func TestProcessWithdrawals(t *testing.T) {
789792
},
790793
{
791794
Args: args{
792-
Name: "Less than max sweep and beginning",
795+
Name: "less than max sweep and beginning",
793796
NextWithdrawalIndex: 22,
794797
NextWithdrawalValidatorIndex: 4,
795798
FullWithdrawalIndices: []primitives.ValidatorIndex{4, 5, 6},
@@ -846,6 +849,36 @@ func TestProcessWithdrawals(t *testing.T) {
846849
},
847850
},
848851
},
852+
{
853+
Args: args{
854+
Name: "success many withdrawals with pending partial withdrawals in state",
855+
NextWithdrawalIndex: 22,
856+
NextWithdrawalValidatorIndex: 88,
857+
FullWithdrawalIndices: []primitives.ValidatorIndex{7, 19, 28},
858+
PendingPartialWithdrawalIndices: []primitives.ValidatorIndex{2, 1, 89, 15},
859+
Withdrawals: []*enginev1.Withdrawal{
860+
PendingPartialWithdrawal(89, 22), PendingPartialWithdrawal(1, 23), PendingPartialWithdrawal(2, 24),
861+
fullWithdrawal(7, 25), PendingPartialWithdrawal(15, 26), fullWithdrawal(19, 27),
862+
fullWithdrawal(28, 28),
863+
},
864+
PendingPartialWithdrawals: []*ethpb.PendingPartialWithdrawal{
865+
{
866+
Index: 11,
867+
Amount: withdrawalAmount(11) - maxEffectiveBalance,
868+
},
869+
},
870+
},
871+
Control: control{
872+
NextWithdrawalValidatorIndex: 40,
873+
NextWithdrawalIndex: 29,
874+
Balances: map[uint64]uint64{
875+
7: 0, 19: 0, 28: 0,
876+
2: maxEffectiveBalance, 1: maxEffectiveBalance, 89: maxEffectiveBalance,
877+
15: maxEffectiveBalance,
878+
},
879+
},
880+
},
881+
849882
{
850883
Args: args{
851884
Name: "success more than max fully withdrawals",
@@ -1011,65 +1044,97 @@ func TestProcessWithdrawals(t *testing.T) {
10111044
}
10121045
}
10131046

1014-
prepareValidators := func(st *ethpb.BeaconStateCapella, arguments args) (state.BeaconState, error) {
1047+
prepareValidators := func(st state.BeaconState, arguments args) error {
10151048
validators := make([]*ethpb.Validator, numValidators)
1016-
st.Balances = make([]uint64, numValidators)
1049+
if err := st.SetBalances(make([]uint64, numValidators)); err != nil {
1050+
return err
1051+
}
10171052
for i := range validators {
10181053
v := &ethpb.Validator{}
10191054
v.EffectiveBalance = maxEffectiveBalance
10201055
v.WithdrawableEpoch = epochInFuture
10211056
v.WithdrawalCredentials = make([]byte, 32)
10221057
v.WithdrawalCredentials[31] = byte(i)
1023-
st.Balances[i] = v.EffectiveBalance - uint64(rand.Intn(1000))
1058+
if err := st.UpdateBalancesAtIndex(primitives.ValidatorIndex(i), v.EffectiveBalance-uint64(rand.Intn(1000))); err != nil {
1059+
return err
1060+
}
10241061
validators[i] = v
10251062
}
10261063
for _, idx := range arguments.FullWithdrawalIndices {
10271064
if idx != notWithdrawableIndex {
10281065
validators[idx].WithdrawableEpoch = epochInPast
10291066
}
1030-
st.Balances[idx] = withdrawalAmount(idx)
1067+
if err := st.UpdateBalancesAtIndex(idx, withdrawalAmount(idx)); err != nil {
1068+
return err
1069+
}
10311070
validators[idx].WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
10321071
}
10331072
for _, idx := range arguments.PendingPartialWithdrawalIndices {
10341073
validators[idx].WithdrawalCredentials[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
1035-
st.Balances[idx] = withdrawalAmount(idx)
1074+
if err := st.UpdateBalancesAtIndex(idx, withdrawalAmount(idx)); err != nil {
1075+
return err
1076+
}
10361077
}
1037-
st.Validators = validators
1038-
return state_native.InitializeFromProtoCapella(st)
1078+
return st.SetValidators(validators)
10391079
}
10401080

10411081
for _, test := range tests {
10421082
t.Run(test.Args.Name, func(t *testing.T) {
1043-
saved := params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep
1044-
params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep = maxSweep
1045-
if test.Args.Withdrawals == nil {
1046-
test.Args.Withdrawals = make([]*enginev1.Withdrawal, 0)
1047-
}
1048-
if test.Args.FullWithdrawalIndices == nil {
1049-
test.Args.FullWithdrawalIndices = make([]primitives.ValidatorIndex, 0)
1050-
}
1051-
if test.Args.PendingPartialWithdrawalIndices == nil {
1052-
test.Args.PendingPartialWithdrawalIndices = make([]primitives.ValidatorIndex, 0)
1053-
}
1054-
slot, err := slots.EpochStart(currentEpoch)
1055-
require.NoError(t, err)
1056-
spb := &ethpb.BeaconStateCapella{
1057-
Slot: slot,
1058-
NextWithdrawalValidatorIndex: test.Args.NextWithdrawalValidatorIndex,
1059-
NextWithdrawalIndex: test.Args.NextWithdrawalIndex,
1060-
}
1061-
st, err := prepareValidators(spb, test.Args)
1062-
require.NoError(t, err)
1063-
p, err := consensusblocks.WrappedExecutionPayloadCapella(&enginev1.ExecutionPayloadCapella{Withdrawals: test.Args.Withdrawals})
1064-
require.NoError(t, err)
1065-
post, err := blocks.ProcessWithdrawals(st, p)
1066-
if test.Control.ExpectedError {
1067-
require.NotNil(t, err)
1068-
} else {
1069-
require.NoError(t, err)
1070-
checkPostState(t, test.Control, post)
1083+
for _, fork := range []int{version.Capella, version.Electra} {
1084+
t.Run(version.String(fork), func(t *testing.T) {
1085+
saved := params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep
1086+
params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep = maxSweep
1087+
if test.Args.Withdrawals == nil {
1088+
test.Args.Withdrawals = make([]*enginev1.Withdrawal, 0)
1089+
}
1090+
if test.Args.FullWithdrawalIndices == nil {
1091+
test.Args.FullWithdrawalIndices = make([]primitives.ValidatorIndex, 0)
1092+
}
1093+
if test.Args.PendingPartialWithdrawalIndices == nil {
1094+
test.Args.PendingPartialWithdrawalIndices = make([]primitives.ValidatorIndex, 0)
1095+
}
1096+
slot, err := slots.EpochStart(currentEpoch)
1097+
require.NoError(t, err)
1098+
var st state.BeaconState
1099+
var p interfaces.ExecutionData
1100+
switch fork {
1101+
case version.Capella:
1102+
spb := &ethpb.BeaconStateCapella{
1103+
Slot: slot,
1104+
NextWithdrawalValidatorIndex: test.Args.NextWithdrawalValidatorIndex,
1105+
NextWithdrawalIndex: test.Args.NextWithdrawalIndex,
1106+
}
1107+
st, err = state_native.InitializeFromProtoUnsafeCapella(spb)
1108+
require.NoError(t, err)
1109+
p, err = consensusblocks.WrappedExecutionPayloadCapella(&enginev1.ExecutionPayloadCapella{Withdrawals: test.Args.Withdrawals})
1110+
require.NoError(t, err)
1111+
case version.Electra:
1112+
spb := &ethpb.BeaconStateElectra{
1113+
Slot: slot,
1114+
NextWithdrawalValidatorIndex: test.Args.NextWithdrawalValidatorIndex,
1115+
NextWithdrawalIndex: test.Args.NextWithdrawalIndex,
1116+
PendingPartialWithdrawals: test.Args.PendingPartialWithdrawals,
1117+
}
1118+
st, err = state_native.InitializeFromProtoUnsafeElectra(spb)
1119+
require.NoError(t, err)
1120+
p, err = consensusblocks.WrappedExecutionPayloadElectra(&enginev1.ExecutionPayloadElectra{Withdrawals: test.Args.Withdrawals})
1121+
require.NoError(t, err)
1122+
default:
1123+
t.Fatalf("Add a beacon state setup for version %s", version.String(fork))
1124+
}
1125+
err = prepareValidators(st, test.Args)
1126+
require.NoError(t, err)
1127+
post, err := blocks.ProcessWithdrawals(st, p)
1128+
if test.Control.ExpectedError {
1129+
require.NotNil(t, err)
1130+
} else {
1131+
require.NoError(t, err)
1132+
checkPostState(t, test.Control, post)
1133+
}
1134+
params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep = saved
1135+
1136+
})
10711137
}
1072-
params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep = saved
10731138
})
10741139
}
10751140
}

0 commit comments

Comments
 (0)