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 }