github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/sync/validate_voluntary_exit_test.go (about) 1 package sync 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "reflect" 8 "testing" 9 10 lru "github.com/hashicorp/golang-lru" 11 pubsub "github.com/libp2p/go-libp2p-pubsub" 12 pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" 13 mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing" 14 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 15 "github.com/prysmaticlabs/prysm/beacon-chain/p2p" 16 p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing" 17 iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface" 18 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1" 19 mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing" 20 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 21 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 22 "github.com/prysmaticlabs/prysm/shared/bls" 23 "github.com/prysmaticlabs/prysm/shared/params" 24 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 25 "github.com/prysmaticlabs/prysm/shared/testutil/require" 26 ) 27 28 func setupValidExit(t *testing.T) (*ethpb.SignedVoluntaryExit, iface.BeaconState) { 29 exit := ðpb.SignedVoluntaryExit{ 30 Exit: ðpb.VoluntaryExit{ 31 ValidatorIndex: 0, 32 Epoch: 1 + params.BeaconConfig().ShardCommitteePeriod, 33 }, 34 } 35 registry := []*ethpb.Validator{ 36 { 37 ExitEpoch: params.BeaconConfig().FarFutureEpoch, 38 ActivationEpoch: 0, 39 }, 40 } 41 state, err := v1.InitializeFromProto(&pb.BeaconState{ 42 Validators: registry, 43 Fork: &pb.Fork{ 44 CurrentVersion: params.BeaconConfig().GenesisForkVersion, 45 PreviousVersion: params.BeaconConfig().GenesisForkVersion, 46 }, 47 Slot: params.BeaconConfig().SlotsPerEpoch * 5, 48 }) 49 require.NoError(t, err) 50 err = state.SetSlot(state.Slot() + params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().ShardCommitteePeriod))) 51 require.NoError(t, err) 52 53 priv, err := bls.RandKey() 54 require.NoError(t, err) 55 exit.Signature, err = helpers.ComputeDomainAndSign(state, helpers.CurrentEpoch(state), exit.Exit, params.BeaconConfig().DomainVoluntaryExit, priv) 56 require.NoError(t, err) 57 58 val, err := state.ValidatorAtIndex(0) 59 require.NoError(t, err) 60 val.PublicKey = priv.PublicKey().Marshal() 61 require.NoError(t, state.UpdateValidatorAtIndex(0, val)) 62 63 b := make([]byte, 32) 64 _, err = rand.Read(b) 65 require.NoError(t, err) 66 67 return exit, state 68 } 69 70 func TestValidateVoluntaryExit_ValidExit(t *testing.T) { 71 p := p2ptest.NewTestP2P(t) 72 ctx := context.Background() 73 74 exit, s := setupValidExit(t) 75 76 c, err := lru.New(10) 77 require.NoError(t, err) 78 r := &Service{ 79 cfg: &Config{ 80 P2P: p, 81 Chain: &mock.ChainService{ 82 State: s, 83 }, 84 InitialSync: &mockSync.Sync{IsSyncing: false}, 85 }, 86 seenExitCache: c, 87 } 88 89 buf := new(bytes.Buffer) 90 _, err = p.Encoding().EncodeGossip(buf, exit) 91 require.NoError(t, err) 92 topic := p2p.GossipTypeMapping[reflect.TypeOf(exit)] 93 m := &pubsub.Message{ 94 Message: &pubsubpb.Message{ 95 Data: buf.Bytes(), 96 Topic: &topic, 97 }, 98 } 99 valid := r.validateVoluntaryExit(ctx, "", m) == pubsub.ValidationAccept 100 assert.Equal(t, true, valid, "Failed validation") 101 assert.NotNil(t, m.ValidatorData, "Decoded message was not set on the message validator data") 102 } 103 104 func TestValidateVoluntaryExit_InvalidExitSlot(t *testing.T) { 105 p := p2ptest.NewTestP2P(t) 106 ctx := context.Background() 107 108 exit, s := setupValidExit(t) 109 // Set state slot to 1 to cause exit object fail to verify. 110 require.NoError(t, s.SetSlot(1)) 111 c, err := lru.New(10) 112 require.NoError(t, err) 113 r := &Service{ 114 cfg: &Config{ 115 P2P: p, 116 Chain: &mock.ChainService{ 117 State: s, 118 }, 119 InitialSync: &mockSync.Sync{IsSyncing: false}, 120 }, 121 seenExitCache: c, 122 } 123 124 buf := new(bytes.Buffer) 125 _, err = p.Encoding().EncodeGossip(buf, exit) 126 require.NoError(t, err) 127 topic := p2p.GossipTypeMapping[reflect.TypeOf(exit)] 128 m := &pubsub.Message{ 129 Message: &pubsubpb.Message{ 130 Data: buf.Bytes(), 131 Topic: &topic, 132 }, 133 } 134 valid := r.validateVoluntaryExit(ctx, "", m) == pubsub.ValidationAccept 135 assert.Equal(t, false, valid, "passed validation") 136 } 137 138 func TestValidateVoluntaryExit_ValidExit_Syncing(t *testing.T) { 139 p := p2ptest.NewTestP2P(t) 140 ctx := context.Background() 141 142 exit, s := setupValidExit(t) 143 144 r := &Service{ 145 cfg: &Config{ 146 P2P: p, 147 Chain: &mock.ChainService{ 148 State: s, 149 }, 150 InitialSync: &mockSync.Sync{IsSyncing: true}, 151 }, 152 } 153 buf := new(bytes.Buffer) 154 _, err := p.Encoding().EncodeGossip(buf, exit) 155 require.NoError(t, err) 156 topic := p2p.GossipTypeMapping[reflect.TypeOf(exit)] 157 m := &pubsub.Message{ 158 Message: &pubsubpb.Message{ 159 Data: buf.Bytes(), 160 Topic: &topic, 161 }, 162 } 163 valid := r.validateVoluntaryExit(ctx, "", m) == pubsub.ValidationAccept 164 assert.Equal(t, false, valid, "Validation should have failed") 165 }