github.com/lino-network/lino@v0.6.11/x/validator/manager/manager.go (about)

     1  package manager
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  
     8  	codec "github.com/cosmos/cosmos-sdk/codec"
     9  	sdk "github.com/cosmos/cosmos-sdk/types"
    10  	abci "github.com/tendermint/tendermint/abci/types"
    11  	crypto "github.com/tendermint/tendermint/crypto"
    12  	tmtypes "github.com/tendermint/tendermint/types"
    13  
    14  	"github.com/lino-network/lino/param"
    15  	linotypes "github.com/lino-network/lino/types"
    16  	"github.com/lino-network/lino/utils"
    17  	acc "github.com/lino-network/lino/x/account"
    18  	"github.com/lino-network/lino/x/global"
    19  	"github.com/lino-network/lino/x/validator/model"
    20  	"github.com/lino-network/lino/x/validator/types"
    21  	"github.com/lino-network/lino/x/vote"
    22  	votetypes "github.com/lino-network/lino/x/vote/types"
    23  )
    24  
    25  const (
    26  	exportVersion = 1
    27  	importVersion = 1
    28  )
    29  
    30  // ValidatorManager - validator manager
    31  type ValidatorManager struct {
    32  	storage model.ValidatorStorage
    33  
    34  	// deps
    35  	paramHolder param.ParamKeeper
    36  	vote        vote.VoteKeeper
    37  	global      global.GlobalKeeper
    38  	acc         acc.AccountKeeper
    39  }
    40  
    41  func NewValidatorManager(key sdk.StoreKey, holder param.ParamKeeper, vote vote.VoteKeeper,
    42  	global global.GlobalKeeper, acc acc.AccountKeeper) ValidatorManager {
    43  	return ValidatorManager{
    44  		storage:     model.NewValidatorStorage(key),
    45  		paramHolder: holder,
    46  		vote:        vote,
    47  		global:      global,
    48  		acc:         acc,
    49  	}
    50  }
    51  
    52  // InitGenesis - initialize KVStore
    53  func (vm ValidatorManager) InitGenesis(ctx sdk.Context) {
    54  	lst := &model.ValidatorList{
    55  		LowestOncallVotes:  linotypes.NewCoinFromInt64(0),
    56  		LowestStandbyVotes: linotypes.NewCoinFromInt64(0),
    57  	}
    58  	vm.storage.SetValidatorList(ctx, lst)
    59  }
    60  
    61  func (vm ValidatorManager) OnBeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
    62  	// update preblock validators
    63  	validatorList := vm.GetValidatorList(ctx)
    64  	vals := vm.GetCommittingValidators(ctx)
    65  	validatorList.PreBlockValidators = vals
    66  	vm.SetValidatorList(ctx, validatorList)
    67  
    68  	// update signing stats.
    69  	updateErr := vm.updateSigningStats(ctx, req.LastCommitInfo.Votes)
    70  	if updateErr != nil {
    71  		panic(updateErr)
    72  	}
    73  
    74  	if err := vm.fireIncompetentValidator(ctx, req.ByzantineValidators); err != nil {
    75  		panic(err)
    76  	}
    77  
    78  	// grant free votes to lino validators for migration.
    79  	if ctx.BlockHeight() == linotypes.Upgrade5Update2 {
    80  		vm.grantFreeVotes(ctx)
    81  	}
    82  }
    83  
    84  func (vm ValidatorManager) grantFreeVotes(ctx sdk.Context) {
    85  	valNames := []linotypes.AccountKey{
    86  		"validator1",
    87  		"validator2",
    88  		"validator3",
    89  		"validator5",
    90  		"validator7",
    91  	}
    92  	votes := make([]*model.ElectionVote, 0)
    93  	for _, name := range valNames {
    94  		votes = append(votes, &model.ElectionVote{
    95  			ValidatorName: name,
    96  			Vote:          linotypes.NewCoinFromInt64(50 * 1000 * 1000 * linotypes.Decimals),
    97  		})
    98  	}
    99  	err := vm.updateValidatorReceivedVotes(ctx, votes)
   100  	if err != nil {
   101  		ctx.Logger().Error(err.Error())
   102  	}
   103  }
   104  
   105  func (vm ValidatorManager) UpdateValidator(ctx sdk.Context, username linotypes.AccountKey, link string) sdk.Error {
   106  	val, err := vm.storage.GetValidator(ctx, username)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	val.Link = link
   111  	vm.storage.SetValidator(ctx, username, val)
   112  	return nil
   113  }
   114  
   115  // RegisterValidator - register a validator.
   116  func (vm ValidatorManager) RegisterValidator(ctx sdk.Context, username linotypes.AccountKey, valPubKey crypto.PubKey, link string) sdk.Error {
   117  	lst := vm.storage.GetValidatorList(ctx)
   118  	if linotypes.FindAccountInList(username, lst.Jail) != -1 {
   119  		return vm.rejoinFromJail(ctx, username)
   120  	}
   121  
   122  	if vm.IsLegalValidator(ctx, username) {
   123  		return types.ErrValidatorAlreadyExist()
   124  	}
   125  
   126  	// must be voter duty
   127  	if duty, err := vm.vote.GetVoterDuty(ctx, username); err != nil || duty != votetypes.DutyVoter {
   128  		return types.ErrInvalidVoterDuty()
   129  	}
   130  
   131  	param := vm.paramHolder.GetValidatorParam(ctx)
   132  
   133  	// assign validator duty in vote
   134  	if err := vm.vote.AssignDuty(ctx, username, votetypes.DutyValidator, param.ValidatorMinDeposit); err != nil {
   135  		return err
   136  	}
   137  
   138  	if err := vm.checkDupPubKey(ctx, valPubKey); err != nil {
   139  		return err
   140  	}
   141  
   142  	// recover data if was revoked: inherite the votes.
   143  	prevVotes := vm.getPrevVotes(ctx, username)
   144  	validator := &model.Validator{
   145  		ABCIValidator: abci.Validator{
   146  			Address: valPubKey.Address(),
   147  			Power:   0,
   148  		},
   149  		ReceivedVotes: prevVotes,
   150  		PubKey:        valPubKey,
   151  		Username:      username,
   152  		Link:          link,
   153  	}
   154  	vm.storage.SetValidator(ctx, username, validator)
   155  
   156  	// join as candidate validator first and vote itself
   157  	if err := vm.addValidatortToCandidateList(ctx, username); err != nil {
   158  		return err
   159  	}
   160  	if err := vm.onCandidateVotesInc(ctx, username); err != nil {
   161  		return err
   162  	}
   163  	if err := vm.VoteValidator(ctx, username, []linotypes.AccountKey{username}); err != nil {
   164  		return err
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  func (vm ValidatorManager) RevokeValidator(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   171  	if !vm.IsLegalValidator(ctx, username) {
   172  		return types.ErrInvalidValidator()
   173  	}
   174  
   175  	me, err := vm.storage.GetValidator(ctx, username)
   176  	if err != nil {
   177  		return err
   178  	}
   179  
   180  	me.HasRevoked = true
   181  	vm.storage.SetValidator(ctx, username, me)
   182  
   183  	if err := vm.removeValidatorFromAllLists(ctx, username); err != nil {
   184  		return err
   185  	}
   186  	if err := vm.balanceValidatorList(ctx); err != nil {
   187  		return err
   188  	}
   189  
   190  	param := vm.paramHolder.GetValidatorParam(ctx)
   191  	if err = vm.vote.UnassignDuty(ctx, username, param.ValidatorRevokePendingSec); err != nil {
   192  		return err
   193  	}
   194  
   195  	return nil
   196  }
   197  
   198  func (vm ValidatorManager) VoteValidator(ctx sdk.Context, username linotypes.AccountKey,
   199  	votedValidators []linotypes.AccountKey) sdk.Error {
   200  	param := vm.paramHolder.GetValidatorParam(ctx)
   201  	if int64(len(votedValidators)) > param.MaxVotedValidators {
   202  		return types.ErrInvalidVotedValidators()
   203  	}
   204  	// check if voted validators exist
   205  	for _, valName := range votedValidators {
   206  		if !vm.IsLegalValidator(ctx, valName) {
   207  			return types.ErrValidatorNotFound(valName)
   208  		}
   209  	}
   210  
   211  	updates, err := vm.getElectionVoteListUpdates(ctx, username, votedValidators)
   212  	if err != nil {
   213  		return err
   214  	}
   215  
   216  	if err := vm.updateValidatorReceivedVotes(ctx, updates); err != nil {
   217  		return err
   218  	}
   219  
   220  	if err := vm.setNewElectionVoteList(ctx, username, votedValidators); err != nil {
   221  		return err
   222  	}
   223  
   224  	if err := vm.vote.ClaimInterest(ctx, username); err != nil {
   225  		return err
   226  	}
   227  	return nil
   228  }
   229  
   230  func (vm ValidatorManager) DistributeInflationToValidator(ctx sdk.Context) sdk.Error {
   231  	coin, err := vm.acc.GetPool(ctx, linotypes.InflationValidatorPool)
   232  	if err != nil {
   233  		return err
   234  	}
   235  	param := vm.paramHolder.GetValidatorParam(ctx)
   236  	lst := vm.storage.GetValidatorList(ctx)
   237  	totalWeight := int64(len(lst.Oncall))*param.OncallInflationWeight +
   238  		int64(len(lst.Standby))*param.StandbyInflationWeight
   239  	index := int64(0)
   240  	// give inflation to each validator according it's weight
   241  	for _, oncall := range lst.Oncall {
   242  		ratPerOncall := coin.ToDec().Mul(sdk.NewDec(param.OncallInflationWeight)).Quo(sdk.NewDec(totalWeight - index))
   243  		err := vm.acc.MoveFromPool(ctx, linotypes.InflationValidatorPool,
   244  			linotypes.NewAccOrAddrFromAcc(oncall),
   245  			linotypes.DecToCoin(ratPerOncall))
   246  		if err != nil {
   247  			return err
   248  		}
   249  		coin = coin.Minus(linotypes.DecToCoin(ratPerOncall))
   250  		index += param.OncallInflationWeight
   251  	}
   252  
   253  	for _, standby := range lst.Standby {
   254  		ratPerStandby := coin.ToDec().Mul(sdk.NewDec(param.StandbyInflationWeight)).Quo(sdk.NewDec(totalWeight - index))
   255  		err := vm.acc.MoveFromPool(ctx, linotypes.InflationValidatorPool,
   256  			linotypes.NewAccOrAddrFromAcc(standby),
   257  			linotypes.DecToCoin(ratPerStandby))
   258  		if err != nil {
   259  			return err
   260  		}
   261  		coin = coin.Minus(linotypes.DecToCoin(ratPerStandby))
   262  		index += param.StandbyInflationWeight
   263  	}
   264  	return nil
   265  }
   266  
   267  func (vm ValidatorManager) rejoinFromJail(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   268  	param := vm.paramHolder.GetValidatorParam(ctx)
   269  	totalStake, err := vm.vote.GetLinoStake(ctx, username)
   270  	if err != nil {
   271  		return err
   272  	}
   273  
   274  	if !totalStake.IsGTE(param.ValidatorMinDeposit) {
   275  		return types.ErrInsufficientDeposit()
   276  	}
   277  
   278  	vm.removeValidatorFromJailList(ctx, username)
   279  	if err := vm.addValidatortToCandidateList(ctx, username); err != nil {
   280  		return err
   281  	}
   282  	if err := vm.onCandidateVotesInc(ctx, username); err != nil {
   283  		return err
   284  	}
   285  	return nil
   286  }
   287  
   288  // calculate the changed votes between current election votes and previous election votes
   289  // negative number means the corresponding validator need to decrease it's received votes
   290  // positive number means the corresponding validator need to increase it's received votes
   291  func (vm ValidatorManager) getElectionVoteListUpdates(ctx sdk.Context, username linotypes.AccountKey,
   292  	votedValidators []linotypes.AccountKey) ([]*model.ElectionVote, sdk.Error) {
   293  	res := []*model.ElectionVote{}
   294  	prevList := vm.storage.GetElectionVoteList(ctx, username)
   295  	totalStake, err := vm.vote.GetLinoStake(ctx, username)
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  
   300  	if len(prevList.ElectionVotes) == 0 && len(votedValidators) == 0 {
   301  		return nil, nil
   302  	}
   303  	if len(votedValidators) == 0 {
   304  		return nil, types.ErrInvalidVotedValidators()
   305  	}
   306  
   307  	voteStake := linotypes.DecToCoin(
   308  		totalStake.ToDec().Quo(sdk.NewDec(int64(len(votedValidators)))))
   309  
   310  	// add all old votes into res set first and default all votes are negative (not in the new list)
   311  	for _, oldVote := range prevList.ElectionVotes {
   312  		changeDec := oldVote.Vote.Neg()
   313  		res = append(res, &model.ElectionVote{
   314  			ValidatorName: oldVote.ValidatorName,
   315  			Vote:          changeDec,
   316  		})
   317  	}
   318  
   319  	// a helper function to return the pointer to the matching ElectionVote.
   320  	findInPrev := func(valName linotypes.AccountKey) *model.ElectionVote {
   321  		for _, oldVote := range res {
   322  			if oldVote.ValidatorName == valName {
   323  				return oldVote
   324  			}
   325  		}
   326  		return nil
   327  	}
   328  
   329  	for _, validatorName := range votedValidators {
   330  		if prev := findInPrev(validatorName); prev != nil {
   331  			prev.Vote = prev.Vote.Plus(voteStake)
   332  		} else {
   333  			res = append(res, &model.ElectionVote{
   334  				ValidatorName: validatorName,
   335  				Vote:          voteStake,
   336  			})
   337  		}
   338  	}
   339  	return res, nil
   340  }
   341  
   342  func (vm ValidatorManager) updateValidatorReceivedVotes(ctx sdk.Context, updates []*model.ElectionVote) sdk.Error {
   343  	for _, update := range updates {
   344  		lst := vm.storage.GetValidatorList(ctx)
   345  		if update.Vote.IsZero() {
   346  			continue
   347  		}
   348  
   349  		// revoked validator's record will still be in kv.
   350  		validator, err := vm.storage.GetValidator(ctx, update.ValidatorName)
   351  		if err != nil {
   352  			return err
   353  		}
   354  		validator.ReceivedVotes = validator.ReceivedVotes.Plus(update.Vote)
   355  		vm.storage.SetValidator(ctx, update.ValidatorName, validator)
   356  
   357  		// the corresponding validator's received votes increase
   358  		if update.Vote.IsPositive() {
   359  			if linotypes.FindAccountInList(update.ValidatorName, lst.Oncall) != -1 {
   360  				if err := vm.onOncallVotesInc(ctx, update.ValidatorName); err != nil {
   361  					return err
   362  				}
   363  			}
   364  			if linotypes.FindAccountInList(update.ValidatorName, lst.Standby) != -1 {
   365  				if err := vm.onStandbyVotesInc(ctx, update.ValidatorName); err != nil {
   366  					return err
   367  				}
   368  			}
   369  			if linotypes.FindAccountInList(update.ValidatorName, lst.Candidates) != -1 {
   370  				if err := vm.onCandidateVotesInc(ctx, update.ValidatorName); err != nil {
   371  					return err
   372  				}
   373  			}
   374  		} else {
   375  			// the corresponding validator's received votes decrease
   376  			if linotypes.FindAccountInList(update.ValidatorName, lst.Oncall) != -1 {
   377  				if err := vm.onOncallVotesDec(ctx, update.ValidatorName); err != nil {
   378  					return err
   379  				}
   380  			}
   381  			if linotypes.FindAccountInList(update.ValidatorName, lst.Standby) != -1 {
   382  				if err := vm.onStandbyVotesDec(ctx, update.ValidatorName); err != nil {
   383  					return err
   384  				}
   385  			}
   386  		}
   387  	}
   388  
   389  	return nil
   390  }
   391  
   392  func (vm ValidatorManager) setNewElectionVoteList(ctx sdk.Context, username linotypes.AccountKey,
   393  	votedValidators []linotypes.AccountKey) sdk.Error {
   394  	if len(votedValidators) == 0 {
   395  		return nil
   396  	}
   397  	lst := &model.ElectionVoteList{}
   398  	totalStake, err := vm.vote.GetLinoStake(ctx, username)
   399  	if err != nil {
   400  		return err
   401  	}
   402  
   403  	voteStakeDec := totalStake.ToDec().Quo(sdk.NewDec(int64(len(votedValidators))))
   404  	for _, validatorName := range votedValidators {
   405  		electionVote := model.ElectionVote{
   406  			ValidatorName: validatorName,
   407  			Vote:          linotypes.DecToCoin(voteStakeDec),
   408  		}
   409  		lst.ElectionVotes = append(lst.ElectionVotes, electionVote)
   410  	}
   411  
   412  	vm.storage.SetElectionVoteList(ctx, username, lst)
   413  	return nil
   414  }
   415  
   416  // IsLegalValidator - check if the validator is a validator and not revoked.
   417  func (vm ValidatorManager) IsLegalValidator(ctx sdk.Context, accKey linotypes.AccountKey) bool {
   418  	val, err := vm.storage.GetValidator(ctx, accKey)
   419  	if err != nil {
   420  		return false
   421  	}
   422  	return !val.HasRevoked
   423  }
   424  
   425  // GetInitValidators return all validators in state.
   426  // XXX(yumin): This is intended to be used only in initChainer
   427  func (vm ValidatorManager) GetInitValidators(ctx sdk.Context) ([]abci.ValidatorUpdate, sdk.Error) {
   428  	committingValidators := vm.GetCommittingValidators(ctx)
   429  	updates := []abci.ValidatorUpdate{}
   430  	for _, curValidator := range committingValidators {
   431  		validator, err := vm.storage.GetValidator(ctx, curValidator)
   432  		if err != nil {
   433  			return nil, err
   434  		}
   435  		updates = append(updates, abci.ValidatorUpdate{
   436  			PubKey: tmtypes.TM2PB.PubKey(validator.PubKey),
   437  			Power:  validator.ABCIValidator.Power,
   438  		})
   439  	}
   440  	return updates, nil
   441  }
   442  
   443  // GetValidatorUpdates - after a block, compare updated validator set with
   444  // recorded validator set before block execution
   445  func (vm ValidatorManager) GetValidatorUpdates(ctx sdk.Context) ([]abci.ValidatorUpdate, sdk.Error) {
   446  	validatorList := vm.storage.GetValidatorList(ctx)
   447  	updates := []abci.ValidatorUpdate{}
   448  	committingValidators := vm.GetCommittingValidators(ctx)
   449  	committingSet := linotypes.AccountListToSet(committingValidators)
   450  
   451  	for _, preValidator := range validatorList.PreBlockValidators {
   452  		// set power to 0 if a previous validator not in oncall and standby list anymore
   453  		if committingSet[preValidator] == false {
   454  			validator, err := vm.storage.GetValidator(ctx, preValidator)
   455  			if err != nil {
   456  				return nil, err
   457  			}
   458  			updates = append(updates, abci.ValidatorUpdate{
   459  				PubKey: tmtypes.TM2PB.PubKey(validator.PubKey),
   460  				Power:  0,
   461  			})
   462  		}
   463  	}
   464  
   465  	for _, curValidator := range committingValidators {
   466  		validator, err := vm.storage.GetValidator(ctx, curValidator)
   467  		if err != nil {
   468  			return nil, err
   469  		}
   470  
   471  		updates = append(updates, abci.ValidatorUpdate{
   472  			PubKey: tmtypes.TM2PB.PubKey(validator.PubKey),
   473  			Power:  validator.ABCIValidator.Power,
   474  		})
   475  
   476  	}
   477  	return updates, nil
   478  }
   479  
   480  // UpdateSigningStats - based on info in beginBlocker, record last block singing info
   481  func (vm ValidatorManager) updateSigningStats(ctx sdk.Context, voteInfos []abci.VoteInfo) sdk.Error {
   482  	// map address to whether that validator has signed.
   483  	addressSigned := make(map[string]bool)
   484  	for _, voteInfo := range voteInfos {
   485  		addressSigned[string(voteInfo.Validator.Address)] = voteInfo.SignedLastBlock
   486  	}
   487  
   488  	// go through oncall and standby validator list to get all address and name mapping
   489  	committingValidators := vm.GetCommittingValidators(ctx)
   490  	for _, curValidator := range committingValidators {
   491  		validator, err := vm.storage.GetValidator(ctx, curValidator)
   492  		if err != nil {
   493  			return err
   494  		}
   495  		signed, exist := addressSigned[string(validator.ABCIValidator.Address)]
   496  		if !exist || !signed {
   497  			validator.AbsentCommit++
   498  		} else {
   499  			validator.ProducedBlocks++
   500  			if validator.AbsentCommit > 0 {
   501  				validator.AbsentCommit--
   502  			}
   503  		}
   504  		vm.storage.SetValidator(ctx, curValidator, validator)
   505  	}
   506  
   507  	return nil
   508  }
   509  
   510  // PunishOncallValidator - punish committing validator
   511  // if 1) byzantine or 2) missing blocks reach limiation
   512  func (vm ValidatorManager) PunishCommittingValidator(ctx sdk.Context, username linotypes.AccountKey,
   513  	penalty linotypes.Coin, punishType linotypes.PunishType) sdk.Error {
   514  	// slash and add slashed coin back into validator inflation pool
   515  	_, err := vm.vote.SlashStake(ctx, username, penalty, linotypes.InflationValidatorPool)
   516  	if err != nil {
   517  		return err
   518  	}
   519  	validator, err := vm.storage.GetValidator(ctx, username)
   520  	if err != nil {
   521  		return err
   522  	}
   523  	validator.NumSlash++
   524  	// reset absent commit
   525  	if punishType == linotypes.PunishAbsentCommit {
   526  		validator.AbsentCommit = 0
   527  	}
   528  	vm.storage.SetValidator(ctx, username, validator)
   529  
   530  	totalStake, err := vm.vote.GetLinoStake(ctx, username)
   531  	if err != nil {
   532  		return err
   533  	}
   534  	// remove this validator and put into jail if its remaining stake is not enough
   535  	// OR, this is byzantine validator
   536  	// OR, the num of slash exceeds limit
   537  	param := vm.paramHolder.GetValidatorParam(ctx)
   538  	if punishType == linotypes.PunishByzantine ||
   539  		!totalStake.IsGTE(param.ValidatorMinDeposit) ||
   540  		validator.NumSlash > param.SlashLimitation {
   541  		if err := vm.removeValidatorFromAllLists(ctx, username); err != nil {
   542  			return err
   543  		}
   544  		if err := vm.addValidatortToJailList(ctx, username); err != nil {
   545  			return err
   546  		}
   547  		if err := vm.balanceValidatorList(ctx); err != nil {
   548  			return err
   549  		}
   550  	}
   551  
   552  	return nil
   553  }
   554  
   555  // FireIncompetentValidator - fire oncall validator if
   556  // 1. absent commit > absent limitation.
   557  // 2. byzantine
   558  func (vm ValidatorManager) fireIncompetentValidator(ctx sdk.Context,
   559  	byzantineValidators []abci.Evidence) sdk.Error {
   560  	param := vm.paramHolder.GetValidatorParam(ctx)
   561  	committingValidators := vm.GetCommittingValidators(ctx)
   562  
   563  	for _, validatorName := range committingValidators {
   564  		validator, err := vm.storage.GetValidator(ctx, validatorName)
   565  		if err != nil {
   566  			return err
   567  		}
   568  
   569  		for _, evidence := range byzantineValidators {
   570  			if reflect.DeepEqual(validator.ABCIValidator.Address, evidence.Validator.Address) {
   571  				if err := vm.PunishCommittingValidator(ctx, validator.Username, param.PenaltyByzantine,
   572  					linotypes.PunishByzantine); err != nil {
   573  					return err
   574  				}
   575  				break
   576  			}
   577  		}
   578  
   579  		if validator.AbsentCommit > param.AbsentCommitLimitation {
   580  			if err := vm.PunishCommittingValidator(ctx, validator.Username, param.PenaltyMissCommit,
   581  				linotypes.PunishAbsentCommit); err != nil {
   582  				return err
   583  			}
   584  		}
   585  	}
   586  
   587  	return nil
   588  }
   589  
   590  func (vm ValidatorManager) checkDupPubKey(ctx sdk.Context, pubKey crypto.PubKey) sdk.Error {
   591  	// make sure the pub key has not been registered
   592  	allValidators := vm.GetAllValidators(ctx)
   593  	for _, validatorName := range allValidators {
   594  		validator, err := vm.storage.GetValidator(ctx, validatorName)
   595  		if err != nil {
   596  			return err
   597  		}
   598  		if reflect.DeepEqual(validator.ABCIValidator.Address, pubKey.Address().Bytes()) {
   599  			return types.ErrValidatorPubKeyAlreadyExist()
   600  		}
   601  	}
   602  
   603  	return nil
   604  }
   605  
   606  func (vm ValidatorManager) onStakeChange(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   607  	lst := vm.storage.GetElectionVoteList(ctx, username)
   608  	oldList := []linotypes.AccountKey{}
   609  	for _, electionVote := range lst.ElectionVotes {
   610  		oldList = append(oldList, electionVote.ValidatorName)
   611  	}
   612  
   613  	updates, err := vm.getElectionVoteListUpdates(ctx, username, oldList)
   614  	if err != nil {
   615  		return err
   616  	}
   617  
   618  	if err := vm.updateValidatorReceivedVotes(ctx, updates); err != nil {
   619  		return err
   620  	}
   621  
   622  	if err := vm.setNewElectionVoteList(ctx, username, oldList); err != nil {
   623  		return err
   624  	}
   625  	return nil
   626  }
   627  
   628  func (vm ValidatorManager) onCandidateVotesInc(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   629  	me, err := vm.GetValidator(ctx, username)
   630  	if err != nil {
   631  		return err
   632  	}
   633  
   634  	lst := vm.GetValidatorList(ctx)
   635  	if me.ReceivedVotes.IsGT(lst.LowestOncallVotes) {
   636  		// join the oncall validator list
   637  		vm.removeValidatorFromCandidateList(ctx, username)
   638  		if err := vm.addValidatortToOncallList(ctx, username); err != nil {
   639  			return err
   640  		}
   641  	} else if me.ReceivedVotes.IsGT(lst.LowestStandbyVotes) {
   642  		// join the standby validator list
   643  		vm.removeValidatorFromCandidateList(ctx, username)
   644  		if err := vm.addValidatortToStandbyList(ctx, username); err != nil {
   645  			return err
   646  		}
   647  	}
   648  
   649  	if err := vm.balanceValidatorList(ctx); err != nil {
   650  		return err
   651  	}
   652  	return nil
   653  }
   654  
   655  func (vm ValidatorManager) onStandbyVotesInc(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   656  	me, err := vm.GetValidator(ctx, username)
   657  	if err != nil {
   658  		return err
   659  	}
   660  
   661  	// join the oncall validator list
   662  	lst := vm.GetValidatorList(ctx)
   663  	if me.ReceivedVotes.IsGT(lst.LowestOncallVotes) {
   664  		vm.removeValidatorFromStandbyList(ctx, username)
   665  		if err := vm.addValidatortToOncallList(ctx, username); err != nil {
   666  			return err
   667  		}
   668  	}
   669  	if err := vm.balanceValidatorList(ctx); err != nil {
   670  		return err
   671  	}
   672  	return nil
   673  }
   674  
   675  func (vm ValidatorManager) onOncallVotesInc(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   676  	if err := vm.setOncallValidatorPower(ctx, username); err != nil {
   677  		return err
   678  	}
   679  	if err := vm.balanceValidatorList(ctx); err != nil {
   680  		return err
   681  	}
   682  	return nil
   683  }
   684  
   685  func (vm ValidatorManager) onStandbyVotesDec(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   686  	lst := vm.GetValidatorList(ctx)
   687  	validator, err := vm.GetValidator(ctx, username)
   688  	if err != nil {
   689  		return err
   690  	}
   691  
   692  	if !validator.ReceivedVotes.IsGTE(lst.LowestStandbyVotes) {
   693  		vm.removeValidatorFromStandbyList(ctx, username)
   694  		if err := vm.addValidatortToCandidateList(ctx, username); err != nil {
   695  			return err
   696  		}
   697  	}
   698  
   699  	if err := vm.balanceValidatorList(ctx); err != nil {
   700  		return err
   701  	}
   702  	return nil
   703  }
   704  
   705  func (vm ValidatorManager) onOncallVotesDec(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   706  	if err := vm.setOncallValidatorPower(ctx, username); err != nil {
   707  		return err
   708  	}
   709  
   710  	lst := vm.GetValidatorList(ctx)
   711  	validator, err := vm.GetValidator(ctx, username)
   712  	if err != nil {
   713  		return err
   714  	}
   715  
   716  	if !validator.ReceivedVotes.IsGTE(lst.LowestStandbyVotes) {
   717  		// move to the candidate validator list
   718  		vm.removeValidatorFromOncallList(ctx, username)
   719  		if err := vm.addValidatortToCandidateList(ctx, username); err != nil {
   720  			return err
   721  		}
   722  	} else if !validator.ReceivedVotes.IsGTE(lst.LowestOncallVotes) {
   723  		// move to the standby validator list
   724  		vm.removeValidatorFromOncallList(ctx, username)
   725  		if err := vm.addValidatortToStandbyList(ctx, username); err != nil {
   726  			return err
   727  		}
   728  	}
   729  	if err := vm.balanceValidatorList(ctx); err != nil {
   730  		return err
   731  	}
   732  	return nil
   733  }
   734  
   735  func (vm ValidatorManager) balanceValidatorList(ctx sdk.Context) sdk.Error {
   736  	if err := vm.removeExtraOncall(ctx); err != nil {
   737  		return err
   738  	}
   739  	if err := vm.removeExtraStandby(ctx); err != nil {
   740  		return err
   741  	}
   742  	if err := vm.fillEmptyOncall(ctx); err != nil {
   743  		return err
   744  	}
   745  	if err := vm.fillEmptyStandby(ctx); err != nil {
   746  		return err
   747  	}
   748  	if err := vm.updateLowestOncall(ctx); err != nil {
   749  		return err
   750  	}
   751  	if err := vm.updateLowestStandby(ctx); err != nil {
   752  		return err
   753  	}
   754  	return nil
   755  }
   756  
   757  // move lowest votes oncall validator to standby list if current oncall size exceeds max
   758  func (vm ValidatorManager) removeExtraOncall(ctx sdk.Context) sdk.Error {
   759  	lst := vm.storage.GetValidatorList(ctx)
   760  	curLen := int64(len(lst.Oncall))
   761  	param := vm.paramHolder.GetValidatorParam(ctx)
   762  
   763  	for curLen > param.OncallSize {
   764  		lst := vm.storage.GetValidatorList(ctx)
   765  		lowestOncall, _, err := vm.getLowestVotesAndValidator(ctx, lst.Oncall)
   766  		if err != nil {
   767  			return err
   768  		}
   769  		vm.removeValidatorFromOncallList(ctx, lowestOncall)
   770  		if err := vm.addValidatortToStandbyList(ctx, lowestOncall); err != nil {
   771  			return err
   772  		}
   773  		curLen--
   774  	}
   775  	return nil
   776  }
   777  
   778  // move lowest votes standby validator to candidate list if current standby size exceeds max
   779  func (vm ValidatorManager) removeExtraStandby(ctx sdk.Context) sdk.Error {
   780  	lst := vm.storage.GetValidatorList(ctx)
   781  	curLen := int64(len(lst.Standby))
   782  	param := vm.paramHolder.GetValidatorParam(ctx)
   783  	for curLen > param.StandbySize {
   784  		lst := vm.storage.GetValidatorList(ctx)
   785  		lowestStandby, _, err := vm.getLowestVotesAndValidator(ctx, lst.Standby)
   786  		if err != nil {
   787  			return err
   788  		}
   789  		vm.removeValidatorFromStandbyList(ctx, lowestStandby)
   790  		if err := vm.addValidatortToCandidateList(ctx, lowestStandby); err != nil {
   791  			return err
   792  		}
   793  		curLen--
   794  	}
   795  	return nil
   796  }
   797  
   798  // move highest votes standby validator to oncall list if current oncall size not full
   799  // if standby validator not enough, try move highest votes candidate validator
   800  func (vm ValidatorManager) fillEmptyOncall(ctx sdk.Context) sdk.Error {
   801  	lst := vm.storage.GetValidatorList(ctx)
   802  	lenOncall := int64(len(lst.Oncall))
   803  	lenStandby := int64(len(lst.Standby))
   804  	lenCandidate := int64(len(lst.Candidates))
   805  	param := vm.paramHolder.GetValidatorParam(ctx)
   806  
   807  	for lenOncall < param.OncallSize && lenStandby > 0 {
   808  		lst := vm.storage.GetValidatorList(ctx)
   809  		highestStandby, _, err := vm.getHighestVotesAndValidator(ctx, lst.Standby)
   810  		if err != nil {
   811  			return err
   812  		}
   813  		vm.removeValidatorFromStandbyList(ctx, highestStandby)
   814  		if err := vm.addValidatortToOncallList(ctx, highestStandby); err != nil {
   815  			return err
   816  		}
   817  		lenOncall++
   818  		lenStandby--
   819  	}
   820  
   821  	for lenOncall < param.OncallSize && lenCandidate > 0 {
   822  		lst := vm.storage.GetValidatorList(ctx)
   823  		highestCandidate, _, err := vm.getHighestVotesAndValidator(ctx, lst.Candidates)
   824  		if err != nil {
   825  			return err
   826  		}
   827  		vm.removeValidatorFromCandidateList(ctx, highestCandidate)
   828  		if err := vm.addValidatortToOncallList(ctx, highestCandidate); err != nil {
   829  			return err
   830  		}
   831  		lenOncall++
   832  		lenCandidate--
   833  	}
   834  
   835  	return nil
   836  }
   837  
   838  // move highest votes candidate validator to standby list if current standby size not full
   839  func (vm ValidatorManager) fillEmptyStandby(ctx sdk.Context) sdk.Error {
   840  	lst := vm.storage.GetValidatorList(ctx)
   841  	lenStandby := int64(len(lst.Standby))
   842  	lenCandidate := int64(len(lst.Candidates))
   843  	param := vm.paramHolder.GetValidatorParam(ctx)
   844  
   845  	for lenStandby < param.StandbySize && lenCandidate > 0 {
   846  		lst := vm.storage.GetValidatorList(ctx)
   847  		highestCandidate, _, err := vm.getHighestVotesAndValidator(ctx, lst.Candidates)
   848  		if err != nil {
   849  			return err
   850  		}
   851  		vm.removeValidatorFromCandidateList(ctx, highestCandidate)
   852  		if err := vm.addValidatortToStandbyList(ctx, highestCandidate); err != nil {
   853  			return err
   854  		}
   855  		lenStandby++
   856  		lenCandidate--
   857  	}
   858  	return nil
   859  }
   860  
   861  func (vm ValidatorManager) removeValidatorFromAllLists(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   862  	vm.removeValidatorFromOncallList(ctx, username)
   863  	vm.removeValidatorFromStandbyList(ctx, username)
   864  	vm.removeValidatorFromCandidateList(ctx, username)
   865  	vm.removeValidatorFromJailList(ctx, username)
   866  	return nil
   867  }
   868  
   869  func (vm ValidatorManager) removeValidatorFromOncallList(ctx sdk.Context, username linotypes.AccountKey) {
   870  	lst := vm.storage.GetValidatorList(ctx)
   871  	lst.Oncall = removeFromList(username, lst.Oncall)
   872  	vm.storage.SetValidatorList(ctx, lst)
   873  }
   874  
   875  func (vm ValidatorManager) removeValidatorFromStandbyList(ctx sdk.Context, username linotypes.AccountKey) {
   876  	lst := vm.storage.GetValidatorList(ctx)
   877  	lst.Standby = removeFromList(username, lst.Standby)
   878  	vm.storage.SetValidatorList(ctx, lst)
   879  }
   880  
   881  func (vm ValidatorManager) removeValidatorFromCandidateList(ctx sdk.Context, username linotypes.AccountKey) {
   882  	lst := vm.storage.GetValidatorList(ctx)
   883  	lst.Candidates = removeFromList(username, lst.Candidates)
   884  	vm.storage.SetValidatorList(ctx, lst)
   885  }
   886  
   887  func (vm ValidatorManager) removeValidatorFromJailList(ctx sdk.Context, username linotypes.AccountKey) {
   888  	lst := vm.storage.GetValidatorList(ctx)
   889  	lst.Jail = removeFromList(username, lst.Jail)
   890  	vm.storage.SetValidatorList(ctx, lst)
   891  }
   892  
   893  func (vm ValidatorManager) addValidatortToOncallList(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   894  	lst := vm.storage.GetValidatorList(ctx)
   895  	lst.Oncall = append(lst.Oncall, username)
   896  	if err := vm.setOncallValidatorPower(ctx, username); err != nil {
   897  		return err
   898  	}
   899  	vm.storage.SetValidatorList(ctx, lst)
   900  	return nil
   901  }
   902  
   903  func (vm ValidatorManager) addValidatortToStandbyList(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   904  	lst := vm.storage.GetValidatorList(ctx)
   905  	lst.Standby = append(lst.Standby, username)
   906  	me, err := vm.storage.GetValidator(ctx, username)
   907  	if err != nil {
   908  		return err
   909  	}
   910  
   911  	// set oncall validator committing power equal to 1
   912  	me.ABCIValidator.Power = 1
   913  	vm.storage.SetValidator(ctx, username, me)
   914  	vm.storage.SetValidatorList(ctx, lst)
   915  	return nil
   916  }
   917  
   918  func (vm ValidatorManager) addValidatortToCandidateList(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   919  	lst := vm.storage.GetValidatorList(ctx)
   920  	lst.Candidates = append(lst.Candidates, username)
   921  	me, err := vm.storage.GetValidator(ctx, username)
   922  	if err != nil {
   923  		return err
   924  	}
   925  
   926  	// set oncall validator committing power equal to 0
   927  	me.ABCIValidator.Power = 0
   928  	vm.storage.SetValidator(ctx, username, me)
   929  	vm.storage.SetValidatorList(ctx, lst)
   930  	return nil
   931  }
   932  
   933  func (vm ValidatorManager) addValidatortToJailList(ctx sdk.Context, username linotypes.AccountKey) sdk.Error {
   934  	lst := vm.storage.GetValidatorList(ctx)
   935  	lst.Jail = append(lst.Jail, username)
   936  	me, err := vm.storage.GetValidator(ctx, username)
   937  	if err != nil {
   938  		return err
   939  	}
   940  
   941  	// set oncall validator committing power equal to 0 and clear all stats
   942  	me.ABCIValidator.Power = 0
   943  	me.AbsentCommit = 0
   944  	me.NumSlash = 0
   945  	vm.storage.SetValidator(ctx, username, me)
   946  	vm.storage.SetValidatorList(ctx, lst)
   947  	return nil
   948  }
   949  
   950  func removeFromList(me linotypes.AccountKey, users []linotypes.AccountKey) []linotypes.AccountKey {
   951  	for i := 0; i < len(users); i++ {
   952  		if me == users[i] {
   953  			return append(users[:i], users[i+1:]...)
   954  		}
   955  	}
   956  	return users
   957  }
   958  
   959  func (vm ValidatorManager) getHighestVotesAndValidator(ctx sdk.Context,
   960  	lst []linotypes.AccountKey) (linotypes.AccountKey, linotypes.Coin, sdk.Error) {
   961  	highestValdator := linotypes.AccountKey("")
   962  	highestValdatorVotes := linotypes.NewCoinFromInt64(0)
   963  
   964  	for i := range lst {
   965  		validator, err := vm.storage.GetValidator(ctx, lst[i])
   966  		if err != nil {
   967  			return highestValdator, linotypes.NewCoinFromInt64(0), err
   968  		}
   969  		if validator.ReceivedVotes.IsGTE(highestValdatorVotes) {
   970  			highestValdator = validator.Username
   971  			highestValdatorVotes = validator.ReceivedVotes
   972  		}
   973  	}
   974  	return highestValdator, highestValdatorVotes, nil
   975  }
   976  
   977  func (vm ValidatorManager) getLowestVotesAndValidator(ctx sdk.Context,
   978  	lst []linotypes.AccountKey) (linotypes.AccountKey, linotypes.Coin, sdk.Error) {
   979  	lowestValdator := linotypes.AccountKey("")
   980  	lowestValdatorVotes := linotypes.NewCoinFromInt64(math.MaxInt64)
   981  
   982  	for i := range lst {
   983  		validator, err := vm.storage.GetValidator(ctx, lst[i])
   984  		if err != nil {
   985  			return lowestValdator, linotypes.NewCoinFromInt64(0), err
   986  		}
   987  		if lowestValdatorVotes.IsGTE(validator.ReceivedVotes) {
   988  			lowestValdator = validator.Username
   989  			lowestValdatorVotes = validator.ReceivedVotes
   990  		}
   991  	}
   992  	return lowestValdator, lowestValdatorVotes, nil
   993  }
   994  
   995  func (vm ValidatorManager) updateLowestOncall(ctx sdk.Context) sdk.Error {
   996  	lst := vm.storage.GetValidatorList(ctx)
   997  	newLowestVotes := linotypes.NewCoinFromInt64(math.MaxInt64)
   998  	newLowestValidator := linotypes.AccountKey("")
   999  
  1000  	for _, validatorKey := range lst.Oncall {
  1001  		validator, err := vm.storage.GetValidator(ctx, validatorKey)
  1002  		if err != nil {
  1003  			return err
  1004  		}
  1005  
  1006  		if newLowestVotes.IsGT(validator.ReceivedVotes) {
  1007  			newLowestVotes = validator.ReceivedVotes
  1008  			newLowestValidator = validator.Username
  1009  		}
  1010  	}
  1011  
  1012  	// set the new lowest power
  1013  	if len(lst.Oncall) == 0 {
  1014  		lst.LowestOncallVotes = linotypes.NewCoinFromInt64(0)
  1015  		lst.LowestOncall = linotypes.AccountKey("")
  1016  	} else {
  1017  		lst.LowestOncallVotes = newLowestVotes
  1018  		lst.LowestOncall = newLowestValidator
  1019  	}
  1020  
  1021  	vm.storage.SetValidatorList(ctx, lst)
  1022  	return nil
  1023  }
  1024  
  1025  func (vm ValidatorManager) updateLowestStandby(ctx sdk.Context) sdk.Error {
  1026  	lst := vm.storage.GetValidatorList(ctx)
  1027  	newLowestVotes := linotypes.NewCoinFromInt64(math.MaxInt64)
  1028  	newLowestValidator := linotypes.AccountKey("")
  1029  
  1030  	for _, validatorKey := range lst.Standby {
  1031  		validator, err := vm.storage.GetValidator(ctx, validatorKey)
  1032  		if err != nil {
  1033  			return err
  1034  		}
  1035  
  1036  		if newLowestVotes.IsGT(validator.ReceivedVotes) {
  1037  			newLowestVotes = validator.ReceivedVotes
  1038  			newLowestValidator = validator.Username
  1039  		}
  1040  	}
  1041  
  1042  	// set the new lowest power
  1043  	if len(lst.Standby) == 0 {
  1044  		lst.LowestStandbyVotes = linotypes.NewCoinFromInt64(0)
  1045  		lst.LowestStandby = linotypes.AccountKey("")
  1046  	} else {
  1047  
  1048  		lst.LowestStandbyVotes = newLowestVotes
  1049  		lst.LowestStandby = newLowestValidator
  1050  	}
  1051  
  1052  	vm.storage.SetValidatorList(ctx, lst)
  1053  	return nil
  1054  }
  1055  
  1056  func (vm ValidatorManager) setOncallValidatorPower(ctx sdk.Context,
  1057  	username linotypes.AccountKey) sdk.Error {
  1058  	me, err := vm.storage.GetValidator(ctx, username)
  1059  	if err != nil {
  1060  		return err
  1061  	}
  1062  
  1063  	votesCoinInt64, err := me.ReceivedVotes.ToInt64()
  1064  	if err != nil {
  1065  		return err
  1066  	}
  1067  	// set oncall validator committing power equal to it's votes (lino)
  1068  	powerLNO := votesCoinInt64 / linotypes.Decimals
  1069  	switch {
  1070  	case powerLNO > linotypes.ValidatorMaxPower:
  1071  		me.ABCIValidator.Power = linotypes.ValidatorMaxPower
  1072  	case powerLNO < 1:
  1073  		me.ABCIValidator.Power = 1
  1074  	default:
  1075  		me.ABCIValidator.Power = powerLNO
  1076  	}
  1077  
  1078  	vm.storage.SetValidator(ctx, username, me)
  1079  	return nil
  1080  }
  1081  
  1082  // getter and setter
  1083  func (vm ValidatorManager) GetValidator(ctx sdk.Context, accKey linotypes.AccountKey) (*model.Validator, sdk.Error) {
  1084  	return vm.storage.GetValidator(ctx, accKey)
  1085  }
  1086  
  1087  func (vm ValidatorManager) GetAllValidators(ctx sdk.Context) []linotypes.AccountKey {
  1088  	lst := vm.GetValidatorList(ctx)
  1089  	tmp := append(lst.Standby, lst.Candidates...)
  1090  	return append(lst.Oncall, tmp...)
  1091  }
  1092  
  1093  func (vm ValidatorManager) GetCommittingValidators(ctx sdk.Context) []linotypes.AccountKey {
  1094  	lst := vm.GetValidatorList(ctx)
  1095  	return append(lst.Oncall, lst.Standby...)
  1096  }
  1097  
  1098  func (vm ValidatorManager) GetValidatorList(ctx sdk.Context) *model.ValidatorList {
  1099  	return vm.storage.GetValidatorList(ctx)
  1100  }
  1101  
  1102  func (vm ValidatorManager) SetValidatorList(ctx sdk.Context, lst *model.ValidatorList) {
  1103  	vm.storage.SetValidatorList(ctx, lst)
  1104  }
  1105  
  1106  func (vm ValidatorManager) GetElectionVoteList(ctx sdk.Context,
  1107  	accKey linotypes.AccountKey) *model.ElectionVoteList {
  1108  	return vm.storage.GetElectionVoteList(ctx, accKey)
  1109  }
  1110  
  1111  func (vm ValidatorManager) getPrevVotes(ctx sdk.Context, user linotypes.AccountKey) linotypes.Coin {
  1112  	val, err := vm.storage.GetValidator(ctx, user)
  1113  	if err != nil {
  1114  		return linotypes.NewCoinFromInt64(0)
  1115  	}
  1116  	return val.ReceivedVotes
  1117  }
  1118  
  1119  func (vm ValidatorManager) GetCommittingValidatorVoteStatus(ctx sdk.Context) []model.ReceivedVotesStatus {
  1120  	lst := vm.GetCommittingValidators(ctx)
  1121  	res := []model.ReceivedVotesStatus{}
  1122  	for _, name := range lst {
  1123  		val, err := vm.storage.GetValidator(ctx, name)
  1124  		if err != nil {
  1125  			panic(err)
  1126  		}
  1127  		res = append(res, model.ReceivedVotesStatus{
  1128  			ValidatorName: name,
  1129  			ReceivedVotes: val.ReceivedVotes,
  1130  		})
  1131  	}
  1132  	return res
  1133  }
  1134  
  1135  // ExportToFile -
  1136  func (vm ValidatorManager) ExportToFile(ctx sdk.Context, cdc *codec.Codec, filepath string) error {
  1137  	state := &model.ValidatorTablesIR{
  1138  		Version: exportVersion,
  1139  	}
  1140  	substores := vm.storage.StoreMap(ctx)
  1141  
  1142  	// export validators
  1143  	substores[string(model.ValidatorSubstore)].Iterate(func(key []byte, val interface{}) bool {
  1144  		validator := val.(*model.Validator)
  1145  		state.Validators = append(state.Validators, model.ValidatorIR{
  1146  			ABCIValidator: model.ABCIValidatorIR{
  1147  				Address: validator.ABCIValidator.Address,
  1148  				Power:   validator.ABCIValidator.Power,
  1149  			},
  1150  			PubKey:         model.NewABCIPubKeyIRFromTM(validator.PubKey),
  1151  			Username:       validator.Username,
  1152  			ReceivedVotes:  validator.ReceivedVotes,
  1153  			HasRevoked:     validator.HasRevoked,
  1154  			AbsentCommit:   validator.AbsentCommit,
  1155  			ProducedBlocks: validator.ProducedBlocks,
  1156  			Link:           validator.Link,
  1157  		})
  1158  		return false
  1159  	})
  1160  
  1161  	// export votes
  1162  	substores[string(model.ElectionVoteListSubstore)].Iterate(func(key []byte, val interface{}) bool {
  1163  		user := linotypes.AccountKey(key)
  1164  		votelist := val.(*model.ElectionVoteList)
  1165  		votesIR := make([]model.ElectionVoteIR, 0)
  1166  		for _, vote := range votelist.ElectionVotes {
  1167  			votesIR = append(votesIR, model.ElectionVoteIR(vote))
  1168  		}
  1169  		state.Votes = append(state.Votes, model.ElectionVoteListIR{
  1170  			Username:      user,
  1171  			ElectionVotes: votesIR,
  1172  		})
  1173  		return false
  1174  	})
  1175  
  1176  	// export validator list.
  1177  	substores[string(model.ValidatorListSubstore)].Iterate(func(key []byte, val interface{}) bool {
  1178  		lst := val.(*model.ValidatorList)
  1179  		state.List = model.ValidatorListIR(*lst)
  1180  		return false
  1181  	})
  1182  
  1183  	return utils.Save(filepath, cdc, state)
  1184  }
  1185  
  1186  // ImportFromFile import state from file.
  1187  func (vs ValidatorManager) ImportFromFile(ctx sdk.Context, cdc *codec.Codec, filepath string) error {
  1188  	rst, err := utils.Load(filepath, cdc, func() interface{} { return &model.ValidatorTablesIR{} })
  1189  	if err != nil {
  1190  		return err
  1191  	}
  1192  	table := rst.(*model.ValidatorTablesIR)
  1193  
  1194  	if table.Version != importVersion {
  1195  		return fmt.Errorf("unsupported import version: %d", table.Version)
  1196  	}
  1197  
  1198  	// import validators.
  1199  	for _, val := range table.Validators {
  1200  		vs.storage.SetValidator(ctx, val.Username, &model.Validator{
  1201  			ABCIValidator: abci.Validator{
  1202  				Address: val.ABCIValidator.Address,
  1203  				Power:   val.ABCIValidator.Power,
  1204  			},
  1205  			PubKey:         val.PubKey.ToTM(),
  1206  			Username:       val.Username,
  1207  			ReceivedVotes:  val.ReceivedVotes,
  1208  			HasRevoked:     val.HasRevoked,
  1209  			AbsentCommit:   val.AbsentCommit,
  1210  			ProducedBlocks: val.ProducedBlocks,
  1211  			Link:           val.Link,
  1212  		})
  1213  	}
  1214  
  1215  	// import votes.
  1216  	for _, vote := range table.Votes {
  1217  		votes := make([]model.ElectionVote, 0)
  1218  		for _, v := range vote.ElectionVotes {
  1219  			votes = append(votes, model.ElectionVote(v))
  1220  		}
  1221  		vs.storage.SetElectionVoteList(ctx, vote.Username, &model.ElectionVoteList{
  1222  			ElectionVotes: votes,
  1223  		})
  1224  	}
  1225  
  1226  	// import validator list
  1227  	validatorList := model.ValidatorList(table.List)
  1228  	vs.storage.SetValidatorList(ctx, &validatorList)
  1229  	return nil
  1230  }