github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/core/vm/election/election_test.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt 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-vnt 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-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package election 18 19 import ( 20 "bytes" 21 "fmt" 22 "math/big" 23 "reflect" 24 "strconv" 25 "testing" 26 27 "github.com/magiconair/properties/assert" 28 "github.com/vntchain/go-vnt/common" 29 "github.com/vntchain/go-vnt/core/state" 30 inter "github.com/vntchain/go-vnt/core/vm/interface" 31 "github.com/vntchain/go-vnt/vntdb" 32 ) 33 34 var url = []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHGq5zZFRW5FBJ9YMbbvSiW4AzGg5CKMCtDeg6FNnjCbGS") 35 36 var InputCase = [][]byte{ 37 common.FromHex("c94ba774"), 38 common.FromHex("68cc738800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a"), 39 common.FromHex("95c96554"), 40 common.FromHex("487a2abb"), 41 common.FromHex("31f080ef"), 42 common.FromHex("c9a63035"), 43 common.FromHex("97107d6d000000000000000000000000a863d8efa01ece6fabfa7e8c85217a3c1af833a9"), 44 common.FromHex("a694fc3a0000000000000000000000000000000000000000000000000000000000000064"), 45 common.FromHex("73cf575a"), 46 common.FromHex("65f7314e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000004d2f6970342f3132372e302e302e312f7463702f33303330332f697066732f316b484771357a5a4652573546424a39594d62627653695734417a476735434b4d437444656736464e6e6a436247530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000317777772e746573746e65742e696e666f2e776562736974652e746573742e746573742e746573742e746573742e74657374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000874657374696e666f000000000000000000000000000000000000000000000000"), 47 common.FromHex("f67ab93e"), 48 } 49 50 type candiRegInfo struct { 51 addr common.Address 52 name []byte 53 website []byte 54 url []byte 55 } 56 57 var ( 58 addr1 = common.HexToAddress("41b0db166cfdf1c4ba3ce657171482a9aa55cc93") 59 addr2 = common.HexToAddress("08b467a881ec34b668254aa956e0c46f9c3b2b83") 60 addr3 = common.HexToAddress("0c0292587ccdc76b8f449002a017bc9479ff0a88") 61 addr4 = common.HexToAddress("0a0292587ccdc76b8f449002a017bc9479ff0a88") 62 addr5 = common.HexToAddress("0b0292587ccdc76b8f449002a017bc9479ff0a88") 63 addr6 = common.HexToAddress("0d0292587ccdc76b8f449002a017bc9479ff0a88") 64 addr7 = common.HexToAddress("0e0292587ccdc76b8f449002a017bc9479ff0a88") 65 addr8 = common.HexToAddress("0e0292587ccdc76b8f449002a017bc9479ff0a81") 66 addr9 = common.HexToAddress("0e0292587ccdc76b8f449002a017bc9479ff0a82") 67 68 candiInfo1 = candiRegInfo{addr1, []byte("node1"), []byte("www.node1.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHNAAfnqXNsxMwJf6QjJFRmVK7iB32U9owwK9KfeLFxEA7")} 69 candiInfo2 = candiRegInfo{addr2, []byte("node2"), []byte("www.node2.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHcch6yuBCgC5nPPSK3Yp7Es4c4eenxAeK167pYwUvNjRo")} 70 candiInfo3 = candiRegInfo{addr3, []byte("node3"), []byte("www.node3.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHJFKr2bzUnMr1NbeyYbYJa3RXT18cEu7cNDrHWjg8XYKB")} 71 candiInfo4 = candiRegInfo{addr4, []byte("node4"), []byte("www.node4.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198")} 72 candiInfo5 = candiRegInfo{addr5, []byte("node5"), []byte("www.node5.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHGG8L1DTrVG3Cad479Q32oGmFAiEjLFwxzNyXH3ehGo73")} 73 candiInfo6 = candiRegInfo{addr6, []byte("node6"), []byte("www.node6.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHmExX4yutwBZLbRsYHq59KfgiM1LUJFW2JSPeSCcBf7rH")} 74 candiInfo7 = candiRegInfo{addr7, []byte("nodd7"), []byte("www.node7.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHSMhv82q5thJkdeJzxCVW8tdXwaDThBZWsH2Q9KUGGFUq")} 75 candiInfo8 = candiRegInfo{addr8, []byte("nodd8"), []byte("www.node8.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHYwV52itn31V5fRXzERMygHFDx6PrSFS8puEr3N4Ujv69")} 76 candiInfo9 = candiRegInfo{addr9, []byte("nodd9"), []byte("www.node9.com"), []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHiEQS9qnK1YJN25eNyTjDRUukTzComAMWYAowTAYCu1K4")} 77 78 candidates = []common.Address{addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8, addr9} 79 candiInfos = []candiRegInfo{candiInfo1, candiInfo2, candiInfo3, candiInfo4, candiInfo5, candiInfo6, candiInfo7, candiInfo8, candiInfo9} 80 81 // 绑定人信息 82 binder = common.HexToAddress("923839919383938289") 83 beneficiary = common.HexToAddress("923839919383938281") 84 ) 85 86 type testContext struct { 87 Origin common.Address 88 Time *big.Int 89 StateDB inter.StateDB 90 BlockNumber *big.Int 91 } 92 93 func (tc *testContext) GetOrigin() common.Address { 94 return tc.Origin 95 } 96 97 func (tc *testContext) GetStateDb() inter.StateDB { 98 return tc.StateDB 99 } 100 101 func (tc *testContext) GetTime() *big.Int { 102 return tc.Time 103 } 104 105 func (tc *testContext) SetTime(t *big.Int) { 106 tc.Time = t 107 } 108 109 func (tc *testContext) GetBlockNum() *big.Int { 110 return tc.BlockNumber 111 } 112 113 func newcontext() inter.ChainContext { 114 db := vntdb.NewMemDatabase() 115 stateDB, _ := state.New(common.Hash{}, state.NewDatabase(db)) 116 c := testContext{ 117 Origin: common.BytesToAddress([]byte{111}), 118 Time: big.NewInt(1531328510), 119 StateDB: stateDB, 120 BlockNumber: big.NewInt(int64(ElectionStart+1)), 121 } 122 return &c 123 } 124 125 func getAllVoter(t *testing.T, db inter.StateDB) []*Voter { 126 var result []*Voter 127 voters := make(map[common.Hash]common.Hash) 128 addrs := make(map[common.Address]struct{}) 129 130 // 根据voter前缀,在db中获取所有的voter地址 131 db.ForEachStorage(contractAddr, func(key common.Hash, value common.Hash) bool { 132 if key[0] == VOTERPREFIX { 133 voters[key] = value 134 135 var addr common.Address 136 copy(addr[:], key[PREFIXLENGTH:PREFIXLENGTH+common.AddressLength]) 137 addrs[addr] = struct{}{} 138 } 139 return true 140 }) 141 142 getFn := func(key common.Hash) common.Hash { 143 return voters[key] 144 } 145 146 // 根据已获得的voter地址获取所有的voter结构体 147 for addr := range addrs { 148 var voter Voter 149 if err := convertToStruct(VOTERPREFIX, addr, &voter, getFn); err != nil { 150 t.Errorf("addr: %s, error: %s", addr.String(), err) 151 } 152 result = append(result, &voter) 153 154 } 155 return result 156 } 157 158 // 计算所有投出的票数,跟候选人所拥有的票数是否想相等 159 func checkValid(t *testing.T, c electionContext) (bool, error) { 160 // 保存原先context的时间 161 currentTime := c.context.GetTime() 162 163 proxyVote := make(map[common.Address]*big.Int) 164 // 从所有voter搜集总票数 165 voteCount := make(map[common.Address]*big.Int) 166 voters := getAllVoter(t, c.context.GetStateDb()) 167 // 循环一遍voter,做一遍初步的检查 168 for _, voter := range voters { 169 // 如果proxy不为空 170 if !bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 171 // 则isProxy为假,且voteCandidates为空 172 if voter.IsProxy || len(voter.VoteCandidates) != 0 { 173 return false, fmt.Errorf("voter owner: %x, proxy: %x, isProxy: %t, voteCandidates: %v\n", voter.Owner, voter.Proxy, voter.IsProxy, voter.VoteCandidates) 174 } 175 // 统计投给代理的票 176 if count, ok := proxyVote[voter.Proxy]; ok { 177 count.Add(count, voter.LastVoteCount) 178 count.Add(count, voter.ProxyVoteCount) 179 } 180 } 181 182 if voter.LastVoteCount != nil && voter.LastVoteCount.Sign() > 0 { 183 if voter.TimeStamp == nil || voter.TimeStamp.Cmp(big.NewInt(0)) == 0 { 184 return false, fmt.Errorf("lastVoteCount is not zero. timeStamp must not be nil") 185 186 } 187 // 比对lastVoteCount,是否是当时的抵押数兑换所得 188 stake := c.getStake(voter.Owner) 189 if stake.TimeStamp == nil || stake.TimeStamp.Cmp(big.NewInt(0)) == 0 { 190 return false, fmt.Errorf("lastVoteCount is not zero. stake.timeStamp must not be nil") 191 192 } 193 // 抵押数大于0,且抵押时间小于投票时间,说明上次投票后抵押数没有变 194 if stake.StakeCount.Sign() > 0 && stake.TimeStamp.Cmp(voter.TimeStamp) <= 0 { 195 if ctx, ok := c.context.(*testContext); ok { 196 ctx.SetTime(voter.TimeStamp) 197 } 198 // 计算抵押数可以兑换的票数,与上次投票所得是否一致 199 calculateCount := c.calculateVoteCount(stake.StakeCount) 200 if voter.LastVoteCount.Cmp(calculateCount) != 0 { 201 if ctx, ok := c.context.(*testContext); ok { 202 ctx.SetTime(currentTime) 203 } 204 return false, fmt.Errorf("time: %v, lastVoteCount : %d, stakeCount: %d,calculateCount : %d ", 205 voter.TimeStamp, voter.LastVoteCount, stake.StakeCount, calculateCount) 206 } 207 } 208 // 统计总投票 209 for _, candi := range voter.VoteCandidates { 210 if voteCount[candi] == nil { 211 voteCount[candi] = big.NewInt(0) 212 } 213 voteCount[candi].Add(voteCount[candi], voter.LastVoteCount) 214 voteCount[candi].Add(voteCount[candi], voter.ProxyVoteCount) 215 } 216 } 217 218 } 219 if ctx, ok := c.context.(*testContext); ok { 220 ctx.SetTime(currentTime) 221 } 222 223 // 检查代理投票数 224 for _, voter := range voters { 225 if _, ok := proxyVote[voter.Owner]; !ok { 226 continue 227 } 228 if voter.ProxyVoteCount.Cmp(proxyVote[voter.Owner]) != 0 { 229 return false, fmt.Errorf("proxyVoteCount is wrong, proxyVoteCount in db: %d, expect proxyVote: %d\n", voter.ProxyVoteCount, proxyVote[voter.Owner]) 230 231 } 232 } 233 234 // 检查候选人收到的票数,与所有人投的是否相等 235 candidates := getAllCandidate(c.context.GetStateDb()) 236 for _, candidate := range candidates { 237 if voteCount[candidate.Owner] == nil { 238 voteCount[candidate.Owner] = big.NewInt(0) 239 } 240 if candidate.VoteCount == nil || candidate.VoteCount.Cmp(voteCount[candidate.Owner]) != 0 { 241 return false, fmt.Errorf("voteCount is wrong. candidate address: %x, voteCount in db: %d, expect voteCount : %d", candidate.Owner, candidate.VoteCount, voteCount[candidate.Owner]) 242 } 243 } 244 245 return true, nil 246 } 247 248 func TestInput(t *testing.T) { 249 var e Election 250 context := newcontext() 251 252 for _, input := range InputCase { 253 _, err := e.Run(context, input, big.NewInt(0)) 254 if err != nil && err == fmt.Errorf("call election contract err: method doesn't exist") { 255 t.Error(err) 256 } 257 } 258 } 259 260 func TestCandidate_votes(t *testing.T) { 261 var addr1 common.Address 262 c1 := &Candidate{ 263 Owner: addr1, 264 VoteCount: big.NewInt(10), 265 Registered: true, 266 Bind: true, 267 } 268 269 if c1.votes().Cmp(big.NewInt(10)) != 0 { 270 t.Errorf("votes() error. want = %v, got = %s", 10, c1.votes().String()) 271 } 272 273 c1.Registered = false 274 if c1.votes().Cmp(big.NewInt(-10)) != 0 { 275 t.Errorf("votes() error. want = %v, got = %s", -10, c1.votes().String()) 276 } 277 } 278 279 func TestCandidate_equal(t *testing.T) { 280 addr1 := common.HexToAddress("0x122369f04f32269598789998de33e3d56e2c507a") 281 addr2 := common.HexToAddress("0x42a875ac43f2b4e6d17f54d288071f5952bf8911") 282 c1 := Candidate{Owner: addr1, VoteCount: big.NewInt(10), Registered: true} 283 c2 := Candidate{Owner: addr2, VoteCount: big.NewInt(20), Registered: false} 284 285 if c1.equal(&c2) { 286 t.Errorf("two Candidate should not equal") 287 } 288 289 c1.Owner = addr2 290 c1.Registered = false 291 c1.VoteCount = big.NewInt(20) 292 293 if c1.equal(&c2) == false { 294 t.Errorf("two Candidate should equal") 295 } 296 } 297 298 func TestCandidateList_Less(t *testing.T) { 299 addr1 := common.HexToAddress("0x522369f04f32269598789998de33e3d56e2c507a") 300 addr2 := common.HexToAddress("0x42a875ac43f2b4e6d17f54d288071f5952bf8911") 301 addr3 := common.HexToAddress("0x18a875ac43f2b4e6d17f54d288071f5952bf8911") 302 c1 := Candidate{Owner: addr1, VoteCount: big.NewInt(10), Registered: true} 303 c2 := Candidate{Owner: addr2, VoteCount: big.NewInt(20), Registered: false} 304 c3 := Candidate{Owner: addr3, VoteCount: big.NewInt(10), Registered: true} 305 306 cl := CandidateList{c1, c2, c3} 307 308 if cl.Less(0, 1) == false { 309 t.Errorf("c1 should greater than c2, c1= %s, c2=%s", c1.String(), c2.String()) 310 } 311 if cl.Less(0, 2) == true { 312 t.Errorf("c1 should less than c3, c1= %s, c3=%s", c1.String(), c3.String()) 313 } 314 } 315 316 func TestCandidateList_Swap(t *testing.T) { 317 c1 := Candidate{common.HexToAddress("0x1"), binder, beneficiary, big.NewInt(100), 318 false, false, []byte("/p2p/1"), []byte("node1.com"), []byte("node1")} 319 c2 := Candidate{common.HexToAddress("0x2"), binder, beneficiary, big.NewInt(20), 320 true, true, []byte("/p2p/2"), []byte("node2.com"), []byte("node2")} 321 322 candidates := CandidateList{c1, c2} 323 swaped := CandidateList{c2, c1} 324 candidates.Swap(0, 1) 325 for i, tt := range candidates { 326 if tt.equal(&swaped[i]) == false { 327 t.Errorf("index: %d, expect: %s, got: %s", i, swaped[i].String(), tt.String()) 328 } 329 } 330 } 331 332 func TestCandidateList_Sort(t *testing.T) { 333 // c1票数为负,c2与c5票数相等,c3票数最多 334 c1 := Candidate{common.HexToAddress("0x1"), binder, beneficiary, big.NewInt(100), 335 false, false, []byte("/p2p/1"), []byte("node1.com"), []byte("node1")} 336 c2 := Candidate{common.HexToAddress("0x2"), binder, beneficiary, big.NewInt(20), 337 true, true, []byte("/p2p/2"), []byte("node2.com"), []byte("node2")} 338 c3 := Candidate{common.HexToAddress("0x3"), binder, beneficiary, big.NewInt(90), 339 true, true, []byte("/p2p/3"), []byte("node3.com"), []byte("node3")} 340 c4 := Candidate{common.HexToAddress("0x4"), binder, beneficiary, big.NewInt(40), 341 true, true, []byte("/p2p/4"), []byte("node4.com"), []byte("node4")} 342 c5 := Candidate{common.HexToAddress("0x5"), binder, beneficiary, big.NewInt(20), 343 true, true, []byte("/p2p/5"), []byte("node5.com"), []byte("node5")} 344 candidates := CandidateList{c1, c2, c3, c4, c5} 345 sorted := CandidateList{c3, c4, c2, c5, c1} 346 347 candidates.Sort() 348 for i, tt := range candidates { 349 if tt.equal(&sorted[i]) == false { 350 t.Errorf("index: %d, expect: %s, got: %s", i, sorted[i].String(), tt.String()) 351 } 352 } 353 } 354 355 // Test voteWitnesses 356 // 投的候选人过多返回错误 357 func TestVoteTooManyCandidates(t *testing.T) { 358 context := newcontext() 359 c := newElectionContext(context) 360 addr := common.BytesToAddress([]byte{111}) 361 362 var candidates []common.Address 363 for i := 1; i <= VoteLimit+1; i++ { 364 candidate := common.BytesToAddress([]byte{byte(i)}) 365 candidates = append(candidates, candidate) 366 website := "www.testnet.info" + strconv.Itoa(i) 367 name := "testinfo" + strconv.Itoa(i) 368 p2pUrl := []byte(string(url)[:13] + strconv.Itoa(i) + string(url)[14:]) 369 // t.Logf("url: %s", string(p2pUrl)) 370 info := &NodeInfo{p2pUrl, []byte(website), []byte(name), binder, beneficiary} 371 if err := c.registerWitness(candidate, info); err != nil { 372 t.Errorf("register failed, addr: %s, error: %s", candidate.String(), err) 373 } 374 } 375 err := c.voteWitnesses(addr, candidates) 376 if err.Error() != fmt.Sprintf("you voted too many candidates: the limit is %d, you voted %d", VoteLimit, len(candidates)) { 377 t.Error(err) 378 } 379 } 380 381 // Test voteWitnesses 382 // 当前无抵押返回错误 383 func TestVoteWithoutStake(t *testing.T) { 384 context := newcontext() 385 c := newElectionContext(context) 386 387 addr := common.BytesToAddress([]byte{111}) 388 389 // 不抵押投票,返回未抵押的错误 390 err := c.voteWitnesses(addr, candidates) 391 if err.Error() != "you must stake before vote" { 392 t.Error(err) 393 } 394 } 395 396 // Test voteWitnesses 397 // 距数据库中上次操作时间不足24小时,返回错误 398 func TestVoteWithoutEnoughTimeGap(t *testing.T) { 399 context := newcontext() 400 c := newElectionContext(context) 401 addr := common.BytesToAddress([]byte{111}) 402 403 // 数据库中塞一条voter数据 404 voter := Voter{ 405 Owner: addr, 406 TimeStamp: big.NewInt(1531328500), 407 } 408 if err := c.setVoter(voter); err != nil { 409 t.Errorf("addr: %s, error: %s", voter.Owner, err) 410 } 411 412 // 抵押 413 c.context.GetStateDb().AddBalance(addr, big.NewInt(1e18)) 414 if err := c.stake(addr, vnt2wei(1)); err != nil { 415 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 416 } 417 // 投票 418 err := c.voteWitnesses(addr, candidates) 419 if err.Error() != fmt.Sprintf("it's less than 24h after your last vote or setProxy, lastTime: %v, now: %v", voter.TimeStamp, c.context.GetTime()) { 420 t.Error(err) 421 } 422 } 423 424 // Test voteWitnesses 425 // 原先没有投票也没有代理的情况 426 func TestVoteCandidatesFistTime(t *testing.T) { 427 context := newcontext() 428 c := newElectionContext(context) 429 430 addr := common.BytesToAddress([]byte{111}) 431 stakeAmount := big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18)) 432 c.context.GetStateDb().AddBalance(addr, stakeAmount) 433 if err := c.stake(addr, vnt2wei(10)); err != nil { 434 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 435 } 436 437 acStakeAmount, _ := getLock(c.context.GetStateDb()) 438 assert.Equal(t, acStakeAmount.Amount, stakeAmount, fmt.Sprintf("stake failed, amount of alllock mismatch, addr: %s", addr.String())) 439 440 // 候选人注册 441 for i := 0; i < len(candidates); i++ { 442 website := "www.testnet.info" + strconv.Itoa(i) 443 name := "testinfo" + strconv.Itoa(i) 444 p2pUrl := []byte(string(url)[:13] + strconv.Itoa(i) + string(url)[14:]) 445 info := &NodeInfo{p2pUrl, []byte(website), []byte(name), binder, beneficiary} 446 if err := c.registerWitness(candidates[i], info); err != nil { 447 t.Errorf("register failed, addr: %s, error: %s", candidates[i].String(), err) 448 } 449 } 450 451 // 投票 452 err := c.voteWitnesses(addr, candidates) 453 if err != nil { 454 t.Error(err) 455 } 456 457 if _, err := checkValid(t, c); err != nil { 458 t.Error(err) 459 } 460 } 461 462 // Test cancelVote 463 // 数据库中无记录 464 func TestCancelVoteNoRecord(t *testing.T) { 465 context := newcontext() 466 c := newElectionContext(context) 467 468 addr := common.BytesToAddress([]byte{111}) 469 err := c.cancelVote(addr) 470 if err.Error() != fmt.Sprintf("the voter %x doesn't exist", addr) { 471 t.Error(err) 472 } 473 } 474 475 // Test cancelVote 476 // 数据库中无记录 477 func TestCancelVoteWithProxy(t *testing.T) { 478 context := newcontext() 479 c := newElectionContext(context) 480 481 addr := common.BytesToAddress([]byte{111}) 482 // 数据库中塞条记录 483 voter := Voter{ 484 Owner: addr, 485 Proxy: common.BytesToAddress([]byte{10}), 486 TimeStamp: big.NewInt(1531328510), 487 } 488 if err := c.setVoter(voter); err != nil { 489 t.Errorf("addr: %s, error: %s", voter.Owner, err) 490 } 491 492 err := c.cancelVote(addr) 493 if err.Error() != fmt.Sprintf("must cancel proxy first, proxy: %x", voter.Proxy) { 494 t.Error(err) 495 } 496 } 497 498 // Test cancelVote 499 func TestCancelVote(t *testing.T) { 500 context := newcontext() 501 c := newElectionContext(context) 502 addr := common.BytesToAddress([]byte{111}) 503 addr1 := common.BytesToAddress([]byte{10}) 504 505 // 抵押1 506 c.context.GetStateDb().AddBalance(addr, big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18))) 507 if err := c.stake(addr, vnt2wei(10)); err != nil { 508 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 509 } 510 511 // 抵押2 512 c.context.GetStateDb().AddBalance(addr1, big.NewInt(0).Mul(big.NewInt(100), big.NewInt(1e18))) 513 if err := c.stake(addr1, vnt2wei(100)); err != nil { 514 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 515 } 516 517 // 设置候选人 518 for i := 0; i < len(candidates); i++ { 519 website := "www.testnet.info" + strconv.Itoa(i) 520 name := "testinfo" + strconv.Itoa(i) 521 p2pUrl := []byte(string(url)[:13] + strconv.Itoa(i) + string(url)[14:]) 522 info := &NodeInfo{p2pUrl, []byte(website), []byte(name), binder, beneficiary} 523 if err := c.registerWitness(candidates[i], info); err != nil { 524 t.Errorf("register failed, addr: %s, error: %s", candidates[i].String(), err) 525 } 526 } 527 528 // 投票1 529 if err := c.voteWitnesses(addr, candidates); err != nil { 530 t.Errorf("vote addr: %s, error: %s", addr.String(), err) 531 } 532 voteCount := c.calculateVoteCount(big.NewInt(10)) 533 if _, err := checkValid(t, c); err != nil { 534 t.Error(err) 535 } 536 537 // 投票2 538 if err := c.voteWitnesses(addr1, candidates); err != nil { 539 t.Errorf("vote addr: %s, error: %s", addr1.String(), err) 540 } 541 voteCount1 := c.calculateVoteCount(big.NewInt(100)) 542 totalVoteCount := new(big.Int).Set(voteCount) 543 totalVoteCount.Add(totalVoteCount, voteCount1) 544 545 // 验证2 546 if _, err := checkValid(t, c); err != nil { 547 t.Error(err) 548 } 549 550 // 取消投票 551 if err := c.cancelVote(addr); err != nil { 552 t.Errorf("cancelVote, addr: %s, error: %s", addr.String(), err) 553 } 554 555 if _, err := checkValid(t, c); err != nil { 556 t.Error(err) 557 } 558 } 559 560 // Test setProxy 561 // 设置代理人为自身返回错误 562 func TestProxySelf(t *testing.T) { 563 context := newcontext() 564 c := newElectionContext(context) 565 addr := common.BytesToAddress([]byte{111}) 566 567 err := c.setProxy(addr, addr) 568 if err.Error() != "cannot proxy to self" { 569 t.Error(err) 570 } 571 } 572 573 // Test setProxy 574 // 设置代理人为自身 575 func TestProxySelfIsProxy(t *testing.T) { 576 context := newcontext() 577 c := newElectionContext(context) 578 addr := common.BytesToAddress([]byte{111}) 579 proxy := common.BytesToAddress([]byte{10}) 580 // addr 成为代理 581 if err := c.startProxy(addr); err != nil { 582 t.Errorf("start proxy, addr: %s, error: %s", addr.String(), err) 583 } 584 if err := c.setProxy(addr, proxy); err.Error() != "account registered as a proxy is not allowed to use a proxy" { 585 t.Error(err) 586 } 587 } 588 589 // Test setProxy 590 // 当前无抵押返回错误 591 func TestProxyWithoutStake(t *testing.T) { 592 context := newcontext() 593 c := newElectionContext(context) 594 595 addr := common.BytesToAddress([]byte{111}) 596 proxy := common.BytesToAddress([]byte{10}) 597 // 不抵押投票,返回未抵押的错误 598 err := c.setProxy(addr, proxy) 599 if err.Error() != "you must stake before vote" { 600 t.Error(err) 601 } 602 } 603 604 // Test setProxy 605 // 距数据库中上次操作时间不足24小时,返回错误 606 func TestProxyWithoutEnoughTimeGap(t *testing.T) { 607 context := newcontext() 608 c := newElectionContext(context) 609 addr := common.BytesToAddress([]byte{111}) 610 proxy := common.BytesToAddress([]byte{10}) 611 612 // 数据库中塞一条voter数据 613 voter := Voter{ 614 Owner: addr, 615 TimeStamp: big.NewInt(1531328500), 616 } 617 if err := c.setVoter(voter); err != nil { 618 t.Errorf("addr: %s, error: %s", voter.Owner, err) 619 } 620 621 // 抵押 622 c.context.GetStateDb().AddBalance(addr, big.NewInt(1e18)) 623 if err := c.stake(addr, vnt2wei(1)); err != nil { 624 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 625 } 626 // 设置代理 627 err := c.setProxy(addr, proxy) 628 if err.Error() != fmt.Sprintf("it's less than 24h after your last vote or setProxy, lastTime: %v, now: %v", voter.TimeStamp, c.context.GetTime()) { 629 t.Error(err) 630 } 631 } 632 633 // Test setProxy 634 // 设置的代理人不是代理 635 func TestProxyIsNotProxy(t *testing.T) { 636 context := newcontext() 637 c := newElectionContext(context) 638 addr := common.BytesToAddress([]byte{111}) 639 proxy := common.BytesToAddress([]byte{10}) 640 641 // 抵押 642 c.context.GetStateDb().AddBalance(addr, big.NewInt(1e18)) 643 if err := c.stake(addr, vnt2wei(1)); err != nil { 644 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 645 } 646 647 // 设置代理 648 err := c.setProxy(addr, proxy) 649 if err.Error() != fmt.Sprintf("%x is not a proxy", proxy) { 650 t.Error(err) 651 } 652 } 653 654 func TestSetProxy(t *testing.T) { 655 context := newcontext() 656 c := newElectionContext(context) 657 658 err := setProxy(t, c) 659 if err != nil { 660 t.Error(err) 661 } 662 } 663 664 // Test cancelProxy 665 // 数据库中无记录 666 func TestCancelProxyNoRecord(t *testing.T) { 667 context := newcontext() 668 c := newElectionContext(context) 669 addr := common.BytesToAddress([]byte{111}) 670 671 err := c.cancelProxy(addr) 672 if err.Error() != "not set proxy" { 673 t.Error(err) 674 } 675 } 676 677 // Test cancelProxy 678 // 数据库中无记录 679 func TestCancelProxyNoProxy(t *testing.T) { 680 context := newcontext() 681 c := newElectionContext(context) 682 addr := common.BytesToAddress([]byte{111}) 683 // 数据库中塞条记录 684 voter := Voter{ 685 Owner: addr, 686 TimeStamp: big.NewInt(1531328500), 687 } 688 if err := c.setVoter(voter); err != nil { 689 t.Errorf("addr: %s, error: %s", voter.Owner, err) 690 } 691 692 err := c.cancelProxy(addr) 693 if err.Error() != "not set proxy" { 694 t.Error(err) 695 } 696 } 697 698 // Test cancelProxy 699 func TestCancelProxy(t *testing.T) { 700 // 111->10 701 context := newcontext() 702 c := newElectionContext(context) 703 704 addr := common.BytesToAddress([]byte{111}) 705 err := setProxy(t, c) 706 if err != nil { 707 t.Error(err) 708 } 709 710 // 取消代理 711 err = c.cancelProxy(addr) 712 if err != nil { 713 t.Error(err) 714 } 715 716 voteCount := c.calculateVoteCount(big.NewInt(100)) 717 candi := c.getCandidate(candidate.Owner) 718 if candi.VoteCount.Cmp(voteCount) != 0 { 719 t.Fatalf("Proxy test want vote count: %v, got: %v", voteCount, candi.VoteCount) 720 } 721 722 if _, err := checkValid(t, c); err != nil { 723 t.Error(err) 724 } 725 } 726 727 // Test startProxy 728 // 已经是代理了 729 func TestStartProxyWithIsProxy(t *testing.T) { 730 context := newcontext() 731 c := newElectionContext(context) 732 err := setProxy(t, c) 733 if err != nil { 734 t.Error(err) 735 } 736 737 err = c.startProxy(common.BytesToAddress([]byte{10})) 738 if err.Error() != "startProxy proxy is already started" { 739 t.Error(err) 740 } 741 } 742 743 // Test startProxy 744 // 设置了代理的不可以成为代理 745 func TestStartProxyWithSetProxy(t *testing.T) { 746 context := newcontext() 747 c := newElectionContext(context) 748 err := setProxy(t, c) 749 if err != nil { 750 t.Error(err) 751 } 752 753 err = c.startProxy(common.BytesToAddress([]byte{111})) 754 if err.Error() != "account that uses a proxy is not allowed to become a proxy" { 755 t.Error(err) 756 } 757 } 758 759 // Test stopProxy 760 // 数据库中无记录 761 func TestStopProxyNoRecord(t *testing.T) { 762 context := newcontext() 763 c := newElectionContext(context) 764 addr := common.BytesToAddress([]byte{111}) 765 err := c.stopProxy(addr) 766 if err.Error() != "stopProxy proxy does not exist." { 767 t.Error(err) 768 } 769 } 770 771 // Test stopProxy 772 // 不是代理 773 func TestStopProxyNotProxy(t *testing.T) { 774 context := newcontext() 775 c := newElectionContext(context) 776 777 voter := newVoter() 778 voter.Owner = common.BytesToAddress([]byte{111}) 779 if err := c.setVoter(voter); err != nil { 780 t.Errorf("addr: %s, error: %s", voter.Owner, err) 781 } 782 783 err := c.stopProxy(common.BytesToAddress([]byte{111})) 784 if err.Error() != "stopProxy address is not proxy" { 785 t.Error(err) 786 } 787 } 788 789 func TestStartAndStopProxy(t *testing.T) { 790 // addr: common.BytesToAddress([]byte{111}) 有10票 791 // proxy: common.BytesToAddress([]byte{10}) 有100票 792 // addr1: common.BytesToAddress([]byte{50}) 有20票 793 // 一开始proxy是代理 794 // addr和addr1都设置proxy为其代理 795 // proxy停止代理,这个时候proxy身上有自身的票,addr和addr1的票 796 // addr取消代理, 这个时候proxy身上有自身的票,addr1的票 797 // proxy重新开始代理,接受新的人给它的代理 798 799 context := newcontext() 800 c := newElectionContext(context) 801 addr := common.BytesToAddress([]byte{111}) 802 addr1 := common.BytesToAddress([]byte{50}) 803 proxy := common.BytesToAddress([]byte{10}) 804 db := c.context.GetStateDb() 805 db.AddBalance(addr1, big.NewInt(0).Mul(big.NewInt(20), big.NewInt(1e18))) 806 stakeVnt := vnt2wei(20) 807 testTransfer(db, addr1, contractAddr, stakeVnt) 808 if err := c.stake(addr1, stakeVnt); err != nil { 809 t.Errorf("stake failed, addr: %s, error: %s", addr.String(), err) 810 } 811 if db.GetBalance(contractAddr).Cmp(stakeVnt) != 0 { 812 t.Fatalf("contract do not have enough vnt") 813 } 814 815 // addr 设置 proxy为代理 816 err := setProxy(t, c) 817 if err != nil { 818 t.Error(err) 819 } 820 821 // addr1 设置 proxy为代理 822 err = c.setProxy(addr1, proxy) 823 if err != nil { 824 t.Error(err) 825 } 826 if _, err := checkValid(t, c); err != nil { 827 t.Error(err) 828 } 829 830 // 停止代理,原先代理的票都还有效 831 if err := c.stopProxy(proxy); err != nil { 832 t.Errorf("stop proxy, addr: %s, error: %s", proxy.String(), err) 833 } 834 if ctx, ok := c.context.(*testContext); ok { 835 ctx.SetTime(big.NewInt(1531795552)) 836 } 837 if err := c.voteWitnesses(proxy, candidates); err != nil { 838 t.Errorf("vote, addr: %s, error: %s", proxy.String(), err) 839 } 840 if _, err := checkValid(t, c); err != nil { 841 t.Error(err) 842 } 843 844 // 取消addr交给proxy的代理 845 if err := c.cancelProxy(addr); err != nil { 846 t.Errorf("cancel proxy, addr: %s, error: %s", addr.String(), err) 847 } 848 if _, err := checkValid(t, c); err != nil { 849 t.Error(err) 850 } 851 852 // 重新开始代理 853 if err := c.startProxy(proxy); err != nil { 854 t.Errorf("start proxy, addr: %s, error: %s", proxy.String(), err) 855 } 856 if err := c.unStake(addr1); err != nil { 857 t.Errorf("unstake, addr: %s, error: %s", addr1.String(), err) 858 } 859 c.context.GetStateDb().AddBalance(addr1, big.NewInt(0).Mul(big.NewInt(20), big.NewInt(1e18))) 860 if err := c.stake(addr1, vnt2wei(30)); err != nil { 861 t.Errorf("stake, addr: %s, error: %s", addr1.String(), err) 862 } 863 864 // 设置代理 865 if err := c.setProxy(addr1, proxy); err != nil { 866 t.Errorf("set proxy, addr: %s, error: %s", addr1.String(), err) 867 } 868 if _, err := checkValid(t, c); err != nil { 869 t.Error(err) 870 } 871 } 872 873 func testTransfer(db inter.StateDB, sender, receiver common.Address, amount *big.Int) { 874 db.AddBalance(receiver, amount) 875 db.SubBalance(sender, amount) 876 } 877 878 func TestStopAndSetProxy(t *testing.T) { 879 // addr: common.BytesToAddress([]byte{111}) 有10票 880 // proxy: common.BytesToAddress([]byte{10}) 有100票 881 // addr1: common.BytesToAddress([]byte{50}) 有20票 882 // 一开始proxy和addr1都是代理 883 // addr开始设置proxy为其代理 884 // proxy停止代理,并设置addr1为其代理, 这个时候addr1身上有自身的票,proxy的票和addr的票 885 // addr1取消代理, 这个时候addr1身上有自身的票,proxy的票 886 context := newcontext() 887 c := newElectionContext(context) 888 addr := common.BytesToAddress([]byte{111}) 889 addr1 := common.BytesToAddress([]byte{50}) 890 proxy := common.BytesToAddress([]byte{10}) 891 892 // addr 设置 proxy为代理 893 err := setProxy(t, c) 894 if err != nil { 895 t.Error(err) 896 } 897 898 voteCount := c.calculateVoteCount(big.NewInt(10)) 899 voteCount1 := c.calculateVoteCount(big.NewInt(100)) 900 proxyVoteCount := big.NewInt(0) 901 proxyVoteCount.Add(proxyVoteCount, voteCount) 902 903 stake := Stake{ 904 Owner: addr1, 905 StakeCount: big.NewInt(20), 906 } 907 if err := c.setStake(stake); err != nil { 908 t.Errorf("stake, addr: %s, error: %s", stake.Owner.String(), err) 909 } 910 911 // addr1 投票 912 // addr1 开始代理 913 if err := c.startProxy(addr1); err != nil { 914 t.Errorf("start proxy, addr: %s, error: %s", addr1.String(), err) 915 } 916 err = c.voteWitnesses(addr1, []common.Address{candidate.Owner}) 917 voteCount2 := c.calculateVoteCount(big.NewInt(20)) 918 totalVoteCount := big.NewInt(0) 919 totalVoteCount.Add(voteCount, voteCount1) 920 totalVoteCount.Add(totalVoteCount, voteCount2) 921 922 if err != nil { 923 t.Error(err) 924 } 925 candi := c.getCandidate(candidate.Owner) 926 if candi.VoteCount.Cmp(totalVoteCount) != 0 { 927 t.Errorf("The vote count %v is Wrong! Expected: %d", candi.VoteCount, totalVoteCount) 928 } 929 930 // proxy 停止代理 931 err = c.stopProxy(proxy) 932 if err != nil { 933 t.Error(err) 934 } 935 936 // proxy 设置代理 937 if ctx, ok := c.context.(*testContext); ok { 938 ctx.SetTime(big.NewInt(1531795552)) 939 } 940 err = c.setProxy(proxy, addr1) 941 totalVoteCount.Sub(totalVoteCount, voteCount1) 942 voteCount1 = c.calculateVoteCount(big.NewInt(100)) 943 totalVoteCount.Add(totalVoteCount, voteCount1) 944 945 if err != nil { 946 t.Error(err) 947 } 948 949 candi = c.getCandidate(candidate.Owner) 950 if candi.VoteCount.Cmp(totalVoteCount) != 0 { 951 t.Errorf("The vote count %v is Wrong! Expected: %d", candi.VoteCount, totalVoteCount) 952 } 953 954 // addr 取消 proxy代理 955 if err := c.cancelProxy(addr); err != nil { 956 t.Errorf("cancel proxy, addr: %s, error: %s", addr.String(), err) 957 } 958 totalVoteCount.Sub(totalVoteCount, voteCount) 959 960 candi = c.getCandidate(candidate.Owner) 961 if candi.VoteCount.Cmp(totalVoteCount) != 0 { 962 t.Errorf("The vote count %v is Wrong! Expected: %d", candi.VoteCount, totalVoteCount) 963 } 964 } 965 966 func setProxy(t *testing.T, c electionContext) error { 967 addr := common.BytesToAddress([]byte{111}) 968 proxy := common.BytesToAddress([]byte{10}) 969 970 // 账户addr抵押 971 c.context.GetStateDb().AddBalance(addr, big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18))) 972 if err := c.stake(addr, vnt2wei(10)); err != nil { 973 t.Errorf("stake, addr: %s, error: %s", addr.String(), err) 974 } 975 976 // 账户proxy抵押 977 c.context.GetStateDb().AddBalance(proxy, big.NewInt(0).Mul(big.NewInt(100), big.NewInt(1e18))) 978 if err := c.stake(proxy, vnt2wei(100)); err != nil { 979 t.Errorf("stake, addr: %s, error: %s", proxy.String(), err) 980 } 981 982 // 账户proxy注册成为代理 983 err := c.startProxy(proxy) 984 if err != nil { 985 return err 986 } 987 988 // 账户addr设置proxy 989 err = c.setProxy(addr, proxy) 990 if err != nil { 991 return err 992 } 993 994 // 保存已active的候选人 995 c.setCandidate(candidate) 996 997 // 代理人投票 998 err = c.voteWitnesses(proxy, []common.Address{candidate.Owner}) 999 if err != nil { 1000 return err 1001 } 1002 1003 if _, err := checkValid(t, c); err != nil { 1004 return err 1005 } 1006 return nil 1007 } 1008 1009 func TestRegisterWitness(t *testing.T) { 1010 context := newcontext() 1011 ec := newElectionContext(context) 1012 1013 addr1 := common.HexToAddress("41b0db166cfdf1c4ba3ce657171482a9aa55cc93") 1014 addr2 := common.HexToAddress("08b467a881ec34b668254aa956e0c46f9c3b2b83") 1015 addr3 := common.HexToAddress("0c0292587ccdc76b8f449002a017bc9479ff0a88") 1016 addr4 := common.HexToAddress("0a0292587ccdc76b8f449002a017bc9479ff0a88") 1017 addr5 := common.HexToAddress("0b0292587ccdc76b8f449002a017bc9479ff0a88") 1018 addr6 := common.HexToAddress("0d0292587ccdc76b8f449002a017bc9479ff0a88") 1019 addr7 := common.HexToAddress("0e0292587ccdc76b8f449002a017bc9479ff0a88") 1020 1021 t.Logf("addr1: %v", addr1.Hex()) 1022 t.Logf("addr2: %v", addr2.Hex()) 1023 t.Logf("addr3: %v", addr3.Hex()) 1024 t.Logf("addr4: %v", addr4.Hex()) 1025 1026 complicatedErr := fmt.Errorf("complicated error, not compare error content") 1027 // 注册见证人的测试用例,err为nil代表需要注册成功 1028 ts := []struct { 1029 addr common.Address 1030 url []byte 1031 website []byte 1032 name []byte 1033 err error 1034 matchErr bool // 是否对error内容进行匹配,p2p类别的错误不易的,可设置为false 1035 desc string // 本case的描述 1036 }{ 1037 {addr1, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHNAAfnqXNsxMwJf6QjJFRmVK7iB32U9owwK9KfeLFxEA7"), []byte("www.testnet1.site"), []byte("node1"), nil, true, "node1 success"}, 1038 {addr1, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHNAAfnqXNsxMwJf6QjJFRmVK7iB32U9owwK9KfeLFxEA7"), []byte("www.testnet1.site"), []byte("node1"), ErrCandiAlreadyReg, true, "node1 dup-register"}, 1039 {addr2, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHcch6yuBCgC5nPPSK3Yp7Es4c4eenxAeK167pYwUvNjRo"), []byte("www.testnet2.site"), []byte("node2"), nil, true, "node2 success"}, 1040 {addr3, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHJFKr2bzUnMr1NbeyYbYJa3RXT18cEu7cNDrHWjg8XYKB"), []byte("www.testnet3.site"), []byte("node3"), nil, true, "node3 success"}, 1041 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("s"), ErrCandiNameLenInvalid, true, "node4 too short name"}, 1042 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("tooloooooooooooooname"), ErrCandiNameLenInvalid, true, "node4 too long name"}, 1043 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("ww"), []byte("right name"), ErrCandiUrlLenInvalid, true, "node4 too short website"}, 1044 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.looooooooooooooooooooooooooooooooooooongwebsite.com/looog"), []byte("right name"), ErrCandiUrlLenInvalid, true, "node4 too long website"}, 1045 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("ABCEFacd"), ErrCandiNameInvalid, true, "node4 name should lowercase"}, 1046 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("acd xyz"), ErrCandiNameInvalid, true, "node4 name should only contain lowercase letter and digits"}, 1047 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("acd.xyz"), ErrCandiNameInvalid, true, "node4 name should only contain lowercase letter and digits"}, 1048 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("node3"), ErrCandiInfoDup, true, "node4 dup name"}, 1049 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet3.site"), []byte("node4"), ErrCandiInfoDup, true, "node4 dup website"}, 1050 {addr4, []byte("/ip9/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("node4"), fmt.Errorf("registerWitness node url is error: no protocol with name ip9"), true, "node4 node url invalid: ip9"}, 1051 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtskLfs5fdafemACtfsEX5H5t6oCRpdL1"), []byte("www.testnet4.site"), []byte("node4"), complicatedErr, false, "node4 node url invalid: id is less"}, 1052 {addr4, []byte("/ip4/127.0.0.1/txp/30303/ipfs/1kHfop9dnUHHmtskLfs5fdafemACtfsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("node4"), fmt.Errorf("registerWitness node url is error: no protocol with name txp"), true, "node4 node url invalid: not tcp"}, 1053 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1111111111111111111111111111111111111111RpdL198"), []byte("www.testnet4.site"), []byte("node4"), complicatedErr, false, "node4 node url invalid: id is invalid"}, 1054 {addr4, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHfop9dnUHHmtBXVkLB5UauAmACtrsEX5H5t6oCRpdL198"), []byte("www.testnet4.site"), []byte("node4"), nil, true, "node4 success"}, 1055 {addr5, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHGG8L1DTrVG3Cad479Q32oGmFAiEjLFwxzNyXH3ehGo73"), []byte("www.testnet5.site"), []byte("20charactornaaaaaame"), nil, true, "node5 success"}, 1056 {addr6, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHmExX4yutwBZLbRsYHq59KfgiM1LUJFW2JSPeSCcBf7rH"), []byte("www"), []byte("node6"), nil, true, "node6 success"}, 1057 {addr7, []byte("/ip4/127.0.0.1/tcp/30303/ipfs/1kHSMhv82q5thJkdeJzxCVW8tdXwaDThBZWsH2Q9KUGGFUq"), []byte("www.just60charactor.com/loooooooooooooooooooooooooooooooooog"), []byte("node7"), nil, true, "node7 success"}, 1058 } 1059 1060 for i, c := range ts { 1061 info := &NodeInfo{c.url, c.website, c.name, binder, beneficiary} 1062 err := ec.registerWitness(c.addr, info) 1063 if !reflect.DeepEqual(err, c.err) { 1064 if c.matchErr { 1065 t.Errorf("TestRegisterWitness case %d, case discrition: %s, want err :%v, got:%v", i, c.desc, c.err, err) 1066 } 1067 } 1068 } 1069 1070 // addr1注册成功了,它应当是register为true,bind为false,active为false 1071 ca := ec.getCandidate(addr1) 1072 if ca.Owner != addr1 || !ca.Registered || ca.Bind || ca.Active() { 1073 t.Errorf("addr1 should success and check the active information: %v", ca.String()) 1074 } 1075 1076 candis := getAllCandidate(context.GetStateDb()) 1077 for _, candi := range candis { 1078 t.Logf("333 addr: %v, voteCount: %v, active: %v", candi.Owner.Hex(), candi.VoteCount, candi.Active()) 1079 } 1080 1081 err := ec.unregisterWitness(addr1) 1082 if err != nil { 1083 t.Errorf("TestRegisterWitness unregisterWitness err:%v", err) 1084 } 1085 1086 candis = getAllCandidate(context.GetStateDb()) 1087 for _, candi := range candis { 1088 t.Logf("444 addr: %v, voteCount: %v, active: %v", candi.Owner.Hex(), candi.VoteCount, candi.Active()) 1089 } 1090 1091 err = ec.unregisterWitness(addr3) 1092 if err != nil { 1093 t.Errorf("TestRegisterWitness unregisterWitness err:%v", err) 1094 } 1095 1096 candis = getAllCandidate(context.GetStateDb()) 1097 for _, candi := range candis { 1098 t.Logf("555 addr: %v, voteCount: %v, active: %v", candi.Owner.Hex(), candi.VoteCount, candi.Active()) 1099 } 1100 1101 err = ec.unregisterWitness(addr2) 1102 if err != nil { 1103 t.Errorf("TestRegisterWitness unregisterWitness err:%v", err) 1104 } 1105 1106 candis = getAllCandidate(context.GetStateDb()) 1107 for _, candi := range candis { 1108 t.Logf("666 addr: %v, voteCount: %v, active: %v", candi.Owner.Hex(), candi.VoteCount, candi.Active()) 1109 } 1110 } 1111 1112 func TestRegisterProxy(t *testing.T) { 1113 context := newcontext() 1114 ec := newElectionContext(context) 1115 1116 addr1 := common.HexToAddress("41b0db166cfdf1c4ba3ce657171482a9aa55cc93") 1117 addr2 := common.HexToAddress("08b467a881ec34b668254aa956e0c46f9c3b2b83") 1118 addr3 := common.HexToAddress("0c0292587ccdc76b8f449002a017bc9479ff0a88") 1119 1120 t.Logf("addr1: %v", addr1.Hex()) 1121 t.Logf("addr2: %v", addr2.Hex()) 1122 t.Logf("addr3: %v", addr3.Hex()) 1123 1124 err := ec.startProxy(addr1) 1125 if err != nil { 1126 t.Errorf("TestRegisterProxy startProxy err: %v", err) 1127 } 1128 1129 proxys := getAllProxy(context.GetStateDb()) 1130 for _, proxy := range proxys { 1131 t.Logf("111 proxy %v", proxy.Owner.Hex()) 1132 } 1133 1134 err = ec.stopProxy(addr1) 1135 if err != nil { 1136 t.Errorf("TestRegisterProxy startProxy err: %v", err) 1137 } 1138 1139 proxys = getAllProxy(context.GetStateDb()) 1140 for _, proxy := range proxys { 1141 t.Logf("222 proxy %v", proxy.Owner.Hex()) 1142 } 1143 1144 err = ec.startProxy(addr2) 1145 if err != nil { 1146 t.Errorf("TestRegisterProxy startProxy err: %v", err) 1147 } 1148 1149 err = ec.startProxy(addr3) 1150 if err != nil { 1151 t.Errorf("TestRegisterProxy startProxy err: %v", err) 1152 } 1153 1154 proxys = getAllProxy(context.GetStateDb()) 1155 for _, proxy := range proxys { 1156 t.Logf("333 proxy %v", proxy.Owner.Hex()) 1157 } 1158 } 1159 1160 type stakeCase struct { 1161 bal *big.Int // 账号总余额 1162 vnt *big.Int // 抵押的VNT数 1163 stake *big.Int // 预期的抵押计数 1164 } 1165 1166 // 测试抵押能成功的流程 1167 func TestStake(t *testing.T) { 1168 sc := []stakeCase{ 1169 // 整数 1170 { 1171 vnt2wei(100), 1172 vnt2wei(20), 1173 big.NewInt(20), 1174 }, 1175 // 抵押代币非VNT整数 1176 { 1177 vnt2wei(100), 1178 big.NewInt(0).Add(vnt2wei(20), big.NewInt(100)), 1179 big.NewInt(20), 1180 }, 1181 } 1182 1183 for i, c := range sc { 1184 t.Logf("case %v\n", i) 1185 testStakeWithCase(t, &c) 1186 } 1187 } 1188 1189 func testStakeWithCase(t *testing.T, c *stakeCase) { 1190 context := newcontext() 1191 ec := newElectionContext(context) 1192 db := ec.context.GetStateDb() 1193 addr := common.HexToAddress("41b0db166cfdf1c4ba3ce657171482a9aa55cc93") 1194 db.AddBalance(addr, c.bal) 1195 1196 // 模拟vm转账 1197 db.AddBalance(contractAddr, c.vnt) 1198 db.SubBalance(addr, c.vnt) 1199 1200 err := ec.stake(addr, c.vnt) 1201 if err != nil { 1202 t.Errorf("TestStake stake err:%v ", err) 1203 } 1204 stake := ec.getStake(addr) 1205 checkStake(t, &stake, addr, c.vnt, c.stake) 1206 1207 acStakeAmount, _ := getLock(db) 1208 assert.Equal(t, acStakeAmount.Amount, c.vnt, fmt.Sprintf("after stake, amount of alllock is wrong")) 1209 1210 bal := db.GetBalance(addr) 1211 shouldLeft := big.NewInt(0).Sub(c.bal, c.vnt) 1212 if bal.Cmp(shouldLeft) != 0 { 1213 t.Fatalf("after stake addr should have %v wei got %v wei", shouldLeft.String(), bal.String()) 1214 } 1215 1216 // 取消抵押 1217 err = ec.unStake(addr) 1218 if err.Error() != "cannot unstake in 24 hours" { 1219 t.Errorf("TestStake unStake err:%v ", err) 1220 } 1221 stake = ec.getStake(addr) 1222 checkStake(t, &stake, addr, c.vnt, c.stake) 1223 1224 acStakeAmount, _ = getLock(db) 1225 assert.Equal(t, acStakeAmount.Amount, c.vnt, fmt.Sprintf("after unstake, amount of alllock is wrong")) 1226 1227 // 取消抵押 1228 twentyFourHoursLater(t, context) 1229 err = ec.unStake(addr) 1230 if err != nil { 1231 t.Errorf("TestStake unStake err:%v ", err) 1232 } 1233 stake = ec.getStake(addr) 1234 checkStake(t, &stake, addr, common.Big0, common.Big0) 1235 1236 acStakeAmount, _ = getLock(db) 1237 assert.Equal(t, acStakeAmount.Amount, common.Big0, fmt.Sprintf("finally, amount of alllock is wrong")) 1238 } 1239 1240 func checkStake(t *testing.T, stake *Stake, expAddr common.Address, expVnt, expStake *big.Int) { 1241 if stake.Owner == expAddr { 1242 if stake.StakeCount.Cmp(expStake) != 0 { 1243 t.Fatalf("stake and get stake mismatch, want: %v, got: %v", expStake.String(), stake.StakeCount.String()) 1244 } 1245 if stake.Vnt.Cmp(expVnt) != 0 { 1246 t.Fatalf("stake and get vnt mismatch, want: %v, got: %v Wei", expVnt.String(), stake.Vnt.String()) 1247 } 1248 } else { 1249 t.Fatalf("stake failed, can not get saved stake for addr: %v", expAddr) 1250 } 1251 } 1252 1253 func twentyFourHoursLater(t *testing.T, context inter.ChainContext) { 1254 if ctx, ok := context.(*testContext); ok { 1255 ctx.SetTime(big.NewInt(0).Add(context.GetTime(), big.NewInt(3600*24+1))) 1256 } 1257 } 1258 1259 func TestStakeInvalid(t *testing.T) { 1260 context := newcontext() 1261 ec := newElectionContext(context) 1262 db := ec.context.GetStateDb() 1263 addr := common.HexToAddress("41b0db166cfdf1c4ba3ce657171482a9aa55cc93") 1264 db.AddBalance(addr, vnt2wei(100)) 1265 1266 // 抵押负值 1267 err := ec.stake(addr, vnt2wei(-20)) 1268 if err.Error() != "stake stakeCount less than 1 VNT" { 1269 t.Errorf("TestStake stake err:%v ", err) 1270 } 1271 1272 stake := ec.getStake(addr) 1273 if stake.Owner != emptyAddress { 1274 t.Fatalf("should no stake information for addr: %v", addr.String()) 1275 } 1276 1277 bal := db.GetBalance(addr) 1278 shouldLeft := vnt2wei(100) 1279 if bal.Cmp(shouldLeft) != 0 { 1280 t.Fatalf("after stake addr should have %v wei got %v wei", shouldLeft.String(), bal.String()) 1281 } 1282 } 1283 1284 func TestCalculateVote(t *testing.T) { 1285 context := newcontext() 1286 ec := newElectionContext(context) 1287 stakeCount := big.NewInt(10000000) 1288 1289 tests := []struct { 1290 curTime *big.Int 1291 stake *big.Int 1292 votes *big.Int 1293 }{ 1294 {eraTimeStamp, stakeCount, big.NewInt(10000000)}, // 半衰期开始时 1295 {big.NewInt(1562256000), stakeCount, big.NewInt(14142135)}, // 半衰期半个周期:26周 1296 {big.NewInt(1578067200), stakeCount, big.NewInt(20000000)}, // 半衰期一个周期:52周 1297 {big.NewInt(1609430400), stakeCount, big.NewInt(40000000)}, // 半衰期二个周期:104周 1298 } 1299 1300 for i, ts := range tests { 1301 if ctx, ok := context.(*testContext); ok { 1302 ctx.SetTime(ts.curTime) 1303 } 1304 voteCount := ec.calculateVoteCount(stakeCount) 1305 if voteCount.Cmp(ts.votes) != 0 { 1306 t.Errorf("case %d error, time: %s, stake: %s, want votes: %s, got votes: %s", i, ts.curTime.String(), ts.stake.String(), ts.votes.String(), voteCount) 1307 } 1308 } 1309 } 1310 1311 var operates []string // 有哪些操作 1312 var alreadySet map[byte]struct{} // alreadySet用来标记节点是否已经扩展过 1313 1314 func dfsState(t *testing.T, c electionContext, address common.Address, checkFn func(byte, string, byte) error) error { 1315 // 进入时保存当前数据库状态,退出时恢复 1316 snap := c.context.GetStateDb().Snapshot() 1317 defer c.context.GetStateDb().RevertToSnapshot(snap) 1318 currentState := checkState(c, address) 1319 for _, op := range operates { 1320 snap1 := c.context.GetStateDb().Snapshot() 1321 err := operateOnState(c, op, address) 1322 if err == nil { 1323 if _, err = checkValid(t, c); err != nil { 1324 return err 1325 } 1326 nextState := checkState(c, address) 1327 // 比较到达的状态是否与预期状态一致 1328 if err = checkFn(currentState, op, nextState); err != nil { 1329 return err 1330 } 1331 // 如果是新的状态加入到队列中 1332 if _, ok := alreadySet[nextState]; !ok { 1333 alreadySet[nextState] = struct{}{} 1334 err = dfsState(t, c, address, checkFn) 1335 if err != nil { 1336 return err 1337 } 1338 } 1339 } 1340 c.context.GetStateDb().RevertToSnapshot(snap1) 1341 } 1342 return nil 1343 } 1344 1345 func TestVoteAndProxyState1(t *testing.T) { 1346 // 定义两种角色addr做为普通用户,操作只有投票,取消投票,设置代理,取消设置代理四种 1347 // proxy做为代理用户,操作有投票,取消投票,设置代理,取消设置代理四种,还有startProxy和stopProxy 1348 // addrStateMap存预先设置好addr相关的状态转化图,proxyStateMap存proxy的状态转化图 1349 addr := common.BytesToAddress([]byte{111}) 1350 operates = []string{ 1351 "voteWitnesses", 1352 "cancelVote", 1353 "setProxy", 1354 "cancelProxy", 1355 } 1356 1357 // addr的状态转化图 1358 addrStateMap := make(map[byte]map[string]byte) 1359 1360 // 0无投票无代理,4无投票有代理,8有投票无代理 1361 addrStateMap[0] = make(map[string]byte) 1362 addrStateMap[8] = make(map[string]byte) 1363 addrStateMap[2] = make(map[string]byte) 1364 1365 addrStateMap[0]["voteWitnesses"] = 8 1366 addrStateMap[0]["setProxy"] = 2 1367 addrStateMap[0]["cancelVote"] = 0 1368 addrStateMap[8]["cancelVote"] = 0 1369 addrStateMap[8]["setProxy"] = 2 1370 addrStateMap[8]["voteWitnesses"] = 8 1371 addrStateMap[2]["voteWitnesses"] = 8 1372 addrStateMap[2]["cancelProxy"] = 0 1373 addrStateMap[2]["setProxy"] = 2 1374 1375 // 抵押一类的初始操作 1376 context := newcontext() 1377 c := newElectionContext(context) 1378 initForStateTest(t, c) 1379 1380 alreadySet = make(map[byte]struct{}) 1381 alreadySet[0] = struct{}{} 1382 checkFn := func(current byte, op string, next byte) error { 1383 if addrStateMap[current][op] != next { 1384 return fmt.Errorf("state error ,current state %d, op %s, nextState %d, expected %d", current, op, next, addrStateMap[current][op]) 1385 } 1386 return nil 1387 } 1388 1389 if err := dfsState(t, c, addr, checkFn); err != nil { 1390 t.Error(err) 1391 } 1392 } 1393 1394 func TestVoteAndProxyState2(t *testing.T) { 1395 // 定义两种角色addr做为普通用户,操作只有投票,取消投票,设置代理,取消设置代理四种 1396 // proxy做为代理用户,操作有投票,取消投票,设置代理,取消设置代理四种,还有startProxy和stopProxy 1397 // addrStateMap存预先设置好addr相关的状态转化图,proxyStateMap存proxy的状态转化图 1398 proxy := common.BytesToAddress([]byte{10}) 1399 proxyStateMap := make(map[byte]map[string]byte) 1400 1401 // 代理的一些状态转变不是自身发起的 1402 proxyOperates := []string{ 1403 "voteWitnesses", 1404 "cancelVote", 1405 "setProxy", 1406 "cancelProxy", 1407 "startProxy", 1408 "stopProxy", 1409 "addrSetProxy", 1410 "addrCancelProxy", 1411 } 1412 operates = proxyOperates 1413 // 4个标志位,一共16种,其中有6中状态是不合法的 1414 for i := 0; i < 14; i++ { 1415 if i == 6 || i == 7 || i == 10 { 1416 continue 1417 } 1418 proxyStateMap[byte(i)] = make(map[string]byte) 1419 } 1420 proxyStateMap[0]["voteWitnesses"] = 8 1421 proxyStateMap[0]["cancelVote"] = 0 1422 proxyStateMap[0]["startProxy"] = 4 1423 proxyStateMap[0]["setProxy"] = 2 1424 proxyStateMap[0]["stopProxy"] = 0 1425 1426 proxyStateMap[1]["voteWitnesses"] = 9 1427 proxyStateMap[1]["cancelVote"] = 1 1428 proxyStateMap[1]["startProxy"] = 5 1429 proxyStateMap[1]["setProxy"] = 3 1430 proxyStateMap[1]["stopProxy"] = 1 1431 proxyStateMap[1]["addrCancelProxy"] = 0 1432 1433 proxyStateMap[2]["voteWitnesses"] = 8 1434 proxyStateMap[2]["setProxy"] = 2 1435 proxyStateMap[2]["stopProxy"] = 2 1436 proxyStateMap[2]["cancelProxy"] = 0 1437 1438 proxyStateMap[3]["voteWitnesses"] = 9 1439 proxyStateMap[3]["setProxy"] = 3 1440 proxyStateMap[3]["stopProxy"] = 3 1441 proxyStateMap[3]["cancelProxy"] = 1 1442 proxyStateMap[3]["addrCancelProxy"] = 2 1443 1444 proxyStateMap[4]["voteWitnesses"] = 12 1445 proxyStateMap[4]["cancelVote"] = 4 1446 proxyStateMap[4]["startProxy"] = 4 1447 proxyStateMap[4]["stopProxy"] = 0 1448 proxyStateMap[4]["addrSetProxy"] = 5 1449 1450 proxyStateMap[5]["voteWitnesses"] = 13 1451 proxyStateMap[5]["cancelVote"] = 5 1452 proxyStateMap[5]["startProxy"] = 5 1453 proxyStateMap[5]["stopProxy"] = 1 1454 proxyStateMap[5]["addrSetProxy"] = 5 1455 proxyStateMap[5]["addrCancelProxy"] = 4 1456 1457 proxyStateMap[8]["cancelVote"] = 0 1458 proxyStateMap[8]["voteWitnesses"] = 8 1459 proxyStateMap[8]["setProxy"] = 2 1460 proxyStateMap[8]["startProxy"] = 12 1461 proxyStateMap[8]["stopProxy"] = 8 1462 1463 proxyStateMap[9]["cancelVote"] = 1 1464 proxyStateMap[9]["setProxy"] = 3 1465 proxyStateMap[9]["voteWitnesses"] = 9 1466 proxyStateMap[9]["stopProxy"] = 9 1467 proxyStateMap[9]["startProxy"] = 13 1468 proxyStateMap[9]["addrCancelProxy"] = 8 1469 1470 proxyStateMap[12]["cancelVote"] = 4 1471 proxyStateMap[12]["voteWitnesses"] = 12 1472 proxyStateMap[12]["startProxy"] = 12 1473 proxyStateMap[12]["stopProxy"] = 8 1474 proxyStateMap[12]["addrSetProxy"] = 13 1475 1476 proxyStateMap[13]["cancelVote"] = 5 1477 proxyStateMap[13]["voteWitnesses"] = 13 1478 proxyStateMap[13]["startProxy"] = 13 1479 proxyStateMap[13]["stopProxy"] = 9 1480 proxyStateMap[13]["addrSetProxy"] = 13 1481 proxyStateMap[13]["addrCancelProxy"] = 12 1482 1483 checkFn := func(current byte, op string, next byte) error { 1484 if proxyStateMap[current][op] != next { 1485 return fmt.Errorf("state error ,current state %d, op %s, nextState %d, expected %d", current, op, next, proxyStateMap[current][op]) 1486 } 1487 return nil 1488 } 1489 1490 // 抵押一类的初始操作 1491 context := newcontext() 1492 c := newElectionContext(context) 1493 initForStateTest(t, c) 1494 1495 alreadySet = make(map[byte]struct{}) 1496 1497 alreadySet[4] = struct{}{} 1498 if err := dfsState(t, c, proxy, checkFn); err != nil { 1499 t.Error(err) 1500 } 1501 } 1502 1503 func initForStateTest(t *testing.T, c electionContext) { 1504 addr := common.BytesToAddress([]byte{111}) 1505 proxy := common.BytesToAddress([]byte{10}) 1506 proxy1 := common.BytesToAddress([]byte{50}) 1507 if ctx, ok := c.context.(*testContext); ok { 1508 ctx.SetTime(new(big.Int).Set(eraTimeStamp)) 1509 } 1510 1511 c.context.GetStateDb().AddBalance(addr, big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18))) 1512 if err := c.stake(addr, vnt2wei(10)); err != nil { 1513 t.Errorf("stake error, addr: %s, error: %s", addr.String(), err) 1514 } 1515 c.context.GetStateDb().AddBalance(proxy, big.NewInt(0).Mul(big.NewInt(100), big.NewInt(1e18))) 1516 if err := c.stake(proxy, vnt2wei(100)); err != nil { 1517 t.Errorf("stake error, addr: %s, error: %s", proxy.String(), err) 1518 } 1519 c.context.GetStateDb().AddBalance(proxy1, big.NewInt(0).Mul(big.NewInt(1000), big.NewInt(1e18))) 1520 if err := c.stake(proxy1, vnt2wei(1000)); err != nil { 1521 t.Errorf("stake error, addr: %s, error: %s", proxy1.String(), err) 1522 } 1523 if err := c.startProxy(proxy); err != nil { 1524 t.Errorf("start proxy, addr: %s, error: %s", proxy.String(), err) 1525 } 1526 if err := c.startProxy(proxy1); err != nil { 1527 t.Errorf("start proxy, addr: %s, error: %s", proxy1.String(), err) 1528 } 1529 if err := c.voteWitnesses(proxy1, candidates); err != nil { 1530 t.Errorf("vote, addr: %s, error: %s", proxy1.String(), err) 1531 } 1532 1533 // 下面只是为了把addr塞进数据库 1534 if err := c.startProxy(addr); err != nil { 1535 t.Errorf("start proxy, addr: %s, error: %s", addr.String(), err) 1536 } 1537 if err := c.stopProxy(addr); err != nil { 1538 t.Errorf("start proxy, addr: %s, error: %s", addr.String(), err) 1539 } 1540 1541 for i, candi := range candidates { 1542 website := "www.testnet.info" + strconv.Itoa(i) 1543 name := "testinfo" + strconv.Itoa(i) 1544 p2pUrl := []byte(string(url)[:13] + strconv.Itoa(i) + string(url)[14:]) 1545 info := &NodeInfo{p2pUrl, []byte(website), []byte(name), binder, beneficiary} 1546 if err := c.registerWitness(candi, info); err != nil { 1547 t.Errorf("register failed, addr: %s, error: %s", candi.String(), err) 1548 } 1549 1550 // 把候选人设置为已绑定 1551 ca := c.getCandidate(candi) 1552 ca.Bind = true 1553 c.setCandidate(ca) 1554 } 1555 } 1556 1557 func operateOnState(c electionContext, op string, address common.Address) error { 1558 addr := address 1559 proxy := common.BytesToAddress([]byte{10}) 1560 switch op { 1561 case "setProxy": 1562 if bytes.Equal(address.Bytes(), common.BytesToAddress([]byte{10}).Bytes()) { 1563 proxy = common.BytesToAddress([]byte{50}) 1564 } 1565 case "addrSetProxy": 1566 fallthrough 1567 case "addrCancelProxy": 1568 addr = common.BytesToAddress([]byte{111}) 1569 } 1570 return operate(c, op, addr, proxy, candidates) 1571 } 1572 1573 func checkState(c electionContext, address common.Address) byte { 1574 voter := c.getVoter(address) 1575 if !bytes.Equal(voter.Owner.Bytes(), address.Bytes()) { 1576 return 0 1577 } 1578 var result byte 1579 // 有投票,判断voteCandidates,或者无代理却有投票数(上次投了个空票) 1580 if len(voter.VoteCandidates) > 0 { 1581 result |= 1 << 3 1582 } else if bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) && voter.LastVoteCount.Sign() > 0 { 1583 result |= 1 << 3 1584 } 1585 // 是代理 1586 if voter.IsProxy { 1587 result |= 1 << 2 1588 } 1589 // 有代理 1590 if !bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 1591 result |= 1 << 1 1592 } 1593 // 有代理投票 1594 if voter.ProxyVoteCount.Sign() > 0 { 1595 result |= 1 1596 } 1597 return result 1598 } 1599 1600 func operate(c electionContext, op string, address common.Address, proxy common.Address, candidates []common.Address) error { 1601 var err error 1602 switch op { 1603 case "voteWitnesses": 1604 if ctx, ok := c.context.(*testContext); ok { 1605 t := c.context.GetTime() 1606 ctx.SetTime(t.Add(t, big.NewInt(24*3600+1))) 1607 } 1608 err = c.voteWitnesses(address, candidates) 1609 case "cancelVote": 1610 err = c.cancelVote(address) 1611 case "setProxy": 1612 if ctx, ok := c.context.(*testContext); ok { 1613 t := c.context.GetTime() 1614 ctx.SetTime(t.Add(t, big.NewInt(24*3600+1))) 1615 } 1616 err = c.setProxy(address, proxy) 1617 case "cancelProxy": 1618 err = c.cancelProxy(address) 1619 case "startProxy": 1620 err = c.startProxy(address) 1621 case "stopProxy": 1622 err = c.stopProxy(address) 1623 case "registerWitness": 1624 website := "www.testnet.info" 1625 name := "testinfo" 1626 info := &NodeInfo{url, []byte(website), []byte(name), binder, beneficiary} 1627 err = c.registerWitness(address, info) 1628 case "unregisterWitness": 1629 err = c.unregisterWitness(address) 1630 default: 1631 err = fmt.Errorf("method not found") 1632 } 1633 return err 1634 } 1635 1636 type bindCase struct { 1637 name string // case name 1638 binder common.Address 1639 info *BindInfo 1640 amount *big.Int // unbind时忽略此字段 1641 bindErr error // 也可以是unbind操作的结果 1642 preCandi *Candidate // bind前的candidate信息 1643 wantCandi *Candidate 1644 } 1645 1646 // 所有绑定候选人的测试用例 1647 func TestBindCandidate(t *testing.T) { 1648 ca := newTestCandi() 1649 // 绑定金额不为1000,返回错误ErrLockAmountMismatch 1650 c1 := bindCase{"c1", ca.Binder, newTestBindInfo(ca), big.NewInt(999), ErrLockAmountMismatch, nil, nil} 1651 c2 := bindCase{"c2", ca.Binder, newTestBindInfo(ca), big.NewInt(1001), ErrLockAmountMismatch, nil, nil} 1652 1653 // 未注册,返回错误未找到candidate 1654 c3 := bindCase{"c3", ca.Binder, newTestBindInfo(ca), bindAmount, fmt.Errorf("bindCandidates failed, candidates not exist: %s", ca.Owner.Hex()), nil, nil} 1655 1656 // 注册,取消注册,返回ErrCandiNotReg 1657 ca4 := newTestCandi() 1658 ca4.Registered = false 1659 ca4.Bind = false 1660 c4 := bindCase{"c4", ca4.Binder, newTestBindInfo(ca4), bindAmount, ErrCandiNotReg, ca4, ca4} 1661 1662 // 已注册,绑定人不一致,返回错误ErrBindInfoMismatch 1663 ca5 := newTestCandi() 1664 ca5.Registered = true 1665 c5 := bindCase{"c5", common.HexToAddress("0x000000012321"), newTestBindInfo(ca5), bindAmount, ErrBindInfoMismatch, ca5, ca5} 1666 1667 // 已注册,受益人不一致,返回错误ErrBindInfoMismatch 1668 ca6 := newTestCandi() 1669 ca6.Registered = true 1670 info := newTestBindInfo(ca6) 1671 info.Beneficiary = common.HexToAddress("0x0000000123") 1672 c6 := bindCase{"c6", ca6.Binder, info, bindAmount, ErrBindInfoMismatch, ca6, ca6} 1673 1674 // 已注册,已绑定,返回错误 ErrCandiAlreadyBind 1675 ca7 := newTestCandi() 1676 ca7.Registered = true 1677 ca7.Bind = true 1678 c7 := bindCase{"c7", ca7.Binder, newTestBindInfo(ca7), bindAmount, ErrCandiAlreadyBind, ca7, ca7} 1679 1680 // 已注册,未绑定,绑定成功,返回错误为nil 1681 ca8 := newTestCandi() 1682 ca8.Registered = true 1683 ca8.Bind = false 1684 ca8Exp := newTestCandi() 1685 ca8Exp.Registered = true 1686 ca8Exp.Bind = true 1687 c8 := bindCase{"c8", ca8.Binder, newTestBindInfo(ca8), bindAmount, nil, ca8, ca8Exp} 1688 cases := []bindCase{c1, c2, c3, c4, c5, c6, c7, c8} 1689 for _, c := range cases { 1690 testBindCandidate(t, &c) 1691 } 1692 } 1693 1694 func testBindCandidate(t *testing.T, cas *bindCase) { 1695 ec := newTestElectionCtx() 1696 1697 // 先填充见证人信息 1698 if cas.preCandi != nil { 1699 if err := ec.setCandidate(*cas.preCandi); err != nil { 1700 t.Errorf("set andiates: %s, error: %s", cas.preCandi.Owner, err) 1701 } 1702 } 1703 1704 // 绑定和校验结果 1705 err := ec.bindCandidate(cas.binder, cas.info, cas.amount) 1706 assert.Equal(t, err, cas.bindErr, fmt.Sprintf(", bind error, case: %v", cas.name)) 1707 1708 // 校验执行绑定后的数据 1709 if cas.wantCandi != nil { 1710 gotCandi := ec.getCandidate(cas.wantCandi.Owner) 1711 assert.Equal(t, gotCandi.String(), (*cas.wantCandi).String(), fmt.Sprintf(", candidate mismtach after bind, case: %v", cas.name)) 1712 } 1713 1714 if cas.bindErr == nil { 1715 acBindAmount, _ := getLock(ec.context.GetStateDb()) 1716 assert.Equal(t, acBindAmount.Amount, bindAmount, fmt.Sprintf("amount of alllock is wrong, case:%v", cas.name)) 1717 } 1718 } 1719 1720 // 取消绑定的所有测试 1721 func TestUnbindCandidate(t *testing.T) { 1722 // 未注册,返回错误未找到candidate 1723 ca1 := newTestCandi() 1724 c1 := bindCase{"c1", ca1.Binder, newTestBindInfo(ca1), bindAmount, fmt.Errorf("bindCandidates failed, candidates not exist: %s", ca1.Owner.Hex()), nil, nil} 1725 1726 // 注册,取消注册,返回或 ErrCandiNotReg 1727 ca2 := newTestCandi() 1728 ca2.Registered = false 1729 ca2.Bind = false 1730 c2 := bindCase{"c2", ca2.Binder, newTestBindInfo(ca2), bindAmount, ErrCandiNotReg, ca2, ca2} 1731 1732 // 未绑定,返回 ErrCandiNotBind 1733 ca3 := newTestCandi() 1734 ca3.Registered = true 1735 ca3.Bind = false 1736 c3 := bindCase{"c3", ca3.Binder, newTestBindInfo(ca3), bindAmount, ErrCandiNotBind, ca3, ca3} 1737 1738 // 已注册,已绑定,返回nil,绑定人多1000vnt 1739 ca4 := newTestCandi() 1740 ca4.Registered = true 1741 ca4.Bind = true 1742 ca4Exp := newTestCandi() 1743 ca4Exp.Registered = true 1744 ca4Exp.Bind = false 1745 c4 := bindCase{"c4", ca4.Binder, newTestBindInfo(ca4), bindAmount, nil, ca4, ca4Exp} 1746 1747 cases := []bindCase{c1, c2, c3, c4} 1748 for _, c := range cases { 1749 testUnbindCandidate(t, &c) 1750 } 1751 } 1752 1753 func testUnbindCandidate(t *testing.T, cas *bindCase) { 1754 ec := newTestElectionCtx() 1755 // ec充1000W VNT 1756 ec.context.GetStateDb().AddBalance(contractAddr, bindAmount) 1757 // AllLock填充1000W VNT 1758 setLock(ec.context.GetStateDb(), AllLock{bindAmount}) 1759 1760 // 先填充见证人信息 1761 if cas.preCandi != nil { 1762 if err := ec.setCandidate(*cas.preCandi); err != nil { 1763 t.Errorf("set andiates: %s, error: %s", cas.preCandi.Owner, err) 1764 } 1765 } 1766 1767 // 绑定和校验结果 1768 err := ec.unbindCandidate(cas.binder, cas.info) 1769 assert.Equal(t, err, cas.bindErr, fmt.Sprintf(", bind error, case: %v", cas.name)) 1770 1771 // 校验执行绑定后的数据 1772 if cas.wantCandi != nil { 1773 gotCandi := ec.getCandidate(cas.wantCandi.Owner) 1774 assert.Equal(t, gotCandi, *cas.wantCandi, fmt.Sprintf(", candidate mismtach after unbind, case: %v", cas.name)) 1775 } 1776 1777 // 检查绑定人余额多1000W VNT 1778 // 检查AllLock减少1000W VNT 1779 if cas.bindErr == nil { 1780 assert.Equal(t, ec.context.GetStateDb().GetBalance(cas.binder), bindAmount, fmt.Sprintf(", balance of binder is wrong, case: %v", cas.name)) 1781 acBindAmount, _ := getLock(ec.context.GetStateDb()) 1782 assert.Equal(t, acBindAmount.Amount, big.NewInt(0), fmt.Sprintf("amount of alllock is wrong, case:%v", cas.name)) 1783 } 1784 1785 } 1786 1787 type unRegCase struct { 1788 name string // case name 1789 retErr error 1790 preCandi *Candidate // 操作前的candidate信息 1791 wantCandi *Candidate // 操作后期望的candidate信息 1792 shouldReturn bool // 是否要返还绑定金 1793 } 1794 1795 // 取消注册 1796 func TestUnregisterCandidate(t *testing.T) { 1797 // 已注册,未绑定,返回nil,绑定人金额不变 1798 ca1 := newTestCandi() 1799 ca1.Registered = true 1800 ca1.Bind = false 1801 ca1Exp := newTestCandi() 1802 ca1Exp.Registered = false 1803 ca1Exp.Bind = false 1804 c1 := unRegCase{"c1", nil, ca1, ca1Exp, false} 1805 1806 // 已注册,已绑定,返回nil,绑定人金额多1000vnt 1807 ca2 := newTestCandi() 1808 ca2.Registered = true 1809 ca2.Bind = true 1810 ca2Exp := newTestCandi() 1811 ca2Exp.Registered = false 1812 ca2Exp.Bind = false 1813 ca2Exp.Beneficiary = emptyAddress 1814 ca2Exp.Binder = emptyAddress 1815 c2 := unRegCase{"c2", nil, ca2, ca2Exp, true} 1816 1817 // 已注册后取消,再取消 1818 ca3 := newTestCandi() 1819 ca3.Registered = false 1820 ca3.Bind = false 1821 c3 := unRegCase{"c3", ErrCandiNotReg, ca3, ca3, false} 1822 1823 cases := []unRegCase{c1, c2, c3} 1824 for _, c := range cases { 1825 testUnregisterCandidate(t, &c) 1826 } 1827 } 1828 1829 func testUnregisterCandidate(t *testing.T, cas *unRegCase) { 1830 ec := newTestElectionCtx() 1831 // ec充1000VNT 1832 ec.context.GetStateDb().AddBalance(contractAddr, bindAmount) 1833 // AllLock填充1000W VNT 1834 setLock(ec.context.GetStateDb(), AllLock{bindAmount}) 1835 1836 // 先填充见证人信息 1837 if cas.preCandi != nil { 1838 if err := ec.setCandidate(*cas.preCandi); err != nil { 1839 t.Errorf("set andiates: %s, error: %s", cas.preCandi.Owner, err) 1840 } 1841 } 1842 1843 // 校验结果 1844 err := ec.unregisterWitness(cas.preCandi.Owner) 1845 assert.Equal(t, err, cas.retErr, fmt.Sprintf(", unregesiter error, case: %v", cas.name)) 1846 1847 // 校验操作后的候选人 1848 if cas.wantCandi != nil { 1849 gotCandi := ec.getCandidate(cas.wantCandi.Owner) 1850 assert.Equal(t, gotCandi.String(), (*cas.wantCandi).String(), fmt.Sprintf(", candidate mismtach after unbind, case: %v", cas.name)) 1851 } 1852 1853 acStakeAmount, _ := getLock(ec.context.GetStateDb()) 1854 // 检查绑定人余额多1000VNT 1855 if cas.shouldReturn { 1856 assert.Equal(t, ec.context.GetStateDb().GetBalance(cas.preCandi.Binder), bindAmount, fmt.Sprintf(", balance of binder is wrong, case: %v", cas.name)) 1857 assert.Equal(t, acStakeAmount.Amount, big.NewInt(0), fmt.Sprintf("UnregisterCandidate failed, amount of alllock mismatch, case: %v", cas.name)) 1858 } else { 1859 assert.Equal(t, acStakeAmount.Amount, bindAmount, fmt.Sprintf("UnregisterCandidate failed, amount of alllock mismatch, case: %v", cas.name)) 1860 } 1861 } 1862 1863 func newTestElectionCtx() electionContext { 1864 ctx := newcontext() 1865 return newElectionContext(ctx) 1866 } 1867 1868 func newTestCandi() *Candidate { 1869 return &Candidate{ 1870 Owner: common.HexToAddress("9ee97d274eb4c215f23238fee1f103d9ea10a234"), 1871 Binder: binder, 1872 Beneficiary: beneficiary, 1873 Registered: true, 1874 Bind: true, 1875 VoteCount: big.NewInt(0), 1876 Url: []byte("/ip4/192.168.9.102/tcp/5210/ipfs/1kHaMUmZgTpjGEhxcGATr1UVWy6iKkygFuknWEtW7LiLrev"), 1877 Website: []byte("www.testwebsite.net/test/witness/website"), 1878 Name: []byte("testNet"), 1879 } 1880 } 1881 1882 func newTestBindInfo(ca *Candidate) *BindInfo { 1883 return &BindInfo{ca.Owner, ca.Beneficiary} 1884 }