github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/consensus/istanbul/validator/default_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package validator 18 19 import ( 20 "math/big" 21 "reflect" 22 "testing" 23 24 "github.com/ethereum/go-ethereum/rlp" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/consensus/istanbul" 28 "github.com/ethereum/go-ethereum/crypto" 29 blscrypto "github.com/ethereum/go-ethereum/crypto/bls" 30 ) 31 32 var ( 33 testAddress = "70524d664ffe731100208a0154e556f9bb679ae6" 34 testAddress2 = "b37866a925bccd69cfa98d43b510f1d23d78a851" 35 ) 36 37 func TestValidatorSet(t *testing.T) { 38 t.Run("NewValidatorSet", testNewValidatorSet) 39 t.Run("NormalValSet", testNormalValSet) 40 t.Run("EmptyValSet", testEmptyValSet) 41 t.Run("AddAndRemoveValidator", testAddAndRemoveValidator) 42 t.Run("QuorumSizes", testQuorumSizes) 43 } 44 45 func testNewValidatorSet(t *testing.T) { 46 var validators []istanbul.Validator 47 const ValCnt = 100 48 49 // Create 100 validators with random addresses 50 b := []byte{} 51 for i := 0; i < ValCnt; i++ { 52 key, _ := crypto.GenerateKey() 53 blsPrivateKey, _ := blscrypto.ECDSAToBLS(key) 54 blsPublicKey, _ := blscrypto.PrivateToPublic(blsPrivateKey) 55 addr := crypto.PubkeyToAddress(key.PublicKey) 56 val := New(addr, blsPublicKey) 57 validators = append(validators, val) 58 b = append(b, val.Address().Bytes()...) 59 b = append(b, blsPublicKey[:]...) 60 } 61 62 // Create ValidatorSet 63 valSet := NewSet(ExtractValidators(b)) 64 if valSet == nil { 65 t.Errorf("the validator byte array cannot be parsed") 66 t.FailNow() 67 } 68 } 69 70 func testNormalValSet(t *testing.T) { 71 b1 := common.Hex2Bytes(testAddress) 72 b2 := common.Hex2Bytes(testAddress2) 73 addr1 := common.BytesToAddress(b1) 74 addr2 := common.BytesToAddress(b2) 75 val1 := New(addr1, blscrypto.SerializedPublicKey{}) 76 val2 := New(addr2, blscrypto.SerializedPublicKey{}) 77 78 validators, _ := istanbul.CombineIstanbulExtraToValidatorData([]common.Address{addr1, addr2}, []blscrypto.SerializedPublicKey{{}, {}}) 79 valSet := newDefaultSet(validators) 80 if valSet == nil { 81 t.Errorf("the format of validator set is invalid") 82 t.FailNow() 83 } 84 85 // check size 86 if size := valSet.Size(); size != 2 { 87 t.Errorf("the size of validator set is wrong: have %v, want 2", size) 88 } 89 // test get by index 90 if val := valSet.GetByIndex(uint64(0)); !reflect.DeepEqual(val, val1) { 91 t.Errorf("validator mismatch: have %v, want %v", val, val1) 92 } 93 // test get by invalid index 94 if val := valSet.GetByIndex(uint64(2)); val != nil { 95 t.Errorf("validator mismatch: have %v, want nil", val) 96 } 97 // test get by address 98 if _, val := valSet.GetByAddress(addr2); !reflect.DeepEqual(val, val2) { 99 t.Errorf("validator mismatch: have %v, want %v", val, val2) 100 } 101 // test get by invalid address 102 invalidAddr := common.HexToAddress("0x9535b2e7faaba5288511d89341d94a38063a349b") 103 if _, val := valSet.GetByAddress(invalidAddr); val != nil { 104 t.Errorf("validator mismatch: have %v, want nil", val) 105 } 106 } 107 108 func testEmptyValSet(t *testing.T) { 109 valSet := NewSet(ExtractValidators([]byte{})) 110 if valSet == nil { 111 t.Errorf("validator set should not be nil") 112 } 113 } 114 115 func testAddAndRemoveValidator(t *testing.T) { 116 valSet := NewSet(ExtractValidators([]byte{})) 117 if !valSet.AddValidators( 118 []istanbul.ValidatorData{ 119 { 120 common.BytesToAddress([]byte(string(3))), 121 blscrypto.SerializedPublicKey{}, 122 }, 123 }, 124 ) { 125 t.Error("the validator should be added") 126 } 127 if valSet.AddValidators( 128 []istanbul.ValidatorData{ 129 { 130 common.BytesToAddress([]byte(string(3))), 131 blscrypto.SerializedPublicKey{}, 132 }, 133 }, 134 ) { 135 t.Error("the existing validator should not be added") 136 } 137 valSet.AddValidators( 138 []istanbul.ValidatorData{ 139 { 140 common.BytesToAddress([]byte(string(2))), 141 blscrypto.SerializedPublicKey{}, 142 }, 143 { 144 common.BytesToAddress([]byte(string(1))), 145 blscrypto.SerializedPublicKey{}, 146 }, 147 }, 148 ) 149 if valSet.Size() != 3 { 150 t.Error("the size of validator set should be 3") 151 } 152 153 expectedOrder := []int{3, 2, 1} 154 for i, v := range valSet.List() { 155 expected := common.BytesToAddress([]byte(string(expectedOrder[i]))) 156 if v.Address() != expected { 157 t.Errorf("the order of validators is wrong: have %v, want %v", v.Address().Hex(), expected.Hex()) 158 } 159 } 160 161 if !valSet.RemoveValidators(big.NewInt(1)) { // remove first falidator 162 t.Error("the validator should be removed") 163 } 164 165 if len(valSet.List()) != 2 || len(valSet.List()) != valSet.Size() { // validators set should have the same size 166 t.Error("the size of validator set should be 2") 167 } 168 valSet.RemoveValidators(big.NewInt(2)) // remove second validator 169 if len(valSet.List()) != 1 || len(valSet.List()) != valSet.Size() { // validators set should have the same size 170 t.Error("the size of validator set should be 1") 171 } 172 valSet.RemoveValidators(big.NewInt(1)) // remove third validator 173 if len(valSet.List()) != 0 || len(valSet.List()) != valSet.Size() { // validators set should have the same size 174 t.Error("the size of validator set should be 0") 175 } 176 } 177 178 func generateValidators(n int) ([]istanbul.ValidatorData, [][]byte) { 179 vals := make([]istanbul.ValidatorData, 0) 180 keys := make([][]byte, 0) 181 for i := 0; i < n; i++ { 182 privateKey, _ := crypto.GenerateKey() 183 blsPrivateKey, _ := blscrypto.ECDSAToBLS(privateKey) 184 blsPublicKey, _ := blscrypto.PrivateToPublic(blsPrivateKey) 185 vals = append(vals, istanbul.ValidatorData{ 186 Address: crypto.PubkeyToAddress(privateKey.PublicKey), 187 BLSPublicKey: blsPublicKey, 188 }) 189 keys = append(keys, blsPrivateKey) 190 } 191 return vals, keys 192 } 193 194 func testQuorumSizes(t *testing.T) { 195 testCases := []struct { 196 validatorSetSize int 197 expectedMinQuorumSize int 198 }{ 199 {validatorSetSize: 1, expectedMinQuorumSize: 1}, 200 {validatorSetSize: 2, expectedMinQuorumSize: 2}, 201 {validatorSetSize: 3, expectedMinQuorumSize: 2}, 202 {validatorSetSize: 4, expectedMinQuorumSize: 3}, 203 {validatorSetSize: 5, expectedMinQuorumSize: 4}, 204 {validatorSetSize: 6, expectedMinQuorumSize: 4}, 205 {validatorSetSize: 7, expectedMinQuorumSize: 5}, 206 } 207 208 for _, testCase := range testCases { 209 vals, _ := generateValidators(testCase.validatorSetSize) 210 valSet := newDefaultSet(vals) 211 212 if valSet.MinQuorumSize() != testCase.expectedMinQuorumSize { 213 t.Errorf("error mismatch quorum size for valset of size %d: have %d, want %d", valSet.Size(), valSet.MinQuorumSize(), testCase.expectedMinQuorumSize) 214 } 215 } 216 } 217 218 func TestValidatorRLPEncoding(t *testing.T) { 219 220 val := New(common.BytesToAddress([]byte(string(2))), blscrypto.SerializedPublicKey{1, 2, 3}) 221 222 rawVal, err := rlp.EncodeToBytes(val) 223 if err != nil { 224 t.Errorf("Error %v", err) 225 } 226 227 var result *defaultValidator 228 if err = rlp.DecodeBytes(rawVal, &result); err != nil { 229 t.Errorf("Error %v", err) 230 } 231 232 if !reflect.DeepEqual(val, result) { 233 t.Errorf("validator mismatch: have %v, want %v", val, result) 234 } 235 } 236 237 func TestValidatorSetRLPEncoding(t *testing.T) { 238 239 valSet := NewSet([]istanbul.ValidatorData{ 240 {Address: common.BytesToAddress([]byte(string(2))), BLSPublicKey: blscrypto.SerializedPublicKey{1, 2, 3}}, 241 {Address: common.BytesToAddress([]byte(string(4))), BLSPublicKey: blscrypto.SerializedPublicKey{3, 1, 4}}, 242 }) 243 244 rawVal, err := rlp.EncodeToBytes(valSet) 245 if err != nil { 246 t.Errorf("Error %v", err) 247 } 248 249 var result *defaultSet 250 if err = rlp.DecodeBytes(rawVal, &result); err != nil { 251 t.Errorf("Error %v", err) 252 } 253 254 if !reflect.DeepEqual(valSet, result) { 255 t.Errorf("validatorSet mismatch: have %v, want %v", valSet, result) 256 } 257 }