github.com/prysmaticlabs/prysm@v1.4.4/validator/rpc/slashing_test.go (about) 1 package rpc 2 3 import ( 4 "context" 5 "encoding/json" 6 "testing" 7 8 "github.com/golang/protobuf/ptypes/empty" 9 pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2" 10 "github.com/prysmaticlabs/prysm/shared/testutil/require" 11 "github.com/prysmaticlabs/prysm/validator/accounts" 12 "github.com/prysmaticlabs/prysm/validator/accounts/wallet" 13 "github.com/prysmaticlabs/prysm/validator/db/kv" 14 "github.com/prysmaticlabs/prysm/validator/keymanager" 15 "github.com/prysmaticlabs/prysm/validator/slashing-protection/local/standard-protection-format/format" 16 mocks "github.com/prysmaticlabs/prysm/validator/testing" 17 ) 18 19 func TestImportSlashingProtection_Preconditions(t *testing.T) { 20 ctx := context.Background() 21 localWalletDir := setupWalletDir(t) 22 defaultWalletPath = localWalletDir 23 24 // Empty JSON. 25 req := &pb.ImportSlashingProtectionRequest{ 26 SlashingProtectionJson: "", 27 } 28 s := &Server{ 29 walletDir: defaultWalletPath, 30 } 31 32 // No validator DB provided. 33 _, err := s.ImportSlashingProtection(ctx, req) 34 require.ErrorContains(t, "err finding validator database at path", err) 35 36 // Create Wallet and add to server for more realistic testing. 37 w, err := accounts.CreateWalletWithKeymanager(ctx, &accounts.CreateWalletConfig{ 38 WalletCfg: &wallet.Config{ 39 WalletDir: defaultWalletPath, 40 KeymanagerKind: keymanager.Imported, 41 WalletPassword: strongPass, 42 }, 43 SkipMnemonicConfirm: true, 44 }) 45 require.NoError(t, err) 46 s.wallet = w 47 48 numValidators := 1 49 // Create public keys for the mock validator DB. 50 pubKeys, err := mocks.CreateRandomPubKeys(numValidators) 51 require.NoError(t, err) 52 53 // Create a validator database. 54 validatorDB, err := kv.NewKVStore(ctx, defaultWalletPath, &kv.Config{ 55 PubKeys: pubKeys, 56 }) 57 require.NoError(t, err) 58 s.valDB = validatorDB 59 60 // Have to close it after import is done otherwise it complains db is not open. 61 defer func() { 62 require.NoError(t, validatorDB.Close()) 63 }() 64 65 // Test empty JSON. 66 _, err = s.ImportSlashingProtection(ctx, req) 67 require.ErrorContains(t, "empty slashing_protection json specified", err) 68 69 // Generate mock slashing history. 70 attestingHistory := make([][]*kv.AttestationRecord, 0) 71 proposalHistory := make([]kv.ProposalHistoryForPubkey, len(pubKeys)) 72 for i := 0; i < len(pubKeys); i++ { 73 proposalHistory[i].Proposals = make([]kv.Proposal, 0) 74 } 75 mockJSON, err := mocks.MockSlashingProtectionJSON(pubKeys, attestingHistory, proposalHistory) 76 require.NoError(t, err) 77 78 // JSON encode the protection JSON and save it in rpc req. 79 encoded, err := json.Marshal(mockJSON) 80 require.NoError(t, err) 81 req.SlashingProtectionJson = string(encoded) 82 83 _, err = s.ImportSlashingProtection(ctx, req) 84 require.NoError(t, err) 85 } 86 87 func TestExportSlashingProtection_Preconditions(t *testing.T) { 88 ctx := context.Background() 89 localWalletDir := setupWalletDir(t) 90 defaultWalletPath = localWalletDir 91 92 s := &Server{ 93 walletDir: defaultWalletPath, 94 } 95 // No validator DB provided. 96 _, err := s.ExportSlashingProtection(ctx, &empty.Empty{}) 97 require.ErrorContains(t, "err finding validator database at path", err) 98 99 numValidators := 10 100 // Create public keys for the mock validator DB. 101 pubKeys, err := mocks.CreateRandomPubKeys(numValidators) 102 require.NoError(t, err) 103 104 // We create a validator database. 105 validatorDB, err := kv.NewKVStore(ctx, defaultWalletPath, &kv.Config{ 106 PubKeys: pubKeys, 107 }) 108 require.NoError(t, err) 109 s.valDB = validatorDB 110 111 // Have to close it after export is done otherwise it complains db is not open. 112 defer func() { 113 require.NoError(t, validatorDB.Close()) 114 }() 115 116 _, err = s.ExportSlashingProtection(ctx, &empty.Empty{}) 117 require.NoError(t, err) 118 } 119 120 func TestImportExportSlashingProtection_RoundTrip(t *testing.T) { 121 ctx := context.Background() 122 localWalletDir := setupWalletDir(t) 123 defaultWalletPath = localWalletDir 124 125 s := &Server{ 126 walletDir: defaultWalletPath, 127 } 128 129 numValidators := 10 130 // Create public keys for the mock validator DB. 131 pubKeys, err := mocks.CreateRandomPubKeys(numValidators) 132 require.NoError(t, err) 133 134 // Create a validator database. 135 validatorDB, err := kv.NewKVStore(ctx, defaultWalletPath, &kv.Config{ 136 PubKeys: pubKeys, 137 }) 138 require.NoError(t, err) 139 s.valDB = validatorDB 140 141 // Have to close it after import is done otherwise it complains db is not open. 142 defer func() { 143 require.NoError(t, validatorDB.Close()) 144 }() 145 146 // Generate mock slashing history. 147 attestingHistory := make([][]*kv.AttestationRecord, 0) 148 proposalHistory := make([]kv.ProposalHistoryForPubkey, len(pubKeys)) 149 for i := 0; i < len(pubKeys); i++ { 150 proposalHistory[i].Proposals = make([]kv.Proposal, 0) 151 } 152 mockJSON, err := mocks.MockSlashingProtectionJSON(pubKeys, attestingHistory, proposalHistory) 153 require.NoError(t, err) 154 155 // JSON encode the protection JSON and save it in rpc req. 156 encoded, err := json.Marshal(mockJSON) 157 require.NoError(t, err) 158 req := &pb.ImportSlashingProtectionRequest{ 159 SlashingProtectionJson: string(encoded), 160 } 161 162 _, err = s.ImportSlashingProtection(ctx, req) 163 require.NoError(t, err) 164 165 reqE, err := s.ExportSlashingProtection(ctx, &empty.Empty{}) 166 require.NoError(t, err) 167 168 // Attempt to read the exported data and convert from string to EIP-3076. 169 enc := []byte(reqE.File) 170 171 receivedJSON := &format.EIPSlashingProtectionFormat{} 172 err = json.Unmarshal(enc, receivedJSON) 173 require.NoError(t, err) 174 175 require.DeepEqual(t, mockJSON.Metadata, receivedJSON.Metadata) 176 }