github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/core/ppos/candidate_state.go (about)

     1  package pposm
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"github.com/PlatONnetwork/PlatON-Go/common"
     8  	"github.com/PlatONnetwork/PlatON-Go/core/ppos_storage"
     9  	"github.com/PlatONnetwork/PlatON-Go/core/state"
    10  	"github.com/PlatONnetwork/PlatON-Go/core/types"
    11  	"github.com/PlatONnetwork/PlatON-Go/core/vm"
    12  	"github.com/PlatONnetwork/PlatON-Go/log"
    13  	"github.com/PlatONnetwork/PlatON-Go/p2p/discover"
    14  	"github.com/PlatONnetwork/PlatON-Go/params"
    15  	"math/big"
    16  	"net"
    17  	"strconv"
    18  	"strings"
    19  	"sync"
    20  )
    21  
    22  const (
    23  	GET_WITNESS   = 1
    24  	GET_IM_RE     = 2
    25  	GET_WIT_IM_RE = 3
    26  )
    27  
    28  var (
    29  	//CandidateEncodeErr          = errors.New("Candidate encoding err")
    30  	//CandidateDecodeErr          = errors.New("Candidate decoding err")
    31  	CandidateEmptyErr           = errors.New("Candidate is empty")
    32  	ContractBalanceNotEnoughErr = errors.New("Contract's balance is not enough")
    33  	CandidateOwnerErr           = errors.New("CandidateOwner Addr is illegal")
    34  	DepositLowErr               = errors.New("Candidate deposit too low")
    35  	WithdrawPriceErr            = errors.New("Withdraw Price err")
    36  	WithdrawLowErr              = errors.New("Withdraw Price too low")
    37  	RefundEmptyErr              = errors.New("Refund is empty")
    38  )
    39  
    40  type candidateStorage map[discover.NodeID]*types.Candidate
    41  type refundStorage map[discover.NodeID]types.CandidateQueue
    42  
    43  type CandidatePool struct {
    44  	// min deposit allow threshold
    45  	threshold *big.Int
    46  	// min deposit limit percentage
    47  	depositLimit uint32
    48  	// allow put into immedidate condition
    49  	allowed uint32
    50  	// allow immediate elected max count
    51  	maxCount uint32
    52  	// allow witness max count
    53  	maxChair uint32
    54  	// allow block interval for refunds
    55  	refundBlockNumber uint32
    56  
    57  	// previous witness
    58  	preOriginCandidates candidateStorage
    59  	// current witnesses
    60  	originCandidates candidateStorage
    61  	// next witnesses
    62  	nextOriginCandidates candidateStorage
    63  	// immediates
    64  	immediateCandidates candidateStorage
    65  	// reserves
    66  	reserveCandidates candidateStorage
    67  	// refunds
    68  	defeatCandidates refundStorage
    69  
    70  	// cache
    71  	//immediateCacheArr types.CandidateQueue
    72  	//reserveCacheArr   types.CandidateQueue
    73  
    74  	storage *ppos_storage.Ppos_storage
    75  }
    76  
    77  // Initialize the global candidate pool object
    78  func NewCandidatePool(configs *params.PposConfig) *CandidatePool {
    79  
    80  	log.Debug("Build a New CandidatePool Info ...")
    81  	if "" == strings.TrimSpace(configs.CandidateConfig.Threshold) {
    82  		configs.CandidateConfig.Threshold = "1000000000000000000000000"
    83  	}
    84  	var threshold *big.Int
    85  	if thd, ok := new(big.Int).SetString(configs.CandidateConfig.Threshold, 10); !ok {
    86  		threshold, _ = new(big.Int).SetString("1000000000000000000000000", 10)
    87  	} else {
    88  		threshold = thd
    89  	}
    90  	return &CandidatePool{
    91  		threshold:            threshold,
    92  		depositLimit:         configs.CandidateConfig.DepositLimit,
    93  		allowed:              configs.CandidateConfig.Allowed,
    94  		maxCount:             configs.CandidateConfig.MaxCount,
    95  		maxChair:             configs.CandidateConfig.MaxChair,
    96  		refundBlockNumber:    configs.CandidateConfig.RefundBlockNumber,
    97  		preOriginCandidates:  make(candidateStorage, 0),
    98  		originCandidates:     make(candidateStorage, 0),
    99  		nextOriginCandidates: make(candidateStorage, 0),
   100  		immediateCandidates:  make(candidateStorage, 0),
   101  		reserveCandidates:    make(candidateStorage, 0),
   102  		defeatCandidates:     make(refundStorage, 0),
   103  		//immediateCacheArr:    make(types.CandidateQueue, 0),
   104  		//reserveCacheArr:      make(types.CandidateQueue, 0),
   105  	}
   106  }
   107  
   108  // flag:
   109  // 0: only init previous witness and current witness and next witness
   110  // 1:init previous witness and current witness and next witness and immediate and reserve
   111  // 2: init all information
   112  //func (c *CandidatePool) initDataByState(state vm.StateDB, flag int) error {
   113  //	log.Info("init data by stateDB...", "statedb addr", fmt.Sprintf("%p", state))
   114  //
   115  //	parentRoutineID := fmt.Sprintf("%s", common.CurrentGoRoutineID())
   116  //
   117  //	//loading  candidates func
   118  //	loadWitFunc := func(title string, canMap candidateStorage,
   119  //		getIndexFn func(state vm.StateDB) ([]discover.NodeID, error),
   120  //		getInfoFn func(state vm.StateDB, id discover.NodeID) (*types.Candidate, error)) error {
   121  //
   122  //		log.Debug("initDataByState by Getting "+title+" parent routine "+parentRoutineID, "statedb addr", fmt.Sprintf("%p", state))
   123  //		var witnessIds []discover.NodeID
   124  //		if ids, err := getIndexFn(state); nil != err {
   125  //			log.Error("Failed to decode "+title+" witnessIds on initDataByState", " err", err)
   126  //			return err
   127  //		} else {
   128  //			witnessIds = ids
   129  //		}
   130  //
   131  //		PrintObject(title+" witnessIds", witnessIds)
   132  //		for _, witnessId := range witnessIds {
   133  //
   134  //			if ca, err := getInfoFn(state, witnessId); nil != err {
   135  //				log.Error("Failed to decode "+title+" witness Candidate on initDataByState", "err", err)
   136  //				return CandidateDecodeErr
   137  //			} else {
   138  //				if nil != ca {
   139  //					PrintObject(title+"Id:"+witnessId.String()+", can", ca)
   140  //					canMap[witnessId] = ca
   141  //				} else {
   142  //					delete(canMap, witnessId)
   143  //				}
   144  //			}
   145  //		}
   146  //		return nil
   147  //	}
   148  //
   149  //	witErrCh := make(chan error, 3)
   150  //	var wg sync.WaitGroup
   151  //	wg.Add(3)
   152  //
   153  //	// loading witnesses
   154  //	go func() {
   155  //		c.preOriginCandidates = make(candidateStorage, 0)
   156  //		witErrCh <- loadWitFunc("previous", c.preOriginCandidates, getPreviousWitnessIdsState, getPreviousWitnessByState)
   157  //		wg.Done()
   158  //	}()
   159  //	go func() {
   160  //		c.originCandidates = make(candidateStorage, 0)
   161  //		witErrCh <- loadWitFunc("current", c.originCandidates, getWitnessIdsByState, getWitnessByState)
   162  //		wg.Done()
   163  //	}()
   164  //	go func() {
   165  //		c.nextOriginCandidates = make(candidateStorage, 0)
   166  //		witErrCh <- loadWitFunc("next", c.nextOriginCandidates, getNextWitnessIdsByState, getNextWitnessByState)
   167  //		wg.Done()
   168  //	}()
   169  //	var err error
   170  //	for i := 1; i <= 3; i++ {
   171  //		if err = <-witErrCh; nil != err {
   172  //			break
   173  //		}
   174  //	}
   175  //	wg.Wait()
   176  //	close(witErrCh)
   177  //	if nil != err {
   178  //		return err
   179  //	}
   180  //
   181  //	// loading elected candidates
   182  //	if flag == 1 || flag == 2 {
   183  //
   184  //		loadElectedFunc := func(title string, canMap candidateStorage,
   185  //			getIndexFn func(state vm.StateDB) ([]discover.NodeID, error),
   186  //			getInfoFn func(state vm.StateDB, id discover.NodeID) (*types.Candidate, error)) (types.CandidateQueue, error) {
   187  //			var witnessIds []discover.NodeID
   188  //
   189  //			log.Debug("initDataByState by Getting "+title+" parent routine "+parentRoutineID, "statedb addr", fmt.Sprintf("%p", state))
   190  //			if ids, err := getIndexFn(state); nil != err {
   191  //				log.Error("Failed to decode "+title+"Ids on initDataByState", " err", err)
   192  //				return nil, err
   193  //			} else {
   194  //				witnessIds = ids
   195  //			}
   196  //			// cache
   197  //			canCache := make(types.CandidateQueue, 0)
   198  //
   199  //			PrintObject(title+" Ids", witnessIds)
   200  //			for _, witnessId := range witnessIds {
   201  //
   202  //				if ca, err := getInfoFn(state, witnessId); nil != err {
   203  //					log.Error("Failed to decode "+title+" Candidate on initDataByState", "err", err)
   204  //					return nil, CandidateDecodeErr
   205  //				} else {
   206  //					if nil != ca {
   207  //						PrintObject(title+"Id:"+witnessId.String()+", can", ca)
   208  //						canMap[witnessId] = ca
   209  //						canCache = append(canCache, ca)
   210  //					} else {
   211  //						delete(canMap, witnessId)
   212  //					}
   213  //				}
   214  //			}
   215  //			return canCache, nil
   216  //		}
   217  //		type result struct {
   218  //			Type int // 1: immediate; 2: reserve
   219  //			Arr  types.CandidateQueue
   220  //			Err  error
   221  //		}
   222  //		resCh := make(chan *result, 2)
   223  //		wg.Add(2)
   224  //		go func() {
   225  //			res := new(result)
   226  //			res.Type = IS_IMMEDIATE
   227  //			c.immediateCandidates = make(candidateStorage, 0)
   228  //			if arr, err := loadElectedFunc("immediate", c.immediateCandidates, getImmediateIdsByState, getImmediateByState); nil != err {
   229  //				res.Err = err
   230  //				resCh <- res
   231  //			} else {
   232  //				res.Arr = arr
   233  //				resCh <- res
   234  //			}
   235  //			wg.Done()
   236  //		}()
   237  //		go func() {
   238  //			res := new(result)
   239  //			res.Type = IS_RESERVE
   240  //			c.reserveCandidates = make(candidateStorage, 0)
   241  //			if arr, err := loadElectedFunc("reserve", c.reserveCandidates, getReserveIdsByState, getReserveByState); nil != err {
   242  //				res.Err = err
   243  //				resCh <- res
   244  //			} else {
   245  //				res.Arr = arr
   246  //				resCh <- res
   247  //			}
   248  //			wg.Done()
   249  //		}()
   250  //		wg.Wait()
   251  //		close(resCh)
   252  //		for res := range resCh {
   253  //			if nil != res.Err {
   254  //				return res.Err
   255  //			}
   256  //			switch res.Type {
   257  //			case IS_IMMEDIATE:
   258  //				c.immediateCacheArr = res.Arr
   259  //			case IS_RESERVE:
   260  //				c.reserveCacheArr = res.Arr
   261  //			default:
   262  //				continue
   263  //			}
   264  //		}
   265  //
   266  //	}
   267  //
   268  //	// load refunds
   269  //	if flag == 2 {
   270  //
   271  //		var defeatIds []discover.NodeID
   272  //		c.defeatCandidates = make(refundStorage, 0)
   273  //		if ids, err := getDefeatIdsByState(state); nil != err {
   274  //			log.Error("Failed to decode defeatIds on initDataByState", "err", err)
   275  //			return err
   276  //		} else {
   277  //			defeatIds = ids
   278  //		}
   279  //		PrintObject("defeatIds", defeatIds)
   280  //		for _, defeatId := range defeatIds {
   281  //			if arr, err := getDefeatsByState(state, defeatId); nil != err {
   282  //				log.Error("Failed to decode defeat CandidateArr on initDataByState", "err", err)
   283  //				return CandidateDecodeErr
   284  //			} else {
   285  //				if nil != arr && len(arr) != 0 {
   286  //					PrintObject("defeatId:"+defeatId.String()+", arr", arr)
   287  //					c.defeatCandidates[defeatId] = arr
   288  //				} else {
   289  //					delete(c.defeatCandidates, defeatId)
   290  //				}
   291  //			}
   292  //		}
   293  //	}
   294  //	return nil
   295  //}
   296  
   297  func (c *CandidatePool) initDataByState(state vm.StateDB) {
   298  	c.storage = state.GetPPOSCache()
   299  
   300  	log.Debug("initDataByState", "state addr", fmt.Sprintf("%p", state))
   301  	log.Debug("initDataByState", "ppos storage addr", fmt.Sprintf("%p", c.storage))
   302  }
   303  
   304  // flag:
   305  // 1: witness
   306  // 2: im and re (im/re)
   307  // 3 : wit + im/re
   308  func (c *CandidatePool) initData2Cache(state vm.StateDB, flag int) {
   309  	c.initDataByState(state)
   310  
   311  	loadQueueFunc := func(arr types.CandidateQueue, canMap candidateStorage) {
   312  		for _, can := range arr {
   313  			canMap[can.CandidateId] = can
   314  		}
   315  	}
   316  	var wg sync.WaitGroup
   317  
   318  	switch flag {
   319  	case GET_WITNESS:
   320  		wg.Add(3)
   321  		c.getWitnessMap(&wg, loadQueueFunc)
   322  		wg.Wait()
   323  	case GET_IM_RE:
   324  		wg.Add(2)
   325  		c.getImAndReMap(&wg, loadQueueFunc)
   326  		wg.Wait()
   327  	case GET_WIT_IM_RE:
   328  		wg.Add(5)
   329  		c.getWitnessMap(&wg, loadQueueFunc)
   330  		c.getImAndReMap(&wg, loadQueueFunc)
   331  		wg.Wait()
   332  	default:
   333  		return
   334  	}
   335  }
   336  
   337  func (c *CandidatePool) getWitnessMap(wg *sync.WaitGroup, loadQueueFunc func(arr types.CandidateQueue, canMap candidateStorage)) {
   338  	go func() {
   339  		loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.PREVIOUS), c.preOriginCandidates)
   340  		wg.Done()
   341  	}()
   342  	go func() {
   343  		loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.CURRENT), c.originCandidates)
   344  		wg.Done()
   345  	}()
   346  	go func() {
   347  		loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.NEXT), c.nextOriginCandidates)
   348  		wg.Done()
   349  	}()
   350  }
   351  func (c *CandidatePool) getImAndReMap(wg *sync.WaitGroup, loadQueueFunc func(arr types.CandidateQueue, canMap candidateStorage)) {
   352  	go func() {
   353  		loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.IMMEDIATE), c.immediateCandidates)
   354  		wg.Done()
   355  	}()
   356  	go func() {
   357  		loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.RESERVE), c.reserveCandidates)
   358  		wg.Done()
   359  	}()
   360  }
   361  
   362  // pledge Candidate
   363  func (c *CandidatePool) SetCandidate(state vm.StateDB, nodeId discover.NodeID, can *types.Candidate) error {
   364  	log.Debug("Call SetCandidate start ...", "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber)
   365  
   366  	PrintObject("Call SetCandidate start ...", *can)
   367  
   368  	c.initData2Cache(state, GET_IM_RE)
   369  	var nodeIds []discover.NodeID
   370  
   371  	// If it is the first pledge, judge the pledge threshold
   372  	if !c.checkFirstThreshold(can) {
   373  		log.Warn("Failed to checkFirstThreshold on SetCandidate", "Deposit", can.Deposit.String(), "threshold", c.threshold)
   374  		return errors.New(DepositLowErr.Error() + ", Current Deposit:" + can.Deposit.String() + ", target threshold:" + fmt.Sprint(c.threshold))
   375  	}
   376  
   377  	// Before each pledge, we need to check whether the current can deposit is not less
   378  	// than the minimum can deposit when the corresponding queue to be placed is full.
   379  	//if _, ok := c.checkDeposit(state, can, false); !ok {
   380  	if ok := c.checkDeposit(can); !ok {
   381  		log.Warn("Failed to checkDeposit on SetCandidate", "nodeId", nodeId.String(), " err", DepositLowErr)
   382  		return DepositLowErr
   383  	}
   384  	nodeIds = c.setCandidateInfo(state, nodeId, can, can.BlockNumber, nil)
   385  	//go ticketPool.DropReturnTicket(state, nodeIds...)
   386  	if len(nodeIds) > 0 {
   387  		if err := tContext.DropReturnTicket(state, can.BlockNumber, nodeIds...); nil != err {
   388  			log.Error("Failed to DropReturnTicket on SetCandidate ...",  "current blockNumber", can.BlockNumber, "err", err)
   389  			//return err
   390  		}
   391  	}
   392  	log.Debug("Call SetCandidate successfully...")
   393  	return nil
   394  }
   395  
   396  // If TCout is small, you must first move to reserves, otherwise it will be counted.
   397  func (c *CandidatePool) setCandidateInfo(state vm.StateDB, nodeId discover.NodeID, can *types.Candidate, currentBlockNumber *big.Int, promoteReserveFunc func(state vm.StateDB, currentBlockNumber *big.Int)/* []discover.NodeID*/) []discover.NodeID {
   398  
   399  	var allowed, delimmediate, delreserve bool
   400  	// check ticket count
   401  	if c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId)) {
   402  		allowed = true
   403  		if _, ok := c.reserveCandidates[can.CandidateId]; ok {
   404  			delreserve = true
   405  		}
   406  		c.immediateCandidates[can.CandidateId] = can
   407  	} else {
   408  		if _, ok := c.immediateCandidates[can.CandidateId]; ok {
   409  			delimmediate = true
   410  		}
   411  		c.reserveCandidates[can.CandidateId] = can
   412  	}
   413  
   414  	// delete Func
   415  	delCandidateFunc := func(nodeId discover.NodeID, flag int) {
   416  		queue := c.getCandidateQueue(flag)
   417  		/*//for i, id := range ids {
   418  		for i := 0; i < len(ids); i++ {
   419  			id := ids[i]
   420  			if id == can.CandidateId {
   421  				ids = append(ids[:i], ids[i+1:]...)
   422  				i--
   423  			}
   424  		}*/
   425  		for i, can := range queue {
   426  			if can.CandidateId == nodeId {
   427  				queue = append(queue[:i], queue[i+1:]...)
   428  				break
   429  			}
   430  		}
   431  		c.setCandidateQueue(queue, flag)
   432  	}
   433  
   434  
   435  	/**
   436  	handle the reserve queue func
   437  	*/
   438  	handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID {
   439  
   440  		re_queueCopy := make(types.CandidateQueue, len(re_queue))
   441  		copy(re_queueCopy, re_queue)
   442  
   443  		str := "Call setCandidateInfo to handleReserveFunc to sort the reserve queue ..."
   444  
   445  		// sort reserve array
   446  		makeCandidateSort(str, state, re_queueCopy)
   447  
   448  		nodeIds := make([]discover.NodeID, 0)
   449  
   450  
   451  		if len(re_queueCopy) > int(c.maxCount) {
   452  			// Intercepting the lost candidates to tmpArr
   453  			tempArr := (re_queueCopy)[c.maxCount:]
   454  			// qualified elected candidates
   455  			re_queueCopy = (re_queueCopy)[:c.maxCount]
   456  
   457  			// handle tmpArr
   458  			for _, tmpCan := range tempArr {
   459  				deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10)
   460  				refund := &types.CandidateRefund{
   461  					Deposit:     deposit,
   462  					BlockNumber: big.NewInt(currentBlockNumber.Int64()),
   463  					Owner:       tmpCan.Owner,
   464  				}
   465  				c.setRefund(tmpCan.CandidateId, refund)
   466  				nodeIds = append(nodeIds, tmpCan.CandidateId)
   467  			}
   468  		}
   469  
   470  		c.setCandidateQueue(re_queueCopy, ppos_storage.RESERVE)
   471  
   472  		return nodeIds
   473  	}
   474  
   475  
   476  	var str string
   477  	// using the cache handle current queue
   478  	cacheArr := make(types.CandidateQueue, 0)
   479  	if allowed {
   480  
   481  		/** first delete this can on reserves */
   482  		if delreserve {
   483  			delCandidateFunc(can.CandidateId, ppos_storage.RESERVE)
   484  		}
   485  
   486  		str = "Call setCandidateInfo to sort the immediate queue ..."
   487  		for _, v := range c.immediateCandidates {
   488  			cacheArr = append(cacheArr, v)
   489  		}
   490  	} else {
   491  
   492  		/** first delete this can on immediates */
   493  		if delimmediate {
   494  			delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE)
   495  		}
   496  
   497  
   498  		str = "Call setCandidateInfo to sort the reserve queue ..."
   499  		for _, v := range c.reserveCandidates {
   500  			cacheArr = append(cacheArr, v)
   501  		}
   502  	}
   503  
   504  
   505  	// sort cache array
   506  	makeCandidateSort(str, state, cacheArr)
   507  
   508  	nodeIds := make([]discover.NodeID, 0)
   509  
   510  	if len(cacheArr) > int(c.maxCount) {
   511  		// Intercepting the lost candidates to tmpArr
   512  		tempArr := (cacheArr)[c.maxCount:]
   513  		// qualified elected candidates
   514  		cacheArr = (cacheArr)[:c.maxCount]
   515  
   516  		// add reserve queue cache
   517  		addreserveQueue := make(types.CandidateQueue, 0)
   518  
   519  		// handle tmpArr
   520  		for _, tmpCan := range tempArr {
   521  
   522  
   523  			// if ticket count great allowed && no need delete reserve
   524  			// so this can move to reserve from immediate now
   525  			if allowed {
   526  				addreserveQueue = append(addreserveQueue, tmpCan)
   527  			} else {
   528  
   529  				deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10)
   530  				refund := &types.CandidateRefund{
   531  					Deposit:     deposit,
   532  					BlockNumber: big.NewInt(currentBlockNumber.Int64()),
   533  					Owner:       tmpCan.Owner,
   534  				}
   535  				c.setRefund(tmpCan.CandidateId, refund)
   536  				nodeIds = append(nodeIds, tmpCan.CandidateId)
   537  			}
   538  
   539  		}
   540  
   541  		if len(addreserveQueue) != 0 {
   542  			re_queue := c.getCandidateQueue(ppos_storage.RESERVE)
   543  			re_queue = append(re_queue, addreserveQueue...)
   544  			if ids := handleReserveFunc(re_queue); len(ids) != 0 {
   545  				nodeIds = append(nodeIds, ids...)
   546  			}
   547  			//c.setCandidateQueue(re_queue, ppos_storage.RESERVE)
   548  		}
   549  
   550  	}
   551  
   552  	if allowed {
   553  		c.setCandidateQueue(cacheArr, ppos_storage.IMMEDIATE)
   554  	} else {
   555  		c.setCandidateQueue(cacheArr, ppos_storage.RESERVE)
   556  	}
   557  
   558  	if nil != promoteReserveFunc {
   559  		promoteReserveFunc(state, currentBlockNumber)
   560  	}
   561  
   562  	return nodeIds
   563  }
   564  
   565  
   566  
   567  // If TCout is small, you must first move to reserves, otherwise it will be counted.
   568  func (c *CandidatePool) electionUpdateCanById(state vm.StateDB, currentBlockNumber *big.Int, nodeIds ... discover.NodeID) []discover.NodeID {
   569  
   570  	im_del_temp := make(candidateStorage, 0)
   571  	re_del_temp := make(candidateStorage, 0)
   572  
   573  	for _, nodeId := range nodeIds {
   574  		// check ticket count
   575  		if c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId)) {
   576  			if can, ok := c.reserveCandidates[nodeId]; ok {
   577  				re_del_temp[nodeId] = can
   578  			}
   579  
   580  		} else {
   581  			if can, ok := c.immediateCandidates[nodeId]; ok {
   582  				im_del_temp[nodeId] = can
   583  			}
   584  		}
   585  	}
   586  
   587  	if len(im_del_temp) == 0 && len(re_del_temp) == 0 {
   588  		log.Debug("Call Election to electionUpdateCanById, had not change on double queue ...")
   589  		return nil
   590  	}
   591  
   592  	im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE)
   593  
   594  	re_queue := c.getCandidateQueue(ppos_storage.RESERVE)
   595  
   596  
   597  	PrintObject("Call Election to electionUpdateCanById, Before shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue)
   598  
   599  	PrintObject("Call Election to electionUpdateCanById, Before shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue)
   600  
   601  	// immediate queue
   602  	for _, can := range re_del_temp{
   603  		im_queue = append(im_queue, can)
   604  	}
   605  	// for i := 0; i < len(ids); i++ {
   606  	for i := 0; i < len(im_queue); i++ {
   607  		im := im_queue[i]
   608  		if _, ok := im_del_temp[im.CandidateId]; ok {
   609  			im_queue = append(im_queue[:i], im_queue[i+1:]...)
   610  			i--
   611  		}
   612  	}
   613  
   614  	// reserve  queue
   615  	for i := 0; i < len(re_queue); i++ {
   616  		re := re_queue[i]
   617  		if _, ok := re_del_temp[re.CandidateId]; ok {
   618  			re_queue = append(re_queue[:i], re_queue[i+1:]...)
   619  			i--
   620  		}
   621  	}
   622  	for _, can := range im_del_temp {
   623  		re_queue = append(re_queue, can)
   624  	}
   625  
   626  
   627  	PrintObject("Call Election to electionUpdateCanById, After shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue)
   628  
   629  	PrintObject("Call Election to electionUpdateCanById, After shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue)
   630  
   631  
   632  	/**
   633  	 handle the reserve queue func
   634  	 */
   635  	handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID {
   636  
   637  		re_queueCopy := make(types.CandidateQueue, len(re_queue))
   638  		copy(re_queueCopy, re_queue)
   639  
   640  		str := "Call Election to handleReserveFunc to sort the reserve queue ..."
   641  
   642  		// sort reserve array
   643  		makeCandidateSort(str, state, re_queueCopy)
   644  
   645  		nodeIds := make([]discover.NodeID, 0)
   646  
   647  
   648  		if len(re_queueCopy) > int(c.maxCount) {
   649  			// Intercepting the lost candidates to tmpArr
   650  			tempArr := (re_queueCopy)[c.maxCount:]
   651  			// qualified elected candidates
   652  			re_queueCopy = (re_queueCopy)[:c.maxCount]
   653  
   654  			// handle tmpArr
   655  			for _, tmpCan := range tempArr {
   656  				deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10)
   657  				refund := &types.CandidateRefund{
   658  					Deposit:     deposit,
   659  					BlockNumber: big.NewInt(currentBlockNumber.Int64()),
   660  					Owner:       tmpCan.Owner,
   661  				}
   662  				c.setRefund(tmpCan.CandidateId, refund)
   663  				nodeIds = append(nodeIds, tmpCan.CandidateId)
   664  			}
   665  		}
   666  
   667  		PrintObject("Call Election to electionUpdateCanById to handleReserveFunc, Finally shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queueCopy)) + " ,queue is", re_queueCopy)
   668  
   669  		c.setCandidateQueue(re_queueCopy, ppos_storage.RESERVE)
   670  
   671  		return nodeIds
   672  	}
   673  
   674  
   675  
   676  
   677  
   678  	str := "Call Election to start sort immediate queue ..."
   679  
   680  	// sort immediate array
   681  	makeCandidateSort(str, state, im_queue)
   682  
   683  	nodeIdArr := make([]discover.NodeID, 0)
   684  
   685  	if len(im_queue) > int(c.maxCount) {
   686  		// Intercepting the lost candidates to tmpArr
   687  		tempArr := (im_queue)[c.maxCount:]
   688  		// qualified elected candidates
   689  		im_queue = (im_queue)[:c.maxCount]
   690  
   691  		// add reserve queue cache
   692  		addreserveQueue := make(types.CandidateQueue, 0)
   693  
   694  		// handle tmpArr
   695  		for _, tmpCan := range tempArr {
   696  			addreserveQueue = append(addreserveQueue, tmpCan)
   697  		}
   698  
   699  		if len(addreserveQueue) != 0 {
   700  			// append into reserve queue
   701  			re_queue = append(re_queue, addreserveQueue...)
   702  		}
   703  
   704  	}/*else {
   705  		PrintObject("Call Election to electionUpdateCanById to direct, Finally shuffle double queue the old reserve queue is", re_queue)
   706  		c.setCandidateQueue(re_queue, ppos_storage.RESERVE)
   707  	}*/
   708  
   709  	// hanle and sets reserve queue
   710  	if ids := handleReserveFunc(re_queue); len(ids) != 0 {
   711  		nodeIdArr = append(nodeIdArr, ids...)
   712  	}
   713  
   714  	PrintObject("Call Election to electionUpdateCanById, Finally shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue)
   715  	// set immediate queue
   716  	c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE)
   717  
   718  	c.promoteReserveQueue(state, currentBlockNumber)
   719  
   720  	return nodeIdArr
   721  }
   722  
   723  
   724  
   725  // Getting immediate or reserve candidate info by nodeId
   726  func (c *CandidatePool) GetCandidate(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) *types.Candidate {
   727  	return c.getCandidate(state, nodeId, blockNumber)
   728  }
   729  
   730  // Getting immediate or reserve candidate info arr by nodeIds
   731  func (c *CandidatePool) GetCandidateArr(state vm.StateDB, blockNumber *big.Int, nodeIds ...discover.NodeID) types.CandidateQueue {
   732  	return c.getCandidates(state, blockNumber, nodeIds...)
   733  }
   734  
   735  // candidate withdraw from immediates or reserve elected candidates
   736  func (c *CandidatePool) WithdrawCandidate(state vm.StateDB, nodeId discover.NodeID, price, blockNumber *big.Int) error {
   737  	log.Info("WithdrawCandidate...", "nodeId", nodeId.String(), "price", price.String(), "blockNumber", blockNumber.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber)
   738  
   739  	c.initData2Cache(state, GET_IM_RE)
   740  	var nodeIds []discover.NodeID
   741  
   742  	if arr, err := c.withdrawCandidate(state, nodeId, price, blockNumber); nil != err {
   743  		return err
   744  	} else {
   745  		nodeIds = arr
   746  	}
   747  	//go ticketPool.DropReturnTicket(state, nodeIds...)
   748  	if len(nodeIds) > 0 {
   749  		if err := tContext.DropReturnTicket(state, blockNumber, nodeIds...); nil != err {
   750  			log.Error("Failed to DropReturnTicket on WithdrawCandidate ...", "blockNumber", blockNumber.String(), "err", err)
   751  		}
   752  	}
   753  	return nil
   754  }
   755  
   756  func (c *CandidatePool) withdrawCandidate(state vm.StateDB, nodeId discover.NodeID, price, blockNumber *big.Int) ([]discover.NodeID, error) {
   757  
   758  	if price.Cmp(new(big.Int).SetUint64(0)) <= 0 {
   759  		log.Error("Failed to WithdrawCandidate price invalid", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), " price", price.String())
   760  		return nil, WithdrawPriceErr
   761  	}
   762  
   763  	// cache
   764  	var can *types.Candidate
   765  	var isImmediate bool
   766  
   767  	if imCan, ok := c.immediateCandidates[nodeId]; !ok {
   768  		reCan, ok := c.reserveCandidates[nodeId]
   769  		if !ok {
   770  			log.Error("Failed to WithdrawCandidate current Candidate is empty", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "price", price.String())
   771  			return nil, CandidateEmptyErr
   772  		} else {
   773  			can = reCan
   774  		}
   775  	} else {
   776  		can = imCan
   777  		isImmediate = true
   778  	}
   779  
   780  
   781  	// delete Func
   782  	delCandidateFunc := func(nodeId discover.NodeID, flag int) {
   783  		queue := c.getCandidateQueue(flag)
   784  
   785  		for i, can := range queue {
   786  			if can.CandidateId == nodeId {
   787  				queue = append(queue[:i], queue[i+1:]...)
   788  				break
   789  			}
   790  		}
   791  		c.setCandidateQueue(queue, flag)
   792  	}
   793  
   794  	var nodeIdArr []discover.NodeID
   795  	deposit, _ := new(big.Int).SetString(can.Deposit.String(), 10)
   796  	// check withdraw price
   797  	if can.Deposit.Cmp(price) < 0 {
   798  		log.Error("Failed to WithdrawCandidate refund price must less or equal deposit", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), " price", price.String())
   799  		return nil, WithdrawPriceErr
   800  	} else if can.Deposit.Cmp(price) == 0 { // full withdraw
   801  
   802  		log.Info("WithdrawCandidate into full withdraw", "blockNumber", blockNumber.String(), "canId", can.CandidateId.String(), "current can deposit", can.Deposit.String(), "withdraw price is", price.String())
   803  
   804  		if isImmediate {
   805  			delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE)
   806  		} else {
   807  			delCandidateFunc(can.CandidateId, ppos_storage.RESERVE)
   808  		}
   809  
   810  		refund := &types.CandidateRefund{
   811  			Deposit:     deposit,
   812  			BlockNumber: big.NewInt(blockNumber.Int64()),
   813  			Owner:       can.Owner,
   814  		}
   815  
   816  		c.setRefund(can.CandidateId, refund)
   817  
   818  		c.promoteReserveQueue(state, blockNumber)
   819  
   820  		nodeIds := []discover.NodeID{nodeId}
   821  
   822  		nodeIdArr = nodeIds
   823  
   824  	} else { // withdraw a few ...
   825  		/*// Only withdraw part of the refunds, need to reorder the immediate elected candidates
   826  		// The remaining candiate price to update current candidate info
   827  
   828  		log.Info("WithdrawCandidate into withdraw a few", "canId", can.CandidateId.String(), "current can deposit", can.Deposit.String(), "withdraw price is", price.String())
   829  
   830  		if err := c.checkWithdraw(can.Deposit, price); nil != err {
   831  			log.Error("Failed to price invalid on WithdrawCandidate", " price", price.String(), "err", err)
   832  			return nil, err
   833  		}
   834  
   835  		remainMoney := new(big.Int).Sub(can.Deposit, price)
   836  		half_threshold := new(big.Int).Mul(c.threshold, big.NewInt(2))
   837  
   838  		var isFullWithdraw bool
   839  		var canNew *types.Candidate
   840  		var refund *types.CandidateRefund
   841  
   842  		if remainMoney.Cmp(half_threshold) < 0 { // full withdraw
   843  			isFullWithdraw = true
   844  
   845  			refund = &types.CandidateRefund{
   846  				Deposit:     deposit,
   847  				BlockNumber: big.NewInt(blockNumber.Int64()),
   848  				Owner:       can.Owner,
   849  			}
   850  
   851  		} else {
   852  			// remain info
   853  			canNew = &types.Candidate{
   854  				Deposit:     remainMoney,
   855  				BlockNumber: big.NewInt(can.BlockNumber.Int64()),
   856  				TxIndex:     can.TxIndex,
   857  				CandidateId: can.CandidateId,
   858  				Host:        can.Host,
   859  				Port:        can.Port,
   860  				Owner:       can.Owner,
   861  				Extra:       can.Extra,
   862  				Fee:         can.Fee,
   863  			}
   864  
   865  			refund = &types.CandidateRefund{
   866  				Deposit:     price,
   867  				BlockNumber: big.NewInt(blockNumber.Int64()),
   868  				Owner:       can.Owner,
   869  			}
   870  
   871  		}
   872  
   873  		if isFullWithdraw {
   874  			if isImmediate {
   875  				delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE)
   876  			} else {
   877  				delCandidateFunc(can.CandidateId, ppos_storage.RESERVE)
   878  			}
   879  
   880  			c.setRefund(can.CandidateId, refund)
   881  
   882  			nIds := c.shuffleQueue(state, blockNumber)
   883  			nodeIds := []discover.NodeID{nodeId}
   884  
   885  			if len(nIds) != 0 {
   886  				nodeIds = append(nodeIds, nIds...)
   887  			}
   888  
   889  			nodeIdArr = nodeIds
   890  		} else {
   891  
   892  			handleFunc := func(nodeId discover.NodeID, flag int) {
   893  				queue := c.getCandidateQueue(flag)
   894  
   895  				for i, can := range queue {
   896  					if can.CandidateId == nodeId {
   897  						queue[i] = canNew
   898  						break
   899  					}
   900  				}
   901  				c.setCandidateQueue(queue, flag)
   902  				c.setRefund(nodeId, refund)
   903  			}
   904  
   905  			if isImmediate {
   906  				handleFunc(can.CandidateId, ppos_storage.IMMEDIATE)
   907  			} else {
   908  				handleFunc(can.CandidateId, ppos_storage.RESERVE)
   909  			}
   910  			nodeIdArr = append(nodeIdArr, nodeId)
   911  			if arr := c.shuffleQueue(state, blockNumber); len(arr) != 0 {
   912  				nodeIdArr = append(nodeIdArr, arr...)
   913  			}
   914  		}*/
   915  		log.Error("Failed to WithdrawCandidate, must full withdraw", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "the can deposit", can.Deposit.String(), "current will withdraw price", price.String())
   916  		return nil, WithdrawLowErr
   917  	}
   918  	log.Info("Call WithdrawCandidate SUCCESS !!!!!!!!!!!!")
   919  	return nodeIdArr, nil
   920  }
   921  
   922  // Getting elected candidates array
   923  // flag:
   924  // 0:  Getting all elected candidates array
   925  // 1:  Getting all immediate elected candidates array
   926  // 2:  Getting all reserve elected candidates array
   927  func (c *CandidatePool) GetChosens(state vm.StateDB, flag int, blockNumber *big.Int) types.KindCanQueue {
   928  	log.Debug("Call GetChosens getting immediate or reserve candidates ...", "blockNumber", blockNumber.String(), "flag", flag)
   929  	c.initDataByState(state)
   930  	im := make(types.CandidateQueue, 0)
   931  	re := make(types.CandidateQueue, 0)
   932  	arr := make(types.KindCanQueue, 0)
   933  	if flag == 0 || flag == 1 {
   934  		im = c.getCandidateQueue(ppos_storage.IMMEDIATE)
   935  	}
   936  	if flag == 0 || flag == 2 {
   937  		re = c.getCandidateQueue(ppos_storage.RESERVE)
   938  
   939  	}
   940  	arr = append(arr, im, re)
   941  	PrintObject("GetChosens return", arr)
   942  	return arr
   943  }
   944  
   945  // Getting elected candidates array
   946  // flag:
   947  // 0:  Getting all elected candidates array
   948  // 1:  Getting all immediate elected candidates array
   949  // 2:  Getting all reserve elected candidates array
   950  func (c *CandidatePool) GetCandidatePendArr(state vm.StateDB, flag int, blockNumber *big.Int) types.CandidateQueue {
   951  	log.Debug("Call GetCandidatePendArr getting immediate candidates ...", "blockNumber", blockNumber.String(), "flag", flag)
   952  	c.initDataByState(state)
   953  	arr := make(types.CandidateQueue, 0)
   954  	if flag == 0 || flag == 1 {
   955  		if queue := c.getCandidateQueue(ppos_storage.IMMEDIATE); len(queue) != 0 {
   956  			arr = append(arr, queue...)
   957  		}
   958  	}
   959  	if flag == 0 || flag == 2 {
   960  		if queue := c.getCandidateQueue(ppos_storage.RESERVE); len(queue) != 0 {
   961  			arr = append(arr, queue...)
   962  		}
   963  	}
   964  	PrintObject("GetChosens ==>", arr)
   965  	return arr
   966  }
   967  
   968  // Getting current witness array
   969  func (c *CandidatePool) GetChairpersons(state vm.StateDB, blockNumber *big.Int) types.CandidateQueue {
   970  	log.Debug("Call GetChairpersons getting witnesses ...", "blockNumber", blockNumber.String())
   971  	c.initDataByState(state)
   972  	return c.getCandidateQueue(ppos_storage.CURRENT)
   973  }
   974  
   975  // Getting all refund array by nodeId
   976  func (c *CandidatePool) GetDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) types.RefundQueue {
   977  	log.Debug("Call GetDefeat getting defeat arr", "blockNumber", blockNumber, "nodeId", nodeId.String())
   978  	c.initDataByState(state)
   979  	return c.getRefunds(nodeId)
   980  }
   981  
   982  // Checked current candidate was defeat by nodeId
   983  func (c *CandidatePool) IsDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) bool {
   984  	log.Debug("Call IsDefeat", "blockNumber", blockNumber.String())
   985  
   986  	c.initData2Cache(state, GET_IM_RE)
   987  
   988  	if _, ok := c.immediateCandidates[nodeId]; ok {
   989  		return false
   990  	}
   991  	if _, ok := c.reserveCandidates[nodeId]; ok {
   992  		return false
   993  	}
   994  	if queue := c.getRefunds(nodeId); len(queue) != 0 {
   995  		return true
   996  	}
   997  	return false
   998  }
   999  
  1000  func (c *CandidatePool) IsChosens(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) bool {
  1001  	log.Debug("Call IsChosens", "blockNumber", blockNumber.String())
  1002  	c.initData2Cache(state, GET_IM_RE)
  1003  	if _, ok := c.immediateCandidates[nodeId]; ok {
  1004  		return true
  1005  	}
  1006  	if _, ok := c.reserveCandidates[nodeId]; ok {
  1007  		return true
  1008  	}
  1009  	return false
  1010  }
  1011  
  1012  // Getting owner's address of candidate info by nodeId
  1013  func (c *CandidatePool) GetOwner(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) common.Address {
  1014  	log.Debug("Call GetOwner", "blockNumber", blockNumber.String(), "curr nodeId", nodeId.String())
  1015  
  1016  	//c.initData2Cache(state, GET_WIT_IM_RE)
  1017  	c.initData2Cache(state, GET_IM_RE)
  1018  
  1019  	/*pre_can, pre_ok := c.preOriginCandidates[nodeId]
  1020  	or_can, or_ok := c.originCandidates[nodeId]
  1021  	ne_can, ne_ok := c.nextOriginCandidates[nodeId]*/
  1022  
  1023  	im_can, im_ok := c.immediateCandidates[nodeId]
  1024  	re_can, re_ok := c.reserveCandidates[nodeId]
  1025  
  1026  	queue := c.getRefunds(nodeId)
  1027  
  1028  	de_ok := len(queue) != 0
  1029  
  1030  	/*
  1031  	if pre_ok {
  1032  		return pre_can.Owner
  1033  	}
  1034  	if or_ok {
  1035  		return or_can.Owner
  1036  	}
  1037  	if ne_ok {
  1038  		return ne_can.Owner
  1039  	}*/
  1040  	if im_ok {
  1041  		return im_can.Owner
  1042  	}
  1043  	if re_ok {
  1044  		return re_can.Owner
  1045  	}
  1046  	if de_ok {
  1047  		return queue[0].Owner
  1048  	}
  1049  	return common.Address{}
  1050  }
  1051  
  1052  // refund once
  1053  func (c *CandidatePool) RefundBalance(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) error {
  1054  
  1055  	log.Info("Call RefundBalance",  "curr blocknumber", blockNumber.String(), "curr nodeId", nodeId.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber)
  1056  
  1057  	c.initDataByState(state)
  1058  	queueCopy := c.getRefunds(nodeId)
  1059  
  1060  	if len(queueCopy) == 0 {
  1061  		log.Warn("Warning Call RefundBalance the refund is empty")
  1062  		return RefundEmptyErr
  1063  	}
  1064  	// cache
  1065  	// Used for verification purposes, that is, the beneficiary in the pledge refund information of each nodeId should be the same
  1066  	var addr common.Address
  1067  	// Grand total refund amount for one-time
  1068  	amount := big.NewInt(0)
  1069  
  1070  	// cantract balance
  1071  	contractBalance := state.GetBalance(common.CandidatePoolAddr)
  1072  
  1073  
  1074  	PrintObject("Call RefundBalance Into a few RefundBlockNumber Remain Refund Arr ,Before  Calculate  curr blocknumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(queueCopy)) + " ,refunds is", queueCopy)
  1075  
  1076  	// Traverse all refund information belong to this nodeId
  1077  	for index := 0; index < len(queueCopy); index++ {
  1078  		refund := queueCopy[index]
  1079  		sub := new(big.Int).Sub(blockNumber, refund.BlockNumber)
  1080  		log.Info("Check defeat detail on RefundBalance", "nodeId:", nodeId.String(), "curr blocknumber:", blockNumber.String(), "withdraw candidate blocknumber:", refund.BlockNumber.String(), " diff:", sub.String(), "config.RefundBlockNumber", c.refundBlockNumber)
  1081  		if sub.Cmp(new(big.Int).SetUint64(uint64(c.refundBlockNumber))) >= 0 { // allow refund
  1082  
  1083  			queueCopy = append(queueCopy[:index], queueCopy[index+1:]...)
  1084  			index--
  1085  			// add up the refund price
  1086  			amount = new(big.Int).Add(amount, refund.Deposit)
  1087  
  1088  		} else {
  1089  			log.Warn("block height number had mismatch, No refunds allowed on RefundBalance", "curr blocknumber:", blockNumber.String(), "deposit block height", refund.BlockNumber.String(), "nodeId", nodeId.String(), "allowed block interval", c.refundBlockNumber)
  1090  			continue
  1091  		}
  1092  
  1093  		if addr == common.ZeroAddr {
  1094  			addr = refund.Owner
  1095  		} else {
  1096  			if addr != refund.Owner {
  1097  				log.Error("Failed to RefundBalance Different beneficiary addresses under the same node", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "addr1", addr.String(), "addr2", refund.Owner)
  1098  				return CandidateOwnerErr
  1099  			}
  1100  		}
  1101  
  1102  		// check contract account balance
  1103  		if (contractBalance.Cmp(amount)) < 0 {
  1104  			PrintObject("Failed to RefundBalance constract account insufficient balance ,curr blocknumber:" + blockNumber.String() + ",len:=" + fmt.Sprint(len(queueCopy)) + " ,remain refunds is", queueCopy)
  1105  			log.Error("Failed to RefundBalance constract account insufficient balance ", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "contract's balance", state.GetBalance(common.CandidatePoolAddr).String(), "amount", amount.String())
  1106  			return ContractBalanceNotEnoughErr
  1107  		}
  1108  	}
  1109  
  1110  	PrintObject("Call RefundBalance Into a few RefundBlockNumber Remain Refund Arr , After Calculate curr blocknumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(queueCopy)) + " ,refunds is", queueCopy)
  1111  
  1112  	// update the tire
  1113  	if len(queueCopy) == 0 { // full RefundBlockNumber
  1114  		log.Info("Call RefundBalance Into full RefundBlockNumber ...", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String())
  1115  		c.delRefunds(nodeId)
  1116  	} else {
  1117  		log.Info("Call RefundBalance Into a few RefundBlockNumber ...", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String())
  1118  		// If have some remaining, update that
  1119  		c.setRefunds(nodeId, queueCopy)
  1120  	}
  1121  	log.Info("Call RefundBalance to tansfer value:", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "contractAddr", common.CandidatePoolAddr.String(),
  1122  		"owner's addr", addr.String(), "Return the amount to be transferred:", amount.String())
  1123  
  1124  	// sub contract account balance
  1125  	state.SubBalance(common.CandidatePoolAddr, amount)
  1126  	// add owner balace
  1127  	state.AddBalance(addr, amount)
  1128  	log.Debug("Call RefundBalance success ...")
  1129  	return nil
  1130  }
  1131  
  1132  // set elected candidate extra value
  1133  func (c *CandidatePool) SetCandidateExtra(state vm.StateDB, nodeId discover.NodeID, extra string) error {
  1134  
  1135  	log.Info("Call SetCandidateExtra:", "nodeId", nodeId.String(), "extra", extra)
  1136  
  1137  	c.initDataByState(state)
  1138  	im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE)
  1139  
  1140  	for i, can := range im_queue {
  1141  		if can.CandidateId == nodeId {
  1142  			can.Extra = extra
  1143  			im_queue[i] = can
  1144  			c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE)
  1145  			log.Debug("Call SetCandidateExtra SUCCESS !!!!!! ")
  1146  			return nil
  1147  		}
  1148  	}
  1149  
  1150  	re_queue := c.getCandidateQueue(ppos_storage.RESERVE)
  1151  
  1152  	for i, can := range re_queue {
  1153  		if can.CandidateId == nodeId {
  1154  			can.Extra = extra
  1155  			re_queue[i] = can
  1156  			c.setCandidateQueue(re_queue, ppos_storage.RESERVE)
  1157  			log.Debug("Call SetCandidateExtra SUCCESS !!!!!! ")
  1158  			return nil
  1159  		}
  1160  	}
  1161  	return CandidateEmptyErr
  1162  }
  1163  
  1164  // Announce witness
  1165  func (c *CandidatePool) Election(state *state.StateDB, parentHash common.Hash, currBlockNumber *big.Int) ([]*discover.Node, error) {
  1166  	log.Info("Call Election start ...", "current blockNumber", currBlockNumber.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber)
  1167  	c.initData2Cache(state, GET_IM_RE)
  1168  
  1169  	var nodes []*discover.Node
  1170  	var nextQueue types.CandidateQueue
  1171  	var isEmptyElection bool
  1172  
  1173  	if nodeArr, canArr, flag, err := c.election(state, parentHash, currBlockNumber); nil != err {
  1174  		return nil, err
  1175  	} else {
  1176  		nodes, nextQueue, isEmptyElection = nodeArr, canArr, flag
  1177  	}
  1178  
  1179  
  1180  	nodeIds := make([]discover.NodeID, 0)
  1181  
  1182  	for _, can := range nextQueue {
  1183  		// Release lucky ticket TODO
  1184  		if (common.Hash{}) != can.TxHash {
  1185  			if err := tContext.ReturnTicket(state, can.CandidateId, can.TxHash, currBlockNumber); nil != err {
  1186  				log.Error("Failed to ReturnTicket on Election", "current blockNumber", currBlockNumber.String(), "nodeId", can.CandidateId.String(), "ticketId", can.TxHash.String(), "err", err)
  1187  				continue
  1188  			}
  1189  
  1190  			if !isEmptyElection {
  1191  				nodeIds = append(nodeIds, can.CandidateId)
  1192  			}
  1193  		}
  1194  
  1195  		/**
  1196  		handing before  Re-pledging
  1197  		*/
  1198  		/*if flag, nIds := c.repledgCheck(state, can, currBlockNumber); !flag {
  1199  			nodeIds = append(nodeIds, nIds...)
  1200  			// continue handle next one
  1201  			continue
  1202  		}*/
  1203  
  1204  		/*if !isEmptyElection {
  1205  			PrintObject("Election Update Candidate to SetCandidate again ...", *can)
  1206  			// Because you need to first ensure if you are in immediates, and if so, move to reserves
  1207  			if ids := c.setCandidateInfo(state, can.CandidateId, can, currBlockNumber, c.promoteReserveQueue); len(ids) != 0 {
  1208  				nodeIds = append(nodeIds, ids...)
  1209  			}
  1210  		}*/
  1211  
  1212  	}
  1213  
  1214  
  1215  	//var dropTick_nodeIds []discover.NodeID
  1216  
  1217  	// finally update the double queue once
  1218  	if !isEmptyElection && len(nodeIds) != 0 {
  1219  
  1220  		nodeIds = c.electionUpdateCanById(state, currBlockNumber, nodeIds...)
  1221  	}
  1222  
  1223  	// Release the lost list
  1224  	//go ticketPool.DropReturnTicket(state, nodeIds...)
  1225  	if len(nodeIds) > 0 {
  1226  		if err := tContext.DropReturnTicket(state, currBlockNumber, nodeIds...); nil != err {
  1227  			log.Error("Failed to DropReturnTicket on Election ...", "current blockNumber", currBlockNumber.String(), "err", err)
  1228  		}
  1229  	}
  1230  	return nodes, nil
  1231  }
  1232  
  1233  //return params
  1234  // []*discover.Node:  		the cleaned nodeId
  1235  // types.CandidateQueue:	the next witness
  1236  // bool:					is empty election
  1237  // error:					err
  1238  func (c *CandidatePool) election(state *state.StateDB, parentHash common.Hash, blockNumber *big.Int) ([]*discover.Node, types.CandidateQueue, bool, error) {
  1239  
  1240  	imm_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE)
  1241  
  1242  	str := "When Election, to election to sort immediate queue ..."
  1243  	// sort immediate candidates
  1244  	makeCandidateSort(str, state, imm_queue)
  1245  
  1246  	log.Info("When Election, Sorted the immediate array length:", "current blockNumber", blockNumber.String(), "len", len(imm_queue))
  1247  	PrintObject("When Election, Sorted the immediate array: current blockNumber:" + blockNumber.String() + ":", imm_queue)
  1248  	// cache ids
  1249  	immediateIds := make([]discover.NodeID, len(imm_queue))
  1250  	for i, can := range imm_queue {
  1251  		immediateIds[i] = can.CandidateId
  1252  	}
  1253  	PrintObject("When Election, current immediate is: current blockNumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(immediateIds)) + " ,arr is:", immediateIds)
  1254  
  1255  	// a certain number of witnesses in front of the cache
  1256  	var nextIdArr []discover.NodeID
  1257  	// If the number of candidate selected does not exceed the number of witnesses
  1258  	if len(immediateIds) <= int(c.maxChair) {
  1259  		nextIdArr = make([]discover.NodeID, len(immediateIds))
  1260  		copy(nextIdArr, immediateIds)
  1261  
  1262  	} else {
  1263  		// If the number of candidate selected exceeds the number of witnesses, the top N is extracted.
  1264  		nextIdArr = make([]discover.NodeID, c.maxChair)
  1265  		copy(nextIdArr, immediateIds)
  1266  	}
  1267  
  1268  	log.Info("When Election, Selected next round of witnesses Ids's count:", "current blockNumber", blockNumber.String(), "len", len(nextIdArr))
  1269  	PrintObject("When Election, Selected next round of witnesses Ids: current blockNumber:" + blockNumber.String() + ":", nextIdArr)
  1270  
  1271  	nextQueue := make(types.CandidateQueue, len(nextIdArr))
  1272  
  1273  
  1274  	for i, next_canId := range nextIdArr {
  1275  		im_can := c.immediateCandidates[next_canId]
  1276  		// deepCopy
  1277  		can := *im_can
  1278  		nextQueue[i] = &can
  1279  	}
  1280  
  1281  
  1282  	log.Info("When Election, the count of the copy the witness info from immediate:", "current blockNumber", blockNumber.String(), "len", len(nextQueue))
  1283  	PrintObject("When Election, the information of the copy the witness info from immediate: current blockNumber:" + blockNumber.String() + ":", nextQueue)
  1284  
  1285  	// clear all old nextwitnesses information (If it is forked, the next round is no empty.)
  1286  	c.delCandidateQueue(ppos_storage.NEXT)
  1287  
  1288  	nodeArr := make([]*discover.Node, 0)
  1289  	// Check election whether it's empty or not
  1290  	nextQueue, isEmptyElection := c.handleEmptyElection(nextQueue)
  1291  
  1292  	// handle all next witness information
  1293  	for i, can := range nextQueue {
  1294  		// After election to call Selected LuckyTicket TODO
  1295  		luckyId, err := tContext.SelectionLuckyTicket(state, can.CandidateId, parentHash)
  1296  		if nil != err {
  1297  			log.Error("Failed to take luckyId on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "err", err)
  1298  			return nil, nil, false, errors.New(err.Error() + ", nodeId: " + can.CandidateId.String())
  1299  		}
  1300  		log.Debug("Call Election, select lucky ticket Id is", "current blockNumber", blockNumber.String(), "lucky ticket Id", luckyId.Hex())
  1301  		if can.TxHash != luckyId {
  1302  			can.TxHash = luckyId
  1303  			if luckyId == (common.Hash{}) {
  1304  				can.TOwner = common.Address{}
  1305  			} else {
  1306  				if tick := tContext.GetTicket(state, luckyId); nil != tick {
  1307  					can.TOwner = tick.Owner
  1308  				}else {
  1309  					can.TOwner = common.Address{}
  1310  					log.Error("Failed to Gets lucky ticketInfo on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "lucky ticketId", luckyId.Hex())
  1311  				}
  1312  
  1313  			}
  1314  		}
  1315  
  1316  		nextQueue[i] = can
  1317  
  1318  		if node, err := buildWitnessNode(can); nil != err {
  1319  			log.Error("Failed to build Node on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "err", err)
  1320  			continue
  1321  		} else {
  1322  			nodeArr = append(nodeArr, node)
  1323  		}
  1324  	}
  1325  
  1326  	// set next witness
  1327  	c.setCandidateQueue(nextQueue, ppos_storage.NEXT)
  1328  
  1329  	log.Info("When Election,next round witness node count is:", "current blockNumber", blockNumber.String(), "len", len(nodeArr))
  1330  	PrintObject("When Election,next round witness node information is: current blockNumber:" + blockNumber.String() + ":", nodeArr)
  1331  	log.Info("Call Election SUCCESS !!!!!!!", "current blockNumber", blockNumber.String())
  1332  	return nodeArr, nextQueue, isEmptyElection, nil
  1333  }
  1334  
  1335  // return params
  1336  // types.CandidateQueue:the next witness
  1337  // bool: is empty election
  1338  func (c *CandidatePool) handleEmptyElection(nextQueue types.CandidateQueue) (types.CandidateQueue, bool) {
  1339  	// There is'nt empty election
  1340  	if len(nextQueue) != 0 {
  1341  		return nextQueue, false
  1342  	}
  1343  	log.Info("Call Election, current is emptyElection, we take current witness become next witness ...")
  1344  	// empty election
  1345  	// Otherwise, it means that the next witness is nil, then we need to check whether the current round has a witness.
  1346  	// If had, use the current round of witness as the next witness,
  1347  	// [remark]: The pool of rewards need to use the witness can info
  1348  	return c.getCandidateQueue(ppos_storage.CURRENT).DeepCopy(), true
  1349  }
  1350  
  1351  /*// The operation before re-setcandiate after election
  1352  // false: direct get out
  1353  // true: pass
  1354  func (c *CandidatePool) repledgCheck(state vm.StateDB, can *types.Candidate, currentBlockNumber *big.Int) (bool, []discover.NodeID) {
  1355  
  1356  	nodeIds := make([]discover.NodeID, 0)
  1357  	// If the verification does not pass,
  1358  	// it will drop the list directly,
  1359  	// but before the list is dropped,
  1360  	// it needs to determine which queue was in the queue.
  1361  	if _, ok := c.checkDeposit(state, can, true); !ok {
  1362  		log.Warn("Failed to checkDeposit on preElectionReset", "nodeId", can.CandidateId.String(), " err", DepositLowErr)
  1363  		var del int // del: 1 del immiedate; 2  del reserve
  1364  		if _, ok := c.immediateCandidates[can.CandidateId]; ok {
  1365  			del = IS_IMMEDIATE
  1366  		}
  1367  		if _, ok := c.reserveCandidates[can.CandidateId]; ok {
  1368  			del = IS_RESERVE
  1369  		}
  1370  
  1371  		delCanFunc := func(flag int) {
  1372  			queue := c.getCandidateQueue(flag)
  1373  
  1374  			for i := 0; i < len(queue); i++ {
  1375  				ca := queue[i]
  1376  				if ca.CandidateId == can.CandidateId {
  1377  					queue = append(queue[:i], queue[i+1:]...)
  1378  					break
  1379  				}
  1380  			}
  1381  
  1382  			c.setCandidateQueue(queue, flag)
  1383  			deposit, _ := new(big.Int).SetString(can.Deposit.String(), 10)
  1384  			refund := &types.CandidateRefund{
  1385  				Deposit:     deposit,
  1386  				BlockNumber: big.NewInt(currentBlockNumber.Int64()),
  1387  				Owner:       can.Owner,
  1388  			}
  1389  			c.setRefund(can.CandidateId, refund)
  1390  			nodeIds = append(nodeIds, can.CandidateId)
  1391  
  1392  			*//*nIds := c.promoteReserveQueue(state, currentBlockNumber)
  1393  
  1394  			if len(nIds) != 0 {
  1395  				nodeIds = append(nodeIds, nIds...)
  1396  			}*//*
  1397  
  1398  			c.promoteReserveQueue(state, currentBlockNumber)
  1399  		}
  1400  		if del == IS_IMMEDIATE {
  1401  			*//** first delete this can on immediates *//*
  1402  			delCanFunc(ppos_storage.IMMEDIATE)
  1403  			return false, nodeIds
  1404  		} else {
  1405  			*//** first delete this can on reserves *//*
  1406  			delCanFunc(ppos_storage.RESERVE)
  1407  			return false, nodeIds
  1408  		}
  1409  	}
  1410  	return true, nodeIds
  1411  }*/
  1412  
  1413  // switch next witnesses to current witnesses
  1414  func (c *CandidatePool) Switch(state *state.StateDB, blockNumber *big.Int) bool {
  1415  	log.Info("Call Switch start ...", "blockNumber", blockNumber.String())
  1416  	c.initDataByState(state)
  1417  	curr_queue := c.getCandidateQueue(ppos_storage.CURRENT)
  1418  	next_queue := c.getCandidateQueue(ppos_storage.NEXT)
  1419  
  1420  	// set previous witness
  1421  	c.setCandidateQueue(curr_queue, ppos_storage.PREVIOUS)
  1422  
  1423  	// set current witness
  1424  	c.setCandidateQueue(next_queue, ppos_storage.CURRENT)
  1425  
  1426  	// set next witness
  1427  	c.delCandidateQueue(ppos_storage.NEXT)
  1428  
  1429  	log.Info("Call Switch SUCCESS !!!!!!!")
  1430  	return true
  1431  }
  1432  
  1433  // Getting nodes of witnesses
  1434  // flag:
  1435  // -1: the previous round of witnesses
  1436  // 0: the current round of witnesses
  1437  // 1: the next round of witnesses
  1438  func (c *CandidatePool) GetWitness(state *state.StateDB, flag int, blockNumber *big.Int) ([]*discover.Node, error) {
  1439  	log.Debug("Call GetWitness", "blockNumber", blockNumber.String(), "flag", strconv.Itoa(flag))
  1440  	c.initDataByState(state)
  1441  	var queue types.CandidateQueue
  1442  
  1443  	if flag == PREVIOUS_C {
  1444  		queue = c.getCandidateQueue(ppos_storage.PREVIOUS)
  1445  	} else if flag == CURRENT_C {
  1446  		queue = c.getCandidateQueue(ppos_storage.CURRENT)
  1447  	} else if flag == NEXT_C {
  1448  		queue = c.getCandidateQueue(ppos_storage.NEXT)
  1449  	}
  1450  
  1451  	arr := make([]*discover.Node, 0)
  1452  	for _, can := range queue {
  1453  		if node, err := buildWitnessNode(can); nil != err {
  1454  			log.Error("Failed to build Node on GetWitness", "nodeId", can.CandidateId.String(), "err", err)
  1455  			return nil, err
  1456  		} else {
  1457  			arr = append(arr, node)
  1458  		}
  1459  	}
  1460  	return arr, nil
  1461  }
  1462  
  1463  // Getting previous and current and next witnesses
  1464  func (c *CandidatePool) GetAllWitness(state *state.StateDB, blockNumber *big.Int) ([]*discover.Node, []*discover.Node, []*discover.Node, error) {
  1465  	log.Debug("Call GetAllWitness ...", "blockNumber", blockNumber.String())
  1466  	c.initDataByState(state)
  1467  	loadFunc := func(title string, flag int) ([]*discover.Node, error) {
  1468  		queue := c.getCandidateQueue(flag)
  1469  		arr := make([]*discover.Node, 0)
  1470  		for _, can := range queue {
  1471  			if node, err := buildWitnessNode(can); nil != err {
  1472  				log.Error("Failed to build Node on Get "+title+" Witness", "nodeId", can.CandidateId.String(), "err", err)
  1473  				return nil, err
  1474  			} else {
  1475  				arr = append(arr, node)
  1476  			}
  1477  		}
  1478  		return arr, nil
  1479  	}
  1480  
  1481  	preArr, curArr, nextArr := make([]*discover.Node, 0), make([]*discover.Node, 0), make([]*discover.Node, 0)
  1482  
  1483  	type result struct {
  1484  		Type  int // -1: previous; 0: current; 1: next
  1485  		Err   error
  1486  		nodes []*discover.Node
  1487  	}
  1488  	var wg sync.WaitGroup
  1489  	wg.Add(3)
  1490  	resCh := make(chan *result, 3)
  1491  
  1492  	go func() {
  1493  		res := new(result)
  1494  		res.Type = PREVIOUS_C
  1495  		if nodes, err := loadFunc("previous", ppos_storage.PREVIOUS); nil != err {
  1496  			res.Err = err
  1497  		} else {
  1498  			res.nodes = nodes
  1499  		}
  1500  		resCh <- res
  1501  		wg.Done()
  1502  	}()
  1503  	go func() {
  1504  		res := new(result)
  1505  		res.Type = CURRENT_C
  1506  		if nodes, err := loadFunc("current", ppos_storage.CURRENT); nil != err {
  1507  			res.Err = err
  1508  		} else {
  1509  			res.nodes = nodes
  1510  		}
  1511  		resCh <- res
  1512  		wg.Done()
  1513  	}()
  1514  	go func() {
  1515  		res := new(result)
  1516  		res.Type = NEXT_C
  1517  		if nodes, err := loadFunc("next", ppos_storage.NEXT); nil != err {
  1518  			res.Err = err
  1519  		} else {
  1520  			res.nodes = nodes
  1521  		}
  1522  		resCh <- res
  1523  		wg.Done()
  1524  	}()
  1525  	wg.Wait()
  1526  	close(resCh)
  1527  	for res := range resCh {
  1528  		if nil != res.Err {
  1529  			return nil, nil, nil, res.Err
  1530  		}
  1531  		switch res.Type {
  1532  		case PREVIOUS_C:
  1533  			preArr = res.nodes
  1534  		case CURRENT_C:
  1535  			curArr = res.nodes
  1536  		case NEXT_C:
  1537  			nextArr = res.nodes
  1538  		default:
  1539  			continue
  1540  		}
  1541  	}
  1542  	return preArr, curArr, nextArr, nil
  1543  }
  1544  
  1545  // Getting can by witnesses
  1546  // flag:
  1547  // -1: 		previous round
  1548  // 0:		current round
  1549  // 1: 		next round
  1550  func (c *CandidatePool) GetWitnessCandidate(state vm.StateDB, nodeId discover.NodeID, flag int, blockNumber *big.Int) *types.Candidate {
  1551  
  1552  	log.Debug("Call GetWitnessCandidate", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "flag", flag)
  1553  
  1554  	c.initDataByState(state)
  1555  	switch flag {
  1556  	case PREVIOUS_C:
  1557  
  1558  		for _, can := range c.getCandidateQueue(ppos_storage.PREVIOUS) {
  1559  			if can.CandidateId == nodeId {
  1560  				return can
  1561  			}
  1562  		}
  1563  		log.Warn("Call GetWitnessCandidate, can no exist in previous witnesses ", "nodeId", nodeId.String())
  1564  		return nil
  1565  
  1566  	case CURRENT_C:
  1567  
  1568  		for _, can := range c.getCandidateQueue(ppos_storage.CURRENT) {
  1569  			if can.CandidateId == nodeId {
  1570  				return can
  1571  			}
  1572  		}
  1573  		log.Warn("Call GetWitnessCandidate, can no exist in current witnesses ", "nodeId", nodeId.String())
  1574  		return nil
  1575  
  1576  	case NEXT_C:
  1577  
  1578  		for _, can := range c.getCandidateQueue(ppos_storage.NEXT) {
  1579  			if can.CandidateId == nodeId {
  1580  				return can
  1581  			}
  1582  		}
  1583  		log.Warn("Call GetWitnessCandidate, can no exist in next witnesses ", "nodeId", nodeId.String())
  1584  		return nil
  1585  
  1586  	default:
  1587  		log.Error("Failed to found can on GetWitnessCandidate, flag is invalid", "flag", flag)
  1588  		return nil
  1589  	}
  1590  }
  1591  
  1592  func (c *CandidatePool) GetRefundInterval(blockNumber *big.Int) uint32 {
  1593  	log.Info("Call GetRefundInterval", "blockNumber", blockNumber.String(), "RefundBlockNumber", c.refundBlockNumber)
  1594  	return c.refundBlockNumber
  1595  }
  1596  
  1597  // According to the nodeId to ensure the current candidate's stay
  1598  func (c *CandidatePool) UpdateElectedQueue(state vm.StateDB, currBlockNumber *big.Int, nodeIds ...discover.NodeID) error {
  1599  	log.Info("Call UpdateElectedQueue start ...", "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber)
  1600  	arr := c.updateQueue(state, currBlockNumber, nodeIds...)
  1601  	log.Info("Call UpdateElectedQueue SUCCESS !!!!!!!!! ")
  1602  	//go ticketPool.DropReturnTicket(state, ids...)
  1603  	if len(arr) > 0 {
  1604  		return tContext.DropReturnTicket(state, currBlockNumber, arr...)
  1605  	}
  1606  	return nil
  1607  }
  1608  
  1609  func (c *CandidatePool) updateQueue(state vm.StateDB, currentBlockNumber *big.Int, nodeIds ...discover.NodeID) []discover.NodeID {
  1610  	log.Info("Call UpdateElectedQueue Update the Campaign queue Start ...")
  1611  	PrintObject("Call UpdateElectedQueue input param's nodeIds len:= " + fmt.Sprint(len(nodeIds)) + " ,is:", nodeIds)
  1612  	if len(nodeIds) == 0 {
  1613  		log.Debug("UpdateElectedQueue FINISH, input param's nodeIds is empty !!!!!!!!!!")
  1614  		return nil
  1615  	}
  1616  
  1617  	c.initData2Cache(state, GET_IM_RE)
  1618  
  1619  
  1620  	/**
  1621  	delete can by queue
  1622  	 */
  1623  	delCanFromQueueFunc := func(title string, nodeId discover.NodeID, queue types.CandidateQueue, flag int)  types.CandidateQueue {
  1624  
  1625  
  1626  		queueCopy := make(types.CandidateQueue, len(queue))
  1627  		copy(queueCopy, queue)
  1628  
  1629  		log.Debug("Call UpdateElectedQueue, Before delete the can by old queue, the queue is " + title, "queue len", len(queueCopy), "nodeId", nodeId.String())
  1630  
  1631  		for i, can := range queueCopy {
  1632  			if nodeId == can.CandidateId {
  1633  				queueCopy = append(queueCopy[:i], queueCopy[i+1:]...)
  1634  				break
  1635  			}
  1636  		}
  1637  
  1638  		PrintObject("Call UpdateElectedQueue, After delete the can by old queue, the queue is " + title + ", queue len:" + fmt.Sprint(len(queueCopy)) + " ,the remain queue is", queueCopy)
  1639  
  1640  		if len(queueCopy) != 0 {
  1641  			c.setCandidateQueue(queueCopy, flag)
  1642  		}else {
  1643  			c.delCandidateQueue(flag)
  1644  		}
  1645  
  1646  		return queueCopy
  1647  	}
  1648  
  1649  
  1650  	/**
  1651  	handler the Reserve queue
  1652  	 */
  1653  	handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID {
  1654  
  1655  		queueCopy := make(types.CandidateQueue, len(re_queue))
  1656  		copy(queueCopy, re_queue)
  1657  
  1658  		PrintObject("Call UpdateElectedQueue, handleReserveFunc, Before update the reserve len is " + fmt.Sprint(len(queueCopy)) + ", config.maxCount:" + fmt.Sprint(c.maxCount) + " , the queue is", queueCopy)
  1659  
  1660  		str := "Call UpdateElectedQueue, handleReserveFunc, o sort reserve queue ..."
  1661  		makeCandidateSort(str, state, queueCopy)
  1662  		if len(queueCopy) > int(c.maxCount) {
  1663  			// Intercepting the lost candidates to tmpArr
  1664  			tmpArr := (queueCopy)[c.maxCount:]
  1665  			// qualified elected candidates
  1666  			queueCopy = (queueCopy)[:c.maxCount]
  1667  
  1668  			// cache
  1669  			nodeIdQueue := make([]discover.NodeID, 0)
  1670  
  1671  			// handle tmpArr
  1672  			for _, tmpCan := range tmpArr {
  1673  				deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10)
  1674  				refund := &types.CandidateRefund{
  1675  					Deposit:     deposit,
  1676  					BlockNumber: big.NewInt(currentBlockNumber.Int64()),
  1677  					Owner:       tmpCan.Owner,
  1678  				}
  1679  
  1680  				c.setRefund(tmpCan.CandidateId, refund)
  1681  				nodeIdQueue = append(nodeIdQueue, tmpCan.CandidateId)
  1682  
  1683  				delete(c.reserveCandidates, tmpCan.CandidateId)
  1684  
  1685  			}
  1686  
  1687  
  1688  
  1689  			PrintObject("Call UpdateElectedQueue, handleReserveFunc, After update the reserve len is " + fmt.Sprint(len(queueCopy)) + " , the queue is", queueCopy)
  1690  
  1691  			c.setCandidateQueue(queueCopy, ppos_storage.RESERVE)
  1692  
  1693  			return nodeIdQueue
  1694  		}else {
  1695  
  1696  			PrintObject("Call UpdateElectedQueue, handleReserveFunc, After update the reserve len is " + fmt.Sprint(len(queueCopy)) + " , the queue is", queueCopy)
  1697  
  1698  			c.setCandidateQueue(queueCopy, ppos_storage.RESERVE)
  1699  			return nil
  1700  		}
  1701  	}
  1702  
  1703  	/**
  1704  	This function handles Immediate queues and Reserve queues
  1705  	for moving into the opposing queue
  1706  	*/
  1707  	workFunc := func(oldQueueFlag, newQueueFlag int, can *types.Candidate) []discover.NodeID {
  1708  		old_queue := c.getCandidateQueue(oldQueueFlag)
  1709  		new_queue := c.getCandidateQueue(newQueueFlag)
  1710  
  1711  		//old_queueCopy := make(types.CandidateQueue, len(old_queue))
  1712  		//new_queueCopy := make(types.CandidateQueue, len(new_queue))
  1713  
  1714  		nodeIdQueue := make([]discover.NodeID, 0)
  1715  
  1716  		/**
  1717  		immediate move to reserve
  1718  		*/
  1719  		if oldQueueFlag == ppos_storage.IMMEDIATE {
  1720  
  1721  			log.Debug("Call UpdateElectedQueue, workFunc the old queue is immediate", "nodeId", can.CandidateId.String())
  1722  
  1723  			// delete immediate
  1724  			delCanFromQueueFunc("imms", can.CandidateId, old_queue, oldQueueFlag)
  1725  			delete(c.immediateCandidates, can.CandidateId)
  1726  
  1727  
  1728  			// input reserve
  1729  			new_queue = append(new_queue, can)
  1730  			if nodeIdArr := handleReserveFunc(new_queue); len(nodeIdArr) != 0 {
  1731  				nodeIdQueue = append(nodeIdQueue, nodeIdArr...)
  1732  			}
  1733  			return nodeIdQueue
  1734  		} else {
  1735  
  1736  			log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve", "nodeId", can.CandidateId.String())
  1737  
  1738  			/**
  1739  			reserve move to immediate
  1740  			*/
  1741  			// delete reserve
  1742  			old_queue = delCanFromQueueFunc("res", can.CandidateId, old_queue, oldQueueFlag)
  1743  			delete(c.reserveCandidates, can.CandidateId)
  1744  
  1745  			str := "Call UpdateElectedQueue, workFunc to sort immediate queue ..."
  1746  			// input immediate
  1747  			new_queue = append(new_queue, can)
  1748  			makeCandidateSort(str, state, new_queue)
  1749  
  1750  			var inRes bool
  1751  			if len(new_queue) > int(c.maxCount) {
  1752  				// Intercepting the lost candidates to tmpArr
  1753  				tmpArr := (new_queue)[c.maxCount:]
  1754  				// qualified elected candidates
  1755  				new_queue = (new_queue)[:c.maxCount]
  1756  
  1757  				inRes = true
  1758  				// reenter into reserve
  1759  				old_queue = append(old_queue, tmpArr...)
  1760  			}
  1761  
  1762  			log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate", "len", len(new_queue), "config.maxCount", c.maxCount)
  1763  			PrintObject("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate", new_queue)
  1764  
  1765  			// update immediate
  1766  			c.setCandidateQueue(new_queue, ppos_storage.IMMEDIATE)
  1767  			if inRes {
  1768  
  1769  				log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate, had add reserve", "reserver len", len(old_queue))
  1770  
  1771  				if nodeIdArr := handleReserveFunc(old_queue); len(nodeIdArr) != 0 {
  1772  					nodeIdQueue = append(nodeIdQueue, nodeIdArr...)
  1773  				}
  1774  			}
  1775  			return nodeIdQueue
  1776  		}
  1777  
  1778  	}
  1779  
  1780  
  1781  	resNodeIds := make([]discover.NodeID, 0)
  1782  
  1783  	/**
  1784  	########
  1785  	Real Handle Can queue
  1786  	########
  1787  	*/
  1788  	for _, nodeId := range nodeIds {
  1789  
  1790  		tcount := c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId))
  1791  
  1792  		switch c.checkExist(nodeId) {
  1793  
  1794  		case IS_IMMEDIATE:
  1795  			log.Debug("Call UpdateElectedQueue The current nodeId was originally in the Immediate ...")
  1796  			can := c.immediateCandidates[nodeId]
  1797  
  1798  			if !tcount {
  1799  
  1800  				log.Debug("Call UpdateElectedQueue, the node will from immediate to reserve ...", "nodeId", nodeId.String())
  1801  				if ids := workFunc(ppos_storage.IMMEDIATE, ppos_storage.RESERVE, can); len(ids) != 0 {
  1802  					resNodeIds = append(resNodeIds, ids...)
  1803  				}
  1804  			}
  1805  
  1806  		case IS_RESERVE:
  1807  			log.Debug("Call UpdateElectedQueue The current nodeId was originally in the Reserve ...")
  1808  			can := c.reserveCandidates[nodeId]
  1809  
  1810  			if tcount {
  1811  
  1812  				log.Debug("Call UpdateElectedQueue, the node will from reserve to immediate ...", "nodeId", nodeId.String())
  1813  				if ids := workFunc(ppos_storage.RESERVE, ppos_storage.IMMEDIATE, can); len(ids) != 0 {
  1814  					resNodeIds = append(resNodeIds, ids...)
  1815  				}
  1816  			}
  1817  
  1818  		default:
  1819  			continue
  1820  		}
  1821  	}
  1822  
  1823  	// promoteReserve queues
  1824  	c.promoteReserveQueue(state, currentBlockNumber)
  1825  
  1826  	return resNodeIds
  1827  }
  1828  
  1829  func (c *CandidatePool) checkFirstThreshold(can *types.Candidate) bool {
  1830  	var exist bool
  1831  	if _, ok := c.immediateCandidates[can.CandidateId]; ok {
  1832  		exist = true
  1833  	}
  1834  
  1835  	if _, ok := c.reserveCandidates[can.CandidateId]; ok {
  1836  		exist = true
  1837  	}
  1838  
  1839  	if !exist && can.Deposit.Cmp(c.threshold) < 0 {
  1840  		return false
  1841  	}
  1842  	return true
  1843  }
  1844  
  1845  // false: invalid deposit
  1846  // true:  pass
  1847  //func (c *CandidatePool) checkDeposit(state vm.StateDB, can *types.Candidate, holdself bool) (bool, bool) {
  1848  //
  1849  //
  1850  //
  1851  //
  1852  //
  1853  //	// Number of vote ticket by nodes
  1854  //	tcount := c.checkTicket(tContext.GetCandidateTicketCount(state, can.CandidateId))
  1855  //
  1856  //	// if self have already exist:
  1857  //	// b、no first pledge: x >= self * 110%
  1858  //	//
  1859  //	// if the pool is full:(Only reserve pool)
  1860  //	// c、x > last * 110 %
  1861  //
  1862  //
  1863  //	compareFunc := func(target, current *types.Candidate, logA, logB string) (bool, bool) {
  1864  //		lastDeposit := target.Deposit
  1865  //
  1866  //		// y = 100 + x
  1867  //		percentage := new(big.Int).Add(big.NewInt(100), big.NewInt(int64(c.depositLimit)))
  1868  //		// z = old * y
  1869  //		tmp := new(big.Int).Mul(lastDeposit, percentage)
  1870  //		// z/100 == old * (100 + x) / 100 == old * (y%)
  1871  //		tmp = new(big.Int).Div(tmp, big.NewInt(100))
  1872  //		if can.Deposit.Cmp(tmp) < 0 {
  1873  //			// If last is self and holdslef flag is true
  1874  //			// we must return true (Keep self on staying in the original queue)
  1875  //			if holdself && can.CandidateId == target.CandidateId {
  1876  //				log.Debug(logA + tmp.String())
  1877  //				return tcount, true
  1878  //			}
  1879  //			log.Debug(logB + tmp.String())
  1880  //			return tcount, false
  1881  //		}
  1882  //		return tcount, true
  1883  //	}
  1884  //
  1885  //
  1886  //	//var queueFlag int
  1887  //	var storageMap candidateStorage
  1888  //
  1889  //	if _, ok := c.immediateCandidates[can.CandidateId]; ok {
  1890  //		//queueFlag = IS_IMMEDIATE
  1891  //		storageMap = c.immediateCandidates
  1892  //	}
  1893  //	if _, ok := c.reserveCandidates[can.CandidateId]; ok {
  1894  //		//queueFlag = IS_RESERVE
  1895  //		storageMap = c.reserveCandidates
  1896  //	}
  1897  //
  1898  //	/*
  1899  //	If the current number of votes achieving the conditions for entering the immediate queue
  1900  //	*/
  1901  //	if tcount {
  1902  //
  1903  //		// if it already exist immediate
  1904  //		// compare old self deposit
  1905  //		if old_self, ok := storageMap[can.CandidateId]; ok {
  1906  //
  1907  //			logA := `The can already exist in queue, and holdslef is true, Keep self on staying in the original queue, current can nodeId:` + can.CandidateId.String() +
  1908  //				` the length of current queue:` + fmt.Sprint(len(storageMap)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) +
  1909  //				` current can's Deposit: ` + can.Deposit.String() + ` 110% of it old_self in the queue: `
  1910  //
  1911  //			logB := `The can already exist in queue, and holdslef is true,and the current can's Deposit is less than 110% of the it old self in the queue.` +
  1912  //				`the length of current queue:` + fmt.Sprint(len(storageMap)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` +
  1913  //				can.Deposit.String() + ` 110% of it old_self in the queue: `
  1914  //
  1915  //			return compareFunc(old_self, can, logA, logB)
  1916  //		}
  1917  //
  1918  //	}
  1919  //
  1920  //	/**
  1921  //	If the can will enter the reserve pool
  1922  //	*/
  1923  //
  1924  //	if !tcount {
  1925  //
  1926  //		reserveArr := c.storage.GetCandidateQueue(ppos_storage.RESERVE)
  1927  //
  1928  //		// Is first pledge and the reserve pool is full
  1929  //		if _, ok := storageMap[can.CandidateId]; !ok && uint32(len(reserveArr)) == c.maxCount {
  1930  //			last := reserveArr[len(reserveArr)-1]
  1931  //
  1932  //			logA := `The reserve pool is full, and last is self and holdslef is true, Keep self on staying in the original queue, the length of current reserve pool: ` +
  1933  //				fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can nodeId: ` + can.CandidateId.String() + ` last can nodeId: ` +
  1934  //				last.CandidateId.String() + ` current can's Deposit: ` + can.Deposit.String() + ` 110% of the last can in the reserve pool:`
  1935  //
  1936  //			logB := `The reserve pool is full,and the current can's Deposit is less than 110% of the last can in the reserve pool., the length of current reserve pool:` +
  1937  //				fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` + can.Deposit.String() +
  1938  //				`110% of the last can in the reserve pool:`
  1939  //
  1940  //			return compareFunc(last, can, logA, logB)
  1941  //
  1942  //		} else if old_self, ok := storageMap[can.CandidateId]; ok { // Is'nt first pledge
  1943  //			logA := `The can already exist in reserve, and holdslef is true, Keep self on staying in the original queue, current can nodeId:` + can.CandidateId.String() +
  1944  //				` the length of current reserve pool:` + fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) +
  1945  //				` current can's Deposit: ` + can.Deposit.String() + ` 110% of it old_self in the reserve pool: `
  1946  //
  1947  //			logB := `The can already exist in reserve, and holdslef is true,and the current can's Deposit is less than 110% of the it old self in the reserve pool.` +
  1948  //				`the length of current reserve pool:` + fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` +
  1949  //				can.Deposit.String() + ` 110% of it old_self in the reserve pool: `
  1950  //
  1951  //			return compareFunc(old_self, can, logA, logB)
  1952  //		}
  1953  //	}
  1954  //	return tcount, true
  1955  //}
  1956  
  1957  func (c *CandidatePool) checkDeposit (can *types.Candidate) bool {
  1958  
  1959  	im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE)
  1960  
  1961  	re_queue := c.getCandidateQueue(ppos_storage.RESERVE)
  1962  
  1963  	if len(im_queue) == int(c.maxCount) && len(re_queue) == int(c.maxCount) {
  1964  		last := re_queue[len(re_queue)-1]
  1965  
  1966  		lastDeposit := last.Deposit
  1967  
  1968  		// y = 100 + x
  1969  		percentage := new(big.Int).Add(big.NewInt(100), big.NewInt(int64(c.depositLimit)))
  1970  		// z = old * y
  1971  		tmp := new(big.Int).Mul(lastDeposit, percentage)
  1972  		// z/100 == old * (100 + x) / 100 == old * (y%)
  1973  		tmp = new(big.Int).Div(tmp, big.NewInt(100))
  1974  		if can.Deposit.Cmp(tmp) < 0 {
  1975  			log.Debug("The current can's Deposit is less than 110% of the last can in the reserve queue.", "current can Deposit", can.Deposit.String(), "last can Deposit", last.Deposit.String(), "the target Deposit", tmp.String())
  1976  			return false
  1977  		}
  1978  	}
  1979  	return true
  1980  }
  1981  
  1982  
  1983  func (c *CandidatePool) checkWithdraw(source, price *big.Int) error {
  1984  	// y = old * x
  1985  	percentage := new(big.Int).Mul(source, big.NewInt(int64(c.depositLimit)))
  1986  	// y/100 == old * (x/100) == old * x%
  1987  	tmp := new(big.Int).Div(percentage, big.NewInt(100))
  1988  	if price.Cmp(tmp) < 0 {
  1989  		log.Debug("When withdrawing the refund, the amount of the current can't be refunded is less than 10% of the remaining amount of self:", "The current amount of can want to refund:", price.String(), "current Can own deposit remaining amount:", tmp.String())
  1990  		return WithdrawLowErr
  1991  	}
  1992  	return nil
  1993  }
  1994  
  1995  // 0: empty
  1996  // 1: in immediates
  1997  // 2: in reserves
  1998  func (c *CandidatePool) checkExist(nodeId discover.NodeID) int {
  1999  	log.Info("Check which queue the current nodeId originally belongs to:", "nodeId", nodeId.String())
  2000  	if _, ok := c.immediateCandidates[nodeId]; ok {
  2001  		log.Info("The current nodeId originally belonged to the immediate queue ...", "nodeId", nodeId.String())
  2002  		return IS_IMMEDIATE
  2003  	}
  2004  	if _, ok := c.reserveCandidates[nodeId]; ok {
  2005  		log.Info("The current nodeId originally belonged to the reserve queue ...", "nodeId", nodeId.String())
  2006  		return IS_RESERVE
  2007  	}
  2008  	log.Info("The current nodeId does not belong to any queue ...", "nodeId", nodeId.String())
  2009  	return IS_LOST
  2010  }
  2011  
  2012  func (c *CandidatePool) checkTicket(t_count uint32) bool {
  2013  	log.Debug("Compare the current candidate’s votes to:", "t_count", t_count, "the allowed limit of config:", c.allowed)
  2014  	if t_count >= c.allowed {
  2015  		log.Debug(" The current candidate’s votes are in line with the immediate pool....")
  2016  		return true
  2017  	}
  2018  	log.Debug("Not eligible to enter the immediate pool ...")
  2019  	return false
  2020  }
  2021  
  2022  func (c *CandidatePool) getCandidate(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) *types.Candidate {
  2023  	log.Debug("Call GetCandidate", "blockNumber", blockNumber.String(), "nodeId", nodeId.String())
  2024  	c.initData2Cache(state, GET_IM_RE)
  2025  	if candidatePtr, ok := c.immediateCandidates[nodeId]; ok {
  2026  		PrintObject("Call GetCandidate return immediate:", *candidatePtr)
  2027  		return candidatePtr
  2028  	}
  2029  	if candidatePtr, ok := c.reserveCandidates[nodeId]; ok {
  2030  		PrintObject("Call GetCandidate return reserve:", *candidatePtr)
  2031  		return candidatePtr
  2032  	}
  2033  	return nil
  2034  }
  2035  
  2036  func (c *CandidatePool) getCandidates(state vm.StateDB, blockNumber *big.Int, nodeIds ...discover.NodeID) types.CandidateQueue {
  2037  	log.Debug("Call GetCandidates...", "blockNumber", blockNumber.String())
  2038  	c.initData2Cache(state, GET_IM_RE)
  2039  	canArr := make(types.CandidateQueue, 0)
  2040  	tem := make(map[discover.NodeID]struct{}, 0)
  2041  	for _, nodeId := range nodeIds {
  2042  		if _, ok := tem[nodeId]; ok {
  2043  			continue
  2044  		}
  2045  		if candidatePtr, ok := c.immediateCandidates[nodeId]; ok {
  2046  			canArr = append(canArr, candidatePtr)
  2047  			tem[nodeId] = struct{}{}
  2048  		}
  2049  		if _, ok := tem[nodeId]; ok {
  2050  			continue
  2051  		}
  2052  		if candidatePtr, ok := c.reserveCandidates[nodeId]; ok {
  2053  			canArr = append(canArr, candidatePtr)
  2054  			tem[nodeId] = struct{}{}
  2055  		}
  2056  	}
  2057  	return canArr
  2058  }
  2059  
  2060  func (c *CandidatePool) MaxChair() uint32 {
  2061  	return c.maxChair
  2062  }
  2063  
  2064  func (c *CandidatePool) MaxCount() uint32 {
  2065  	return c.maxCount
  2066  }
  2067  
  2068  // TODO
  2069  func (c *CandidatePool) promoteReserveQueue(state vm.StateDB, currentBlockNumber *big.Int) /*[]discover.NodeID */ {
  2070  
  2071  	log.Debug("Call promoteReserveQueue Start ...", "blockNumber", currentBlockNumber.String())
  2072  
  2073  	// Violence traverses the pools
  2074  	im_queue := c.storage.GetCandidateQueue(ppos_storage.IMMEDIATE)
  2075  	re_queue := c.storage.GetCandidateQueue(ppos_storage.RESERVE)
  2076  
  2077  	PrintObject("Call promoteReserveQueue Before the immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue)
  2078  	PrintObject("Call promoteReserveQueue Before the reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue)
  2079  
  2080  
  2081  	// current ticket price
  2082  	ticket_price := tContext.GetTicketPrice(state)
  2083  
  2084  
  2085  	//for i, can := range re_queue {
  2086  	for i := 0; i < len(re_queue); i++ {
  2087  
  2088  		// current re can
  2089  		can := re_queue[i]
  2090  
  2091  		log.Debug("Call promoteReserveQueue for range , Current reserve id", "blockNumber", currentBlockNumber.String(), "nodeId", can.CandidateId.String())
  2092  
  2093  		re_tCount := tContext.GetCandidateTicketCount(state, can.CandidateId)
  2094  		if re_tCount < c.allowed {
  2095  			continue
  2096  		}
  2097  
  2098  		// check immediate
  2099  		// if the immediate queue is full
  2100  		// We can take the immediate last can and current reserve can compare
  2101  		if uint32(len(im_queue)) >= c.maxCount {
  2102  
  2103  			// last im can
  2104  			last := im_queue[len(im_queue)-1]
  2105  			last_tCount := tContext.GetCandidateTicketCount(state, last.CandidateId)
  2106  
  2107  			last_tmoney := new(big.Int).Mul(big.NewInt(int64(last_tCount)), ticket_price)
  2108  			last_money := new(big.Int).Add(last.Deposit, last_tmoney)
  2109  
  2110  			// current re can
  2111  			re_tmoney := new(big.Int).Mul(big.NewInt(int64(re_tCount)), ticket_price)
  2112  			re_money := new(big.Int).Add(can.Deposit, re_tmoney)
  2113  
  2114  			// Terminate the cycle comparison.
  2115  			// When current re can's money is
  2116  			// less than the last one in the im queue
  2117  			if types.CompareCan(can, last, re_money, last_money) < 0 {
  2118  				break
  2119  			}
  2120  
  2121  
  2122  			// into immediate queue If match condition
  2123  			im_queue = append(im_queue, can)
  2124  			re_queue = append(re_queue[:i], re_queue[i+1:]...)
  2125  			i--
  2126  		} else {
  2127  			// direct - into immediate queue
  2128  			im_queue = append(im_queue, can)
  2129  			re_queue = append(re_queue[:i], re_queue[i+1:]...)
  2130  			i--
  2131  		}
  2132  	}
  2133  
  2134  
  2135  	str := "Call promoteReserveQueue to sort the new immediate queue ..."
  2136  	// sort immediate
  2137  	makeCandidateSort(str, state, im_queue)
  2138  
  2139  	//nodeIds := make([]discover.NodeID, 0)
  2140  
  2141  	var addRe_queue types.CandidateQueue
  2142  
  2143  
  2144  	// Cut off the immediate queue
  2145  	if len(im_queue) > int(c.maxCount) {
  2146  		// Intercepting the lost candidates to tmpArr
  2147  		tempArr := (im_queue)[c.maxCount:]
  2148  		// qualified elected candidates
  2149  		im_queue = (im_queue)[:c.maxCount]
  2150  
  2151  
  2152  
  2153  
  2154  		//newRe_queue = make(types.CandidateQueue, 0)
  2155  		addRe_queue = make(types.CandidateQueue, len(tempArr))
  2156  
  2157  		// handle tmpArr
  2158  		for i, tmpCan := range tempArr {
  2159  
  2160  			addRe_queue[i] = tmpCan
  2161  		}
  2162  	}
  2163  
  2164  	// Sets the new immediate queue
  2165  	c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE)
  2166  
  2167  	// sort new reserve queue
  2168  	if len(addRe_queue) > 0 {
  2169  		re_queue = append(re_queue, addRe_queue...)
  2170  
  2171  		str := "Call promoteReserveQueue to sort the new reserve queue ..."
  2172  		makeCandidateSort(str, state, re_queue)
  2173  
  2174  	}
  2175  
  2176  	// Sets the new reserve queue
  2177  	c.setCandidateQueue(re_queue, ppos_storage.RESERVE)
  2178  
  2179  	PrintObject("Call promoteReserveQueue Finish the immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue)
  2180  	PrintObject("Call promoteReserveQueue Finish the reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue)
  2181  	log.Debug("Call promoteReserveQueue Finish !!! ...", "blockNumber", currentBlockNumber.String())
  2182  }
  2183  
  2184  /** builin function */
  2185  
  2186  func (c *CandidatePool) setCandidateQueue(queue types.CandidateQueue, flag int) {
  2187  	c.storage.SetCandidateQueue(queue, flag)
  2188  }
  2189  
  2190  func (c *CandidatePool) getCandidateQueue(flag int) types.CandidateQueue {
  2191  	return c.storage.GetCandidateQueue(flag)
  2192  }
  2193  
  2194  func (c *CandidatePool) delCandidateQueue(flag int) {
  2195  	c.storage.DelCandidateQueue(flag)
  2196  }
  2197  
  2198  func (c *CandidatePool) setRefund(nodeId discover.NodeID, refund *types.CandidateRefund) {
  2199  	c.storage.SetRefund(nodeId, refund)
  2200  }
  2201  
  2202  func (c *CandidatePool) setRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) {
  2203  	c.storage.SetRefunds(nodeId, refundArr)
  2204  }
  2205  
  2206  func (c *CandidatePool) appendRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) {
  2207  	c.storage.AppendRefunds(nodeId, refundArr)
  2208  }
  2209  
  2210  func (c *CandidatePool) getRefunds(nodeId discover.NodeID) types.RefundQueue {
  2211  	return c.storage.GetRefunds(nodeId)
  2212  }
  2213  
  2214  func (c *CandidatePool) delRefunds(nodeId discover.NodeID) {
  2215  	c.storage.DelRefunds(nodeId)
  2216  }
  2217  
  2218  /*func getPreviousWitnessIdsState(state vm.StateDB) ([]discover.NodeID, error) {
  2219  	var witnessIds []discover.NodeID
  2220  	if valByte := state.GetState(common.CandidatePoolAddr, PreviousWitnessListKey()); len(valByte) != 0 {
  2221  		if err := rlp.DecodeBytes(valByte, &witnessIds); nil != err {
  2222  			return nil, err
  2223  		}
  2224  	} else {
  2225  		return nil, nil
  2226  	}
  2227  	return witnessIds, nil
  2228  }
  2229  
  2230  func setPreviosWitnessIdsState(state vm.StateDB, arrVal []byte) {
  2231  	state.SetState(common.CandidatePoolAddr, PreviousWitnessListKey(), arrVal)
  2232  }
  2233  
  2234  func getPreviousWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) {
  2235  	var can types.Candidate
  2236  	if valByte := state.GetState(common.CandidatePoolAddr, PreviousWitnessKey(id)); len(valByte) != 0 {
  2237  		if err := rlp.DecodeBytes(valByte, &can); nil != err {
  2238  			return nil, err
  2239  		}
  2240  	} else {
  2241  		return nil, nil
  2242  	}
  2243  	return &can, nil
  2244  }
  2245  
  2246  func setPreviousWitnessState(state vm.StateDB, id discover.NodeID, val []byte) {
  2247  	state.SetState(common.CandidatePoolAddr, PreviousWitnessKey(id), val)
  2248  }
  2249  
  2250  func getWitnessIdsByState(state vm.StateDB) ([]discover.NodeID, error) {
  2251  	var witnessIds []discover.NodeID
  2252  	if valByte := state.GetState(common.CandidatePoolAddr, WitnessListKey()); len(valByte) != 0 {
  2253  		if err := rlp.DecodeBytes(valByte, &witnessIds); nil != err {
  2254  			return nil, err
  2255  		}
  2256  	} else {
  2257  		return nil, nil
  2258  	}
  2259  	return witnessIds, nil
  2260  }
  2261  
  2262  func setWitnessIdsState(state vm.StateDB, arrVal []byte) {
  2263  	state.SetState(common.CandidatePoolAddr, WitnessListKey(), arrVal)
  2264  }
  2265  
  2266  func getWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) {
  2267  	var can types.Candidate
  2268  	if valByte := state.GetState(common.CandidatePoolAddr, WitnessKey(id)); len(valByte) != 0 {
  2269  		if err := rlp.DecodeBytes(valByte, &can); nil != err {
  2270  			return nil, err
  2271  		}
  2272  	} else {
  2273  		return nil, nil
  2274  	}
  2275  	return &can, nil
  2276  }
  2277  
  2278  func setWitnessState(state vm.StateDB, id discover.NodeID, val []byte) {
  2279  	state.SetState(common.CandidatePoolAddr, WitnessKey(id), val)
  2280  }
  2281  
  2282  func getNextWitnessIdsByState(state vm.StateDB) ([]discover.NodeID, error) {
  2283  	var nextWitnessIds []discover.NodeID
  2284  	if valByte := state.GetState(common.CandidatePoolAddr, NextWitnessListKey()); len(valByte) != 0 {
  2285  		if err := rlp.DecodeBytes(valByte, &nextWitnessIds); nil != err {
  2286  			return nil, err
  2287  		}
  2288  	} else {
  2289  		return nil, nil
  2290  	}
  2291  	return nextWitnessIds, nil
  2292  }
  2293  
  2294  func setNextWitnessIdsState(state vm.StateDB, arrVal []byte) {
  2295  	state.SetState(common.CandidatePoolAddr, NextWitnessListKey(), arrVal)
  2296  }
  2297  
  2298  func getNextWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) {
  2299  	var can types.Candidate
  2300  	if valByte := state.GetState(common.CandidatePoolAddr, NextWitnessKey(id)); len(valByte) != 0 {
  2301  		if err := rlp.DecodeBytes(valByte, &can); nil != err {
  2302  			return nil, err
  2303  		}
  2304  	} else {
  2305  		return nil, nil
  2306  	}
  2307  	return &can, nil
  2308  }
  2309  
  2310  func setNextWitnessState(state vm.StateDB, id discover.NodeID, val []byte) {
  2311  	state.SetState(common.CandidatePoolAddr, NextWitnessKey(id), val)
  2312  }
  2313  
  2314  func getImmediateIdsByState(state vm.StateDB) ([]discover.NodeID, error) {
  2315  	var immediateIds []discover.NodeID
  2316  	if valByte := state.GetState(common.CandidatePoolAddr, ImmediateListKey()); len(valByte) != 0 {
  2317  		if err := rlp.DecodeBytes(valByte, &immediateIds); nil != err {
  2318  			return nil, err
  2319  		}
  2320  	} else {
  2321  		return nil, nil
  2322  	}
  2323  	return immediateIds, nil
  2324  }
  2325  
  2326  func setImmediateIdsState(state vm.StateDB, arrVal []byte) {
  2327  	state.SetState(common.CandidatePoolAddr, ImmediateListKey(), arrVal)
  2328  }
  2329  
  2330  func getImmediateByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) {
  2331  	var can types.Candidate
  2332  	if valByte := state.GetState(common.CandidatePoolAddr, ImmediateKey(id)); len(valByte) != 0 {
  2333  		if err := rlp.DecodeBytes(valByte, &can); nil != err {
  2334  			return nil, err
  2335  		}
  2336  	} else {
  2337  		return nil, nil
  2338  	}
  2339  	return &can, nil
  2340  }
  2341  
  2342  func setImmediateState(state vm.StateDB, id discover.NodeID, val []byte) {
  2343  	state.SetState(common.CandidatePoolAddr, ImmediateKey(id), val)
  2344  }
  2345  
  2346  func getReserveIdsByState(state vm.StateDB) ([]discover.NodeID, error) {
  2347  	var reserveIds []discover.NodeID
  2348  	if valByte := state.GetState(common.CandidatePoolAddr, ReserveListKey()); len(valByte) != 0 {
  2349  		if err := rlp.DecodeBytes(valByte, &reserveIds); nil != err {
  2350  			return nil, err
  2351  		}
  2352  	} else {
  2353  		return nil, nil
  2354  	}
  2355  	return reserveIds, nil
  2356  }
  2357  
  2358  func setReserveIdsState(state vm.StateDB, arrVal []byte) {
  2359  	state.SetState(common.CandidatePoolAddr, ReserveListKey(), arrVal)
  2360  }
  2361  
  2362  func getReserveByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) {
  2363  	var can types.Candidate
  2364  	if valByte := state.GetState(common.CandidatePoolAddr, ReserveKey(id)); len(valByte) != 0 {
  2365  		if err := rlp.DecodeBytes(valByte, &can); nil != err {
  2366  			return nil, err
  2367  		}
  2368  	} else {
  2369  		return nil, nil
  2370  	}
  2371  	return &can, nil
  2372  }
  2373  
  2374  func setReserveState(state vm.StateDB, id discover.NodeID, val []byte) {
  2375  	state.SetState(common.CandidatePoolAddr, ReserveKey(id), val)
  2376  }
  2377  
  2378  func getDefeatIdsByState(state vm.StateDB) ([]discover.NodeID, error) {
  2379  	var defeatIds []discover.NodeID
  2380  	if valByte := state.GetState(common.CandidatePoolAddr, DefeatListKey()); len(valByte) != 0 {
  2381  		if err := rlp.DecodeBytes(valByte, &defeatIds); nil != err {
  2382  			return nil, err
  2383  		}
  2384  	} else {
  2385  		return nil, nil
  2386  	}
  2387  	return defeatIds, nil
  2388  }
  2389  
  2390  func setDefeatIdsState(state vm.StateDB, arrVal []byte) {
  2391  	state.SetState(common.CandidatePoolAddr, DefeatListKey(), arrVal)
  2392  }
  2393  
  2394  func getDefeatsByState(state vm.StateDB, id discover.NodeID) (types.CandidateQueue, error) {
  2395  	var canArr types.CandidateQueue
  2396  	if valByte := state.GetState(common.CandidatePoolAddr, DefeatKey(id)); len(valByte) != 0 {
  2397  		if err := rlp.DecodeBytes(valByte, &canArr); nil != err {
  2398  			return nil, err
  2399  		}
  2400  	} else {
  2401  		return nil, nil
  2402  	}
  2403  	return canArr, nil
  2404  }
  2405  
  2406  func setDefeatState(state vm.StateDB, id discover.NodeID, val []byte) {
  2407  	log.Debug("SetDefeatArr ... ...", "nodeId:", id.String(), "keyTrie:", buildKeyTrie(DefeatKey(id)))
  2408  	state.SetState(common.CandidatePoolAddr, DefeatKey(id), val)
  2409  }*/
  2410  
  2411  func copyCandidateMapByIds(target, source candidateStorage, ids []discover.NodeID) {
  2412  	for _, id := range ids {
  2413  		if v, ok := source[id]; ok {
  2414  			target[id] = v
  2415  		}
  2416  	}
  2417  }
  2418  
  2419  //func GetCandidatePtr() *CandidatePool {
  2420  //	return candidatePool
  2421  //}
  2422  
  2423  func PrintObject(s string, obj interface{}) {
  2424  	objs, _ := json.Marshal(obj)
  2425  	log.Debug(s, "==", string(objs))
  2426  }
  2427  
  2428  func buildWitnessNode(can *types.Candidate) (*discover.Node, error) {
  2429  	if nil == can {
  2430  		return nil, CandidateEmptyErr
  2431  	}
  2432  	ip := net.ParseIP(can.Host)
  2433  	// uint16
  2434  	var port uint16
  2435  	if portInt, err := strconv.Atoi(can.Port); nil != err {
  2436  		return nil, err
  2437  	} else {
  2438  		port = uint16(portInt)
  2439  	}
  2440  	return discover.NewNode(can.CandidateId, ip, port, port), nil
  2441  }
  2442  
  2443  func makeCandidateSort(logStr string, state vm.StateDB, arr types.CandidateQueue) {
  2444  
  2445  	log.Debug(logStr)
  2446  
  2447  	cand := make(types.CanConditions, 0)
  2448  	for _, can := range arr {
  2449  		tCount := tContext.GetCandidateTicketCount(state, can.CandidateId)
  2450  		price := tContext.GetTicketPrice(state)
  2451  		tprice := new(big.Int).Mul(big.NewInt(int64(tCount)), price)
  2452  
  2453  		money := new(big.Int).Add(can.Deposit, tprice)
  2454  
  2455  		cand[can.CandidateId] = money
  2456  	}
  2457  	arr.CandidateSort(cand)
  2458  }
  2459  
  2460  /*
  2461  func ImmediateKey(nodeId discover.NodeID) []byte {
  2462  	return immediateKey(nodeId.Bytes())
  2463  }
  2464  func immediateKey(key []byte) []byte {
  2465  	return append(append(common.CandidatePoolAddr.Bytes(), ImmediateBytePrefix...), key...)
  2466  }
  2467  
  2468  func ReserveKey(nodeId discover.NodeID) []byte {
  2469  	return reserveKey(nodeId.Bytes())
  2470  }
  2471  
  2472  func reserveKey(key []byte) []byte {
  2473  	return append(append(common.CandidatePoolAddr.Bytes(), ReserveBytePrefix...), key...)
  2474  }
  2475  
  2476  func PreviousWitnessKey(nodeId discover.NodeID) []byte {
  2477  	return prewitnessKey(nodeId.Bytes())
  2478  }
  2479  
  2480  func prewitnessKey(key []byte) []byte {
  2481  	return append(append(common.CandidatePoolAddr.Bytes(), PreWitnessBytePrefix...), key...)
  2482  }
  2483  
  2484  func WitnessKey(nodeId discover.NodeID) []byte {
  2485  	return witnessKey(nodeId.Bytes())
  2486  }
  2487  func witnessKey(key []byte) []byte {
  2488  	return append(append(common.CandidatePoolAddr.Bytes(), WitnessBytePrefix...), key...)
  2489  }
  2490  
  2491  func NextWitnessKey(nodeId discover.NodeID) []byte {
  2492  	return nextWitnessKey(nodeId.Bytes())
  2493  }
  2494  func nextWitnessKey(key []byte) []byte {
  2495  	return append(append(common.CandidatePoolAddr.Bytes(), NextWitnessBytePrefix...), key...)
  2496  }
  2497  
  2498  func DefeatKey(nodeId discover.NodeID) []byte {
  2499  	return defeatKey(nodeId.Bytes())
  2500  }
  2501  func defeatKey(key []byte) []byte {
  2502  	return append(append(common.CandidatePoolAddr.Bytes(), DefeatBytePrefix...), key...)
  2503  }
  2504  
  2505  func ImmediateListKey() []byte {
  2506  	return append(common.CandidatePoolAddr.Bytes(), ImmediateListBytePrefix...)
  2507  }
  2508  
  2509  func ReserveListKey() []byte {
  2510  	return append(common.CandidatePoolAddr.Bytes(), ReserveListBytePrefix...)
  2511  }
  2512  
  2513  func PreviousWitnessListKey() []byte {
  2514  	return append(common.CandidatePoolAddr.Bytes(), PreWitnessListBytePrefix...)
  2515  }
  2516  
  2517  func WitnessListKey() []byte {
  2518  	return append(common.CandidatePoolAddr.Bytes(), WitnessListBytePrefix...)
  2519  }
  2520  
  2521  func NextWitnessListKey() []byte {
  2522  	return append(common.CandidatePoolAddr.Bytes(), NextWitnessListBytePrefix...)
  2523  }
  2524  
  2525  func DefeatListKey() []byte {
  2526  	return append(common.CandidatePoolAddr.Bytes(), DefeatListBytePrefix...)
  2527  }
  2528  
  2529  func (c *CandidatePool) ForEachStorage(state vm.StateDB, title string) {
  2530  	c.lock.Lock()
  2531  	log.Debug(title + ":Full view of data in the candidate pool ...")
  2532  	c.initDataByState(state, 2)
  2533  	c.lock.Unlock()
  2534  }
  2535  */