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 }