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  }