github.com/Gessiux/neatchain@v1.3.1/chain/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 Foundation, 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 "fmt" 22 "io" 23 "math/big" 24 25 "github.com/Gessiux/neatchain/utilities/common" 26 "github.com/Gessiux/neatchain/utilities/crypto" 27 "github.com/Gessiux/neatchain/utilities/rlp" 28 ) 29 30 var emptyCodeHash = crypto.Keccak256(nil) 31 32 type Code []byte 33 34 func (self Code) String() string { 35 return string(self) //strings.Join(Disassemble(self), " ") 36 } 37 38 type Storage map[common.Hash]common.Hash 39 40 func (self Storage) String() (str string) { 41 for key, value := range self { 42 str += fmt.Sprintf("%X : %X\n", key, value) 43 } 44 45 return 46 } 47 48 func (self Storage) Copy() Storage { 49 cpy := make(Storage) 50 for key, value := range self { 51 cpy[key] = value 52 } 53 54 return cpy 55 } 56 57 // stateObject represents an Ethereum account which is being modified. 58 // 59 // The usage pattern is as follows: 60 // First you need to obtain a state object. 61 // Account values can be accessed and modified through the object. 62 // Finally, call CommitTrie to write the modified storage trie into a database. 63 type stateObject struct { 64 address common.Address 65 addrHash common.Hash // hash of ethereum address of the account 66 data Account 67 db *StateDB 68 69 // DB error. 70 // State objects are used by the consensus core and VM which are 71 // unable to deal with database-level errors. Any error that occurs 72 // during a database read is memoized here and will eventually be returned 73 // by StateDB.Commit. 74 dbErr error 75 76 // Write caches. 77 trie Trie // storage trie, which becomes non-nil on first access 78 code Code // contract bytecode, which gets set when code is loaded 79 80 originStorage Storage // Storage cache of original entries to dedup rewrites 81 dirtyStorage Storage // Storage entries that need to be flushed to disk 82 83 // Cross Chain TX trie 84 tx1Trie Trie // tx1 trie, which become non-nil on first access 85 tx3Trie Trie // tx3 trie, which become non-nil on first access 86 87 dirtyTX1 map[common.Hash]struct{} // tx1 entries that need to be flushed to disk 88 dirtyTX3 map[common.Hash]struct{} // tx3 entries that need to be flushed to disk 89 90 // Delegate Trie 91 proxiedTrie Trie // proxied trie, store the proxied balance from other user 92 originProxied Proxied // cache data of proxied trie 93 dirtyProxied Proxied // dirty data of proxied trie, need to be flushed to disk later 94 95 rewardTrie Trie // Reward Trie, store the pending reward balance for this account 96 originReward Reward // cache data of Reward trie 97 dirtyReward Reward // dirty data of Reward trie, need to be flushed to disk later 98 99 // Cache flags. 100 // When an object is marked suicided it will be delete from the trie 101 // during the "update" phase of the state transition. 102 dirtyCode bool // true if the code was updated 103 suicided bool 104 touched bool 105 deleted bool 106 onDirty func(addr common.Address) // Callback method to mark a state object newly dirty 107 } 108 109 // empty returns whether the account is considered empty. 110 func (s *stateObject) empty() bool { 111 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) && s.data.DepositBalance.Sign() == 0 && len(s.data.SideChainDepositBalance) == 0 && s.data.ChainBalance.Sign() == 0 && s.data.DelegateBalance.Sign() == 0 && s.data.ProxiedBalance.Sign() == 0 && s.data.DepositProxiedBalance.Sign() == 0 && s.data.PendingRefundBalance.Sign() == 0 && s.data.AvailableRewardBalance.Sign() == 0 112 } 113 114 // Account is the Ethereum consensus representation of accounts. 115 // These objects are stored in the main account trie. 116 type Account struct { 117 Nonce uint64 118 Balance *big.Int // for normal user 119 DepositBalance *big.Int // for validator, can not be consumed 120 SideChainDepositBalance []*sideChainDepositBalance // only valid in main chain for side chain validator before side chain launch, can not be consumed 121 ChainBalance *big.Int // only valid in main chain for side chain owner, can not be consumed 122 Root common.Hash // merkle root of the storage trie 123 TX1Root common.Hash // merkle root of the TX1 trie 124 TX3Root common.Hash // merkle root of the TX3 trie 125 CodeHash []byte 126 127 // Delegation 128 DelegateBalance *big.Int // the accumulative balance which this account delegate the Balance to other user 129 ProxiedBalance *big.Int // the accumulative balance which other user delegate to this account (this balance can be revoked, can be deposit for validator) 130 DepositProxiedBalance *big.Int // the deposit proxied balance for validator which come from ProxiedBalance (this balance can not be revoked) 131 PendingRefundBalance *big.Int // the accumulative balance which other user try to cancel their delegate balance (this balance will be refund to user's address after epoch end) 132 ProxiedRoot common.Hash // merkle root of the Proxied trie 133 // Candidate 134 Candidate bool // flag for Account, true indicate the account has been applied for the Delegation Candidate 135 Commission uint8 // commission percentage of Delegation Candidate (0-100) 136 BlockTime *big.Int // number for mined blocks current epoch 137 ForbiddenTime *big.Int // timestamp for last consensus block 138 IsForbidden bool // candidate is forbidden or not 139 Pubkey string 140 141 // Reward 142 RewardBalance *big.Int // the accumulative reward balance for this account 143 AvailableRewardBalance *big.Int // the available reward balance for this account 144 RewardRoot common.Hash // merkle root of the Reward trie 145 146 } 147 148 // newObject creates a state object. 149 func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { 150 if data.Balance == nil { 151 data.Balance = new(big.Int) 152 } 153 if data.DepositBalance == nil { 154 data.DepositBalance = new(big.Int) 155 } 156 if data.ChainBalance == nil { 157 data.ChainBalance = new(big.Int) 158 } 159 // init delegate balance 160 if data.DelegateBalance == nil { 161 data.DelegateBalance = new(big.Int) 162 } 163 if data.ProxiedBalance == nil { 164 data.ProxiedBalance = new(big.Int) 165 } 166 if data.DepositProxiedBalance == nil { 167 data.DepositProxiedBalance = new(big.Int) 168 } 169 if data.PendingRefundBalance == nil { 170 data.PendingRefundBalance = new(big.Int) 171 } 172 // init reward balance 173 if data.RewardBalance == nil { 174 data.RewardBalance = new(big.Int) 175 } 176 177 if data.AvailableRewardBalance == nil { 178 data.AvailableRewardBalance = new(big.Int) 179 } 180 181 if data.BlockTime == nil { 182 data.BlockTime = new(big.Int) 183 } 184 185 if data.ForbiddenTime == nil { 186 data.ForbiddenTime = new(big.Int) 187 } 188 189 if data.CodeHash == nil { 190 data.CodeHash = emptyCodeHash 191 } 192 return &stateObject{ 193 db: db, 194 address: address, 195 addrHash: crypto.Keccak256Hash(address[:]), 196 data: data, 197 originStorage: make(Storage), 198 dirtyStorage: make(Storage), 199 dirtyTX1: make(map[common.Hash]struct{}), 200 dirtyTX3: make(map[common.Hash]struct{}), 201 originProxied: make(Proxied), 202 dirtyProxied: make(Proxied), 203 originReward: make(Reward), 204 dirtyReward: make(Reward), 205 onDirty: onDirty, 206 } 207 } 208 209 // EncodeRLP implements rlp.Encoder. 210 func (c *stateObject) EncodeRLP(w io.Writer) error { 211 return rlp.Encode(w, c.data) 212 } 213 214 // setError remembers the first non-nil error it is called with. 215 func (self *stateObject) setError(err error) { 216 if self.dbErr == nil { 217 self.dbErr = err 218 } 219 } 220 221 func (self *stateObject) markSuicided() { 222 self.suicided = true 223 if self.onDirty != nil { 224 self.onDirty(self.Address()) 225 self.onDirty = nil 226 } 227 } 228 229 func (c *stateObject) touch() { 230 c.db.journal = append(c.db.journal, touchChange{ 231 account: &c.address, 232 prev: c.touched, 233 prevDirty: c.onDirty == nil, 234 }) 235 if c.onDirty != nil { 236 c.onDirty(c.Address()) 237 c.onDirty = nil 238 } 239 c.touched = true 240 } 241 242 func (c *stateObject) getTX1Trie(db Database) Trie { 243 if c.tx1Trie == nil { 244 var err error 245 c.tx1Trie, err = db.OpenTX1Trie(c.addrHash, c.data.TX1Root) 246 if err != nil { 247 c.tx1Trie, _ = db.OpenTX1Trie(c.addrHash, common.Hash{}) 248 c.setError(fmt.Errorf("can't create TX1 trie: %v", err)) 249 } 250 } 251 return c.tx1Trie 252 } 253 254 // HasTX1 returns true if tx1 is in account TX1 trie. 255 func (self *stateObject) HasTX1(db Database, txHash common.Hash) bool { 256 // check the dirtyTX1 firstly. 257 _, ok := self.dirtyTX1[txHash] 258 if ok { 259 return true 260 } 261 262 // Load from DB in case it is missing. 263 enc, err := self.getTX1Trie(db).TryGet(txHash[:]) 264 if err != nil { 265 return false 266 } 267 if len(enc) > 0 { 268 _, content, _, err := rlp.Split(enc) 269 if err != nil { 270 self.setError(err) 271 return false 272 } 273 if !bytes.Equal(content, txHash[:]) { 274 self.setError(fmt.Errorf("content mismatch the tx hash")) 275 return false 276 } 277 278 return true 279 } 280 281 return false 282 } 283 284 // AddTX1 adds a tx1 in account tx1 trie. 285 func (self *stateObject) AddTX1(db Database, txHash common.Hash) { 286 self.db.journal = append(self.db.journal, addTX1Change{ 287 account: &self.address, 288 txHash: txHash, 289 }) 290 self.addTX1(txHash) 291 } 292 293 func (self *stateObject) addTX1(txHash common.Hash) { 294 self.dirtyTX1[txHash] = struct{}{} 295 } 296 297 func (self *stateObject) removeTX1(txHash common.Hash) { 298 delete(self.dirtyTX1, txHash) 299 } 300 301 // updateTX1Trie writes cached tx1 modifications into the object's tx1 trie. 302 func (self *stateObject) updateTX1Trie(db Database) Trie { 303 tr := self.getTX1Trie(db) 304 305 for tx1 := range self.dirtyTX1 { 306 delete(self.dirtyTX1, tx1) 307 308 // Encoding []byte cannot fail, ok to ignore the error. 309 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx1[:], "\x00")) 310 self.setError(tr.TryUpdate(tx1[:], v)) 311 } 312 return tr 313 } 314 315 // updateTX1Root sets the trie root to the current root hash 316 func (self *stateObject) updateTX1Root(db Database) { 317 self.updateTX1Trie(db) 318 self.data.TX1Root = self.tx1Trie.Hash() 319 } 320 321 // CommitTX1Trie the tx1 trie of the object to dwb. 322 // This updates the trie root. 323 func (self *stateObject) CommitTX1Trie(db Database) error { 324 self.updateTX1Trie(db) 325 if self.dbErr != nil { 326 return self.dbErr 327 } 328 root, err := self.tx1Trie.Commit(nil) 329 if err == nil { 330 self.data.TX1Root = root 331 } 332 return err 333 } 334 335 func (c *stateObject) getTX3Trie(db Database) Trie { 336 if c.tx3Trie == nil { 337 var err error 338 c.tx3Trie, err = db.OpenTX3Trie(c.addrHash, c.data.TX3Root) 339 if err != nil { 340 c.tx3Trie, _ = db.OpenTX3Trie(c.addrHash, common.Hash{}) 341 c.setError(fmt.Errorf("can't create TX3 trie: %v", err)) 342 } 343 } 344 return c.tx3Trie 345 } 346 347 // HasTX3 returns true if tx3 is in account TX3 trie. 348 func (self *stateObject) HasTX3(db Database, txHash common.Hash) bool { 349 // check the dirtyTX3 firstly. 350 _, ok := self.dirtyTX3[txHash] 351 if ok { 352 return true 353 } 354 355 // Load from DB in case it is missing. 356 enc, err := self.getTX3Trie(db).TryGet(txHash[:]) 357 if err != nil { 358 return false 359 } 360 if len(enc) > 0 { 361 _, content, _, err := rlp.Split(enc) 362 if err != nil { 363 self.setError(err) 364 return false 365 } 366 if !bytes.Equal(content, txHash[:]) { 367 self.setError(fmt.Errorf("content mismatch the tx hash")) 368 return false 369 } 370 371 return true 372 } 373 374 return false 375 } 376 377 // AddTX3 adds a tx3 in account tx3 trie. 378 func (self *stateObject) AddTX3(db Database, txHash common.Hash) { 379 self.db.journal = append(self.db.journal, addTX3Change{ 380 account: &self.address, 381 txHash: txHash, 382 }) 383 self.addTX3(txHash) 384 } 385 386 func (self *stateObject) addTX3(txHash common.Hash) { 387 self.dirtyTX3[txHash] = struct{}{} 388 } 389 390 func (self *stateObject) removeTX3(txHash common.Hash) { 391 delete(self.dirtyTX3, txHash) 392 } 393 394 // updateTX3Trie writes cached tx3 modifications into the object's tx3 trie. 395 func (self *stateObject) updateTX3Trie(db Database) Trie { 396 tr := self.getTX3Trie(db) 397 398 for tx3 := range self.dirtyTX3 { 399 delete(self.dirtyTX3, tx3) 400 401 // Encoding []byte cannot fail, ok to ignore the error. 402 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx3[:], "\x00")) 403 self.setError(tr.TryUpdate(tx3[:], v)) 404 } 405 return tr 406 } 407 408 // updateTX3Root sets the trie root to the current root hash 409 func (self *stateObject) updateTX3Root(db Database) { 410 self.updateTX3Trie(db) 411 self.data.TX3Root = self.tx3Trie.Hash() 412 } 413 414 // CommitTX3Trie the tx3 trie of the object to dwb. 415 // This updates the trie root. 416 func (self *stateObject) CommitTX3Trie(db Database) error { 417 self.updateTX3Trie(db) 418 if self.dbErr != nil { 419 return self.dbErr 420 } 421 root, err := self.tx3Trie.Commit(nil) 422 if err == nil { 423 self.data.TX3Root = root 424 } 425 return err 426 } 427 428 func (c *stateObject) getTrie(db Database) Trie { 429 if c.trie == nil { 430 var err error 431 c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) 432 if err != nil { 433 c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) 434 c.setError(fmt.Errorf("can't create storage trie: %v", err)) 435 } 436 } 437 return c.trie 438 } 439 440 // GetState returns a value in account storage. 441 func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { 442 // If we have a dirty value for this state entry, return it 443 value, dirty := self.dirtyStorage[key] 444 if dirty { 445 return value 446 } 447 // Otherwise return the entry's original value 448 return self.GetCommittedState(db, key) 449 } 450 451 // GetCommittedState retrieves a value from the committed account storage trie. 452 func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 453 // If we have the original value cached, return that 454 value, cached := self.originStorage[key] 455 if cached { 456 return value 457 } 458 // Otherwise load the value from the database 459 enc, err := self.getTrie(db).TryGet(key[:]) 460 if err != nil { 461 self.setError(err) 462 return common.Hash{} 463 } 464 if len(enc) > 0 { 465 _, content, _, err := rlp.Split(enc) 466 if err != nil { 467 self.setError(err) 468 } 469 value.SetBytes(content) 470 } 471 self.originStorage[key] = value 472 return value 473 } 474 475 // SetState updates a value in account storage. 476 func (self *stateObject) SetState(db Database, key, value common.Hash) { 477 self.db.journal = append(self.db.journal, storageChange{ 478 account: &self.address, 479 key: key, 480 prevalue: self.GetState(db, key), 481 }) 482 self.setState(key, value) 483 } 484 485 func (self *stateObject) setState(key, value common.Hash) { 486 self.dirtyStorage[key] = value 487 488 if self.onDirty != nil { 489 self.onDirty(self.Address()) 490 self.onDirty = nil 491 } 492 } 493 494 // updateTrie writes cached storage modifications into the object's storage trie. 495 func (self *stateObject) updateTrie(db Database) Trie { 496 tr := self.getTrie(db) 497 for key, value := range self.dirtyStorage { 498 delete(self.dirtyStorage, key) 499 500 // Skip noop changes, persist actual changes 501 if value == self.originStorage[key] { 502 continue 503 } 504 self.originStorage[key] = value 505 506 if (value == common.Hash{}) { 507 self.setError(tr.TryDelete(key[:])) 508 continue 509 } 510 // Encoding []byte cannot fail, ok to ignore the error. 511 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) 512 self.setError(tr.TryUpdate(key[:], v)) 513 } 514 return tr 515 } 516 517 // UpdateRoot sets the trie root to the current root hash of 518 func (self *stateObject) updateRoot(db Database) { 519 self.updateTrie(db) 520 self.data.Root = self.trie.Hash() 521 } 522 523 // CommitTrie the storage trie of the object to dwb. 524 // This updates the trie root. 525 func (self *stateObject) CommitTrie(db Database) error { 526 self.updateTrie(db) 527 if self.dbErr != nil { 528 return self.dbErr 529 } 530 root, err := self.trie.Commit(nil) 531 if err == nil { 532 self.data.Root = root 533 } 534 return err 535 } 536 537 // AddBalance removes amount from c's balance. 538 // It is used to add funds to the destination account of a transfer. 539 func (c *stateObject) AddBalance(amount *big.Int) { 540 // EIP158: We must check emptiness for the objects such that the account 541 // clearing (0,0,0 objects) can take effect. 542 if amount.Sign() == 0 { 543 if c.empty() { 544 c.touch() 545 } 546 547 return 548 } 549 c.SetBalance(new(big.Int).Add(c.Balance(), amount)) 550 } 551 552 // SubBalance removes amount from c's balance. 553 // It is used to remove funds from the origin account of a transfer. 554 func (c *stateObject) SubBalance(amount *big.Int) { 555 if amount.Sign() == 0 { 556 return 557 } 558 c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) 559 } 560 561 func (self *stateObject) SetBalance(amount *big.Int) { 562 self.db.journal = append(self.db.journal, balanceChange{ 563 account: &self.address, 564 prev: new(big.Int).Set(self.data.Balance), 565 }) 566 self.setBalance(amount) 567 } 568 569 func (self *stateObject) setBalance(amount *big.Int) { 570 self.data.Balance = amount 571 if self.onDirty != nil { 572 self.onDirty(self.Address()) 573 self.onDirty = nil 574 } 575 } 576 577 // Return the gas back to the origin. Used by the Virtual machine or Closures 578 func (c *stateObject) ReturnGas(gas *big.Int) {} 579 580 func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { 581 stateObject := newObject(db, self.address, self.data, onDirty) 582 if self.trie != nil { 583 stateObject.trie = db.db.CopyTrie(self.trie) 584 } 585 if self.tx1Trie != nil { 586 stateObject.tx1Trie = db.db.CopyTrie(self.tx1Trie) 587 } 588 if self.tx3Trie != nil { 589 stateObject.tx3Trie = db.db.CopyTrie(self.tx3Trie) 590 } 591 if self.proxiedTrie != nil { 592 stateObject.proxiedTrie = db.db.CopyTrie(self.proxiedTrie) 593 } 594 if self.rewardTrie != nil { 595 stateObject.rewardTrie = db.db.CopyTrie(self.rewardTrie) 596 } 597 stateObject.code = self.code 598 stateObject.dirtyStorage = self.dirtyStorage.Copy() 599 stateObject.originStorage = self.originStorage.Copy() 600 stateObject.suicided = self.suicided 601 stateObject.dirtyCode = self.dirtyCode 602 stateObject.deleted = self.deleted 603 stateObject.dirtyTX1 = make(map[common.Hash]struct{}) 604 for tx1 := range self.dirtyTX1 { 605 stateObject.dirtyTX1[tx1] = struct{}{} 606 } 607 stateObject.dirtyTX3 = make(map[common.Hash]struct{}) 608 for tx3 := range self.dirtyTX3 { 609 stateObject.dirtyTX3[tx3] = struct{}{} 610 } 611 stateObject.dirtyProxied = self.dirtyProxied.Copy() 612 stateObject.originProxied = self.originProxied.Copy() 613 stateObject.dirtyReward = self.dirtyReward.Copy() 614 stateObject.originReward = self.originReward.Copy() 615 return stateObject 616 } 617 618 // 619 // Attribute accessors 620 // 621 622 // Returns the address of the contract/account 623 func (c *stateObject) Address() common.Address { 624 return c.address 625 } 626 627 // Code returns the contract code associated with this object, if any. 628 func (self *stateObject) Code(db Database) []byte { 629 if self.code != nil { 630 return self.code 631 } 632 if bytes.Equal(self.CodeHash(), emptyCodeHash) { 633 return nil 634 } 635 code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) 636 if err != nil { 637 self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) 638 } 639 self.code = code 640 return code 641 } 642 643 func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { 644 prevcode := self.Code(self.db.db) 645 self.db.journal = append(self.db.journal, codeChange{ 646 account: &self.address, 647 prevhash: self.CodeHash(), 648 prevcode: prevcode, 649 }) 650 self.setCode(codeHash, code) 651 } 652 653 func (self *stateObject) setCode(codeHash common.Hash, code []byte) { 654 self.code = code 655 self.data.CodeHash = codeHash[:] 656 self.dirtyCode = true 657 if self.onDirty != nil { 658 self.onDirty(self.Address()) 659 self.onDirty = nil 660 } 661 } 662 663 func (self *stateObject) SetNonce(nonce uint64) { 664 self.db.journal = append(self.db.journal, nonceChange{ 665 account: &self.address, 666 prev: self.data.Nonce, 667 }) 668 self.setNonce(nonce) 669 } 670 671 func (self *stateObject) setNonce(nonce uint64) { 672 self.data.Nonce = nonce 673 if self.onDirty != nil { 674 self.onDirty(self.Address()) 675 self.onDirty = nil 676 } 677 } 678 679 func (self *stateObject) CodeHash() []byte { 680 return self.data.CodeHash 681 } 682 683 func (self *stateObject) Balance() *big.Int { 684 return self.data.Balance 685 } 686 687 func (self *stateObject) Nonce() uint64 { 688 return self.data.Nonce 689 } 690 691 // Never called, but must be present to allow stateObject to be used 692 // as a vm.Account interface that also satisfies the vm.ContractRef 693 // interface. Interfaces are awesome. 694 func (self *stateObject) Value() *big.Int { 695 panic("Value on stateObject should never be called") 696 }