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