github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/state/state_object_delegate.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/intfoundation/intchain/common"
     6  	"github.com/intfoundation/intchain/core/types"
     7  	"github.com/intfoundation/intchain/rlp"
     8  	"math/big"
     9  )
    10  
    11  // ----- Type
    12  type accountProxiedBalance struct {
    13  	ProxiedBalance        *big.Int
    14  	DepositProxiedBalance *big.Int
    15  	PendingRefundBalance  *big.Int
    16  }
    17  
    18  func (a *accountProxiedBalance) String() (str string) {
    19  	return fmt.Sprintf("pb: %v, dpb: %v, rb: %v", a.ProxiedBalance, a.DepositProxiedBalance, a.PendingRefundBalance)
    20  }
    21  
    22  func (a *accountProxiedBalance) Copy() *accountProxiedBalance {
    23  	cpy := *a
    24  	return &cpy
    25  }
    26  
    27  func (a *accountProxiedBalance) Equal(b *accountProxiedBalance) bool {
    28  	if b == nil {
    29  		return false
    30  	}
    31  	return a.ProxiedBalance.Cmp(b.ProxiedBalance) == 0 && a.DepositProxiedBalance.Cmp(b.DepositProxiedBalance) == 0 && a.PendingRefundBalance.Cmp(b.PendingRefundBalance) == 0
    32  }
    33  
    34  func (a *accountProxiedBalance) IsEmpty() bool {
    35  	return a.ProxiedBalance.Sign() == 0 && a.DepositProxiedBalance.Sign() == 0 && a.PendingRefundBalance.Sign() == 0
    36  }
    37  
    38  func NewAccountProxiedBalance() *accountProxiedBalance {
    39  	return &accountProxiedBalance{
    40  		ProxiedBalance:        big.NewInt(0),
    41  		DepositProxiedBalance: big.NewInt(0),
    42  		PendingRefundBalance:  big.NewInt(0),
    43  	}
    44  }
    45  
    46  type Proxied map[common.Address]*accountProxiedBalance
    47  
    48  func (p Proxied) String() (str string) {
    49  	for key, value := range p {
    50  		str += fmt.Sprintf("%v : %X\n", key.String(), value)
    51  	}
    52  	return
    53  }
    54  
    55  func (p Proxied) Copy() Proxied {
    56  	cpy := make(Proxied)
    57  	for key, value := range p {
    58  		cpy[key] = value.Copy()
    59  	}
    60  	return cpy
    61  }
    62  
    63  // ----- DelegateBalance
    64  
    65  // AddDelegateBalance add amount to c's DelegateBalance.
    66  func (c *stateObject) AddDelegateBalance(amount *big.Int) {
    67  	// EIP158: We must check emptiness for the objects such that the account
    68  	// clearing (0,0,0 objects) can take effect.
    69  	if amount.Sign() == 0 {
    70  		if c.empty() {
    71  			c.touch()
    72  		}
    73  		return
    74  	}
    75  	c.SetDelegateBalance(new(big.Int).Add(c.DelegateBalance(), amount))
    76  }
    77  
    78  // SubDelegateBalance removes amount from c's DelegateBalance.
    79  func (c *stateObject) SubDelegateBalance(amount *big.Int) {
    80  	if amount.Sign() == 0 {
    81  		return
    82  	}
    83  	c.SetDelegateBalance(new(big.Int).Sub(c.DelegateBalance(), amount))
    84  }
    85  
    86  func (self *stateObject) SetDelegateBalance(amount *big.Int) {
    87  	self.db.journal = append(self.db.journal, delegateBalanceChange{
    88  		account: &self.address,
    89  		prev:    new(big.Int).Set(self.data.DelegateBalance),
    90  	})
    91  	self.setDelegateBalance(amount)
    92  }
    93  
    94  func (self *stateObject) setDelegateBalance(amount *big.Int) {
    95  	self.data.DelegateBalance = amount
    96  	if self.onDirty != nil {
    97  		self.onDirty(self.Address())
    98  		self.onDirty = nil
    99  	}
   100  }
   101  
   102  func (self *stateObject) DelegateBalance() *big.Int {
   103  	return self.data.DelegateBalance
   104  }
   105  
   106  // ----- ProxiedBalance
   107  
   108  // AddProxiedBalance add amount to c's ProxiedBalance.
   109  func (c *stateObject) AddProxiedBalance(amount *big.Int) {
   110  	// EIP158: We must check emptiness for the objects such that the account
   111  	// clearing (0,0,0 objects) can take effect.
   112  	if amount.Sign() == 0 {
   113  		if c.empty() {
   114  			c.touch()
   115  		}
   116  		return
   117  	}
   118  	c.SetProxiedBalance(new(big.Int).Add(c.ProxiedBalance(), amount))
   119  }
   120  
   121  // SubProxiedBalance removes amount from c's ProxiedBalance.
   122  func (c *stateObject) SubProxiedBalance(amount *big.Int) {
   123  	if amount.Sign() == 0 {
   124  		return
   125  	}
   126  	c.SetProxiedBalance(new(big.Int).Sub(c.ProxiedBalance(), amount))
   127  }
   128  
   129  func (self *stateObject) SetProxiedBalance(amount *big.Int) {
   130  	self.db.journal = append(self.db.journal, proxiedBalanceChange{
   131  		account: &self.address,
   132  		prev:    new(big.Int).Set(self.data.ProxiedBalance),
   133  	})
   134  	self.setProxiedBalance(amount)
   135  }
   136  
   137  func (self *stateObject) setProxiedBalance(amount *big.Int) {
   138  	self.data.ProxiedBalance = amount
   139  	if self.onDirty != nil {
   140  		self.onDirty(self.Address())
   141  		self.onDirty = nil
   142  	}
   143  }
   144  
   145  func (self *stateObject) ProxiedBalance() *big.Int {
   146  	return self.data.ProxiedBalance
   147  }
   148  
   149  // ----- DepositProxiedBalance
   150  
   151  // AddDepositProxiedBalance add amount to c's DepositProxiedBalance.
   152  func (c *stateObject) AddDepositProxiedBalance(amount *big.Int) {
   153  	// EIP158: We must check emptiness for the objects such that the account
   154  	// clearing (0,0,0 objects) can take effect.
   155  	if amount.Sign() == 0 {
   156  		if c.empty() {
   157  			c.touch()
   158  		}
   159  		return
   160  	}
   161  	c.SetDepositProxiedBalance(new(big.Int).Add(c.DepositProxiedBalance(), amount))
   162  }
   163  
   164  // SubDepositProxiedBalance removes amount from c's DepositProxiedBalance.
   165  func (c *stateObject) SubDepositProxiedBalance(amount *big.Int) {
   166  	if amount.Sign() == 0 {
   167  		return
   168  	}
   169  	c.SetDepositProxiedBalance(new(big.Int).Sub(c.DepositProxiedBalance(), amount))
   170  }
   171  
   172  func (self *stateObject) SetDepositProxiedBalance(amount *big.Int) {
   173  	self.db.journal = append(self.db.journal, depositProxiedBalanceChange{
   174  		account: &self.address,
   175  		prev:    new(big.Int).Set(self.data.DepositProxiedBalance),
   176  	})
   177  	self.setDepositProxiedBalance(amount)
   178  }
   179  
   180  func (self *stateObject) setDepositProxiedBalance(amount *big.Int) {
   181  	self.data.DepositProxiedBalance = amount
   182  	if self.onDirty != nil {
   183  		self.onDirty(self.Address())
   184  		self.onDirty = nil
   185  	}
   186  }
   187  
   188  func (self *stateObject) DepositProxiedBalance() *big.Int {
   189  	return self.data.DepositProxiedBalance
   190  }
   191  
   192  // ----- PendingRefundBalance
   193  
   194  // AddPendingRefundBalance add amount to c's PendingRefundBalance.
   195  func (c *stateObject) AddPendingRefundBalance(amount *big.Int) {
   196  	// EIP158: We must check emptiness for the objects such that the account
   197  	// clearing (0,0,0 objects) can take effect.
   198  	if amount.Sign() == 0 {
   199  		if c.empty() {
   200  			c.touch()
   201  		}
   202  		return
   203  	}
   204  	c.SetPendingRefundBalance(new(big.Int).Add(c.PendingRefundBalance(), amount))
   205  }
   206  
   207  // SubPendingRefundBalance removes amount from c's PendingRefundBalance.
   208  func (c *stateObject) SubPendingRefundBalance(amount *big.Int) {
   209  	if amount.Sign() == 0 {
   210  		return
   211  	}
   212  	c.SetPendingRefundBalance(new(big.Int).Sub(c.PendingRefundBalance(), amount))
   213  }
   214  
   215  func (self *stateObject) SetPendingRefundBalance(amount *big.Int) {
   216  	self.db.journal = append(self.db.journal, pendingRefundBalanceChange{
   217  		account: &self.address,
   218  		prev:    new(big.Int).Set(self.data.PendingRefundBalance),
   219  	})
   220  	self.setPendingRefundBalance(amount)
   221  }
   222  
   223  func (self *stateObject) setPendingRefundBalance(amount *big.Int) {
   224  	self.data.PendingRefundBalance = amount
   225  	if self.onDirty != nil {
   226  		self.onDirty(self.Address())
   227  		self.onDirty = nil
   228  	}
   229  }
   230  
   231  func (self *stateObject) PendingRefundBalance() *big.Int {
   232  	return self.data.PendingRefundBalance
   233  }
   234  
   235  // ----- Delegate Trie
   236  
   237  func (c *stateObject) getProxiedTrie(db Database) Trie {
   238  	if c.proxiedTrie == nil {
   239  		var err error
   240  		c.proxiedTrie, err = db.OpenProxiedTrie(c.addrHash, c.data.ProxiedRoot)
   241  		if err != nil {
   242  			c.proxiedTrie, _ = db.OpenProxiedTrie(c.addrHash, common.Hash{})
   243  			c.setError(fmt.Errorf("can't create proxied trie: %v", err))
   244  		}
   245  	}
   246  	return c.proxiedTrie
   247  }
   248  
   249  // GetAccountProxiedBalance returns a value in proxied trie
   250  func (self *stateObject) GetAccountProxiedBalance(db Database, key common.Address) *accountProxiedBalance {
   251  	// If we have a dirty value for this state entry, return it
   252  	value, dirty := self.dirtyProxied[key]
   253  	if dirty {
   254  		return value
   255  	}
   256  	// If we have the original value cached, return that
   257  	value, cached := self.originProxied[key]
   258  	if cached {
   259  		return value
   260  	}
   261  	// Otherwise load the value from the database
   262  	enc, err := self.getProxiedTrie(db).TryGet(key[:])
   263  	if err != nil {
   264  		self.setError(err)
   265  		return nil
   266  	}
   267  	if len(enc) > 0 {
   268  		value = new(accountProxiedBalance)
   269  		err := rlp.DecodeBytes(enc, value)
   270  		if err != nil {
   271  			self.setError(err)
   272  		}
   273  	}
   274  	self.originProxied[key] = value
   275  	return value
   276  }
   277  
   278  // SetAccountProxiedBalance updates a value in account storage.
   279  func (self *stateObject) SetAccountProxiedBalance(db Database, key common.Address, proxiedBalance *accountProxiedBalance) {
   280  	self.db.journal = append(self.db.journal, accountProxiedBalanceChange{
   281  		account:  &self.address,
   282  		key:      key,
   283  		prevalue: self.GetAccountProxiedBalance(db, key),
   284  	})
   285  	self.setAccountProxiedBalance(key, proxiedBalance)
   286  }
   287  
   288  func (self *stateObject) setAccountProxiedBalance(key common.Address, proxiedBalance *accountProxiedBalance) {
   289  	self.dirtyProxied[key] = proxiedBalance
   290  
   291  	if self.onDirty != nil {
   292  		self.onDirty(self.Address())
   293  		self.onDirty = nil
   294  	}
   295  }
   296  
   297  // updateProxiedTrie writes cached proxied modifications into the object's proxied trie.
   298  func (self *stateObject) updateProxiedTrie(db Database) Trie {
   299  	tr := self.getProxiedTrie(db)
   300  	for key, value := range self.dirtyProxied {
   301  		delete(self.dirtyProxied, key)
   302  
   303  		// Skip noop changes, persist actual changes
   304  		if value.Equal(self.originProxied[key]) {
   305  			continue
   306  		}
   307  		self.originProxied[key] = value
   308  
   309  		if value.IsEmpty() {
   310  			self.setError(tr.TryDelete(key[:]))
   311  			continue
   312  		}
   313  		// Encoding []byte cannot fail, ok to ignore the error.
   314  		v, _ := rlp.EncodeToBytes(value)
   315  		self.setError(tr.TryUpdate(key[:], v))
   316  	}
   317  	return tr
   318  }
   319  
   320  // updateProxiedRoot sets the proxiedTrie root to the current root hash of
   321  func (self *stateObject) updateProxiedRoot(db Database) {
   322  	self.updateProxiedTrie(db)
   323  	self.data.ProxiedRoot = self.proxiedTrie.Hash()
   324  }
   325  
   326  // CommitProxiedTrie the proxied trie of the object to dwb.
   327  // This updates the proxied trie root.
   328  func (self *stateObject) CommitProxiedTrie(db Database) error {
   329  	self.updateProxiedTrie(db)
   330  	if self.dbErr != nil {
   331  		return self.dbErr
   332  	}
   333  	root, err := self.proxiedTrie.Commit(nil)
   334  	if err == nil {
   335  		self.data.ProxiedRoot = root
   336  	}
   337  	return err
   338  }
   339  
   340  func (self *stateObject) IsEmptyTrie() bool {
   341  	return self.data.ProxiedRoot == types.EmptyRootHash
   342  }
   343  
   344  // ----- Candidate
   345  
   346  func (self *stateObject) IsCandidate() bool {
   347  	return self.data.Candidate
   348  }
   349  
   350  func (self *stateObject) SetCandidate(isCandidate bool) {
   351  	self.db.journal = append(self.db.journal, candidateChange{
   352  		account: &self.address,
   353  		prev:    self.data.Candidate,
   354  	})
   355  	self.setCandidate(isCandidate)
   356  }
   357  
   358  func (self *stateObject) setCandidate(isCandidate bool) {
   359  	self.data.Candidate = isCandidate
   360  
   361  	if self.onDirty != nil {
   362  		self.onDirty(self.Address())
   363  		self.onDirty = nil
   364  	}
   365  }
   366  
   367  func (self *stateObject) Pubkey() string {
   368  	return self.data.Pubkey
   369  }
   370  
   371  func (self *stateObject) SetPubkey(pubkey string) {
   372  	self.db.journal = append(self.db.journal, pubkeyChange{
   373  		account: &self.address,
   374  		prev:    self.data.Pubkey,
   375  	})
   376  
   377  	self.setPubkey(pubkey)
   378  }
   379  
   380  func (self *stateObject) setPubkey(pubkey string) {
   381  	self.data.Pubkey = pubkey
   382  
   383  	if self.onDirty != nil {
   384  		self.onDirty(self.Address())
   385  		self.onDirty = nil
   386  	}
   387  }
   388  
   389  func (self *stateObject) Commission() uint8 {
   390  	return self.data.Commission
   391  }
   392  
   393  func (self *stateObject) SetCommission(commission uint8) {
   394  	self.db.journal = append(self.db.journal, commissionChange{
   395  		account: &self.address,
   396  		prev:    self.data.Commission,
   397  	})
   398  	self.setCommission(commission)
   399  }
   400  
   401  func (self *stateObject) setCommission(commission uint8) {
   402  	self.data.Commission = commission
   403  
   404  	if self.onDirty != nil {
   405  		self.onDirty(self.Address())
   406  		self.onDirty = nil
   407  	}
   408  }
   409  
   410  //func (self *stateObject) IsForbidden() bool {
   411  //	return self.data.IsForbidden
   412  //}
   413  //
   414  //func (self *stateObject) SetForbidden(forbidden bool) {
   415  //	self.db.journal = append(self.db.journal, forbiddenChange{
   416  //		account: &self.address,
   417  //		prev:    self.data.IsForbidden,
   418  //	})
   419  //	self.setForbidden(forbidden)
   420  //}
   421  //
   422  //func (self *stateObject) setForbidden(forbidden bool) {
   423  //	self.data.IsForbidden = forbidden
   424  //
   425  //	if self.onDirty != nil {
   426  //		self.onDirty(self.Address())
   427  //		self.onDirty = nil
   428  //	}
   429  //}
   430  
   431  //func (self *stateObject) BlockTime() *big.Int {
   432  //	return self.data.BlockTime
   433  //}
   434  //
   435  //func (self *stateObject) SetBlockTime(blockTime *big.Int) {
   436  //	self.db.journal = append(self.db.journal, blockTimeChange{
   437  //		account: &self.address,
   438  //		prev:    self.data.BlockTime,
   439  //	})
   440  //	self.setBlockTime(blockTime)
   441  //}
   442  //
   443  //func (self *stateObject) setBlockTime(blockTime *big.Int) {
   444  //	self.data.BlockTime = blockTime
   445  //
   446  //	if self.onDirty != nil {
   447  //		self.onDirty(self.Address())
   448  //		self.onDirty = nil
   449  //	}
   450  //}
   451  
   452  //func (self *stateObject) ForbiddenTime() *big.Int {
   453  //	return self.data.ForbiddenTime
   454  //}
   455  //
   456  //func (self *stateObject) SetForbiddenTime(forbiddenTime *big.Int) {
   457  //	self.db.journal = append(self.db.journal, forbiddenTimeChange{
   458  //		account: &self.address,
   459  //		prev:    self.data.ForbiddenTime,
   460  //	})
   461  //	self.setForbiddenTime(forbiddenTime)
   462  //}
   463  //
   464  //func (self *stateObject) setForbiddenTime(forbiddenTime *big.Int) {
   465  //	self.data.ForbiddenTime = forbiddenTime
   466  //
   467  //	if self.onDirty != nil {
   468  //		self.onDirty(self.Address())
   469  //		self.onDirty = nil
   470  //	}
   471  //}