github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/consensus/neatcon/epoch/epoch_vote.go (about)

     1  package epoch
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"sync"
     7  
     8  	"github.com/neatio-net/crypto-go"
     9  	"github.com/neatio-net/db-go"
    10  	"github.com/neatio-net/neatio/chain/log"
    11  	"github.com/neatio-net/neatio/utilities/common"
    12  	"github.com/neatio-net/wire-go"
    13  )
    14  
    15  var voteRWMutex sync.RWMutex
    16  
    17  func calcEpochValidatorVoteKey(epochNumber uint64) []byte {
    18  	return []byte(fmt.Sprintf("EpochValidatorVote_%v", epochNumber))
    19  }
    20  
    21  type EpochValidatorVoteSet struct {
    22  	Votes          []*EpochValidatorVote
    23  	votesByAddress map[common.Address]*EpochValidatorVote
    24  }
    25  
    26  type EpochValidatorVote struct {
    27  	Address  common.Address
    28  	PubKey   crypto.PubKey
    29  	Amount   *big.Int
    30  	Salt     string
    31  	VoteHash common.Hash
    32  	TxHash   common.Hash
    33  }
    34  
    35  func NewEpochValidatorVoteSet() *EpochValidatorVoteSet {
    36  	return &EpochValidatorVoteSet{
    37  		Votes:          make([]*EpochValidatorVote, 0),
    38  		votesByAddress: make(map[common.Address]*EpochValidatorVote),
    39  	}
    40  }
    41  
    42  func (voteSet *EpochValidatorVoteSet) GetVoteByAddress(address common.Address) (vote *EpochValidatorVote, exist bool) {
    43  	voteRWMutex.RLock()
    44  	defer voteRWMutex.RUnlock()
    45  
    46  	vote, exist = voteSet.votesByAddress[address]
    47  	return
    48  }
    49  
    50  func (voteSet *EpochValidatorVoteSet) StoreVote(vote *EpochValidatorVote) {
    51  	voteRWMutex.Lock()
    52  	defer voteRWMutex.Unlock()
    53  
    54  	oldVote, exist := voteSet.votesByAddress[vote.Address]
    55  	if exist {
    56  		index := -1
    57  		for i := 0; i < len(voteSet.Votes); i++ {
    58  			if voteSet.Votes[i] == oldVote {
    59  				index = i
    60  				break
    61  			}
    62  		}
    63  		voteSet.Votes = append(voteSet.Votes[:index], voteSet.Votes[index+1:]...)
    64  	}
    65  	voteSet.votesByAddress[vote.Address] = vote
    66  	voteSet.Votes = append(voteSet.Votes, vote)
    67  }
    68  
    69  func SaveEpochVoteSet(epochDB db.DB, epochNumber uint64, voteSet *EpochValidatorVoteSet) {
    70  	voteRWMutex.Lock()
    71  	defer voteRWMutex.Unlock()
    72  
    73  	epochDB.SetSync(calcEpochValidatorVoteKey(epochNumber), wire.BinaryBytes(*voteSet))
    74  }
    75  
    76  func LoadEpochVoteSet(epochDB db.DB, epochNumber uint64) *EpochValidatorVoteSet {
    77  	voteRWMutex.RLock()
    78  	defer voteRWMutex.RUnlock()
    79  
    80  	data := epochDB.Get(calcEpochValidatorVoteKey(epochNumber))
    81  	if len(data) == 0 {
    82  		return nil
    83  	} else {
    84  		var voteSet EpochValidatorVoteSet
    85  		err := wire.ReadBinaryBytes(data, &voteSet)
    86  		if err != nil {
    87  			log.Error("Load Epoch Vote Set failed", "error", err)
    88  			return nil
    89  		}
    90  		voteSet.votesByAddress = make(map[common.Address]*EpochValidatorVote)
    91  		for _, v := range voteSet.Votes {
    92  			voteSet.votesByAddress[v.Address] = v
    93  		}
    94  		return &voteSet
    95  	}
    96  }
    97  
    98  func (voteSet *EpochValidatorVoteSet) Copy() *EpochValidatorVoteSet {
    99  	if voteSet == nil {
   100  		return nil
   101  	}
   102  
   103  	votes_copy := make([]*EpochValidatorVote, 0, len(voteSet.Votes))
   104  	votesByAddress_copy := make(map[common.Address]*EpochValidatorVote, len(voteSet.Votes))
   105  	for _, vote := range voteSet.Votes {
   106  		v := vote.Copy()
   107  		votes_copy = append(votes_copy, v)
   108  		votesByAddress_copy[vote.Address] = v
   109  	}
   110  
   111  	return &EpochValidatorVoteSet{
   112  		Votes:          votes_copy,
   113  		votesByAddress: votesByAddress_copy,
   114  	}
   115  }
   116  
   117  func (voteSet *EpochValidatorVoteSet) IsEmpty() bool {
   118  	return voteSet == nil || len(voteSet.Votes) == 0
   119  }
   120  
   121  func (vote *EpochValidatorVote) Copy() *EpochValidatorVote {
   122  	vCopy := *vote
   123  	return &vCopy
   124  }