github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/state/state_object_reward.go (about) 1 package state 2 3 import ( 4 "fmt" 5 "math/big" 6 7 "github.com/neatlab/neatio/chain/log" 8 "github.com/neatlab/neatio/utilities/common" 9 "github.com/neatlab/neatio/utilities/rlp" 10 ) 11 12 type Reward map[common.Address]*big.Int 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] = value 26 } 27 return cpy 28 } 29 30 func (c *stateObject) AddRewardBalance(amount *big.Int) { 31 32 if amount.Sign() == 0 { 33 if c.empty() { 34 c.touch() 35 } 36 return 37 } 38 c.SetRewardBalance(new(big.Int).Add(c.RewardBalance(), amount)) 39 } 40 41 func (c *stateObject) SubRewardBalance(amount *big.Int) { 42 if amount.Sign() == 0 { 43 return 44 } 45 c.SetRewardBalance(new(big.Int).Sub(c.RewardBalance(), amount)) 46 } 47 48 func (self *stateObject) SetRewardBalance(amount *big.Int) { 49 if amount.Sign() < 0 { 50 log.Infof("!!!amount is negative, not support yet, make it 0 by force") 51 amount = big.NewInt(0) 52 } 53 54 self.db.journal = append(self.db.journal, rewardBalanceChange{ 55 account: &self.address, 56 prev: new(big.Int).Set(self.data.RewardBalance), 57 }) 58 self.setRewardBalance(amount) 59 } 60 61 func (self *stateObject) setRewardBalance(amount *big.Int) { 62 self.data.RewardBalance = amount 63 if self.onDirty != nil { 64 self.onDirty(self.Address()) 65 self.onDirty = nil 66 } 67 } 68 69 func (self *stateObject) RewardBalance() *big.Int { 70 return self.data.RewardBalance 71 } 72 73 func (c *stateObject) getRewardTrie(db Database) Trie { 74 if c.rewardTrie == nil { 75 var err error 76 c.rewardTrie, err = db.OpenRewardTrie(c.addrHash, c.data.RewardRoot) 77 if err != nil { 78 c.rewardTrie, _ = db.OpenRewardTrie(c.addrHash, common.Hash{}) 79 c.setError(fmt.Errorf("can't create reward trie: %v", err)) 80 } 81 } 82 return c.rewardTrie 83 } 84 85 func (self *stateObject) GetDelegateRewardBalance(db Database, key common.Address) *big.Int { 86 87 value, dirty := self.dirtyReward[key] 88 if dirty { 89 return value 90 } 91 92 value, cached := self.originReward[key] 93 if cached { 94 return value 95 } 96 97 k, _ := rlp.EncodeToBytes(key) 98 enc, err := self.getRewardTrie(db).TryGet(k) 99 if err != nil { 100 self.setError(err) 101 return nil 102 } 103 if len(enc) > 0 { 104 value = new(big.Int) 105 err := rlp.DecodeBytes(enc, value) 106 if err != nil { 107 self.setError(err) 108 } 109 } 110 self.originReward[key] = value 111 return value 112 } 113 114 func (self *stateObject) SetDelegateRewardBalance(db Database, key common.Address, rewardAmount *big.Int) { 115 self.db.journal = append(self.db.journal, delegateRewardBalanceChange{ 116 account: &self.address, 117 key: key, 118 prevalue: self.GetDelegateRewardBalance(db, key), 119 }) 120 self.setDelegateRewardBalance(key, rewardAmount) 121 } 122 123 func (self *stateObject) setDelegateRewardBalance(key common.Address, rewardAmount *big.Int) { 124 self.dirtyReward[key] = rewardAmount 125 126 if self.onDirty != nil { 127 self.onDirty(self.Address()) 128 self.onDirty = nil 129 } 130 } 131 132 func (self *stateObject) updateRewardTrie(db Database) Trie { 133 tr := self.getRewardTrie(db) 134 for key, value := range self.dirtyReward { 135 delete(self.dirtyReward, key) 136 137 if self.originReward[key] != nil && value.Cmp(self.originReward[key]) == 0 { 138 continue 139 } 140 self.originReward[key] = value 141 142 k, _ := rlp.EncodeToBytes(key) 143 if value.Sign() == 0 { 144 self.setError(tr.TryDelete(k)) 145 continue 146 } 147 148 v, _ := rlp.EncodeToBytes(value) 149 self.setError(tr.TryUpdate(k, v)) 150 } 151 return tr 152 } 153 154 func (self *stateObject) updateRewardRoot(db Database) { 155 self.updateRewardTrie(db) 156 self.data.RewardRoot = self.rewardTrie.Hash() 157 } 158 159 func (self *stateObject) CommitRewardTrie(db Database) error { 160 self.updateRewardTrie(db) 161 if self.dbErr != nil { 162 return self.dbErr 163 } 164 root, err := self.rewardTrie.Commit(nil) 165 if err == nil { 166 self.data.RewardRoot = root 167 } 168 return err 169 }