github.com/klaytn/klaytn@v1.10.2/consensus/istanbul/validator/weighted_random_test.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package validator 18 19 import ( 20 "math/big" 21 "math/rand" 22 "reflect" 23 "sort" 24 "strconv" 25 "strings" 26 "testing" 27 "time" 28 29 "github.com/klaytn/klaytn/common" 30 "github.com/klaytn/klaytn/consensus/istanbul" 31 "github.com/klaytn/klaytn/crypto" 32 "github.com/klaytn/klaytn/fork" 33 "github.com/klaytn/klaytn/params" 34 "github.com/stretchr/testify/assert" 35 ) 36 37 var ( 38 testAddrs = []common.Address{ 39 common.HexToAddress("0x0adBC7b05Da383157200a9Fa192285898aB2CaAc"), 40 common.HexToAddress("0x371F315BeBe961776AC84B29e044b01074b93E69"), 41 common.HexToAddress("0x5845EAa7ac251542Dc96fBaD09E3CAd3ec105a7a"), 42 common.HexToAddress("0x63805D23fC86Aa16EFB157C036F226f3aa93099d"), 43 common.HexToAddress("0x68E0DEf1e6beb308eF5FdF2e19dB2884571c465c"), 44 common.HexToAddress("0x72E23aAe2Cc6eE54682bD67B6093F7b7971f3D2F"), 45 common.HexToAddress("0x78B898e37A45069518775972AB8155493e69A2F0"), 46 common.HexToAddress("0x8704Ffb473a16638ea42c7704995d6505102a4Ca"), 47 common.HexToAddress("0x93d3Ce8940c7907b0C1c3898dF7Aa797C457cD0f"), 48 common.HexToAddress("0x9a049EefC01aAE911F2B6F19d724dF9d3ca5cAe6"), 49 common.HexToAddress("0xC14124d61fc940c7aF29F62438D1B54fD7FFB65B"), 50 common.HexToAddress("0xc4cB0B3c2682C15D96739f9a13fE26f17c893f8f"), 51 common.HexToAddress("0xd4aB68fcEC8Fa23856188163B131F3E443e09EF8"), 52 } 53 testRewardAddrs = []common.Address{ 54 common.HexToAddress("0x0a6e50a28f10CD9dba36DD9D3B95BaA32F9fe77a"), 55 common.HexToAddress("0x23FB6C77E069BD6456181f48a9c77f3a3812E7e7"), 56 common.HexToAddress("0x43d5e084D8A6c7FbCd0EbA9a517533fF384f0577"), 57 common.HexToAddress("0x4d180C12FB3B061f44E91D30d574F78D1DeCAD90"), 58 common.HexToAddress("0x53094cE69ea701bfb9D06239087d4CF09F127B78"), 59 common.HexToAddress("0x5F2152bf0C97f1d2c3Ffec8A98FEEB1e50798090"), 60 common.HexToAddress("0x653f42fb1F3474de222F7DDa2109250218989B19"), 61 common.HexToAddress("0x93eaEAa38D534B52E7DB3AB939330022330cD427"), 62 common.HexToAddress("0x96a0d7f6A82B860313FF8668b858aD4930d7B2d6"), 63 common.HexToAddress("0xB89ff800C21b3334f0e355A73242bB4363cf6e10"), 64 common.HexToAddress("0xDEeeF6fAC16f095Fa944E481F8e6c3b42ae3Cefa"), 65 common.HexToAddress("0xbDE3Ee8c01484dDBD59a425457Ab138cf3aa0E11"), 66 common.HexToAddress("0xdD5572A7aC7AB7407e8e4082dB442668C02924E3"), 67 } 68 testStakingAddrs = []common.Address{ 69 common.HexToAddress("0x3776A66698babFA24F0316e4363B2E6C95B09ceF"), 70 common.HexToAddress("0x4d086A88329233E00158FEcbe7b38Dd8667Dd9f9"), 71 common.HexToAddress("0x5d7d13278AEF56263B7d25d51E1B2519Ac0D656B"), 72 common.HexToAddress("0x60fA2326f6C1A7a90Bd1B3c31Bd1A7f9Aed61443"), 73 common.HexToAddress("0x681C55B2CD831D262C785e213a70e277D0226c79"), 74 common.HexToAddress("0x6EeA09FF2bB16F1cD075c748E1684f1100085541"), 75 common.HexToAddress("0x817617C3f09d08a5d475bf72b4723A755CD9b8c7"), 76 common.HexToAddress("0x83F28D3512dC32701F375b112d0CB0810Cb736e4"), 77 common.HexToAddress("0x92D03E4998fB3F91A1E24496EDCf625136037f9e"), 78 common.HexToAddress("0xA0360cDC935A9f3bFe7Ad03D1C34989427ad239f"), 79 common.HexToAddress("0xE2946677DcEEDDF36F1f6EA00421635804872D49"), 80 common.HexToAddress("0xF246283a57A8018085AF39bdadFCC4aaC682e6dD"), 81 common.HexToAddress("0xF3c6f39e231C7363F9B5F4d71b5EE7Eb1fB265d7"), 82 } 83 testVotingPowers = []uint64{ 84 1, 1, 1, 1, 1, 85 1, 1, 1, 1, 1, 86 1, 1, 1, 87 } 88 testZeroWeights = []uint64{ 89 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 91 0, 0, 0, 92 } 93 testPrevHash = common.HexToHash("0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a") 94 95 testExpectedProposers = []common.Address{ 96 common.HexToAddress("0x8704Ffb473a16638ea42c7704995d6505102a4Ca"), 97 common.HexToAddress("0xC14124d61fc940c7aF29F62438D1B54fD7FFB65B"), 98 common.HexToAddress("0x72E23aAe2Cc6eE54682bD67B6093F7b7971f3D2F"), 99 common.HexToAddress("0xc4cB0B3c2682C15D96739f9a13fE26f17c893f8f"), 100 common.HexToAddress("0x68E0DEf1e6beb308eF5FdF2e19dB2884571c465c"), 101 common.HexToAddress("0x371F315BeBe961776AC84B29e044b01074b93E69"), 102 common.HexToAddress("0x63805D23fC86Aa16EFB157C036F226f3aa93099d"), 103 common.HexToAddress("0x93d3Ce8940c7907b0C1c3898dF7Aa797C457cD0f"), 104 common.HexToAddress("0x5845EAa7ac251542Dc96fBaD09E3CAd3ec105a7a"), 105 common.HexToAddress("0x78B898e37A45069518775972AB8155493e69A2F0"), 106 common.HexToAddress("0x0adBC7b05Da383157200a9Fa192285898aB2CaAc"), 107 common.HexToAddress("0xd4aB68fcEC8Fa23856188163B131F3E443e09EF8"), 108 common.HexToAddress("0x9a049EefC01aAE911F2B6F19d724dF9d3ca5cAe6"), 109 } 110 111 testNonZeroWeights = []uint64{ 112 1, 1, 2, 1, 1, 113 1, 0, 3, 2, 1, 114 0, 1, 5, 115 } 116 ) 117 118 func makeTestValidators(weights []uint64) (validators istanbul.Validators) { 119 validators = make([]istanbul.Validator, len(testAddrs)) 120 for i := range testAddrs { 121 validators[i] = newWeightedValidator(testAddrs[i], testRewardAddrs[i], testVotingPowers[i], weights[i]) 122 } 123 sort.Sort(validators) 124 125 return 126 } 127 128 func makeTestWeightedCouncil(weights []uint64) (valSet *weightedCouncil) { 129 // prepare weighted council 130 valSet = NewWeightedCouncil(testAddrs, nil, testRewardAddrs, testVotingPowers, weights, istanbul.WeightedRandom, 21, 0, 0, nil) 131 return 132 } 133 134 func TestWeightedCouncil_List(t *testing.T) { 135 validators := makeTestValidators(testZeroWeights) 136 137 valSet := makeTestWeightedCouncil(testZeroWeights) 138 139 validators_in_valset := valSet.List() 140 141 if len(validators_in_valset) != len(validators) { 142 t.Errorf("len of validators in valSet is different from len of given test set %v, validators %v", len(validators_in_valset), len(validators)) 143 } 144 145 for i := 0; i < len(validators); i++ { 146 if validators[i].String() != validators_in_valset[i].String() { 147 t.Errorf("The element in validators in valset is different from given test set%v, validators %v", validators_in_valset[i], validators[i]) 148 } 149 } 150 } 151 152 func TestWeightedCouncil_GetByIndex(t *testing.T) { 153 validators := makeTestValidators(testZeroWeights) 154 valSet := makeTestWeightedCouncil(testZeroWeights) 155 156 for i := 0; i < len(validators); i++ { 157 validatorToCheck := valSet.GetByIndex(uint64(i)) 158 159 if validators[i].Address() != validatorToCheck.Address() { 160 t.Errorf("The validator with given index is different. index=%v, expected validator=%v, gotten validator %v", i, validators[i], valSet.GetByIndex(uint64(i))) 161 } 162 } 163 164 for errorIndex := len(validators) + 1; errorIndex < 100; errorIndex++ { 165 validatorToCheck := valSet.GetByIndex(uint64(errorIndex)) 166 167 if validatorToCheck != nil { 168 t.Errorf("The result should be nil with given index. index=%v", errorIndex) 169 } 170 } 171 172 for errorIndex := -1; errorIndex > -100; errorIndex-- { 173 validatorToCheck := valSet.GetByIndex(uint64(errorIndex)) 174 175 if validatorToCheck != nil { 176 t.Errorf("The result should be nil with given index. index=%v", errorIndex) 177 } 178 } 179 } 180 181 func TestWeightedCouncil_GetByAddress(t *testing.T) { 182 validators := makeTestValidators(testZeroWeights) 183 valSet := makeTestWeightedCouncil(testZeroWeights) 184 185 for i := 0; i < len(validators); i++ { 186 index, validatorToCheck := valSet.getByAddress(validators[i].Address()) 187 188 if validators[index].Address() != validatorToCheck.Address() { 189 t.Errorf("The validator with given address is different index=%v, expected validator=%v, gotten validator %v", i, validators[i], valSet.GetByIndex(uint64(i))) 190 } 191 } 192 193 _, errorValidator := valSet.getByAddress(common.Address{}) 194 if errorValidator != nil { 195 t.Errorf("The validator with given address should be nil.") 196 } 197 } 198 199 func TestWeightedCouncil_GetProposer(t *testing.T) { 200 validators := makeTestValidators(testZeroWeights) 201 valSet := makeTestWeightedCouncil(testZeroWeights) 202 203 // at the first, proposer is the first validator in the validator list 204 expectedProposer := validators[0] 205 proposerToCheck := valSet.GetProposer() 206 207 if expectedProposer.Address() != proposerToCheck.Address() { 208 t.Errorf("proposer should be same. Expected proposer: %v, gotten proposer %v", expectedProposer, proposerToCheck) 209 } 210 211 // random check. give random validator to valSet and check GetProposer() if it is same as the given validator 212 r := rand.New(rand.NewSource(time.Now().Unix())) 213 for i := 0; i < 100; i++ { 214 choosenIndex := r.Intn(len(validators)) 215 216 valSet.proposer.Store(validators[choosenIndex]) 217 218 expectedProposer := validators[choosenIndex] 219 proposerToCheck := valSet.GetProposer() 220 221 if expectedProposer.Address() != proposerToCheck.Address() { 222 t.Errorf("proposer should be same. Expected proposer: %v, gotten proposer %v", expectedProposer, proposerToCheck) 223 } 224 } 225 } 226 227 func TestDefaultSet_IsProposer(t *testing.T) { 228 validators := makeTestValidators(testZeroWeights) 229 valSet := makeTestWeightedCouncil(testZeroWeights) 230 231 currentProposer := valSet.GetProposer() 232 233 for i := 0; i < len(validators); i++ { 234 validatorToTest := validators[i] 235 236 expectedResult := validatorToTest.Address() == currentProposer.Address() 237 result := valSet.IsProposer(validatorToTest.Address()) 238 239 if result != expectedResult { 240 t.Errorf("The result is different from the expected result. Expected Result : %v, Gotten Result : %v, CurrentProposer Address : %v, TestValidator Address : %v", expectedResult, result, currentProposer.Address(), validatorToTest.Address()) 241 } 242 } 243 } 244 245 func TestWeightedCouncil_RefreshWithZeroWeight(t *testing.T) { 246 validators := makeTestValidators(testZeroWeights) 247 248 valSet := makeTestWeightedCouncil(testZeroWeights) 249 runRefreshForTest(valSet) 250 251 // Run tests 252 253 // 1. check all validators are chosen for proposers 254 var sortedProposers istanbul.Validators 255 sortedProposers = make([]istanbul.Validator, len(testAddrs)) 256 copy(sortedProposers, valSet.proposers) 257 sort.Sort(sortedProposers) 258 if !reflect.DeepEqual(sortedProposers, validators) { 259 t.Errorf("All validators are not in proposers: sorted proposers %v, validators %v", sortedProposers, validators) 260 } 261 262 // 2. check proposers 263 for i, val := range valSet.proposers { 264 if !reflect.DeepEqual(val.Address(), testExpectedProposers[i]) { 265 t.Errorf("proposer mismatch: have %v, want %v", val.Address().String(), testExpectedProposers[i].String()) 266 } 267 } 268 269 // 3. test calculate proposer different round 270 checkCalcProposerWithRound(t, valSet, testAddrs[0], 0) 271 checkCalcProposerWithRound(t, valSet, testAddrs[0], 1) 272 checkCalcProposerWithRound(t, valSet, testAddrs[0], 5) 273 checkCalcProposerWithRound(t, valSet, testAddrs[0], 13) 274 checkCalcProposerWithRound(t, valSet, testAddrs[0], 1000) 275 276 // 4. test calculate proposer different block number 277 for i := 0; i < 100; i++ { 278 valSet.blockNum = uint64(i) 279 checkCalcProposerWithBlockNumber(t, valSet, testAddrs[0], 0) 280 } 281 282 // 5. test calculate proposer different block number and round 283 for i := 0; i < 100; i++ { 284 valSet.blockNum = uint64(i) 285 for j := 0; j < 100; j++ { 286 round := uint64(j) 287 checkCalcProposerWithBlockNumberAndRound(t, valSet, testAddrs[0], round) 288 } 289 } 290 } 291 292 func checkCalcProposerWithRound(t *testing.T, valSet *weightedCouncil, lastProposer common.Address, round uint64) { 293 valSet.CalcProposer(lastProposer, round) 294 _, expectedVal := valSet.GetByAddress(testExpectedProposers[round%uint64(len(valSet.proposers))]) 295 if val := valSet.GetProposer(); !reflect.DeepEqual(val, expectedVal) { 296 t.Errorf("proposer mismatch: have %v, want %v", val.String(), expectedVal.Address().String()) 297 } 298 } 299 300 func checkCalcProposerWithBlockNumber(t *testing.T, valSet *weightedCouncil, lastProposer common.Address, round uint64) { 301 valSet.CalcProposer(lastProposer, round) 302 _, expectedVal := valSet.GetByAddress(testExpectedProposers[valSet.blockNum%uint64(len(valSet.proposers))]) 303 if val := valSet.GetProposer(); !reflect.DeepEqual(val, expectedVal) { 304 t.Errorf("proposer mismatch: have %v, want %v", val.String(), expectedVal.Address().String()) 305 } 306 } 307 308 func checkCalcProposerWithBlockNumberAndRound(t *testing.T, valSet *weightedCouncil, lastProposer common.Address, round uint64) { 309 valSet.CalcProposer(lastProposer, round) 310 _, expectedVal := valSet.GetByAddress(testExpectedProposers[(valSet.blockNum+round)%uint64(len(valSet.proposers))]) 311 if val := valSet.GetProposer(); !reflect.DeepEqual(val, expectedVal) { 312 t.Errorf("proposer mismatch: have %v, want %v", val.String(), expectedVal.Address().String()) 313 } 314 } 315 316 func TestWeightedCouncil_RefreshWithNonZeroWeight(t *testing.T) { 317 validators := makeTestValidators(testNonZeroWeights) 318 319 valSet := makeTestWeightedCouncil(testNonZeroWeights) 320 runRefreshForTest(valSet) 321 322 // Run tests 323 324 // 1. number of proposers 325 totalWeights := uint64(0) 326 for _, v := range validators { 327 totalWeights += v.Weight() 328 } 329 assert.Equal(t, totalWeights, uint64(len(valSet.proposers))) 330 331 // 2. weight and appearance frequency 332 for _, v := range validators { 333 weight := v.Weight() 334 appearance := uint64(0) 335 for _, p := range valSet.proposers { 336 if v.Address() == p.Address() { 337 appearance++ 338 } 339 } 340 assert.Equal(t, weight, appearance) 341 } 342 } 343 344 func TestWeightedCouncil_RemoveValidator(t *testing.T) { 345 validators := makeTestValidators(testNonZeroWeights) 346 valSet := makeTestWeightedCouncil(testNonZeroWeights) 347 runRefreshForTest(valSet) 348 349 for _, val := range validators { 350 351 _, removedVal := valSet.GetByAddress(val.Address()) 352 if removedVal == nil { 353 t.Errorf("Fail to find validator with address %v", removedVal.Address().String()) 354 } 355 356 if !valSet.RemoveValidator(removedVal.Address()) { 357 t.Errorf("Fail to remove validator %v", removedVal.String()) 358 } 359 360 // check whether removedVal is really removed from validators 361 for _, v := range valSet.validators { 362 if removedVal.Address() == v.Address() { 363 t.Errorf("Validator(%v) does not removed from validators", removedVal.Address().String()) 364 } 365 } 366 367 // check whether removedVal is also removed from proposers immediately 368 for _, p := range valSet.proposers { 369 if removedVal.Address() == p.Address() { 370 t.Errorf("Validator(%v) does not removed from proposers", removedVal.Address().String()) 371 } 372 } 373 } 374 375 assert.Equal(t, uint64(0), valSet.Size()) 376 assert.Equal(t, 0, len(valSet.Proposers())) 377 } 378 379 func TestWeightedCouncil_RefreshAfterRemoveValidator(t *testing.T) { 380 validators := makeTestValidators(testNonZeroWeights) 381 valSet := makeTestWeightedCouncil(testNonZeroWeights) 382 runRefreshForTest(valSet) 383 384 for _, val := range validators { 385 386 _, removedVal := valSet.GetByAddress(val.Address()) 387 if removedVal == nil { 388 t.Errorf("Fail to find validator with address %v", removedVal.Address().String()) 389 } 390 391 if !valSet.RemoveValidator(removedVal.Address()) { 392 t.Errorf("Fail to remove validator %v", removedVal.String()) 393 } 394 395 // check whether removedVal is really removed from validators 396 for _, v := range valSet.validators { 397 if removedVal.Address() == v.Address() { 398 t.Errorf("Validator(%v) does not removed from validators", removedVal.Address().String()) 399 } 400 } 401 402 runRefreshForTest(valSet) 403 404 // check whether removedVal is excluded as expected when refreshing proposers 405 for _, p := range valSet.proposers { 406 if removedVal.Address() == p.Address() { 407 t.Errorf("Validator(%v) does not removed from proposers", removedVal.Address().String()) 408 } 409 } 410 } 411 412 assert.Equal(t, uint64(0), valSet.Size()) 413 assert.Equal(t, 0, len(valSet.Proposers())) 414 } 415 416 func runRefreshForTest(valSet *weightedCouncil) { 417 hashString := strings.TrimPrefix(testPrevHash.Hex(), "0x") 418 if len(hashString) > 15 { 419 hashString = hashString[:15] 420 } 421 seed, _ := strconv.ParseInt(hashString, 16, 64) 422 valSet.refreshProposers(seed, 0) 423 } 424 425 func TestWeightedCouncil_SetSubGroupSize(t *testing.T) { 426 validators := makeTestValidators(testNonZeroWeights) 427 valSet := makeTestWeightedCouncil(testNonZeroWeights) 428 429 validatorsLen := len(validators) 430 431 for i := 1; i < validatorsLen; i++ { 432 valSet.SetSubGroupSize(uint64(i)) 433 434 expectedSubGroupSize := uint64(i) 435 gottenSubGroupSize := valSet.SubGroupSize() 436 437 if expectedSubGroupSize != gottenSubGroupSize { 438 t.Errorf("SubGroupSize should be %v but gotten SubGroupSize is %v", expectedSubGroupSize, gottenSubGroupSize) 439 } 440 } 441 } 442 443 func TestWeightedCouncil_SubListWithProposer(t *testing.T) { 444 var ( 445 validators = makeTestValidators(testNonZeroWeights) 446 prevHash = crypto.Keccak256Hash([]byte("This is a test")) 447 valSet = makeTestWeightedCouncil(testNonZeroWeights) 448 449 BlockBeforeHF = big.NewInt(4) 450 HFBlock = big.NewInt(5) 451 BlockAfterHF = big.NewInt(6) 452 453 expectIndexOfSubsetLenTest = []int{1, 2, 7, 3, 11, 6, 9, 4, 0, 8, 12, 10} 454 expectIndexOfRoundTestBeforeIstanbulCompatible = [][]int{ 455 {1, 2, 7, 3, 11, 6, 9, 4, 0, 8, 12, 10}, 456 {2, 3, 7, 1, 11, 6, 9, 4, 0, 8, 12, 10}, 457 {3, 4, 7, 1, 11, 6, 9, 2, 0, 8, 12, 10}, 458 {4, 5, 7, 1, 11, 6, 9, 2, 0, 8, 12, 10}, 459 {5, 6, 7, 1, 11, 4, 9, 2, 0, 8, 12, 10}, 460 {6, 7, 5, 1, 11, 4, 9, 2, 0, 8, 12, 10}, 461 {7, 8, 5, 1, 11, 4, 9, 2, 0, 6, 12, 10}, 462 {8, 9, 5, 1, 11, 4, 7, 2, 0, 6, 12, 10}, 463 {9, 10, 5, 1, 11, 4, 7, 2, 0, 6, 12, 8}, 464 {10, 11, 5, 1, 9, 4, 7, 2, 0, 6, 12, 8}, 465 {11, 12, 5, 1, 9, 4, 7, 2, 0, 6, 10, 8}, 466 {12, 0, 6, 2, 10, 5, 8, 3, 1, 7, 11, 9}, 467 {0, 1, 7, 3, 11, 6, 9, 4, 2, 8, 12, 10}, 468 {1, 2, 7, 3, 11, 6, 9, 4, 0, 8, 12, 10}, 469 {2, 3, 7, 1, 11, 6, 9, 4, 0, 8, 12, 10}, 470 } 471 expectIndexOfRoundTestAfterIstanbulCompatible = [][]int{ 472 {1, 2, 7, 3, 11, 6, 9, 4, 0, 8, 12, 10}, 473 {2, 3, 6, 8, 10, 9, 1, 11, 5, 0, 4, 7}, 474 {3, 4, 10, 5, 8, 0, 7, 9, 12, 6, 1, 11}, 475 {4, 5, 6, 0, 7, 1, 3, 12, 2, 8, 9, 11}, 476 {5, 6, 4, 9, 12, 7, 0, 3, 8, 2, 1, 11}, 477 {6, 7, 2, 3, 8, 9, 11, 12, 5, 1, 4, 0}, 478 {7, 8, 3, 11, 5, 10, 0, 1, 2, 6, 9, 12}, 479 {8, 9, 5, 7, 11, 3, 1, 0, 10, 6, 4, 12}, 480 {9, 10, 3, 7, 5, 6, 2, 0, 12, 8, 11, 1}, 481 {10, 11, 7, 1, 0, 9, 8, 6, 12, 5, 2, 4}, 482 {11, 12, 4, 8, 1, 6, 0, 3, 9, 10, 2, 7}, 483 {12, 0, 7, 2, 4, 1, 6, 10, 9, 11, 8, 3}, 484 {0, 1, 9, 8, 2, 3, 10, 5, 7, 12, 4, 6}, 485 {1, 2, 11, 10, 6, 8, 7, 4, 9, 12, 0, 5}, 486 {2, 3, 4, 8, 6, 5, 11, 1, 12, 0, 9, 10}, 487 } 488 ) 489 490 getExpectSubList := func(indices []int) []istanbul.Validator { 491 var expectSubList []istanbul.Validator 492 for _, index := range indices { 493 expectSubList = append(expectSubList, validators[index]) 494 } 495 return expectSubList 496 } 497 498 fork.SetHardForkBlockNumberConfig(¶ms.ChainConfig{IstanbulCompatibleBlock: HFBlock}) 499 defer fork.ClearHardForkBlockNumberConfig() 500 501 // SubsetLen test: various subset length test 502 valSet.SetBlockNum(1) 503 for testSubsetLen := 2; testSubsetLen < len(validators); testSubsetLen++ { 504 // set committee size and calculate proposer 505 valSet.SetSubGroupSize(uint64(testSubsetLen)) 506 valSet.CalcProposer(valSet.GetProposer().Address(), uint64(0)) 507 508 // get committee list 509 expectSubList := getExpectSubList(expectIndexOfSubsetLenTest[0:testSubsetLen]) 510 511 // compare the subList of valSet with expected committee list 512 viewBeforeHF := &istanbul.View{Sequence: BlockBeforeHF, Round: big.NewInt(int64(0))} 513 viewAfterHF := &istanbul.View{Sequence: BlockAfterHF, Round: big.NewInt(int64(0))} 514 assert.Equal(t, expectSubList, valSet.SubList(prevHash, viewBeforeHF), "test Subset length: %d(before istanbulCompatible)", testSubsetLen) 515 assert.Equal(t, expectSubList, valSet.SubList(prevHash, viewAfterHF), "test subset length: %d(after istanbulCompatible)", testSubsetLen) 516 } 517 518 // Check: compare the size of the test data arrays 519 assert.Equal(t, len(expectIndexOfRoundTestBeforeIstanbulCompatible), len(expectIndexOfRoundTestAfterIstanbulCompatible)) 520 521 // Round test: various round test 522 valSet.SetBlockNum(1) 523 valSet.SetSubGroupSize(uint64(len(validators) - 1)) 524 for round := 0; round < len(expectIndexOfRoundTestBeforeIstanbulCompatible); round++ { 525 // calculate proposer and set view with test round value 526 valSet.CalcProposer(valSet.GetProposer().Address(), uint64(round)) 527 528 // get committee list 529 expectSubListBeforeHF := getExpectSubList(expectIndexOfRoundTestBeforeIstanbulCompatible[round]) 530 expectSubListAfterHF := getExpectSubList(expectIndexOfRoundTestAfterIstanbulCompatible[round]) 531 532 // compare the subList of valSet with expected committee list 533 viewBeforeHF := &istanbul.View{Sequence: BlockBeforeHF, Round: big.NewInt(int64(round))} 534 viewAfterHF := &istanbul.View{Sequence: BlockAfterHF, Round: big.NewInt(int64(round))} 535 assert.Equal(t, expectSubListBeforeHF, valSet.SubList(prevHash, viewBeforeHF), "test round: %d(before istanbulCompatible)", round) 536 assert.Equal(t, expectSubListAfterHF, valSet.SubList(prevHash, viewAfterHF), "test round: %d(after istanbulCompatible)", round) 537 } 538 } 539 540 func TestWeightedCouncil_Copy(t *testing.T) { 541 valSet := makeTestWeightedCouncil(testNonZeroWeights) 542 543 copiedValSet := valSet.Copy().(*weightedCouncil) 544 545 // check each variable is same except selector(function) 546 if valSet.blockNum != copiedValSet.blockNum || valSet.GetProposer() != copiedValSet.GetProposer() || 547 valSet.subSize != copiedValSet.subSize || valSet.policy != copiedValSet.policy || 548 valSet.proposersBlockNum != copiedValSet.proposersBlockNum || 549 !reflect.DeepEqual(valSet.validators, copiedValSet.validators) || 550 !reflect.DeepEqual(valSet.proposers, copiedValSet.proposers) || 551 !reflect.DeepEqual(valSet.stakingInfo, copiedValSet.stakingInfo) { 552 t.Errorf("copied weightedCouncil is different from original.") 553 t.Errorf("block number. original : %v, Copied : %v", valSet.blockNum, copiedValSet.blockNum) 554 t.Errorf("proposer. original : %v, Copied : %v", valSet.GetProposer(), copiedValSet.GetProposer()) 555 t.Errorf("subSize. original : %v, Copied : %v", valSet.subSize, copiedValSet.subSize) 556 t.Errorf("policy. original : %v, Copied : %v", valSet.policy, copiedValSet.policy) 557 t.Errorf("proposersBlockNum. original : %v, Copied : %v", valSet.proposersBlockNum, copiedValSet.proposersBlockNum) 558 t.Errorf("validators. original : %v, Copied : %v", valSet.validators, copiedValSet.validators) 559 t.Errorf("proposers. original : %v, Copied : %v", valSet.proposers, copiedValSet.proposers) 560 t.Errorf("staking. original : %v, Copied : %v", valSet.stakingInfo, copiedValSet.stakingInfo) 561 } 562 }