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

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