github.com/bcskill/bcschain/v3@v3.4.9-beta2/consensus/clique/clique_test.go (about) 1 package clique 2 3 import ( 4 "bytes" 5 "sort" 6 "testing" 7 8 "github.com/bcskill/bcschain/v3/common" 9 ) 10 11 func TestExtraData(t *testing.T) { 12 for _, test := range []extraDataTest{ 13 { 14 name: "normal-voter-vote", 15 data: []byte("vanity string!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01#Eg\x89\xff"), 16 vanity: "vanity string!", 17 candidate: common.HexToAddress("0x123456789"), 18 voterElection: true, 19 }, 20 { 21 name: "normal-signer-vote", 22 data: []byte("test\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01#Eg\x89\x00"), 23 vanity: "test", 24 candidate: common.HexToAddress("0x123456789"), 25 voterElection: false, 26 }, 27 { 28 name: "spaces-no-vote", 29 data: []byte(" spaces \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 30 vanity: " spaces ", 31 }, 32 } { 33 t.Run(test.name, test.run) 34 } 35 } 36 37 type extraDataTest struct { 38 name string 39 data []byte 40 vanity string 41 candidate common.Address 42 voterElection bool 43 } 44 45 func (test *extraDataTest) run(t *testing.T) { 46 if vanity := string(bytes.TrimRight(ExtraVanity(test.data), "\x00")); vanity != test.vanity { 47 t.Errorf("expected vanity %q but got %q", test.vanity, vanity) 48 } 49 if ExtraHasVote(test.data) { 50 if test.candidate == (common.Address{}) { 51 t.Errorf("unexpected vote: %s voter election: %t", ExtraCandidate(test.data), ExtraIsVoterElection(test.data)) 52 } else { 53 candidate, isVoter := ExtraCandidate(test.data), ExtraIsVoterElection(test.data) 54 if candidate != test.candidate { 55 t.Errorf("expected candidate %s but got %s", test.candidate.Hex(), candidate.Hex()) 56 } 57 if isVoter != test.voterElection { 58 t.Errorf("expected voterElections %t but got %t", test.voterElection, isVoter) 59 } 60 } 61 } else { 62 if test.candidate != (common.Address{}) { 63 t.Errorf("expected vote but got none: %s voter election: %t", test.candidate.Hex(), test.voterElection) 64 } 65 } 66 67 var extra []byte 68 extra = append(extra, test.vanity...) 69 extra = ExtraEnsureVanity(extra) 70 if test.candidate != (common.Address{}) { 71 extra = ExtraAppendVote(extra, test.candidate, test.voterElection) 72 } 73 if !bytes.Equal(test.data, extra) { 74 t.Errorf("expected:\n\t%q\ngot:\n\t%q", test.data, extra) 75 } 76 } 77 78 func TestCalcDifficulty(t *testing.T) { 79 addrs := []common.Address{ 80 common.StringToAddress("0abcdefghijklmnopqrs"), 81 common.StringToAddress("1abcdefghijklmnopqrs"), 82 common.StringToAddress("2abcdefghijklmnopqrs"), 83 common.StringToAddress("3abcdefghijklmnopqrs"), 84 common.StringToAddress("4abcdefghijklmnopqrs"), 85 common.StringToAddress("5abcdefghijklmnopqrs"), 86 } 87 for _, test := range []testCalcDifficulty{ 88 // Genesis. 89 { 90 name: "3/genesis", 91 lastSigned: map[common.Address]uint64{ 92 addrs[0]: 0, 93 addrs[1]: 0, 94 addrs[2]: 0, 95 }, 96 }, 97 { 98 name: "6/genesis", 99 lastSigned: map[common.Address]uint64{ 100 addrs[0]: 0, 101 addrs[1]: 0, 102 addrs[2]: 0, 103 addrs[3]: 0, 104 addrs[4]: 0, 105 addrs[5]: 0, 106 }, 107 }, 108 109 // All signed. 110 { 111 name: "3/all-signed/in-turn", 112 lastSigned: map[common.Address]uint64{ 113 addrs[0]: 1, 114 addrs[1]: 2, 115 addrs[2]: 3, 116 }, 117 }, 118 { 119 name: "3/all-signed/out-of-turn", 120 lastSigned: map[common.Address]uint64{ 121 addrs[0]: 1, 122 addrs[1]: 4, 123 addrs[2]: 3, 124 }, 125 }, 126 { 127 name: "6/all-signed/in-turn", 128 lastSigned: map[common.Address]uint64{ 129 addrs[0]: 1, 130 addrs[1]: 2, 131 addrs[2]: 3, 132 addrs[3]: 4, 133 addrs[4]: 5, 134 addrs[5]: 6, 135 }, 136 }, 137 { 138 name: "6/all-signed/out-of-turn", 139 lastSigned: map[common.Address]uint64{ 140 addrs[0]: 9, 141 addrs[1]: 2, 142 addrs[2]: 7, 143 addrs[3]: 8, 144 addrs[4]: 5, 145 addrs[5]: 6, 146 }, 147 }, 148 149 // One new. 150 { 151 name: "3/one-new", 152 lastSigned: map[common.Address]uint64{ 153 addrs[0]: 0, 154 addrs[1]: 4, 155 addrs[2]: 3, 156 }, 157 }, 158 { 159 name: "6/one-new", 160 lastSigned: map[common.Address]uint64{ 161 addrs[0]: 1, 162 addrs[1]: 2, 163 addrs[2]: 3, 164 addrs[3]: 4, 165 addrs[4]: 5, 166 addrs[5]: 0, 167 }, 168 }, 169 170 // Multiple new. 171 { 172 name: "3/multiple-new", 173 lastSigned: map[common.Address]uint64{ 174 addrs[0]: 0, 175 addrs[1]: 0, 176 addrs[2]: 3, 177 }, 178 }, 179 { 180 name: "6/multiple-new", 181 lastSigned: map[common.Address]uint64{ 182 addrs[0]: 0, 183 addrs[1]: 0, 184 addrs[2]: 3, 185 addrs[3]: 0, 186 addrs[4]: 0, 187 addrs[5]: 0, 188 }, 189 }, 190 } { 191 t.Run(test.name, test.run) 192 } 193 } 194 195 type testCalcDifficulty struct { 196 name string 197 lastSigned map[common.Address]uint64 198 } 199 200 func (test *testCalcDifficulty) run(t *testing.T) { 201 var signers []common.Address 202 for addr := range test.lastSigned { 203 signers = append(signers, addr) 204 } 205 sort.Slice(signers, func(i, j int) bool { 206 iAddr, jAddr := signers[i], signers[j] 207 iN, jN := test.lastSigned[iAddr], test.lastSigned[jAddr] 208 if iN != jN { 209 return iN < jN 210 } 211 return bytes.Compare(iAddr[:], jAddr[:]) < 0 212 }) 213 for i, signer := range signers { 214 exp := len(signers) - i 215 if exp <= len(signers)/2 { 216 exp = 0 217 } 218 got := CalcDifficulty(test.lastSigned, signer) 219 if got != uint64(exp) { 220 t.Errorf("expected difficulty %d but got %d", exp, got) 221 } 222 } 223 }