github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/core/state/state_object.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software MiningReward, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package state 18 19 import ( 20 "bytes" 21 "errors" 22 "fmt" 23 "github.com/insight-chain/inb-go/common" 24 "github.com/insight-chain/inb-go/core/types" 25 "github.com/insight-chain/inb-go/params" 26 27 "github.com/insight-chain/inb-go/crypto" 28 "github.com/insight-chain/inb-go/rlp" 29 "io" 30 "math/big" 31 ) 32 33 var emptyCodeHash = crypto.Keccak256(nil) 34 35 type Code []byte 36 37 func (self Code) String() string { 38 return string(self) //strings.Join(Disassemble(self), " ") 39 } 40 41 type Storage map[common.Hash]common.Hash 42 43 func (self Storage) String() (str string) { 44 for key, value := range self { 45 str += fmt.Sprintf("%X : %X\n", key, value) 46 } 47 48 return 49 } 50 51 func (self Storage) Copy() Storage { 52 cpy := make(Storage) 53 for key, value := range self { 54 cpy[key] = value 55 } 56 57 return cpy 58 } 59 60 // stateObject represents an Ethereum account which is being modified. 61 // 62 // The usage pattern is as follows: 63 // First you need to obtain a state object. 64 // Account values can be accessed and modified through the object. 65 // Finally, call CommitTrie to write the modified storage trie into a database. 66 type stateObject struct { 67 address common.Address 68 addrHash common.Hash // hash of ethereum address of the account 69 data Account 70 db *StateDB 71 72 // DB error. 73 // State objects are used by the consensus core and VM which are 74 // unable to deal with database-level errors. Any error that occurs 75 // during a database read is memoized here and will eventually be returned 76 // by StateDB.Commit. 77 dbErr error 78 79 // Write caches. 80 trie Trie // storage trie, which becomes non-nil on first access 81 code Code // contract bytecode, which gets set when code is loaded 82 83 originStorage Storage // Storage cache of original entries to dedup rewrites 84 dirtyStorage Storage // Storage entries that need to be flushed to disk 85 86 // Cache flags. 87 // When an object is marked suicided it will be delete from the trie 88 // during the "update" phase of the state transition. 89 dirtyCode bool // true if the code was updated 90 suicided bool 91 deleted bool 92 } 93 94 // empty returns whether the account is considered empty. 95 func (s *stateObject) empty() bool { 96 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 97 } 98 99 // Account is the Ethereum consensus representation of accounts. 100 // These objects are stored in the main account trie. 101 type Account struct { 102 Nonce uint64 103 Balance *big.Int 104 Root common.Hash // merkle root of the storage trie 105 CodeHash []byte 106 Res Resource // resource for account 107 Stakings []Staking // slice of regular mortgaging 108 //Recommender common.Address 109 UnStaking UnStaking // redeeming nets 110 //Regular *big.Int // total of regular mortgaging 111 Voted *big.Int //current vote to someone else number 112 LastReceivedVoteRewardHeight *big.Int 113 } 114 115 type Resource struct { 116 Used *big.Int // used 117 Usable *big.Int // unuse 118 StakingValue *big.Int // total number of mortgage 119 Height *big.Int 120 } 121 122 //Resource by zc 123 //type Resources struct { 124 // CPU Resource 125 // NET Resource 126 // Date *big.Int 127 //} 128 //type Resource struct { 129 // Used *big.Int // used 130 // Usableness *big.Int // unuse 131 // MortgagteINB *big.Int // 132 //} 133 134 type Staking struct { 135 Hash common.Hash // transaction of regular mortgaging 136 StartHeight *big.Int // start time 137 LockHeights *big.Int // duration of mortgaging 138 Value *big.Int // amount of mortgaging 139 Received *big.Int // amount of already received value 140 LastReceivedHeight *big.Int // Last receive time 141 } 142 143 type UnStaking struct { 144 StartHeight *big.Int // start time 145 Value *big.Int // amount of redeeming 146 } 147 148 //Resource by zc 149 // newObject creates a state object. 150 func newObject(db *StateDB, address common.Address, data Account) *stateObject { 151 if data.Balance == nil { 152 data.Balance = new(big.Int) 153 } 154 if data.CodeHash == nil { 155 data.CodeHash = emptyCodeHash 156 } 157 //Resource by zc 158 if data.Res.Used == nil { 159 data.Res.Used = new(big.Int) 160 } 161 if data.Res.Usable == nil { 162 data.Res.Usable = new(big.Int) 163 } 164 if data.Res.StakingValue == nil { 165 data.Res.StakingValue = new(big.Int) 166 } 167 if data.Res.Height == nil { 168 data.Res.Height = new(big.Int) 169 } 170 if data.Stakings == nil { 171 data.Stakings = make([]Staking, 0) 172 } 173 //if data.UnStaking == nil { 174 // data.UnStaking = new(UnStaking) 175 //} 176 //if data.Regular == nil { 177 // data.Regular = new(big.Int) 178 //} 179 if data.LastReceivedVoteRewardHeight == nil { 180 data.LastReceivedVoteRewardHeight = new(big.Int) 181 } 182 if data.Voted == nil { 183 data.Voted = new(big.Int) 184 } 185 //Resource by zc 186 return &stateObject{ 187 db: db, 188 address: address, 189 addrHash: crypto.Keccak256Hash(address[:]), 190 data: data, 191 originStorage: make(Storage), 192 dirtyStorage: make(Storage), 193 } 194 } 195 196 // EncodeRLP implements rlp.Encoder. 197 func (c *stateObject) EncodeRLP(w io.Writer) error { 198 return rlp.Encode(w, c.data) 199 } 200 201 // setError remembers the first non-nil error it is called with. 202 func (self *stateObject) setError(err error) { 203 if self.dbErr == nil { 204 self.dbErr = err 205 } 206 } 207 208 func (self *stateObject) markSuicided() { 209 self.suicided = true 210 } 211 212 func (c *stateObject) touch() { 213 c.db.journal.append(touchChange{ 214 account: &c.address, 215 }) 216 if c.address == ripemd { 217 // Explicitly put it in the dirty-cache, which is otherwise generated from 218 // flattened journals. 219 c.db.journal.dirty(c.address) 220 } 221 } 222 223 func (c *stateObject) getTrie(db Database) Trie { 224 if c.trie == nil { 225 var err error 226 c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) 227 if err != nil { 228 c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) 229 c.setError(fmt.Errorf("can't create storage trie: %v", err)) 230 } 231 } 232 return c.trie 233 } 234 235 // GetState retrieves a value from the account storage trie. 236 func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { 237 // If we have a dirty value for this state entry, return it 238 value, dirty := self.dirtyStorage[key] 239 if dirty { 240 return value 241 } 242 // Otherwise return the entry's original value 243 return self.GetCommittedState(db, key) 244 } 245 246 // GetCommittedState retrieves a value from the committed account storage trie. 247 func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 248 // If we have the original value cached, return that 249 value, cached := self.originStorage[key] 250 if cached { 251 return value 252 } 253 // Otherwise load the value from the database 254 enc, err := self.getTrie(db).TryGet(key[:]) 255 if err != nil { 256 self.setError(err) 257 return common.Hash{} 258 } 259 if len(enc) > 0 { 260 _, content, _, err := rlp.Split(enc) 261 if err != nil { 262 self.setError(err) 263 } 264 value.SetBytes(content) 265 } 266 self.originStorage[key] = value 267 return value 268 } 269 270 // SetState updates a value in account storage. 271 func (self *stateObject) SetState(db Database, key, value common.Hash) { 272 // If the new value is the same as old, don't set 273 prev := self.GetState(db, key) 274 if prev == value { 275 return 276 } 277 // New value is different, update and journal the change 278 self.db.journal.append(storageChange{ 279 account: &self.address, 280 key: key, 281 prevalue: prev, 282 }) 283 self.setState(key, value) 284 } 285 286 func (self *stateObject) setState(key, value common.Hash) { 287 self.dirtyStorage[key] = value 288 } 289 290 // updateTrie writes cached storage modifications into the object's storage trie. 291 func (self *stateObject) updateTrie(db Database) Trie { 292 tr := self.getTrie(db) 293 for key, value := range self.dirtyStorage { 294 delete(self.dirtyStorage, key) 295 296 // Skip noop changes, persist actual changes 297 if value == self.originStorage[key] { 298 continue 299 } 300 self.originStorage[key] = value 301 302 if (value == common.Hash{}) { 303 self.setError(tr.TryDelete(key[:])) 304 continue 305 } 306 // Encoding []byte cannot fail, ok to ignore the error. 307 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) 308 self.setError(tr.TryUpdate(key[:], v)) 309 } 310 return tr 311 } 312 313 // UpdateRoot sets the trie root to the current root hash of 314 func (self *stateObject) updateRoot(db Database) { 315 self.updateTrie(db) 316 self.data.Root = self.trie.Hash() 317 } 318 319 // CommitTrie the storage trie of the object to db. 320 // This updates the trie root. 321 func (self *stateObject) CommitTrie(db Database) error { 322 self.updateTrie(db) 323 if self.dbErr != nil { 324 return self.dbErr 325 } 326 root, err := self.trie.Commit(nil) 327 if err == nil { 328 self.data.Root = root 329 } 330 return err 331 } 332 333 // AddBalance removes amount from c's balance. 334 // It is used to add funds to the destination account of a transfer. 335 func (c *stateObject) AddBalance(amount *big.Int) { 336 // EIP158: We must check emptiness for the objects such that the account 337 // clearing (0,0,0 objects) can take effect. 338 if amount.Sign() == 0 { 339 if c.empty() { 340 c.touch() 341 } 342 343 return 344 } 345 c.SetBalance(new(big.Int).Add(c.Balance(), amount)) 346 } 347 348 func (c *stateObject) AddVoteRecord(amount *big.Int) { 349 // EIP158: We must check emptiness for the objects such that the account 350 // clearing (0,0,0 objects) can take effect. 351 //if amount.Sign() == 0 { 352 // if c.empty() { 353 // c.touch() 354 // } 355 // 356 // return 357 //} 358 c.SetVoteRecord(amount) 359 } 360 361 // SubBalance removes amount from c's balance. 362 // It is used to remove funds from the origin account of a transfer. 363 func (c *stateObject) SubBalance(amount *big.Int) { 364 if amount.Sign() == 0 { 365 return 366 } 367 c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) 368 } 369 370 func (self *stateObject) SetBalance(amount *big.Int) { 371 self.db.journal.append(balanceChange{ 372 account: &self.address, 373 prev: new(big.Int).Set(self.data.Balance), 374 }) 375 self.setBalance(amount) 376 } 377 378 func (self *stateObject) SetVoteRecord(amount *big.Int) { 379 380 self.setVoteRecord(amount) 381 } 382 383 func (self *stateObject) setBalance(amount *big.Int) { 384 self.data.Balance = amount 385 } 386 387 func (self *stateObject) setVoteRecord(amount *big.Int) { 388 self.data.Voted = amount 389 } 390 391 //achilles MortgageNet add nets from c's resource 392 func (self *stateObject) MortgageNet(amount *big.Int, duration *big.Int, sTime big.Int, hash common.Hash) *big.Int { 393 if amount.Sign() == 0 { 394 return nil 395 } 396 netUse := self.db.ConvertToNets(amount) 397 self.SetRes(self.UsedNet(), new(big.Int).Add(self.Net(), netUse), new(big.Int).Add(self.StakingValue(), amount)) 398 399 mortgageStateObject := self.db.GetMortgageStateObject() 400 mortgageStateObject.AddBalance(amount) 401 402 if duration.Cmp(big.NewInt(0)) > 0 { 403 staking := Staking{ 404 Hash: hash, 405 StartHeight: &sTime, 406 LockHeights: duration, 407 Value: amount, 408 LastReceivedHeight: &sTime, 409 } 410 stakings := append(self.data.Stakings, staking) 411 self.SetStakings(stakings) 412 } 413 414 if !(big.NewInt(0).Cmp(self.Date()) < 0) { 415 self.SetDate(&sTime) 416 } 417 418 //2019.8.29 inb by ghy begin 419 votes := self.data.Voted 420 421 if votes.Cmp(big.NewInt(0)) == 1 && self.data.LastReceivedVoteRewardHeight.Cmp(big.NewInt(0)) == 1 { 422 self.Vote(&sTime) 423 HeightNow := sTime 424 lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight 425 if HeightNow.Cmp(lastReceiveVoteAwardHeight) != 1 { 426 return netUse 427 } 428 fromLastReceiveVoteAwardTimeToNowHeight := new(big.Int).Sub(&HeightNow, lastReceiveVoteAwardHeight) 429 cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeight, common.VoteRewardCycleSecondsForChange) 430 if cycles.Cmp(common.VoteRewardCycleTimesForChange) != -1 { 431 votes1 := new(big.Int).Mul(votes, common.VoteDenominatorForChange) 432 votes2 := new(big.Int).Div(votes1, common.VoteHundredForChange) 433 votes3 := new(big.Int).Div(votes2, common.VoteNumberOfDaysOneYearForChange) 434 value := new(big.Int).Mul(votes3, cycles) 435 self.ReceiveVoteAward(value, &HeightNow) 436 } 437 } 438 //2019.8.29 inb by ghy end 439 return netUse 440 } 441 442 func (self *stateObject) ResetNet(update *big.Int) *big.Int { 443 netUse := self.db.ConvertToNets(self.StakingValue()) 444 netUsed := big.NewInt(0) 445 446 self.SetRes(netUsed, netUse, self.StakingValue()) 447 self.SetDate(update) 448 return netUse 449 } 450 451 //2019.7.22 inb by ghy begin 452 func (self *stateObject) CanReceiveLockedAward(nonce common.Hash, height *big.Int, consensus types.SpecialConsensus) (err error, value *big.Int, isAll bool) { 453 if self.data.Voted.Cmp(big.NewInt(0)) != 1 { 454 return errors.New("can only receive locked rewards after voting"), big.NewInt(0), false 455 } 456 if len(self.data.Stakings) == 0 { 457 return errors.New("no lock record"), big.NewInt(0), false 458 } 459 LockedRewardCycleHeight := new(big.Int) 460 LockedRewardCycleTimes := new(big.Int) 461 LockedDenominator := new(big.Int) 462 LockedHundred := new(big.Int) 463 LockedNumberOfDaysOneYear := new(big.Int) 464 465 for _, v := range self.data.Stakings { 466 if nonce == v.Hash { 467 switch v.LockHeights.Uint64() { 468 case params.HeightOf30Days.Uint64(): 469 LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor30days 470 LockedRewardCycleTimes = common.LockedRewardCycleTimesFor30days 471 LockedDenominator = common.LockedDenominatorFor30days 472 LockedHundred = common.LockedHundredFor30days 473 LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor30days 474 case params.HeightOf90Days.Uint64(): 475 LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor90days 476 LockedRewardCycleTimes = common.LockedRewardCycleTimesFor90days 477 LockedDenominator = common.LockedDenominatorFor90days 478 LockedHundred = common.LockedHundredFor90days 479 LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor90days 480 case params.HeightOf180Days.Uint64(): 481 LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor180days 482 LockedRewardCycleTimes = common.LockedRewardCycleTimesFor180days 483 LockedDenominator = common.LockedDenominatorFor180days 484 LockedHundred = common.LockedHundredFor180days 485 LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor180days 486 case params.HeightOf360Days.Uint64(), params.HeightOf720Days.Uint64(), params.HeightOf1080Days.Uint64(), params.HeightOf1800Days.Uint64(), params.HeightOf3600Days.Uint64(): 487 LockedRewardCycleHeight = common.LockedRewardCycleSecondsForMoreThan360days 488 LockedRewardCycleTimes = common.LockedRewardCycleTimesForMoreThan360days 489 LockedDenominator = common.LockedDenominatorForMoreThan360days 490 LockedHundred = common.LockedHundredForMoreThan360days 491 LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearForMoreThan360days 492 default: 493 return errors.New("unknow times"), big.NewInt(0), false 494 } 495 496 HeightNow := height 497 498 startHeight := v.StartHeight 499 500 lastReceivedHeight := v.LastReceivedHeight 501 502 lockHeights := v.LockHeights 503 504 endTimeHeight := new(big.Int).Add(startHeight, lockHeights) 505 506 totalValue := v.Value 507 receivedValue := v.Received 508 509 if startHeight.Cmp(lastReceivedHeight) == 1 { 510 return errors.New("last receipt time and start time error"), big.NewInt(0), false 511 } 512 if lastReceivedHeight.Cmp(HeightNow) == 1 { 513 return errors.New("last receipt time error"), big.NewInt(0), false 514 } 515 if lastReceivedHeight.Cmp(endTimeHeight) == 1 { 516 return errors.New("all the rewards are received"), big.NewInt(0), false 517 } 518 519 FromLastReceivedPassTimeHeight := new(big.Int).Sub(HeightNow, lastReceivedHeight) 520 FromStartPassTimeHeight := new(big.Int).Sub(HeightNow, startHeight) 521 522 if HeightNow.Cmp(endTimeHeight) >= 0 { 523 //HeightNow = endTimeHeight 524 FromLastReceivedPassTimeHeight = new(big.Int).Sub(endTimeHeight, lastReceivedHeight) 525 FromStartPassTimeHeight = new(big.Int).Sub(endTimeHeight, startHeight) 526 } 527 528 FromLastReceivedPassDays := new(big.Int).Div(FromLastReceivedPassTimeHeight, LockedRewardCycleHeight) 529 530 FromStartPassDays := new(big.Int).Div(FromStartPassTimeHeight, LockedRewardCycleHeight) 531 532 totalValue1 := new(big.Int).Mul(totalValue, LockedDenominator) 533 totalValue2 := new(big.Int).Mul(totalValue1, FromStartPassDays) 534 totalValue3 := new(big.Int).Div(totalValue2, LockedHundred) 535 MaxReceivedValueNow := new(big.Int).Div(totalValue3, LockedNumberOfDaysOneYear) 536 subValue := new(big.Int).Sub(MaxReceivedValueNow, receivedValue) 537 538 if subValue.Cmp(big.NewInt(0)) != 1 { 539 return errors.New("have no rewards to received"), big.NewInt(0), false 540 } 541 542 if HeightNow.Cmp(endTimeHeight) == -1 && FromLastReceivedPassDays.Cmp(LockedRewardCycleTimes) == -1 { 543 return errors.New("not block height to receive rewards"), big.NewInt(0), false 544 } 545 return nil, subValue, HeightNow.Cmp(endTimeHeight) >= 0 546 } 547 } 548 return errors.New("no such lock record"), big.NewInt(0), false 549 550 } 551 552 func (self *stateObject) ReceiveLockedAward(nonce common.Hash, value *big.Int, isAll bool, height *big.Int) { 553 554 if len(self.data.Stakings) > 0 { 555 for k, v := range self.data.Stakings { 556 if nonce == v.Hash { 557 self.AddBalance(value) 558 self.data.Stakings[k].LastReceivedHeight = height 559 if isAll { 560 self.AddBalance(v.Value) 561 562 //afterRegular := new(big.Int).Sub(self.data.Regular, v.Value) 563 //self.data.Regular = afterRegular 564 afterMortgagteINB := new(big.Int).Sub(self.data.Res.StakingValue, v.Value) 565 self.data.Res.StakingValue = afterMortgagteINB 566 567 self.data.Stakings = append(self.data.Stakings[:k], self.data.Stakings[k+1:]...) 568 569 mortgageStateObject := self.db.GetMortgageStateObject() 570 if mortgageStateObject.Balance().Cmp(value) < 0 { 571 return 572 } 573 //balance := new(big.Int).Sub(mortgageStateObject.MortgageOfRes(), value) 574 mortgageStateObject.SubBalance(value) 575 576 } else { 577 578 //receiveAdd := v.Received.Int64() + int64(value) 579 receiveAdd := new(big.Int).Add(v.Received, value) 580 self.data.Stakings[k].Received = receiveAdd 581 } 582 } 583 } 584 } 585 } 586 587 func (self *stateObject) CanReceiveVoteAward(height *big.Int) (err error, value *big.Int) { 588 //account := pool.currentState.GetAccountInfo(from) 589 votes := self.data.Voted 590 if votes.Cmp(big.NewInt(0)) != 1 { 591 return errors.New("please receive vote award after voting"), big.NewInt(0) 592 593 } 594 heightNow := height 595 lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight 596 if heightNow.Cmp(lastReceiveVoteAwardHeight) != 1 { 597 return errors.New("please receive vote award after voting"), big.NewInt(0) 598 } 599 fromLastReceiveVoteAwardTimeToNowHeights := new(big.Int).Sub(heightNow, lastReceiveVoteAwardHeight) 600 cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeights, common.VoteRewardCycleSeconds) 601 if cycles.Cmp(common.VoteRewardCycleTimes) != -1 { 602 votes1 := new(big.Int).Mul(votes, common.VoteDenominator) 603 votes2 := new(big.Int).Mul(votes1, cycles) 604 votes3 := new(big.Int).Div(votes2, common.VoteHundred) 605 value := new(big.Int).Div(votes3, common.VoteNumberOfDaysOneYear) 606 return nil, value 607 } 608 return errors.New("not receive vote award time"), big.NewInt(0) 609 } 610 611 func (self *stateObject) ReceiveVoteAward(value *big.Int, height *big.Int) { 612 self.data.LastReceivedVoteRewardHeight = height 613 self.AddBalance(value) 614 615 } 616 617 func (self *stateObject) Vote(height *big.Int) { 618 self.data.Voted = self.data.Res.StakingValue 619 self.data.LastReceivedVoteRewardHeight = height 620 } 621 622 //2019.7.22 inb by ghy end 623 624 //achilles Redeem freeze inb of mortgaging from c's balance 625 func (self *stateObject) Redeem(amount *big.Int, sTime *big.Int) { 626 if amount.Sign() == 0 { 627 return 628 } 629 available := new(big.Int).Sub(self.StakingValue(), self.GetTotalStaking()) 630 available.Sub(available, self.GetUnStaking()) 631 if available.Cmp(amount) < 0 { 632 return 633 } 634 // freeze inb of redeeming 635 mortgaging := new(big.Int).Sub(self.StakingValue(), amount) 636 self.SetRes(self.UsedNet(), self.Net(), mortgaging) 637 638 unStaking := UnStaking{ 639 StartHeight: sTime, 640 Value: new(big.Int).Add(self.GetUnStaking(), amount), 641 } 642 self.SetUnStaking(unStaking) 643 } 644 645 func (self *stateObject) Receive(sTime *big.Int) *big.Int { 646 647 value := self.GetUnStaking() 648 unStaking := UnStaking{ 649 StartHeight: sTime, 650 Value: big.NewInt(0), 651 } 652 self.SetUnStaking(unStaking) 653 654 self.AddBalance(value) 655 mortgageStateObject := self.db.GetMortgageStateObject() 656 if mortgageStateObject.Balance().Cmp(value) < 0 { 657 return nil 658 } 659 //balance := new(big.Int).Sub(mortgageStateObject.MortgageOfRes(), value) 660 mortgageStateObject.SubBalance(value) 661 662 //2019.8.29 inb by ghy begin 663 votes := self.data.Voted 664 665 if votes.Cmp(big.NewInt(0)) == 1 && self.data.LastReceivedVoteRewardHeight.Cmp(big.NewInt(0)) == 1 { 666 self.Vote(sTime) 667 HeightNow := sTime 668 lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight 669 if HeightNow.Cmp(lastReceiveVoteAwardHeight) != 1 { 670 return value 671 } 672 fromLastReceiveVoteAwardTimeToNowHeight := new(big.Int).Sub(HeightNow, lastReceiveVoteAwardHeight) 673 cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeight, common.VoteRewardCycleSecondsForChange) 674 if cycles.Cmp(common.VoteRewardCycleTimesForChange) != -1 { 675 votes1 := new(big.Int).Mul(votes, common.VoteDenominatorForChange) 676 votes2 := new(big.Int).Div(votes1, common.VoteHundredForChange) 677 votes3 := new(big.Int).Div(votes2, common.VoteNumberOfDaysOneYearForChange) 678 value := new(big.Int).Mul(votes3, cycles) 679 self.ReceiveVoteAward(value, HeightNow) 680 } 681 } 682 //2019.8.29 inb by ghy end 683 return value 684 } 685 686 func (self *stateObject) SetRes(used *big.Int, usable *big.Int, stakingValue *big.Int) { 687 688 self.db.journal.append(resChange{ 689 account: &self.address, 690 Used: new(big.Int).Set(self.data.Res.Used), 691 Usable: new(big.Int).Set(self.data.Res.Usable), 692 StakingValue: new(big.Int).Set(self.data.Res.StakingValue), 693 }) 694 self.setRes(used, usable, stakingValue) 695 } 696 697 func (self *stateObject) setRes(used *big.Int, usable *big.Int, stakingValue *big.Int) { 698 self.data.Res.Used = used 699 self.data.Res.Usable = usable 700 self.data.Res.StakingValue = stakingValue 701 } 702 703 func (self *stateObject) SetUnStaking(unStaking UnStaking) { 704 self.db.journal.append(unStakingChange{ 705 account: &self.address, 706 unStaking: self.data.UnStaking, 707 }) 708 self.setUnStaking(unStaking) 709 } 710 711 func (self *stateObject) setUnStaking(unStaking UnStaking) { 712 self.data.UnStaking = unStaking 713 } 714 715 func (self *stateObject) SetDate(update *big.Int) { 716 717 self.db.journal.append(dateChange{ 718 account: &self.address, 719 prev: new(big.Int).Set(self.data.Res.Height), 720 }) 721 self.setDate(update) 722 } 723 724 func (self *stateObject) setDate(update *big.Int) { 725 self.data.Res.Height = update 726 } 727 728 //achilles0718 regular mortgagtion 729 func (self *stateObject) SetStakings(stakings []Staking) { 730 self.db.journal.append(stakingChange{ 731 account: &self.address, 732 stakings: self.data.Stakings, 733 }) 734 self.setStakings(stakings) 735 } 736 737 func (self *stateObject) setStakings(stakings []Staking) { 738 self.data.Stakings = stakings 739 } 740 741 // Return the gas back to the origin. Used by the Virtual machine or Closures 742 func (c *stateObject) ReturnGas(gas *big.Int) {} 743 744 func (self *stateObject) deepCopy(db *StateDB) *stateObject { 745 stateObject := newObject(db, self.address, self.data) 746 if self.trie != nil { 747 stateObject.trie = db.db.CopyTrie(self.trie) 748 } 749 stateObject.code = self.code 750 stateObject.dirtyStorage = self.dirtyStorage.Copy() 751 stateObject.originStorage = self.originStorage.Copy() 752 stateObject.suicided = self.suicided 753 stateObject.dirtyCode = self.dirtyCode 754 stateObject.deleted = self.deleted 755 return stateObject 756 } 757 758 // 759 // Attribute accessors 760 // 761 762 // Returns the address of the contract/account 763 func (c *stateObject) Address() common.Address { 764 return c.address 765 } 766 767 // Code returns the contract code associated with this object, if any. 768 func (self *stateObject) Code(db Database) []byte { 769 if self.code != nil { 770 return self.code 771 } 772 if bytes.Equal(self.CodeHash(), emptyCodeHash) { 773 return nil 774 } 775 code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) 776 if err != nil { 777 self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) 778 } 779 self.code = code 780 return code 781 } 782 783 func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { 784 prevcode := self.Code(self.db.db) 785 self.db.journal.append(codeChange{ 786 account: &self.address, 787 prevhash: self.CodeHash(), 788 prevcode: prevcode, 789 }) 790 self.setCode(codeHash, code) 791 } 792 793 func (self *stateObject) setCode(codeHash common.Hash, code []byte) { 794 self.code = code 795 self.data.CodeHash = codeHash[:] 796 self.dirtyCode = true 797 } 798 799 func (self *stateObject) SetNonce(nonce uint64) { 800 self.db.journal.append(nonceChange{ 801 account: &self.address, 802 prev: self.data.Nonce, 803 }) 804 self.setNonce(nonce) 805 } 806 807 func (self *stateObject) setNonce(nonce uint64) { 808 self.data.Nonce = nonce 809 } 810 811 func (self *stateObject) CodeHash() []byte { 812 return self.data.CodeHash 813 } 814 815 func (self *stateObject) Balance() *big.Int { 816 return self.data.Balance 817 } 818 819 //achilles0718 regular mortgagtion 820 func (self *stateObject) StoreLength() int { 821 stakings := self.data.Stakings 822 return len(stakings) 823 } 824 825 //Resource by zc 826 func (self *stateObject) Net() *big.Int { 827 return self.data.Res.Usable 828 } 829 func (self *stateObject) UsedNet() *big.Int { 830 return self.data.Res.Used 831 } 832 func (self *stateObject) StakingValue() *big.Int { 833 return self.data.Res.StakingValue 834 } 835 836 func (self *stateObject) GetUnStaking() *big.Int { 837 return self.data.UnStaking.Value 838 } 839 840 func (self *stateObject) GetUnStakingHeight() *big.Int { 841 return self.data.UnStaking.StartHeight 842 } 843 844 func (self *stateObject) GetTotalStaking() *big.Int { 845 total := big.NewInt(0) 846 if nil != self.data.Stakings && len(self.data.Stakings) > 0 { 847 for _,staking := range self.data.Stakings { 848 total.Add(total, staking.Value) 849 } 850 } 851 return total 852 } 853 854 func (self *stateObject) GetTotalStakingYear() *big.Int { 855 total := big.NewInt(0) 856 if nil != self.data.Stakings && len(self.data.Stakings) > 0 { 857 for _,staking := range self.data.Stakings { 858 if staking.LockHeights.Cmp(params.HeightOf360Days) >= 0{ 859 total.Add(total, staking.Value) 860 } 861 } 862 } 863 return total 864 } 865 866 func (self *stateObject) Date() *big.Int { 867 return self.data.Res.Height 868 } 869 870 //Resource by zc 871 func (self *stateObject) Nonce() uint64 { 872 return self.data.Nonce 873 } 874 875 //2019.6.28 inb by ghy begin 876 func (self *stateObject) Resource() Resource { 877 return self.data.Res 878 } 879 880 // 881 //func (self *stateObject) MortgageOfINB() *big.Int { 882 // return self.data.Res.Mortgage 883 //} 884 885 //2019.6.28 inb by ghy end 886 // Never called, but must be present to allow stateObject to be used 887 // as a vm.Account interface that also satisfies the vm.ContractRef 888 // interface. Interfaces are awesome. 889 func (self *stateObject) Value() *big.Int { 890 panic("Value on stateObject should never be called") 891 }