github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/state/state_object_reward.go (about) 1 package state 2 3 import ( 4 "fmt" 5 "github.com/intfoundation/intchain/common" 6 "github.com/intfoundation/intchain/log" 7 "github.com/intfoundation/intchain/rlp" 8 "math/big" 9 ) 10 11 // ----- Type 12 type Reward map[common.Address]*big.Int // key = Delegate Address, value = Reward Amount 13 14 func (p Reward) String() (str string) { 15 for key, value := range p { 16 str += fmt.Sprintf("Address %v : %v\n", key.String(), value) 17 } 18 return 19 } 20 21 func (p Reward) Copy() Reward { 22 cpy := make(Reward) 23 for key, value := range p { 24 25 //cpy[key] = new(big.Int).Set(value) 26 cpy[key] = value 27 } 28 return cpy 29 } 30 31 // ----- RewardBalance 32 33 // AddRewardBalance add amount to c's RewardBalance. 34 func (c *stateObject) AddRewardBalance(amount *big.Int) { 35 // EIP158: We must check emptiness for the objects such that the account 36 // clearing (0,0,0 objects) can take effect. 37 if amount.Sign() == 0 { 38 if c.empty() { 39 c.touch() 40 } 41 return 42 } 43 c.SetRewardBalance(new(big.Int).Add(c.RewardBalance(), amount)) 44 } 45 46 // SubRewardBalance removes amount from c's RewardBalance. 47 func (c *stateObject) SubRewardBalance(amount *big.Int) { 48 if amount.Sign() == 0 { 49 return 50 } 51 c.SetRewardBalance(new(big.Int).Sub(c.RewardBalance(), amount)) 52 } 53 54 func (self *stateObject) SetRewardBalance(amount *big.Int) { 55 if amount.Sign() < 0 { 56 log.Infof("!!!amount is negative, not support yet, make it 0 by force") 57 amount = big.NewInt(0) 58 } 59 60 self.db.journal = append(self.db.journal, rewardBalanceChange{ 61 account: &self.address, 62 prev: new(big.Int).Set(self.data.RewardBalance), 63 }) 64 self.setRewardBalance(amount) 65 } 66 67 func (self *stateObject) setRewardBalance(amount *big.Int) { 68 self.data.RewardBalance = amount 69 if self.onDirty != nil { 70 self.onDirty(self.Address()) 71 self.onDirty = nil 72 } 73 } 74 75 func (self *stateObject) RewardBalance() *big.Int { 76 return self.data.RewardBalance 77 } 78 79 // AvailableRewardBalance 80 81 //func (self *stateObject) AddAvailableRewardBalance(amount *big.Int) { 82 // if amount.Sign() == 0 { 83 // if self.empty() { 84 // self.touch() 85 // } 86 // return 87 // } 88 // self.SetAvailableRewardBalance(new(big.Int).Add(self.AvailableRewardBalance(), amount)) 89 //} 90 // 91 //func (self *stateObject) SubAvailableRewardBalance(amount *big.Int) { 92 // if amount.Sign() == 0 { 93 // return 94 // } 95 // self.SetAvailableRewardBalance(new(big.Int).Sub(self.AvailableRewardBalance(), amount)) 96 //} 97 // 98 //func (self *stateObject) SetAvailableRewardBalance(amount *big.Int) { 99 // self.db.journal = append(self.db.journal, availableRewardBalanceChange{ 100 // account: &self.address, 101 // prev: new(big.Int).Set(self.data.AvailableRewardBalance), 102 // }) 103 // 104 // self.setAvailableRewardBalance(amount) 105 //} 106 // 107 //func (self *stateObject) setAvailableRewardBalance(amount *big.Int) { 108 // self.data.AvailableRewardBalance = amount 109 // if self.onDirty != nil { 110 // self.onDirty(self.Address()) 111 // self.onDirty = nil 112 // } 113 //} 114 // 115 //func (self *stateObject) AvailableRewardBalance() *big.Int { 116 // return self.data.AvailableRewardBalance 117 //} 118 119 // ----- Reward Trie 120 121 func (c *stateObject) getRewardTrie(db Database) Trie { 122 if c.rewardTrie == nil { 123 var err error 124 c.rewardTrie, err = db.OpenRewardTrie(c.addrHash, c.data.RewardRoot) 125 if err != nil { 126 c.rewardTrie, _ = db.OpenRewardTrie(c.addrHash, common.Hash{}) 127 c.setError(fmt.Errorf("can't create reward trie: %v", err)) 128 } 129 } 130 return c.rewardTrie 131 } 132 133 //func (self *stateObject) GetDelegateRewardAddress(db Database) []common.Address { 134 // var deleAddr []common.Address 135 // reward := Reward{} 136 // if len(self.dirtyReward) > len(self.originReward) { 137 // reward = self.dirtyReward 138 // } else { 139 // reward = self.originReward 140 // } 141 // 142 // it := self.getRewardTrie(db).NodeIterator(nil) 143 // for it.Next() { 144 // var key common.Address 145 // rlp.DecodeBytes(db.trie.GetKey(it.Key), &key) 146 // } 147 // 148 // return deleAddr 149 //} 150 151 // GetDelegateRewardBalance returns a value in Reward trie 152 func (self *stateObject) GetDelegateRewardBalance(db Database, key common.Address) *big.Int { 153 // If we have a dirty value for this state entry, return it 154 value, dirty := self.dirtyReward[key] 155 if dirty { 156 return value 157 } 158 // If we have the original value cached, return that 159 value, cached := self.originReward[key] 160 if cached { 161 return value 162 } 163 // Otherwise load the value from the database 164 k, _ := rlp.EncodeToBytes(key) 165 enc, err := self.getRewardTrie(db).TryGet(k) 166 if err != nil { 167 self.setError(err) 168 return nil 169 } 170 if len(enc) > 0 { 171 value = new(big.Int) 172 err := rlp.DecodeBytes(enc, value) 173 if err != nil { 174 self.setError(err) 175 } 176 } 177 self.originReward[key] = value 178 return value 179 } 180 181 // SetDelegateRewardBalance updates a value in Epoch Reward. 182 func (self *stateObject) SetDelegateRewardBalance(db Database, key common.Address, rewardAmount *big.Int) { 183 self.db.journal = append(self.db.journal, delegateRewardBalanceChange{ 184 account: &self.address, 185 key: key, 186 prevalue: self.GetDelegateRewardBalance(db, key), 187 }) 188 self.setDelegateRewardBalance(key, rewardAmount) 189 } 190 191 func (self *stateObject) setDelegateRewardBalance(key common.Address, rewardAmount *big.Int) { 192 self.dirtyReward[key] = rewardAmount 193 194 if self.onDirty != nil { 195 self.onDirty(self.Address()) 196 self.onDirty = nil 197 } 198 } 199 200 // updateRewardTrie writes cached reward modifications into the object's reward trie. 201 func (self *stateObject) updateRewardTrie(db Database) Trie { 202 tr := self.getRewardTrie(db) 203 for key, value := range self.dirtyReward { 204 delete(self.dirtyReward, key) 205 206 // Skip noop changes, persist actual changes 207 if self.originReward[key] != nil && value.Cmp(self.originReward[key]) == 0 { 208 continue 209 } 210 self.originReward[key] = value 211 212 k, _ := rlp.EncodeToBytes(key) 213 if value.Sign() == 0 { 214 self.setError(tr.TryDelete(k)) 215 continue 216 } 217 // Encoding []byte cannot fail, ok to ignore the error. 218 v, _ := rlp.EncodeToBytes(value) 219 self.setError(tr.TryUpdate(k, v)) 220 } 221 return tr 222 } 223 224 // updateRewardRoot sets the rewardTrie root to the current root hash of 225 func (self *stateObject) updateRewardRoot(db Database) { 226 self.updateRewardTrie(db) 227 self.data.RewardRoot = self.rewardTrie.Hash() 228 } 229 230 // CommitRewardTrie the reward trie of the object to dwb. 231 // This updates the reward trie root. 232 func (self *stateObject) CommitRewardTrie(db Database) error { 233 self.updateRewardTrie(db) 234 if self.dbErr != nil { 235 return self.dbErr 236 } 237 root, err := self.rewardTrie.Commit(nil) 238 if err == nil { 239 self.data.RewardRoot = root 240 } 241 return err 242 }