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

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