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  }