github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/core/vm/election/election.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" 23 "math/big" 24 "reflect" 25 "sort" 26 "strings" 27 "unicode" 28 29 "github.com/pkg/errors" 30 "github.com/vntchain/go-vnt/accounts/abi" 31 "github.com/vntchain/go-vnt/common" 32 inter "github.com/vntchain/go-vnt/core/vm/interface" 33 "github.com/vntchain/go-vnt/log" 34 "github.com/vntchain/go-vnt/vntp2p" 35 ) 36 37 const ( 38 ContractAddr = "0x0000000000000000000000000000000000000009" 39 VoteLimit = 30 40 OneDay = int64(24) * 3600 41 oneWeek = OneDay * 7 42 year2019 = 1546272000 43 ElectionStart = int64(4443777) 44 ) 45 46 var ( 47 ErrCandiNameLenInvalid = errors.New("the length of candidate's name should between [3, 20]") 48 ErrCandiUrlLenInvalid = errors.New("the length of candidate's website url should between [3, 60]") 49 ErrCandiNameInvalid = errors.New("candidate's name should consist of digits and lowercase letters") 50 ErrCandiInfoDup = errors.New("candidate's name, website url or node url is duplicated with a registered candidate") 51 ErrCandiAlreadyReg = errors.New("candidate is already registered") 52 ErrCandiNotReg = errors.New("candidate is not registered") 53 ErrCandiAlreadyBind = errors.New("candidate is already bind") 54 ErrCandiNotBind = errors.New("candidate is not bind") 55 ErrBindInfoMismatch = errors.New("bind address not match candidates saved") 56 ErrLockAmountMismatch = errors.New("bind amount is not equal 10,000,000 VNT") 57 ) 58 59 var ( 60 contractAddr = common.HexToAddress(ContractAddr) 61 emptyAddress = common.Address{} 62 eraTimeStamp = big.NewInt(year2019) 63 64 // stake minimum time period 65 unstakePeriod = big.NewInt(OneDay) 66 bindAmount = big.NewInt(0).Mul(big.NewInt(1e+18), big.NewInt(1e7)) // 1000万VNT 67 ) 68 69 type Election struct{} 70 71 type electionContext struct { 72 context inter.ChainContext 73 } 74 75 type Voter struct { 76 Owner common.Address // 投票人的地址 77 IsProxy bool // 是否是代理人 78 ProxyVoteCount *big.Int // 收到的代理的票数 79 Proxy common.Address // 代理人 80 LastStakeCount *big.Int // 投票时抵押的金额 81 LastVoteCount *big.Int // 票数 82 TimeStamp *big.Int // 时间戳 83 VoteCandidates []common.Address // 投了哪些人 84 } 85 86 // Candidate information of witness candidates. 87 // Tips: Modify CandidateList.Swap() and Candidate.String() when adding or removing element of Candidate. 88 type Candidate struct { 89 Owner common.Address // 候选人地址 90 Binder common.Address // 锁仓人/绑定人 91 Beneficiary common.Address // 收益受益人 92 VoteCount *big.Int // 收到的票数 93 Registered bool // 当前是否注册为候选人 94 Bind bool // 是否被绑定 95 Url []byte // 节点的URL 96 Website []byte // 节点网站地址 97 Name []byte // 节点名字 98 } 99 100 func (c *Candidate) String() string { 101 return fmt.Sprintf("candidate{ addr:%s, votes:%s, registered:%v, bind:%v, active:%v, url:%s, WebSite: %s, Name: %s}\n", 102 c.Owner.String(), c.VoteCount.String(), c.Registered, c.Bind, c.Active(), string(c.Url), string(c.Website), string(c.Name)) 103 } 104 105 // Active 判断候选人是否已激活 106 func (c *Candidate) Active() bool { 107 return c.Registered && c.Bind 108 } 109 110 func newVoter() Voter { 111 return Voter{ 112 Owner: emptyAddress, 113 IsProxy: false, 114 ProxyVoteCount: big.NewInt(0), 115 Proxy: emptyAddress, 116 LastStakeCount: big.NewInt(0), 117 LastVoteCount: big.NewInt(0), 118 TimeStamp: big.NewInt(0), 119 VoteCandidates: nil, 120 } 121 } 122 123 func newCandidate() Candidate { 124 return Candidate{ 125 Owner: emptyAddress, 126 Binder: emptyAddress, 127 Beneficiary: emptyAddress, 128 VoteCount: big.NewInt(0), 129 Registered: false, 130 Bind: false, 131 } 132 } 133 134 func (c *Candidate) votes() *big.Int { 135 if c.Active() { 136 return c.VoteCount 137 } 138 139 one := big.NewInt(-1) 140 return one.Mul(c.VoteCount, one) 141 } 142 143 // Equal two object is equal 144 func (c *Candidate) equal(d *Candidate) bool { 145 return reflect.DeepEqual(c, d) 146 } 147 148 type CandidateList []Candidate 149 150 func (c CandidateList) Len() int { 151 return len(c) 152 } 153 154 // Less for Sort interface, actually implement of c[i] more than c[j] 155 // Rule 1: 票数越多排名越靠前 156 // Rule 2: 票数相等,地址越小越靠前 157 // 158 // sort.Stable对于big.Int并不能真正的stable,所以排序还参考地址,并且排序不再使用stable 159 func (c CandidateList) Less(i, j int) bool { 160 ret := c[i].votes().Cmp(c[j].votes()) 161 if ret != 0 { 162 return ret > 0 163 } 164 165 return bytes.Compare(c[i].Owner.Bytes(), c[j].Owner.Bytes()) < 0 166 } 167 168 func (c CandidateList) Swap(i, j int) { 169 c[i].Owner, c[j].Owner = c[j].Owner, c[i].Owner 170 c[i].Binder, c[j].Binder = c[j].Binder, c[i].Binder 171 c[i].Beneficiary, c[j].Beneficiary = c[j].Beneficiary, c[i].Beneficiary 172 c[i].VoteCount, c[j].VoteCount = c[j].VoteCount, c[i].VoteCount 173 c[i].Registered, c[j].Registered = c[j].Registered, c[i].Registered 174 c[i].Bind, c[j].Bind = c[j].Bind, c[i].Bind 175 c[i].Url, c[j].Url = c[j].Url, c[i].Url 176 c[i].Website, c[j].Website = c[j].Website, c[i].Website 177 c[i].Name, c[j].Name = c[j].Name, c[i].Name 178 } 179 180 // Sort 181 func (c CandidateList) Sort() { 182 sort.Sort(c) 183 } 184 185 func (c CandidateList) dump() { 186 fmt.Println("dump candidats list") 187 for i, ca := range c { 188 fmt.Printf("can:%d, addr:%s, votes:%s, active:%v \n", i, ca.Owner.String(), ca.VoteCount.String(), ca.Active()) 189 } 190 } 191 192 type Stake struct { 193 Owner common.Address // 抵押人地址 194 StakeCount *big.Int // 抵押的数量,单位VNT,向下取整 195 Vnt *big.Int // 抵押的实际代币数,单位Wei 196 TimeStamp *big.Int // 时间戳 197 } 198 199 func newElectionContext(ctx inter.ChainContext) electionContext { 200 return electionContext{ 201 context: ctx, 202 } 203 } 204 205 func (e *Election) RequiredGas(input []byte) uint64 { 206 return 0 207 } 208 209 type NodeInfo struct { 210 NodeUrl []byte 211 Website []byte 212 NodeName []byte 213 Binder common.Address // 绑定人 214 Beneficiary common.Address // 受益人 215 } 216 217 type BindInfo struct { 218 Candidate common.Address // 绑定的候选账号 219 Beneficiary common.Address // 收益的账号 220 } 221 222 func (e *Election) Run(ctx inter.ChainContext, input []byte, value *big.Int) ([]byte, error) { 223 nonce := ctx.GetStateDb().GetNonce(contractAddr) 224 ctx.GetStateDb().SetNonce(contractAddr, nonce+1) 225 226 electionABI, err := abi.JSON(strings.NewReader(ElectionAbiJSON)) 227 if err != nil { 228 return nil, err 229 } 230 231 if len(input) < 4 { 232 return nil, nil 233 } 234 // input的组成见abi.Pack函数 235 methodId := input[:4] 236 methodArgs := input[4:] 237 238 methodName := "None" 239 isMethod := func(name string) bool { 240 if bytes.Equal(methodId, electionABI.Methods[name].Id()) { 241 methodName = name 242 return true 243 } 244 return false 245 } 246 247 c := newElectionContext(ctx) 248 sender := ctx.GetOrigin() 249 switch { 250 case isMethod("registerWitness"): 251 var nodeInfo NodeInfo 252 if err = electionABI.UnpackInput(&nodeInfo, methodName, methodArgs); err == nil { 253 err = c.registerWitness(sender, &nodeInfo) 254 } 255 case isMethod("unregisterWitness"): 256 err = c.unregisterWitness(sender) 257 case isMethod("voteWitnesses"): 258 var candidates []common.Address 259 if err = electionABI.UnpackInput(&candidates, methodName, methodArgs); err == nil { 260 err = c.voteWitnesses(sender, candidates) 261 } 262 case isMethod("cancelVote"): 263 err = c.cancelVote(sender) 264 case isMethod("startProxy"): 265 err = c.startProxy(sender) 266 case isMethod("stopProxy"): 267 err = c.stopProxy(sender) 268 case isMethod("cancelProxy"): 269 err = c.cancelProxy(sender) 270 case isMethod("setProxy"): 271 var proxy common.Address 272 if err = electionABI.UnpackInput(&proxy, methodName, methodArgs); err == nil { 273 err = c.setProxy(sender, proxy) 274 } 275 case isMethod("$stake"): 276 err = c.stake(sender, value) 277 case isMethod("unStake"): 278 err = c.unStake(sender) 279 case isMethod("$bindCandidate"): 280 var info BindInfo 281 if err = electionABI.UnpackInput(&info, methodName, methodArgs); err == nil { 282 err = c.bindCandidate(sender, &info, value) 283 } 284 case isMethod("unbindCandidate"): 285 var info BindInfo 286 if err = electionABI.UnpackInput(&info, methodName, methodArgs); err == nil { 287 err = c.unbindCandidate(sender, &info) 288 } 289 case isMethod("$depositReward"): 290 err = c.depositReward(sender, value) 291 default: 292 log.Error("call election contract err: method doesn't exist") 293 err = fmt.Errorf("call election contract err: method doesn't exist") 294 } 295 296 log.Debug("Election call", "method", methodName) 297 298 if err != nil { 299 log.Error("call election contract err:", "method", methodName, "err", err) 300 } 301 return nil, err 302 } 303 304 func (ec electionContext) registerWitness(address common.Address, info *NodeInfo) error { 305 // get candidate from db 306 candidate := ec.getCandidate(address) 307 308 // if candidate is active 309 if bytes.Equal(candidate.Owner.Bytes(), address.Bytes()) { 310 // if candidate is already active, just ignore 311 if candidate.Registered { 312 log.Warn("registerWitness witness already exists", "address", address.Hex()) 313 return ErrCandiAlreadyReg 314 } 315 } else { 316 // if candidate is not found in db 317 // make a new candidate 318 candidate.Owner = address 319 candidate.VoteCount = big.NewInt(0) 320 } 321 322 // Sanity check 323 if err := ec.checkCandi(address, string(info.NodeName), string(info.Website), string(info.NodeUrl)); err != nil { 324 return err 325 } 326 327 // Reset candidate's info 328 candidate.Registered = true 329 candidate.Binder = info.Binder 330 candidate.Beneficiary = info.Beneficiary 331 candidate.Url = info.NodeUrl 332 candidate.Website = info.Website 333 candidate.Name = info.NodeName 334 335 // save candidate info db 336 err := ec.setCandidate(candidate) 337 if err != nil { 338 log.Error("registerWitness setCandidate err.", "address", address.Hex(), "err", err) 339 return err 340 } 341 342 return nil 343 } 344 345 // checkCandi 候选人基本参数的校验 346 func (ec electionContext) checkCandi(addr common.Address, name string, website string, url string) error { 347 // length check 348 if len(name) < 3 || len(name) > 20 { 349 return ErrCandiNameLenInvalid 350 } 351 if len(website) < 3 || len(website) > 60 { 352 return ErrCandiUrlLenInvalid 353 } 354 355 digitalAndLower := func(s string) bool { 356 for _, ru := range s { 357 if !unicode.IsDigit(ru) && !unicode.IsLower(ru) { 358 return false 359 } 360 } 361 return true 362 } 363 if !digitalAndLower(name) { 364 return ErrCandiNameInvalid 365 } 366 367 // p2p node url format check 368 if _, err := vntp2p.ParseNode(url); err != nil { 369 return fmt.Errorf("registerWitness node url is error: %s", err) 370 } 371 372 // duplication check 373 wits := getAllCandidate(ec.context.GetStateDb()) 374 for _, w := range wits { 375 if w.Owner != addr && (string(w.Name) == name || string(w.Website) == website || string(w.Url) == url) { 376 return ErrCandiInfoDup 377 } 378 } 379 return nil 380 } 381 382 // unregisterWitness 取消注册见证人 383 // 1. 未注册时不处理 384 // 2. 已注册,未绑定时,取消注册,不返回绑定金 385 // 3. 已注册,已绑定时,取消注册,返回绑定金 386 func (ec electionContext) unregisterWitness(address common.Address) error { 387 // get candidate from db 388 candidate := ec.getCandidate(address) 389 390 // if candidate is not found in db 391 if !bytes.Equal(candidate.Owner.Bytes(), address.Bytes()) { 392 log.Warn("unregisterWitness unregister unknown witness.", "address", address.Hex()) 393 return fmt.Errorf("unregisterWitness unregister unknown witness") 394 } 395 396 // if candidate is already inactive, just ignore 397 if !candidate.Registered { 398 log.Warn("unregisterWitness witness", "address", address.Hex(), "error", ErrCandiNotReg) 399 return ErrCandiNotReg 400 } 401 402 // set candidate active false 403 candidate.Registered = false 404 405 // 已经解除绑定 406 binder := candidate.Binder 407 shouldReturnToken := candidate.Bind == true 408 candidate.Bind = false 409 candidate.Binder = emptyAddress 410 candidate.Beneficiary = emptyAddress 411 412 // save candidate info db 413 err := ec.setCandidate(candidate) 414 if err != nil { 415 log.Error("unregisterWitness setCandidate err.", "address", address.Hex(), "err", err) 416 return err 417 } 418 419 // 返还绑定金 420 if shouldReturnToken { 421 err = ec.updateLockAmount(bindAmount, false) 422 if err != nil { 423 log.Error("unregisterWitness subLockAmount err.", "address", address.Hex(), "err", err) 424 return err 425 } 426 return ec.transfer(contractAddr, binder, bindAmount) 427 } 428 return nil 429 } 430 431 // bindCandidate 绑定候选节点,绑定人受益人信息需与候选人注册信息一致 432 func (ec electionContext) bindCandidate(locker common.Address, info *BindInfo, amount *big.Int) error { 433 candi := info.Candidate 434 beneficiary := info.Beneficiary 435 436 // Check bind amount 437 if amount.Cmp(bindAmount) != 0 { 438 return ErrLockAmountMismatch 439 } 440 441 candidate, err := ec.matchLockerAndCandi(locker, candi, beneficiary) 442 if err != nil { 443 return err 444 } 445 446 if !candidate.Registered { 447 return ErrCandiNotReg 448 } 449 450 // if candidate is already active, just ignore 451 if candidate.Bind { 452 return ErrCandiAlreadyBind 453 } 454 455 candidate.Bind = true 456 if err := ec.setCandidate(*candidate); err != nil { 457 log.Error("bindCandidate setCandidate err.", "address", candi.Hex(), "err", err) 458 return err 459 } 460 461 err = ec.updateLockAmount(bindAmount, true) 462 if err != nil { 463 log.Error("bindCandidate addLockAmount err.", "address", candi.Hex(), "err", err) 464 return err 465 } 466 467 return nil 468 } 469 470 // unbindCandidate 绑定人取消绑定候选节点 471 func (ec electionContext) unbindCandidate(locker common.Address, info *BindInfo) error { 472 candi := info.Candidate 473 beneficiary := info.Beneficiary 474 candidate, err := ec.matchLockerAndCandi(locker, candi, beneficiary) 475 if err != nil { 476 return err 477 } 478 479 if !candidate.Registered { 480 return ErrCandiNotReg 481 } 482 if !candidate.Bind { 483 return ErrCandiNotBind 484 } 485 486 // 取消绑定 487 candidate.Bind = false 488 if err := ec.setCandidate(*candidate); err != nil { 489 log.Error("unbindCandidate setCandidate err.", "address", candi.Hex(), "err", err) 490 return err 491 } 492 493 err = ec.updateLockAmount(bindAmount, false) 494 if err != nil { 495 log.Error("unbindCandidate subLockAmount err.", "address", candi.Hex(), "err", err) 496 return err 497 } 498 499 // 返回绑定人锁仓金额 500 return ec.transfer(contractAddr, locker, bindAmount) 501 } 502 503 func (ec electionContext) matchLockerAndCandi(locker, candi, beneficiary common.Address) (*Candidate, error) { 504 // get candidate from db 505 candidate := ec.getCandidate(candi) 506 507 if candidate.Owner != candi { 508 return nil, fmt.Errorf("bindCandidates failed, candidates not exist: %v", candi.Hex()) 509 } 510 511 // Match information 512 if candidate.Binder != locker || candidate.Beneficiary != beneficiary { 513 return nil, ErrBindInfoMismatch 514 } 515 516 return &candidate, nil 517 } 518 519 func (ec electionContext) voteWitnesses(address common.Address, candidates []common.Address) error { 520 // 入参校验,如果投的候选人过多,返回错误 521 if len(candidates) > VoteLimit { 522 return fmt.Errorf("you voted too many candidates: the limit is %d, you voted %d", VoteLimit, len(candidates)) 523 } 524 525 voter := ec.getVoter(address) 526 var ( 527 voteCount *big.Int 528 stake *Stake 529 err error 530 ) 531 532 if voteCount, stake, err = ec.prepareForVote(&voter, address); err != nil { 533 return err 534 } 535 // 计算当前stake可以兑换得到的票数 536 voter.LastVoteCount = new(big.Int).Set(voteCount) 537 voter.LastStakeCount = stake.StakeCount 538 539 if voter.ProxyVoteCount != nil && voter.ProxyVoteCount.Sign() > 0 { 540 voteCount.Add(voteCount, voter.ProxyVoteCount) 541 } 542 543 // 逐个检查是否投给了非候选者,并给相应的候选者加上票数 544 candiSet := make(map[common.Address]struct{}) 545 voter.VoteCandidates = nil 546 for _, candidate := range candidates { 547 if _, ok := candiSet[candidate]; ok { 548 continue 549 } 550 candiSet[candidate] = struct{}{} 551 552 // 如果是候选人则增加相应的选票 553 candi := ec.getCandidate(candidate) 554 if bytes.Equal(candi.Owner.Bytes(), candidate.Bytes()) && candi.Active() { 555 voter.VoteCandidates = append(voter.VoteCandidates, candidate) 556 candi.VoteCount.Add(candi.VoteCount, voteCount) 557 err = ec.setCandidate(candi) 558 if err != nil { 559 return fmt.Errorf("setCandidate error: %s", err) 560 } 561 } 562 } 563 564 // 保存投票信息 565 return ec.setVoter(voter) 566 } 567 568 func (ec electionContext) cancelVote(address common.Address) error { 569 voter := ec.getVoter(address) 570 if !bytes.Equal(voter.Owner.Bytes(), address.Bytes()) { 571 return fmt.Errorf("the voter %x doesn't exist", address) 572 } 573 // 设置了代理,则返回错误,让其取消代理 574 if !bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 575 return fmt.Errorf("must cancel proxy first, proxy: %x", voter.Proxy) 576 } 577 // 投的候选人为空,不需要取消投票,返回 578 if len(voter.VoteCandidates) == 0 { 579 log.Warn("voteCandidates is nil, need not cancel", "address", address.Hex()) 580 return nil 581 } 582 // 减去原候选人得到的投票 583 err := ec.subVoteFromCandidates(&voter) 584 if err != nil { 585 return fmt.Errorf("subVoteFromCandidates error: %s", err) 586 } 587 588 // 将上次投票信息置空 589 voter.LastVoteCount = big.NewInt(0) 590 voter.LastStakeCount = big.NewInt(0) 591 voter.VoteCandidates = nil 592 593 return ec.setVoter(voter) 594 } 595 596 func (ec electionContext) startProxy(address common.Address) error { 597 // get voter from db 598 voter := ec.getVoter(address) 599 600 // proxy already in db 601 if bytes.Equal(voter.Owner.Bytes(), address.Bytes()) { 602 603 // already registered as proxy 604 if voter.IsProxy { 605 log.Info("startProxy proxy is already started", "address", address.Hex()) 606 return fmt.Errorf("startProxy proxy is already started") 607 } 608 // 已经设置了代理,则不可以成为代理 609 if !bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 610 return fmt.Errorf("account that uses a proxy is not allowed to become a proxy") 611 } 612 613 // not registered as proxy yet 614 voter.IsProxy = true 615 // voter.ProxyVoteCount = big.NewInt(0) 616 } else { 617 // proxy not in db 618 voter.Owner = address 619 voter.IsProxy = true 620 } 621 622 // save voter into db 623 err := ec.setVoter(voter) 624 if err != nil { 625 log.Error("startProxy setVoter err.", "address", address.Hex(), "err", err) 626 return err 627 } 628 629 return nil 630 } 631 632 func (ec electionContext) stopProxy(address common.Address) error { 633 // get voter from db 634 voter := ec.getVoter(address) 635 636 // proxy not in db 637 if !bytes.Equal(voter.Owner.Bytes(), address.Bytes()) { 638 log.Warn("stopProxy proxy does not exist.", "address", address.Hex()) 639 return fmt.Errorf("stopProxy proxy does not exist.") 640 } 641 642 // voter is not a proxy, just ignore 643 if !voter.IsProxy { 644 log.Warn("stopProxy address is not proxy", "address", address.Hex()) 645 return fmt.Errorf("stopProxy address is not proxy") 646 } 647 648 voter.IsProxy = false 649 // voter.ProxyVoteCount = big.NewInt(0) 650 651 // save voter into db 652 err := ec.setVoter(voter) 653 if err != nil { 654 log.Error("stopProxy setVoter err.", "address", address.Hex(), "err", err) 655 return err 656 } 657 658 return nil 659 } 660 661 func (ec electionContext) setProxy(address common.Address, proxy common.Address) error { 662 // 不可以将自身设置为自己的代理 663 if bytes.Equal(address.Bytes(), proxy.Bytes()) { 664 return fmt.Errorf("cannot proxy to self") 665 } 666 667 voter := ec.getVoter(address) 668 // 如果自己也是个代理,返回错误 669 if voter.IsProxy { 670 return fmt.Errorf("account registered as a proxy is not allowed to use a proxy") 671 } 672 673 var ( 674 voteCount *big.Int 675 stake *Stake 676 err error 677 ) 678 // 撤销上次的投票或者设置代理 679 if voteCount, stake, err = ec.prepareForVote(&voter, address); err != nil { 680 return err 681 } 682 voter.LastVoteCount = new(big.Int).Set(voteCount) 683 voter.LastStakeCount = stake.StakeCount 684 685 if voter.ProxyVoteCount != nil && voter.ProxyVoteCount.Sign() > 0 { 686 voteCount.Add(voteCount, voter.ProxyVoteCount) 687 } 688 689 proxyVoter := ec.getVoter(proxy) 690 if !proxyVoter.IsProxy { 691 return fmt.Errorf("%x is not a proxy", proxy) 692 } 693 694 // 增加代理人投的票 695 proxyVoter.ProxyVoteCount.Add(proxyVoter.ProxyVoteCount, voteCount) 696 err = ec.setVoter(proxyVoter) 697 if err != nil { 698 return fmt.Errorf("setVoter error: %s", err) 699 } 700 701 // 找到了最终代理 702 if bytes.Equal(proxyVoter.Proxy.Bytes(), emptyAddress.Bytes()) { 703 // 把票数加到该代理人投的候选者身上 704 if len(proxyVoter.VoteCandidates) > 0 { 705 addOp := func(count *big.Int) { 706 count.Add(count, voteCount) 707 } 708 if err := ec.opCandidates(&proxyVoter, addOp); err != nil { 709 return err 710 } 711 } 712 } 713 714 voter.VoteCandidates = nil 715 voter.Proxy = proxy 716 return ec.setVoter(voter) 717 } 718 719 func (ec electionContext) cancelProxy(address common.Address) error { 720 voter := ec.getVoter(address) 721 if !bytes.Equal(voter.Owner.Bytes(), address.Bytes()) || bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 722 return fmt.Errorf("not set proxy") 723 } 724 proxy := voter.Proxy 725 voteCount := new(big.Int).Set(voter.LastVoteCount) 726 if voter.ProxyVoteCount != nil && voter.ProxyVoteCount.Sign() > 0 { 727 voteCount.Add(voteCount, voter.ProxyVoteCount) 728 } 729 730 for { 731 proxyVoter := ec.getVoter(proxy) 732 // 减少其代理的票 733 proxyVoter.ProxyVoteCount.Sub(proxyVoter.ProxyVoteCount, voteCount) 734 err := ec.setVoter(proxyVoter) 735 if err != nil { 736 return fmt.Errorf("setVoter error: %s", err) 737 } 738 739 // 找到了最终代理 740 if bytes.Equal(proxyVoter.Proxy.Bytes(), emptyAddress.Bytes()) { 741 if len(proxyVoter.VoteCandidates) > 0 { 742 subOp := func(count *big.Int) { 743 count.Sub(count, voteCount) 744 } 745 if err := ec.opCandidates(&proxyVoter, subOp); err != nil { 746 return err 747 } 748 } 749 break 750 } 751 752 proxy = proxyVoter.Proxy 753 } 754 755 // 清空老数据 756 voter.Proxy = emptyAddress 757 voter.LastVoteCount = big.NewInt(0) 758 voter.LastStakeCount = big.NewInt(0) 759 return ec.setVoter(voter) 760 } 761 762 func (ec electionContext) stake(address common.Address, value *big.Int) error { 763 if value.Cmp(vnt2wei(1)) < 0 { 764 log.Error("stake less than 1 VNT", "address", address.Hex(), "VNT", value.String()) 765 return fmt.Errorf("stake stakeCount less than 1 VNT") 766 } 767 768 // if stake already exists, just add stakeCount to origin stake 769 stake := ec.getStake(address) 770 if bytes.Equal(stake.Owner.Bytes(), address.Bytes()) { 771 // add vnt to user 772 stake.Vnt = big.NewInt(0).Add(stake.Vnt, value) 773 } else { 774 // else set StakeCount as @StakeCount 775 stake.Owner = address 776 stake.Vnt = value 777 } 778 779 // Set stake count 780 stake.StakeCount = big.NewInt(0).Div(stake.Vnt, big.NewInt(1e+18)) 781 782 // update last stake time 783 stake.TimeStamp = ec.context.GetTime() 784 785 // put stake into db 786 err := ec.setStake(stake) 787 if err != nil { 788 log.Error("stake setStake err.", "address", address.Hex(), "err", err) 789 return err 790 } 791 792 err = ec.updateLockAmount(value, true) 793 if err != nil { 794 log.Error("stake addLockAmount err.", "address", address.Hex(), "err", err) 795 return err 796 } 797 return nil 798 } 799 800 func (ec electionContext) unStake(address common.Address) error { 801 // get stake from db 802 stake := ec.getStake(address) 803 804 // if stake is not found in db, just ignore 805 if !bytes.Equal(stake.Owner.Bytes(), address.Bytes()) { 806 log.Error("unStake stake is not found in db.", "address", address.Hex()) 807 return fmt.Errorf("unStake stake is not found in db") 808 } 809 810 // no stake, no need to unstake, just ignore 811 if stake.Vnt.Cmp(big.NewInt(0)) == 0 { 812 log.Error("unStake 0 stakeCount.", "address", address.Hex()) 813 return fmt.Errorf("unStake 0 stakeCount") 814 } 815 816 // get the time point that can unstake 817 canUnstakeTime := big.NewInt(0).Add(stake.TimeStamp, unstakePeriod) 818 819 // if time is less than minimum stake period, cannot untake, just ignore 820 if ec.context.GetTime().Cmp(canUnstakeTime) < 0 { 821 log.Error("cannot unstake in 24 hours", "address", address.Hex()) 822 return fmt.Errorf("cannot unstake in 24 hours") 823 } 824 825 amount := stake.Vnt 826 // sub stakeCount of staker 827 stake.StakeCount = big.NewInt(0) 828 stake.Vnt = big.NewInt(0) 829 830 // save stake into db 831 err := ec.setStake(stake) 832 if err != nil { 833 log.Error("unStake setStake err.", "address", address.Hex(), "err", err) 834 return err 835 } 836 837 err = ec.updateLockAmount(amount, false) 838 if err != nil { 839 log.Error("unStake subLockAmount err.", "address", address.Hex(), "err", err) 840 return err 841 } 842 843 // add balance of staker 844 return ec.transfer(contractAddr, address, amount) 845 } 846 847 // transfer 系统合约内的转账 848 func (ec electionContext) transfer(sender, receiver common.Address, amount *big.Int) error { 849 return transfer(ec.context.GetStateDb(), sender, receiver, amount) 850 } 851 852 func transfer(db inter.StateDB, sender, receiver common.Address, amount *big.Int) error { 853 if db.GetBalance(sender).Cmp(amount) < 0 { 854 return fmt.Errorf("sender[%v] do not have enough balance", sender.Hex()) 855 } 856 857 db.AddBalance(receiver, amount) 858 db.SubBalance(sender, amount) 859 return nil 860 } 861 862 func (ec electionContext) prepareForVote(voter *Voter, address common.Address) (*big.Int, *Stake, error) { 863 now := ec.context.GetTime() 864 stake := ec.getStake(address) 865 // 查看当前是否有抵押,无抵押返回无权投票的错误 866 if !bytes.Equal(stake.Owner.Bytes(), address.Bytes()) || stake.StakeCount == nil || stake.StakeCount.Sign() <= 0 { 867 return nil, nil, fmt.Errorf("you must stake before vote") 868 } 869 voteCount := ec.calculateVoteCount(stake.StakeCount) 870 // 第一次投票 871 if !bytes.Equal(voter.Owner.Bytes(), address.Bytes()) { 872 voter.Owner = address 873 voter.TimeStamp = now 874 } else { 875 // 如果距离上次投票时间不足24小时,拒绝投票 876 if now.Cmp(voter.TimeStamp) < 0 || now.Cmp(new(big.Int).Add(voter.TimeStamp, big.NewInt(OneDay))) < 0 { 877 return nil, nil, fmt.Errorf("it's less than 24h after your last vote or setProxy, lastTime: %v, now: %v", voter.TimeStamp, ec.context.GetTime()) 878 } else { 879 voter.TimeStamp = now 880 } 881 // 如果当前设置了代理,要先取消代理,或者取消之前的投票 882 if !bytes.Equal(voter.Proxy.Bytes(), emptyAddress.Bytes()) { 883 voter.Proxy = emptyAddress 884 return voteCount, &stake, ec.cancelProxy(voter.Owner) 885 } else { 886 // 代理的票数和自身的票数 887 return voteCount, &stake, ec.subVoteFromCandidates(voter) 888 } 889 } 890 return voteCount, &stake, nil 891 } 892 893 func (ec electionContext) subVoteFromCandidates(voter *Voter) error { 894 lastVoteCount := new(big.Int).Set(voter.LastVoteCount) 895 if voter.ProxyVoteCount != nil && voter.ProxyVoteCount.Sign() > 0 { 896 lastVoteCount.Add(lastVoteCount, voter.ProxyVoteCount) 897 } 898 subOp := func(count *big.Int) { 899 count.Sub(count, lastVoteCount) 900 } 901 return ec.opCandidates(voter, subOp) 902 } 903 904 func (ec electionContext) opCandidates(voter *Voter, opFn func(*big.Int)) error { 905 for _, candidate := range voter.VoteCandidates { 906 candi := ec.getCandidate(candidate) 907 if !bytes.Equal(candi.Owner.Bytes(), candidate.Bytes()) { 908 return fmt.Errorf("The candidate %x doesn't exist.", candidate) 909 } 910 911 if candi.VoteCount == nil { 912 candi.VoteCount = big.NewInt(0) 913 } 914 // 操作候选人的相应投票 915 opFn(candi.VoteCount) 916 if candi.VoteCount.Sign() < 0 { 917 return fmt.Errorf("the voteCount %v of candidate %x is negative", candi.VoteCount, candi.Owner) 918 } 919 err := ec.setCandidate(candi) 920 if err != nil { 921 return fmt.Errorf("setCandidate error: %s", err) 922 } 923 } 924 return nil 925 } 926 927 func (ec electionContext) calculateVoteCount(stakeCount *big.Int) *big.Int { 928 deltaTime := big.NewInt(0) 929 deltaTime.Sub(ec.context.GetTime(), eraTimeStamp) 930 deltaTime.Div(deltaTime, big.NewInt(oneWeek)) 931 932 weight := float64(deltaTime.Uint64()) / 52 933 934 votes := float64(stakeCount.Uint64()) * math.Exp2(weight) 935 return big.NewInt(int64(votes)) 936 } 937 938 // GetFirstNCandidates get candidates with most votes as witness from specific stateDB 939 func GetFirstNCandidates(stateDB inter.StateDB, witnessesNum int) ([]common.Address, []string) { 940 var witnesses []common.Address 941 var urls []string 942 candidates := getAllCandidate(stateDB) 943 if candidates == nil { 944 log.Warn("There is no witness candidates. If you want to be a witness, please register now.") 945 return nil, nil 946 } 947 if len(candidates) < witnessesNum { 948 log.Warn("Witness candidates is too less. If you want to be a witness, please register now.", "num of candidates", len(candidates), "want", witnessesNum) 949 return nil, nil 950 } 951 952 candidates.Sort() 953 witnessSet := make(map[common.Address]struct{}) 954 for i := 0; i < len(candidates) && len(witnesses) < witnessesNum; i++ { 955 if candidates[i].VoteCount.Cmp(big.NewInt(0)) >= 0 && candidates[i].Active() { 956 witnesses = append(witnesses, candidates[i].Owner) 957 witnessSet[candidates[i].Owner] = struct{}{} 958 urls = append(urls, string(candidates[i].Url)) 959 } 960 } 961 if len(witnessSet) != witnessesNum { 962 log.Warn("Valid witness candidates is too less. If you want to be a witness, please register now.", "num of valid candidates", len(witnessSet), "want", witnessesNum) 963 return nil, nil 964 } 965 966 return witnesses, urls 967 } 968 969 // GetAllCandidates return the list of all candidate. Candidates will be 970 // sort by votes and address, if sorted is true. 971 func GetAllCandidates(stateDB inter.StateDB, sorted bool) CandidateList { 972 candidates := getAllCandidate(stateDB) 973 if sorted { 974 candidates.Sort() 975 } 976 return candidates 977 } 978 979 // GetCandidate returns a candidate's information. Return nil if not find. 980 func GetCandidate(stateDB inter.StateDB, addr common.Address) *Candidate { 981 v := getCandidateFrom(addr, genGetFunc(stateDB)) 982 if v.Owner == addr { 983 return &v 984 } 985 return nil 986 } 987 988 // GetVoter returns a voter's information. Return nil if not find. 989 func GetVoter(stateDB inter.StateDB, addr common.Address) *Voter { 990 v := getVoterFrom(addr, genGetFunc(stateDB)) 991 if v.Owner == addr { 992 return &v 993 } 994 return nil 995 } 996 997 // GetStake returns a user's information. Return nil if not find. 998 func GetStake(stateDB inter.StateDB, addr common.Address) *Stake { 999 v := getStakeFrom(addr, genGetFunc(stateDB)) 1000 if v.Owner == addr { 1001 return &v 1002 } 1003 return nil 1004 } 1005 1006 func vnt2wei(vnt int) *big.Int { 1007 return big.NewInt(0).Mul(big.NewInt(int64(vnt)), big.NewInt(1e18)) 1008 }