github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/core/state/state_object_reward.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/neatio-net/neatio/chain/log"
     8  	"github.com/neatio-net/neatio/utilities/common"
     9  	"github.com/neatio-net/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  }