github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/dbft/validator/default_test.go (about) 1 package validator 2 3 import ( 4 "reflect" 5 "strings" 6 "testing" 7 8 "github.com/quickchainproject/quickchain/common" 9 "github.com/quickchainproject/quickchain/consensus/dbft" 10 "github.com/quickchainproject/quickchain/crypto" 11 ) 12 13 var ( 14 testAddress = "70524d664ffe731100208a0154e556f9bb679ae6" 15 testAddress2 = "b37866a925bccd69cfa98d43b510f1d23d78a851" 16 ) 17 18 func TestValidatorSet(t *testing.T) { 19 testNewValidatorSet(t) 20 testNormalValSet(t) 21 testEmptyValSet(t) 22 testStickyProposer(t) 23 testAddAndRemoveValidator(t) 24 } 25 26 func testNewValidatorSet(t *testing.T) { 27 var validators []bft.Validator 28 const ValCnt = 100 29 30 // Create 100 validators with random addresses 31 b := []byte{} 32 for i := 0; i < ValCnt; i++ { 33 key, _ := crypto.GenerateKey() 34 addr := crypto.PubkeyToAddress(key.PublicKey) 35 val := New(addr) 36 validators = append(validators, val) 37 b = append(b, val.Address().Bytes()...) 38 } 39 40 // Create ValidatorSet 41 valSet := NewSet(ExtractValidators(b), bft.RoundRobin) 42 if valSet == nil { 43 t.Errorf("the validator byte array cannot be parsed") 44 t.FailNow() 45 } 46 47 // Check validators sorting: should be in ascending order 48 for i := 0; i < ValCnt-1; i++ { 49 val := valSet.GetByIndex(uint64(i)) 50 nextVal := valSet.GetByIndex(uint64(i + 1)) 51 if strings.Compare(val.String(), nextVal.String()) >= 0 { 52 t.Errorf("validator set is not sorted in ascending order") 53 } 54 } 55 } 56 57 func testNormalValSet(t *testing.T) { 58 b1 := common.Hex2Bytes(testAddress) 59 b2 := common.Hex2Bytes(testAddress2) 60 addr1 := common.BytesToAddress(b1) 61 addr2 := common.BytesToAddress(b2) 62 val1 := New(addr1) 63 val2 := New(addr2) 64 65 valSet := newDefaultSet([]common.Address{addr1, addr2}, bft.RoundRobin) 66 if valSet == nil { 67 t.Errorf("the format of validator set is invalid") 68 t.FailNow() 69 } 70 71 // check size 72 if size := valSet.Size(); size != 2 { 73 t.Errorf("the size of validator set is wrong: have %v, want 2", size) 74 } 75 // test get by index 76 if val := valSet.GetByIndex(uint64(0)); !reflect.DeepEqual(val, val1) { 77 t.Errorf("validator mismatch: have %v, want %v", val, val1) 78 } 79 // test get by invalid index 80 if val := valSet.GetByIndex(uint64(2)); val != nil { 81 t.Errorf("validator mismatch: have %v, want nil", val) 82 } 83 // test get by address 84 if _, val := valSet.GetByAddress(addr2); !reflect.DeepEqual(val, val2) { 85 t.Errorf("validator mismatch: have %v, want %v", val, val2) 86 } 87 // test get by invalid address 88 invalidAddr := common.HexToAddress("0x9535b2e7faaba5288511d89341d94a38063a349b") 89 if _, val := valSet.GetByAddress(invalidAddr); val != nil { 90 t.Errorf("validator mismatch: have %v, want nil", val) 91 } 92 // test get proposer 93 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { 94 t.Errorf("proposer mismatch: have %v, want %v", val, val1) 95 } 96 // test calculate proposer 97 lastProposer := addr1 98 valSet.CalcProposer(lastProposer, uint64(0)) 99 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { 100 t.Errorf("proposer mismatch: have %v, want %v", val, val2) 101 } 102 valSet.CalcProposer(lastProposer, uint64(3)) 103 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { 104 t.Errorf("proposer mismatch: have %v, want %v", val, val1) 105 } 106 // test empty last proposer 107 lastProposer = common.Address{} 108 valSet.CalcProposer(lastProposer, uint64(3)) 109 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { 110 t.Errorf("proposer mismatch: have %v, want %v", val, val2) 111 } 112 } 113 114 func testEmptyValSet(t *testing.T) { 115 valSet := NewSet(ExtractValidators([]byte{}), bft.RoundRobin) 116 if valSet == nil { 117 t.Errorf("validator set should not be nil") 118 } 119 } 120 121 func testAddAndRemoveValidator(t *testing.T) { 122 valSet := NewSet(ExtractValidators([]byte{}), bft.RoundRobin) 123 if !valSet.AddValidator(common.StringToAddress(string(2))) { 124 t.Error("the validator should be added") 125 } 126 if valSet.AddValidator(common.StringToAddress(string(2))) { 127 t.Error("the existing validator should not be added") 128 } 129 valSet.AddValidator(common.StringToAddress(string(1))) 130 valSet.AddValidator(common.StringToAddress(string(0))) 131 if len(valSet.List()) != 3 { 132 t.Error("the size of validator set should be 3") 133 } 134 135 for i, v := range valSet.List() { 136 expected := common.StringToAddress(string(i)) 137 if v.Address() != expected { 138 t.Errorf("the order of validators is wrong: have %v, want %v", v.Address().Hex(), expected.Hex()) 139 } 140 } 141 142 if !valSet.RemoveValidator(common.StringToAddress(string(2))) { 143 t.Error("the validator should be removed") 144 } 145 if valSet.RemoveValidator(common.StringToAddress(string(2))) { 146 t.Error("the non-existing validator should not be removed") 147 } 148 if len(valSet.List()) != 2 { 149 t.Error("the size of validator set should be 2") 150 } 151 valSet.RemoveValidator(common.StringToAddress(string(1))) 152 if len(valSet.List()) != 1 { 153 t.Error("the size of validator set should be 1") 154 } 155 valSet.RemoveValidator(common.StringToAddress(string(0))) 156 if len(valSet.List()) != 0 { 157 t.Error("the size of validator set should be 0") 158 } 159 } 160 161 func testStickyProposer(t *testing.T) { 162 b1 := common.Hex2Bytes(testAddress) 163 b2 := common.Hex2Bytes(testAddress2) 164 addr1 := common.BytesToAddress(b1) 165 addr2 := common.BytesToAddress(b2) 166 val1 := New(addr1) 167 val2 := New(addr2) 168 169 valSet := newDefaultSet([]common.Address{addr1, addr2}, bft.Sticky) 170 171 // test get proposer 172 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { 173 t.Errorf("proposer mismatch: have %v, want %v", val, val1) 174 } 175 // test calculate proposer 176 lastProposer := addr1 177 valSet.CalcProposer(lastProposer, uint64(0)) 178 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { 179 t.Errorf("proposer mismatch: have %v, want %v", val, val1) 180 } 181 182 valSet.CalcProposer(lastProposer, uint64(1)) 183 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { 184 t.Errorf("proposer mismatch: have %v, want %v", val, val2) 185 } 186 // test empty last proposer 187 lastProposer = common.Address{} 188 valSet.CalcProposer(lastProposer, uint64(3)) 189 if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { 190 t.Errorf("proposer mismatch: have %v, want %v", val, val2) 191 } 192 }