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  }