github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/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/neatio-net/neatio/chain/trie"
    11  	"github.com/neatio-net/neatio/utilities/common"
    12  	"github.com/neatio-net/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  }