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

     1  package state
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"math/big"
     8  	"sort"
     9  
    10  	"github.com/neatio-net/neatio/chain/trie"
    11  	"github.com/neatio-net/neatio/utilities/common"
    12  	"github.com/neatio-net/neatio/utilities/rlp"
    13  )
    14  
    15  // ----- DelegateBalance
    16  
    17  // GetDelegateBalance Retrieve the delegate balance from the given address or 0 if object not found
    18  func (self *StateDB) GetDelegateBalance(addr common.Address) *big.Int {
    19  	stateObject := self.getStateObject(addr)
    20  	if stateObject != nil {
    21  		return stateObject.DelegateBalance()
    22  	}
    23  	return common.Big0
    24  }
    25  
    26  // AddDelegateBalance adds delegate amount to the account associated with addr
    27  func (self *StateDB) AddDelegateBalance(addr common.Address, amount *big.Int) {
    28  	stateObject := self.GetOrNewStateObject(addr)
    29  	if stateObject != nil {
    30  		stateObject.AddDelegateBalance(amount)
    31  	}
    32  }
    33  
    34  // SubDelegateBalance subtracts delegate amount from the account associated with addr
    35  func (self *StateDB) SubDelegateBalance(addr common.Address, amount *big.Int) {
    36  	stateObject := self.GetOrNewStateObject(addr)
    37  	if stateObject != nil {
    38  		stateObject.SubDelegateBalance(amount)
    39  	}
    40  }
    41  
    42  // ----- ProxiedBalance (Total)
    43  
    44  // GetTotalProxiedBalance Retrieve the proxied balance from the given address or 0 if object not found
    45  func (self *StateDB) GetTotalProxiedBalance(addr common.Address) *big.Int {
    46  	stateObject := self.getStateObject(addr)
    47  	if stateObject != nil {
    48  		return stateObject.ProxiedBalance()
    49  	}
    50  	return common.Big0
    51  }
    52  
    53  // ----- DepositProxiedBalance (Total)
    54  
    55  // GetTotalDepositProxiedBalance Retrieve the deposit proxied balance from the given address or 0 if object not found
    56  func (self *StateDB) GetTotalDepositProxiedBalance(addr common.Address) *big.Int {
    57  	stateObject := self.getStateObject(addr)
    58  	if stateObject != nil {
    59  		return stateObject.DepositProxiedBalance()
    60  	}
    61  	return common.Big0
    62  }
    63  
    64  // ----- PendingRefundBalance (Total)
    65  
    66  // GetTotalPendingRefundBalance Retrieve the pending refund balance from the given address or 0 if object not found
    67  func (self *StateDB) GetTotalPendingRefundBalance(addr common.Address) *big.Int {
    68  	stateObject := self.getStateObject(addr)
    69  	if stateObject != nil {
    70  		return stateObject.PendingRefundBalance()
    71  	}
    72  	return common.Big0
    73  }
    74  
    75  // ----- Proxied Trie
    76  
    77  // GetProxiedBalanceByUser
    78  func (self *StateDB) GetProxiedBalanceByUser(addr, user common.Address) *big.Int {
    79  	stateObject := self.getStateObject(addr)
    80  	if stateObject != nil {
    81  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
    82  		if apb == nil {
    83  			return common.Big0
    84  		} else {
    85  			return apb.ProxiedBalance
    86  		}
    87  	}
    88  	return common.Big0
    89  }
    90  
    91  // AddProxiedBalanceByUser adds proxied amount to the account associated with addr
    92  func (self *StateDB) AddProxiedBalanceByUser(addr, user common.Address, amount *big.Int) {
    93  	stateObject := self.GetOrNewStateObject(addr)
    94  	if stateObject != nil {
    95  		// Get AccountProxiedBalance and update ProxiedBalance
    96  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
    97  		var dirtyApb *accountProxiedBalance
    98  		if apb == nil {
    99  			dirtyApb = NewAccountProxiedBalance()
   100  		} else {
   101  			dirtyApb = apb.Copy()
   102  		}
   103  		dirtyApb.ProxiedBalance = new(big.Int).Add(dirtyApb.ProxiedBalance, amount)
   104  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   105  
   106  		// Add amount to Total Proxied Balance
   107  		stateObject.AddProxiedBalance(amount)
   108  	}
   109  }
   110  
   111  // SubProxiedBalanceByUser subtracts proxied amount from the account associated with addr
   112  func (self *StateDB) SubProxiedBalanceByUser(addr, user common.Address, amount *big.Int) {
   113  	stateObject := self.GetOrNewStateObject(addr)
   114  	if stateObject != nil {
   115  		// Get AccountProxiedBalance and update ProxiedBalance
   116  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   117  		var dirtyApb *accountProxiedBalance
   118  		if apb == nil {
   119  			dirtyApb = NewAccountProxiedBalance()
   120  		} else {
   121  			dirtyApb = apb.Copy()
   122  		}
   123  		dirtyApb.ProxiedBalance = new(big.Int).Sub(dirtyApb.ProxiedBalance, amount)
   124  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   125  
   126  		// Sub amount from Total Proxied Balance
   127  		stateObject.SubProxiedBalance(amount)
   128  	}
   129  }
   130  
   131  // GetDepositProxiedBalanceByUser
   132  func (self *StateDB) GetDepositProxiedBalanceByUser(addr, user common.Address) *big.Int {
   133  	stateObject := self.getStateObject(addr)
   134  	if stateObject != nil {
   135  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   136  		if apb == nil {
   137  			return common.Big0
   138  		} else {
   139  			return apb.DepositProxiedBalance
   140  		}
   141  	}
   142  	return common.Big0
   143  }
   144  
   145  func (self *StateDB) GetProxiedAddressNumber(addr common.Address) int {
   146  	stateObject := self.getStateObject(addr)
   147  	if stateObject == nil {
   148  		return 0
   149  	}
   150  	number := 0
   151  	it := trie.NewIterator(stateObject.getProxiedTrie(self.db).NodeIterator(nil))
   152  	for it.Next() {
   153  		number++
   154  	}
   155  	return number
   156  }
   157  
   158  // AddDepositProxiedBalanceByUser adds proxied amount to the account associated with addr
   159  func (self *StateDB) AddDepositProxiedBalanceByUser(addr, user common.Address, amount *big.Int) {
   160  	stateObject := self.GetOrNewStateObject(addr)
   161  	if stateObject != nil {
   162  		// Get AccountProxiedBalance and update DepositProxiedBalance
   163  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   164  		var dirtyApb *accountProxiedBalance
   165  		if apb == nil {
   166  			dirtyApb = NewAccountProxiedBalance()
   167  		} else {
   168  			dirtyApb = apb.Copy()
   169  		}
   170  		dirtyApb.DepositProxiedBalance = new(big.Int).Add(dirtyApb.DepositProxiedBalance, amount)
   171  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   172  
   173  		// Add amount to Total Proxied Balance
   174  		stateObject.AddDepositProxiedBalance(amount)
   175  	}
   176  }
   177  
   178  // SubDepositProxiedBalanceByUser subtracts proxied amount from the account associated with addr
   179  func (self *StateDB) SubDepositProxiedBalanceByUser(addr, user common.Address, amount *big.Int) {
   180  	stateObject := self.GetOrNewStateObject(addr)
   181  	if stateObject != nil {
   182  		// Get AccountProxiedBalance and update DepositProxiedBalance
   183  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   184  		var dirtyApb *accountProxiedBalance
   185  		if apb == nil {
   186  			dirtyApb = NewAccountProxiedBalance()
   187  		} else {
   188  			dirtyApb = apb.Copy()
   189  		}
   190  		dirtyApb.DepositProxiedBalance = new(big.Int).Sub(dirtyApb.DepositProxiedBalance, amount)
   191  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   192  
   193  		// Sub amount from Total Proxied Balance
   194  		stateObject.SubDepositProxiedBalance(amount)
   195  	}
   196  }
   197  
   198  // GetPendingRefundBalanceByUser
   199  func (self *StateDB) GetPendingRefundBalanceByUser(addr, user common.Address) *big.Int {
   200  	stateObject := self.getStateObject(addr)
   201  	if stateObject != nil {
   202  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   203  		if apb == nil {
   204  			return common.Big0
   205  		} else {
   206  			return apb.PendingRefundBalance
   207  		}
   208  	}
   209  	return common.Big0
   210  }
   211  
   212  // AddPendingRefundBalanceByUser adds pending refund amount to the account associated with addr
   213  func (self *StateDB) AddPendingRefundBalanceByUser(addr, user common.Address, amount *big.Int) {
   214  	stateObject := self.GetOrNewStateObject(addr)
   215  	if stateObject != nil {
   216  		// Get AccountProxiedBalance and update PendingRefundBalance
   217  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   218  		var dirtyApb *accountProxiedBalance
   219  		if apb == nil {
   220  			dirtyApb = NewAccountProxiedBalance()
   221  		} else {
   222  			dirtyApb = apb.Copy()
   223  		}
   224  		dirtyApb.PendingRefundBalance = new(big.Int).Add(dirtyApb.PendingRefundBalance, amount)
   225  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   226  
   227  		// Add amount to Total pending refund Balance
   228  		stateObject.AddPendingRefundBalance(amount)
   229  	}
   230  }
   231  
   232  // SubPendingRefundBalanceByUser subtracts pending refund amount from the account associated with addr
   233  func (self *StateDB) SubPendingRefundBalanceByUser(addr, user common.Address, amount *big.Int) {
   234  	stateObject := self.GetOrNewStateObject(addr)
   235  	if stateObject != nil {
   236  		// Get AccountProxiedBalance and update PendingRefundBalance
   237  		apb := stateObject.GetAccountProxiedBalance(self.db, user)
   238  		var dirtyApb *accountProxiedBalance
   239  		if apb == nil {
   240  			dirtyApb = NewAccountProxiedBalance()
   241  		} else {
   242  			dirtyApb = apb.Copy()
   243  		}
   244  		dirtyApb.PendingRefundBalance = new(big.Int).Sub(dirtyApb.PendingRefundBalance, amount)
   245  		stateObject.SetAccountProxiedBalance(self.db, user, dirtyApb)
   246  
   247  		// Sub amount from Total pending refund Balance
   248  		stateObject.SubPendingRefundBalance(amount)
   249  	}
   250  }
   251  
   252  // ----- Candidate
   253  
   254  // IsCandidate Retrieve the candidate flag of the given address or false if object not found
   255  func (self *StateDB) IsCandidate(addr common.Address) bool {
   256  	stateObject := self.getStateObject(addr)
   257  	if stateObject != nil {
   258  		return stateObject.IsCandidate()
   259  	}
   260  	return false
   261  }
   262  
   263  func (self *StateDB) IsCleanAddress(addr common.Address) bool {
   264  	stateObject := self.getStateObject(addr)
   265  	if stateObject != nil {
   266  		return !stateObject.IsCandidate() && stateObject.IsEmptyTrie()
   267  	}
   268  	return true
   269  }
   270  
   271  func (self *StateDB) GetPubkey(addr common.Address) string {
   272  	stateObject := self.getStateObject(addr)
   273  	if stateObject != nil {
   274  		return stateObject.Pubkey()
   275  	}
   276  	return ""
   277  }
   278  
   279  // GetCommission Retrieve the commission percentage of the given address or 0 if object not found
   280  func (self *StateDB) GetCommission(addr common.Address) uint8 {
   281  	stateObject := self.getStateObject(addr)
   282  	if stateObject != nil {
   283  		return stateObject.Commission()
   284  	}
   285  	return 0
   286  }
   287  
   288  func (self *StateDB) SetCommission(addr common.Address, commission uint8) {
   289  	stateObject := self.GetOrNewStateObject(addr)
   290  	if stateObject != nil {
   291  		stateObject.SetCommission(commission)
   292  	}
   293  }
   294  
   295  // ApplyForCandidate Set the Candidate Flag of the given address to true and commission to given value
   296  func (self *StateDB) ApplyForCandidate(addr common.Address, pubkey string, commission uint8) {
   297  	stateObject := self.GetOrNewStateObject(addr)
   298  	if stateObject != nil {
   299  		stateObject.SetCandidate(true)
   300  		stateObject.SetCommission(commission)
   301  		stateObject.SetPubkey(pubkey)
   302  	}
   303  }
   304  
   305  // CancelCandidate Set the Candidate Flag of the given address to false and commission to 0
   306  func (self *StateDB) CancelCandidate(addr common.Address, allRefund bool) {
   307  	stateObject := self.GetOrNewStateObject(addr)
   308  	if stateObject != nil {
   309  		stateObject.SetCandidate(false)
   310  		// remove pubkey
   311  		stateObject.SetPubkey("")
   312  
   313  		if allRefund {
   314  			stateObject.SetCommission(0)
   315  		}
   316  	}
   317  }
   318  
   319  //func (self *StateDB) GetBanned(addr common.Address) bool {
   320  //	stateObject := self.GetOrNewStateObject(addr)
   321  //	if stateObject != nil {
   322  //		return stateObject.IsBanned()
   323  //	}
   324  //	return false
   325  //}
   326  
   327  //func (self *StateDB) SetBanned(addr common.Address, forbidden bool) {
   328  //	stateObject := self.GetOrNewStateObject(addr)
   329  //	if stateObject != nil {
   330  //		stateObject.SetBanned(forbidden)
   331  //	}
   332  //}
   333  
   334  //func (self *StateDB) GetBannedTime(addr common.Address) *big.Int {
   335  //	stateObject := self.GetOrNewStateObject(addr)
   336  //	if stateObject != nil {
   337  //		return stateObject.BannedTime()
   338  //	}
   339  //	return common.Big0
   340  //}
   341  
   342  //func (self *StateDB) SetBannedTime(addr common.Address, forbiddenTime *big.Int) {
   343  //	stateObject := self.GetOrNewStateObject(addr)
   344  //	if stateObject != nil {
   345  //		stateObject.SetBannedTime(forbiddenTime)
   346  //	}
   347  //}
   348  
   349  //func (self *StateDB) GetMinedBlocks(addr common.Address) *big.Int {
   350  //	stateObject := self.GetOrNewStateObject(addr)
   351  //	if stateObject != nil {
   352  //		return stateObject.BlockTime()
   353  //	}
   354  //
   355  //	return common.Big0
   356  //}
   357  
   358  //func (self *StateDB) SetMinedBlocks(addr common.Address, blocks *big.Int) {
   359  //	stateObject := self.GetOrNewStateObject(addr)
   360  //	if stateObject != nil {
   361  //		stateObject.SetBlockTime(blocks)
   362  //	}
   363  //}
   364  
   365  func (self *StateDB) SetAddress(addr, fAddr common.Address) {
   366  	stateObject := self.GetOrNewStateObject(addr)
   367  	if stateObject != nil {
   368  		stateObject.SetAddress(fAddr)
   369  	}
   370  }
   371  
   372  func (self *StateDB) GetAddress(addr common.Address) common.Address {
   373  	stateObject := self.GetOrNewStateObject(addr)
   374  	if stateObject != nil {
   375  		return stateObject.GetAddress()
   376  	}
   377  
   378  	return common.Address{}
   379  }
   380  
   381  // ClearCommission Set the Candidate commission to 0
   382  func (self *StateDB) ClearCommission(addr common.Address) {
   383  	stateObject := self.GetOrNewStateObject(addr)
   384  	if stateObject != nil {
   385  		stateObject.SetCommission(0)
   386  	}
   387  }
   388  
   389  // ----- Refund Set
   390  
   391  // MarkDelegateAddressRefund adds the specified object to the dirty map to avoid
   392  func (self *StateDB) MarkDelegateAddressRefund(addr common.Address) {
   393  	if _, exist := self.GetDelegateAddressRefundSet()[addr]; !exist {
   394  		self.delegateRefundSet[addr] = struct{}{}
   395  		self.delegateRefundSetDirty = true
   396  	}
   397  }
   398  
   399  func (self *StateDB) GetDelegateAddressRefundSet() DelegateRefundSet {
   400  	if len(self.delegateRefundSet) != 0 {
   401  		return self.delegateRefundSet
   402  	}
   403  	// Try to get from Trie
   404  	enc, err := self.trie.TryGet(refundSetKey)
   405  	if err != nil {
   406  		self.setError(err)
   407  		return nil
   408  	}
   409  	var value DelegateRefundSet
   410  	if len(enc) > 0 {
   411  		err := rlp.DecodeBytes(enc, &value)
   412  		if err != nil {
   413  			self.setError(err)
   414  		}
   415  		self.delegateRefundSet = value
   416  	}
   417  	return value
   418  }
   419  
   420  func (self *StateDB) commitDelegateRefundSet() {
   421  	data, err := rlp.EncodeToBytes(self.delegateRefundSet)
   422  	if err != nil {
   423  		panic(fmt.Errorf("can't encode delegate refund set : %v", err))
   424  	}
   425  	self.setError(self.trie.TryUpdate(refundSetKey, data))
   426  }
   427  
   428  func (self *StateDB) ClearDelegateRefundSet() {
   429  	self.setError(self.trie.TryDelete(refundSetKey))
   430  	self.delegateRefundSet = make(DelegateRefundSet)
   431  	self.delegateRefundSetDirty = false
   432  }
   433  
   434  // Store the Delegate Refund Set
   435  
   436  var refundSetKey = []byte("DelegateRefundSet")
   437  
   438  type DelegateRefundSet map[common.Address]struct{}
   439  
   440  func (set DelegateRefundSet) EncodeRLP(w io.Writer) error {
   441  	var list []common.Address
   442  	for addr := range set {
   443  		list = append(list, addr)
   444  	}
   445  	sort.Slice(list, func(i, j int) bool {
   446  		return bytes.Compare(list[i].Bytes(), list[j].Bytes()) == 1
   447  	})
   448  	return rlp.Encode(w, list)
   449  }
   450  
   451  func (set *DelegateRefundSet) DecodeRLP(s *rlp.Stream) error {
   452  	var list []common.Address
   453  	if err := s.Decode(&list); err != nil {
   454  		return err
   455  	}
   456  	refundSet := make(DelegateRefundSet, len(list))
   457  	for _, addr := range list {
   458  		refundSet[addr] = struct{}{}
   459  	}
   460  	*set = refundSet
   461  	return nil
   462  }