github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/state/statedb_reward.go (about) 1 package state 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "math/big" 8 "sort" 9 10 "github.com/neatlab/neatio/chain/trie" 11 "github.com/neatlab/neatio/utilities/common" 12 "github.com/neatlab/neatio/utilities/rlp" 13 ) 14 15 func (self *StateDB) GetTotalRewardBalance(addr common.Address) *big.Int { 16 stateObject := self.getStateObject(addr) 17 if stateObject != nil { 18 return stateObject.RewardBalance() 19 } 20 return common.Big0 21 } 22 23 func (self *StateDB) AddRewardBalance(addr common.Address, amount *big.Int) { 24 stateObject := self.GetOrNewStateObject(addr) 25 if stateObject != nil { 26 27 stateObject.AddRewardBalance(amount) 28 } 29 } 30 31 func (self *StateDB) SubRewardBalance(addr common.Address, amount *big.Int) { 32 stateObject := self.GetOrNewStateObject(addr) 33 if stateObject != nil { 34 35 stateObject.SubRewardBalance(amount) 36 } 37 } 38 39 func (self *StateDB) GetDelegateRewardAddress(addr common.Address) map[common.Address]struct{} { 40 var deleAddr map[common.Address]struct{} 41 reward := Reward{} 42 43 so := self.getStateObject(addr) 44 if so == nil { 45 return deleAddr 46 } 47 48 it := trie.NewIterator(so.getRewardTrie(self.db).NodeIterator(nil)) 49 for it.Next() { 50 var key common.Address 51 rlp.DecodeBytes(self.trie.GetKey(it.Key), &key) 52 deleAddr[key] = struct{}{} 53 } 54 55 if len(so.dirtyReward) > len(deleAddr) { 56 reward = so.dirtyReward 57 for key := range reward { 58 deleAddr[key] = struct{}{} 59 } 60 } 61 62 if len(so.originReward) > len(deleAddr) { 63 reward = so.originReward 64 for key := range reward { 65 deleAddr[key] = struct{}{} 66 } 67 } 68 69 return deleAddr 70 } 71 72 func (self *StateDB) GetRewardBalanceByDelegateAddress(addr common.Address, deleAddress common.Address) *big.Int { 73 stateObject := self.getStateObject(addr) 74 if stateObject != nil { 75 rewardBalance := stateObject.GetDelegateRewardBalance(self.db, deleAddress) 76 if rewardBalance == nil { 77 return common.Big0 78 } else { 79 return rewardBalance 80 } 81 } 82 return common.Big0 83 } 84 85 func (self *StateDB) AddRewardBalanceByDelegateAddress(addr common.Address, deleAddress common.Address, amount *big.Int) { 86 stateObject := self.GetOrNewStateObject(addr) 87 if stateObject != nil { 88 89 rewardBalance := stateObject.GetDelegateRewardBalance(self.db, deleAddress) 90 var dirtyRewardBalance *big.Int 91 if rewardBalance == nil { 92 dirtyRewardBalance = amount 93 } else { 94 dirtyRewardBalance = new(big.Int).Add(rewardBalance, amount) 95 } 96 stateObject.SetDelegateRewardBalance(self.db, deleAddress, dirtyRewardBalance) 97 98 stateObject.AddRewardBalance(amount) 99 } 100 } 101 102 func (self *StateDB) SubRewardBalanceByDelegateAddress(addr common.Address, deleAddress common.Address, amount *big.Int) { 103 stateObject := self.GetOrNewStateObject(addr) 104 if stateObject != nil { 105 106 rewardBalance := stateObject.GetDelegateRewardBalance(self.db, deleAddress) 107 var dirtyRewardBalance *big.Int 108 if rewardBalance == nil { 109 panic("you can't subtract the amount from nil balance, check the code, this should not happen") 110 } else { 111 dirtyRewardBalance = new(big.Int).Sub(rewardBalance, amount) 112 } 113 stateObject.SetDelegateRewardBalance(self.db, deleAddress, dirtyRewardBalance) 114 115 stateObject.SubRewardBalance(amount) 116 } 117 } 118 119 func (db *StateDB) ForEachReward(addr common.Address, cb func(key common.Address, rewardBalance *big.Int) bool) { 120 so := db.getStateObject(addr) 121 if so == nil { 122 return 123 } 124 it := trie.NewIterator(so.getRewardTrie(db.db).NodeIterator(nil)) 125 for it.Next() { 126 var key common.Address 127 rlp.DecodeBytes(db.trie.GetKey(it.Key), &key) 128 if value, dirty := so.dirtyReward[key]; dirty { 129 cb(key, value) 130 continue 131 } 132 var value big.Int 133 rlp.DecodeBytes(it.Value, &value) 134 cb(key, &value) 135 } 136 } 137 138 func (self *StateDB) MarkAddressReward(addr common.Address) { 139 if _, exist := self.GetRewardSet()[addr]; !exist { 140 self.rewardSet[addr] = struct{}{} 141 self.rewardSetDirty = true 142 } 143 } 144 145 func (self *StateDB) GetRewardSet() RewardSet { 146 if len(self.rewardSet) != 0 { 147 return self.rewardSet 148 } 149 150 enc, err := self.trie.TryGet(rewardSetKey) 151 if err != nil { 152 self.setError(err) 153 return nil 154 } 155 var value RewardSet 156 if len(enc) > 0 { 157 err := rlp.DecodeBytes(enc, &value) 158 if err != nil { 159 self.setError(err) 160 } 161 self.rewardSet = value 162 } 163 return value 164 } 165 166 func (self *StateDB) commitRewardSet() { 167 data, err := rlp.EncodeToBytes(self.rewardSet) 168 if err != nil { 169 panic(fmt.Errorf("can't encode reward set : %v", err)) 170 } 171 self.setError(self.trie.TryUpdate(rewardSetKey, data)) 172 } 173 174 func (self *StateDB) ClearRewardSetByAddress(addr common.Address) { 175 delete(self.rewardSet, addr) 176 self.rewardSetDirty = true 177 } 178 179 var rewardSetKey = []byte("RewardSet") 180 181 type RewardSet map[common.Address]struct{} 182 183 func (set RewardSet) EncodeRLP(w io.Writer) error { 184 var list []common.Address 185 for addr := range set { 186 list = append(list, addr) 187 } 188 sort.Slice(list, func(i, j int) bool { 189 return bytes.Compare(list[i].Bytes(), list[j].Bytes()) == 1 190 }) 191 return rlp.Encode(w, list) 192 } 193 194 func (set *RewardSet) DecodeRLP(s *rlp.Stream) error { 195 var list []common.Address 196 if err := s.Decode(&list); err != nil { 197 return err 198 } 199 rewardSet := make(RewardSet, len(list)) 200 for _, addr := range list { 201 rewardSet[addr] = struct{}{} 202 } 203 *set = rewardSet 204 return nil 205 } 206 207 func (self *StateDB) SetSideChainRewardPerBlock(rewardPerBlock *big.Int) { 208 self.sideChainRewardPerBlock = rewardPerBlock 209 self.sideChainRewardPerBlockDirty = true 210 } 211 212 func (self *StateDB) GetSideChainRewardPerBlock() *big.Int { 213 if self.sideChainRewardPerBlock != nil { 214 return self.sideChainRewardPerBlock 215 } 216 217 enc, err := self.trie.TryGet(sideChainRewardPerBlockKey) 218 if err != nil { 219 self.setError(err) 220 return nil 221 } 222 value := new(big.Int) 223 if len(enc) > 0 { 224 err := rlp.DecodeBytes(enc, value) 225 if err != nil { 226 self.setError(err) 227 } 228 self.sideChainRewardPerBlock = value 229 } 230 return value 231 } 232 233 func (self *StateDB) commitSideChainRewardPerBlock() { 234 data, err := rlp.EncodeToBytes(self.sideChainRewardPerBlock) 235 if err != nil { 236 panic(fmt.Errorf("can't encode child chain reward per block : %v", err)) 237 } 238 self.setError(self.trie.TryUpdate(sideChainRewardPerBlockKey, data)) 239 } 240 241 var sideChainRewardPerBlockKey = []byte("RewardPerBlock") 242 243 func (self *StateDB) MarkProposedInEpoch(address common.Address, epoch uint64) error { 244 245 return self.db.TrieDB().MarkProposedInEpoch(address, epoch) 246 } 247 248 func (self *StateDB) CheckProposedInEpoch(address common.Address, epoch uint64) bool { 249 250 return self.db.TrieDB().CheckProposedInEpoch(address, epoch) 251 }