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 }