github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/blocks/exit_test.go (about) 1 package blocks_test 2 3 import ( 4 "context" 5 "testing" 6 7 types "github.com/prysmaticlabs/eth2-types" 8 "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" 9 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 10 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1" 11 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 12 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 13 "github.com/prysmaticlabs/prysm/shared/bls" 14 "github.com/prysmaticlabs/prysm/shared/params" 15 "github.com/prysmaticlabs/prysm/shared/testutil" 16 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 17 "github.com/prysmaticlabs/prysm/shared/testutil/require" 18 ) 19 20 func TestProcessVoluntaryExits_NotActiveLongEnoughToExit(t *testing.T) { 21 exits := []*ethpb.SignedVoluntaryExit{ 22 { 23 Exit: ðpb.VoluntaryExit{ 24 ValidatorIndex: 0, 25 Epoch: 0, 26 }, 27 }, 28 } 29 registry := []*ethpb.Validator{ 30 { 31 ExitEpoch: params.BeaconConfig().FarFutureEpoch, 32 }, 33 } 34 state, err := v1.InitializeFromProto(&pb.BeaconState{ 35 Validators: registry, 36 Slot: 10, 37 }) 38 require.NoError(t, err) 39 b := testutil.NewBeaconBlock() 40 b.Block = ðpb.BeaconBlock{ 41 Body: ðpb.BeaconBlockBody{ 42 VoluntaryExits: exits, 43 }, 44 } 45 46 want := "validator has not been active long enough to exit" 47 _, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits) 48 assert.ErrorContains(t, want, err) 49 } 50 51 func TestProcessVoluntaryExits_ExitAlreadySubmitted(t *testing.T) { 52 exits := []*ethpb.SignedVoluntaryExit{ 53 { 54 Exit: ðpb.VoluntaryExit{ 55 Epoch: 10, 56 }, 57 }, 58 } 59 registry := []*ethpb.Validator{ 60 { 61 ExitEpoch: 10, 62 }, 63 } 64 state, err := v1.InitializeFromProto(&pb.BeaconState{ 65 Validators: registry, 66 Slot: 0, 67 }) 68 require.NoError(t, err) 69 b := testutil.NewBeaconBlock() 70 b.Block = ðpb.BeaconBlock{ 71 Body: ðpb.BeaconBlockBody{ 72 VoluntaryExits: exits, 73 }, 74 } 75 76 want := "validator with index 0 has already submitted an exit, which will take place at epoch: 10" 77 _, err = blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits) 78 assert.ErrorContains(t, want, err) 79 } 80 81 func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) { 82 exits := []*ethpb.SignedVoluntaryExit{ 83 { 84 Exit: ðpb.VoluntaryExit{ 85 ValidatorIndex: 0, 86 Epoch: 0, 87 }, 88 }, 89 } 90 registry := []*ethpb.Validator{ 91 { 92 ExitEpoch: params.BeaconConfig().FarFutureEpoch, 93 ActivationEpoch: 0, 94 }, 95 } 96 state, err := v1.InitializeFromProto(&pb.BeaconState{ 97 Validators: registry, 98 Fork: &pb.Fork{ 99 CurrentVersion: params.BeaconConfig().GenesisForkVersion, 100 PreviousVersion: params.BeaconConfig().GenesisForkVersion, 101 }, 102 Slot: params.BeaconConfig().SlotsPerEpoch * 5, 103 }) 104 require.NoError(t, err) 105 err = state.SetSlot(state.Slot() + params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod))) 106 require.NoError(t, err) 107 108 priv, err := bls.RandKey() 109 require.NoError(t, err) 110 111 val, err := state.ValidatorAtIndex(0) 112 require.NoError(t, err) 113 val.PublicKey = priv.PublicKey().Marshal() 114 require.NoError(t, state.UpdateValidatorAtIndex(0, val)) 115 exits[0].Signature, err = helpers.ComputeDomainAndSign(state, helpers.CurrentEpoch(state), exits[0].Exit, params.BeaconConfig().DomainVoluntaryExit, priv) 116 require.NoError(t, err) 117 118 b := testutil.NewBeaconBlock() 119 b.Block = ðpb.BeaconBlock{ 120 Body: ðpb.BeaconBlockBody{ 121 VoluntaryExits: exits, 122 }, 123 } 124 125 newState, err := blocks.ProcessVoluntaryExits(context.Background(), state, b.Block.Body.VoluntaryExits) 126 require.NoError(t, err, "Could not process exits") 127 newRegistry := newState.Validators() 128 if newRegistry[0].ExitEpoch != helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)) { 129 t.Errorf("Expected validator exit epoch to be %d, got %d", 130 helpers.ActivationExitEpoch(types.Epoch(state.Slot()/params.BeaconConfig().SlotsPerEpoch)), newRegistry[0].ExitEpoch) 131 } 132 }