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  }