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: &ethpb.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 = &ethpb.BeaconBlock{
    41  		Body: &ethpb.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: &ethpb.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 = &ethpb.BeaconBlock{
    71  		Body: &ethpb.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: &ethpb.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 = &ethpb.BeaconBlock{
   120  		Body: &ethpb.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  }