github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/core/state/statedb.go (about) 1 // Package state provides a caching layer atop the Ethereum state trie. 2 package state 3 4 import ( 5 "fmt" 6 "math/big" 7 "sort" 8 "sync" 9 10 "github.com/quickchainproject/quickchain/common" 11 "github.com/quickchainproject/quickchain/core/types" 12 "github.com/quickchainproject/quickchain/crypto" 13 "github.com/quickchainproject/quickchain/log" 14 "github.com/quickchainproject/quickchain/rlp" 15 "github.com/quickchainproject/quickchain/trie" 16 ) 17 18 type revision struct { 19 id int 20 journalIndex int 21 } 22 23 var ( 24 // emptyState is the known hash of an empty state trie entry. 25 emptyState = crypto.Keccak256Hash(nil) 26 27 // emptyCode is the known hash of the empty EVM bytecode. 28 emptyCode = crypto.Keccak256Hash(nil) 29 ) 30 31 // StateDBs within the quickchain protocol are used to store anything 32 // within the merkle trie. StateDBs take care of caching and storing 33 // nested states. It's the general query interface to retrieve: 34 // * Contracts 35 // * Accounts 36 type StateDB struct { 37 db Database 38 trie Trie 39 40 // This map holds 'live' objects, which will get modified while processing a state transition. 41 stateObjects map[common.Address]*stateObject 42 stateObjectsDirty map[common.Address]struct{} 43 44 // DB error. 45 // State objects are used by the consensus core and VM which are 46 // unable to deal with database-level errors. Any error that occurs 47 // during a database read is memoized here and will eventually be returned 48 // by StateDB.Commit. 49 dbErr error 50 51 // The refund counter, also used by state transitioning. 52 refund uint64 53 54 thash, bhash common.Hash 55 txIndex int 56 logs map[common.Hash][]*types.Log 57 logSize uint 58 59 preimages map[common.Hash][]byte 60 61 // Journal of state modifications. This is the backbone of 62 // Snapshot and RevertToSnapshot. 63 journal *journal 64 validRevisions []revision 65 nextRevisionId int 66 67 lock sync.Mutex 68 } 69 70 // Create a new state from a given trie. 71 func New(root common.Hash, db Database) (*StateDB, error) { 72 tr, err := db.OpenTrie(root) 73 if err != nil { 74 return nil, err 75 } 76 return &StateDB{ 77 db: db, 78 trie: tr, 79 stateObjects: make(map[common.Address]*stateObject), 80 stateObjectsDirty: make(map[common.Address]struct{}), 81 logs: make(map[common.Hash][]*types.Log), 82 preimages: make(map[common.Hash][]byte), 83 journal: newJournal(), 84 }, nil 85 } 86 87 // setError remembers the first non-nil error it is called with. 88 func (self *StateDB) setError(err error) { 89 if self.dbErr == nil { 90 self.dbErr = err 91 } 92 } 93 94 func (self *StateDB) Error() error { 95 return self.dbErr 96 } 97 98 // Reset clears out all ephemeral state objects from the state db, but keeps 99 // the underlying state trie to avoid reloading data for the next operations. 100 func (self *StateDB) Reset(root common.Hash) error { 101 tr, err := self.db.OpenTrie(root) 102 if err != nil { 103 return err 104 } 105 self.trie = tr 106 self.stateObjects = make(map[common.Address]*stateObject) 107 self.stateObjectsDirty = make(map[common.Address]struct{}) 108 self.thash = common.Hash{} 109 self.bhash = common.Hash{} 110 self.txIndex = 0 111 self.logs = make(map[common.Hash][]*types.Log) 112 self.logSize = 0 113 self.preimages = make(map[common.Hash][]byte) 114 self.clearJournalAndRefund() 115 return nil 116 } 117 118 func (self *StateDB) AddLog(log *types.Log) { 119 self.journal.append(addLogChange{txhash: self.thash}) 120 121 log.TxHash = self.thash 122 log.BlockHash = self.bhash 123 log.TxIndex = uint(self.txIndex) 124 log.Index = self.logSize 125 self.logs[self.thash] = append(self.logs[self.thash], log) 126 self.logSize++ 127 } 128 129 func (self *StateDB) GetLogs(hash common.Hash) []*types.Log { 130 return self.logs[hash] 131 } 132 133 func (self *StateDB) Logs() []*types.Log { 134 var logs []*types.Log 135 for _, lgs := range self.logs { 136 logs = append(logs, lgs...) 137 } 138 return logs 139 } 140 141 // AddPreimage records a SHA3 preimage seen by the VM. 142 func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) { 143 if _, ok := self.preimages[hash]; !ok { 144 self.journal.append(addPreimageChange{hash: hash}) 145 pi := make([]byte, len(preimage)) 146 copy(pi, preimage) 147 self.preimages[hash] = pi 148 } 149 } 150 151 // Preimages returns a list of SHA3 preimages that have been submitted. 152 func (self *StateDB) Preimages() map[common.Hash][]byte { 153 return self.preimages 154 } 155 156 func (self *StateDB) AddRefund(gas uint64) { 157 self.journal.append(refundChange{prev: self.refund}) 158 self.refund += gas 159 } 160 161 // Exist reports whether the given account address exists in the state. 162 // Notably this also returns true for suicided accounts. 163 func (self *StateDB) Exist(addr common.Address) bool { 164 return self.getStateObject(addr) != nil 165 } 166 167 // Empty returns whether the state object is either non-existent 168 // or empty according to the EIP161 specification (balance = nonce = code = 0) 169 func (self *StateDB) Empty(addr common.Address) bool { 170 so := self.getStateObject(addr) 171 return so == nil || so.empty() 172 } 173 174 // Retrieve the balance from the given address or 0 if object not found 175 func (self *StateDB) GetBalance(addr common.Address) *big.Int { 176 stateObject := self.getStateObject(addr) 177 if stateObject != nil { 178 return stateObject.Balance() 179 } 180 return common.Big0 181 } 182 183 func (self *StateDB) GetNonce(addr common.Address) uint64 { 184 stateObject := self.getStateObject(addr) 185 if stateObject != nil { 186 return stateObject.Nonce() 187 } 188 189 return 0 190 } 191 192 func (self *StateDB) GetCode(addr common.Address) []byte { 193 stateObject := self.getStateObject(addr) 194 if stateObject != nil { 195 return stateObject.Code(self.db) 196 } 197 return nil 198 } 199 200 func (self *StateDB) GetCodeSize(addr common.Address) int { 201 stateObject := self.getStateObject(addr) 202 if stateObject == nil { 203 return 0 204 } 205 if stateObject.code != nil { 206 return len(stateObject.code) 207 } 208 size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) 209 if err != nil { 210 self.setError(err) 211 } 212 return size 213 } 214 215 func (self *StateDB) GetCodeHash(addr common.Address) common.Hash { 216 stateObject := self.getStateObject(addr) 217 if stateObject == nil { 218 return common.Hash{} 219 } 220 return common.BytesToHash(stateObject.CodeHash()) 221 } 222 223 func (self *StateDB) GetState(addr common.Address, bhash common.Hash) common.Hash { 224 stateObject := self.getStateObject(addr) 225 if stateObject != nil { 226 return stateObject.GetState(self.db, bhash) 227 } 228 return common.Hash{} 229 } 230 231 // Database retrieves the low level database supporting the lower level trie ops. 232 func (self *StateDB) Database() Database { 233 return self.db 234 } 235 236 // StorageTrie returns the storage trie of an account. 237 // The return value is a copy and is nil for non-existent accounts. 238 func (self *StateDB) StorageTrie(addr common.Address) Trie { 239 stateObject := self.getStateObject(addr) 240 if stateObject == nil { 241 return nil 242 } 243 cpy := stateObject.deepCopy(self) 244 return cpy.updateTrie(self.db) 245 } 246 247 func (self *StateDB) HasSuicided(addr common.Address) bool { 248 stateObject := self.getStateObject(addr) 249 if stateObject != nil { 250 return stateObject.suicided 251 } 252 return false 253 } 254 255 /* 256 * SETTERS 257 */ 258 259 // AddBalance adds amount to the account associated with addr. 260 func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) { 261 stateObject := self.GetOrNewStateObject(addr) 262 if stateObject != nil { 263 stateObject.AddBalance(amount) 264 } 265 } 266 267 // SubBalance subtracts amount from the account associated with addr. 268 func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) { 269 stateObject := self.GetOrNewStateObject(addr) 270 if stateObject != nil { 271 stateObject.SubBalance(amount) 272 } 273 } 274 275 func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) { 276 stateObject := self.GetOrNewStateObject(addr) 277 if stateObject != nil { 278 stateObject.SetBalance(amount) 279 } 280 } 281 282 func (self *StateDB) SetNonce(addr common.Address, nonce uint64) { 283 stateObject := self.GetOrNewStateObject(addr) 284 if stateObject != nil { 285 stateObject.SetNonce(nonce) 286 } 287 } 288 289 func (self *StateDB) SetCode(addr common.Address, code []byte) { 290 stateObject := self.GetOrNewStateObject(addr) 291 if stateObject != nil { 292 stateObject.SetCode(crypto.Keccak256Hash(code), code) 293 } 294 } 295 296 func (self *StateDB) SetState(addr common.Address, key, value common.Hash) { 297 stateObject := self.GetOrNewStateObject(addr) 298 if stateObject != nil { 299 stateObject.SetState(self.db, key, value) 300 } 301 } 302 303 // Suicide marks the given account as suicided. 304 // This clears the account balance. 305 // 306 // The account's state object is still available until the state is committed, 307 // getStateObject will return a non-nil account after Suicide. 308 func (self *StateDB) Suicide(addr common.Address) bool { 309 stateObject := self.getStateObject(addr) 310 if stateObject == nil { 311 return false 312 } 313 self.journal.append(suicideChange{ 314 account: &addr, 315 prev: stateObject.suicided, 316 prevbalance: new(big.Int).Set(stateObject.Balance()), 317 }) 318 stateObject.markSuicided() 319 stateObject.data.Balance = new(big.Int) 320 321 return true 322 } 323 324 // 325 // Setting, updating & deleting state object methods. 326 // 327 328 // updateStateObject writes the given object to the trie. 329 func (self *StateDB) updateStateObject(stateObject *stateObject) { 330 addr := stateObject.Address() 331 data, err := rlp.EncodeToBytes(stateObject) 332 if err != nil { 333 panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err)) 334 } 335 self.setError(self.trie.TryUpdate(addr[:], data)) 336 } 337 338 // deleteStateObject removes the given object from the state trie. 339 func (self *StateDB) deleteStateObject(stateObject *stateObject) { 340 stateObject.deleted = true 341 addr := stateObject.Address() 342 self.setError(self.trie.TryDelete(addr[:])) 343 } 344 345 // Retrieve a state object given my the address. Returns nil if not found. 346 func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) { 347 // Prefer 'live' objects. 348 if obj := self.stateObjects[addr]; obj != nil { 349 if obj.deleted { 350 return nil 351 } 352 return obj 353 } 354 355 // Load the object from the database. 356 enc, err := self.trie.TryGet(addr[:]) 357 if len(enc) == 0 { 358 self.setError(err) 359 return nil 360 } 361 var data Account 362 if err := rlp.DecodeBytes(enc, &data); err != nil { 363 log.Error("Failed to decode state object", "addr", addr, "err", err) 364 return nil 365 } 366 // Insert into the live set. 367 obj := newObject(self, addr, data) 368 self.setStateObject(obj) 369 return obj 370 } 371 372 func (self *StateDB) setStateObject(object *stateObject) { 373 self.stateObjects[object.Address()] = object 374 } 375 376 // Retrieve a state object or create a new state object if nil. 377 func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { 378 stateObject := self.getStateObject(addr) 379 if stateObject == nil || stateObject.deleted { 380 stateObject, _ = self.createObject(addr) 381 } 382 return stateObject 383 } 384 385 // createObject creates a new state object. If there is an existing account with 386 // the given address, it is overwritten and returned as the second return value. 387 func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { 388 prev = self.getStateObject(addr) 389 newobj = newObject(self, addr, Account{}) 390 newobj.setNonce(0) // sets the object to dirty 391 if prev == nil { 392 self.journal.append(createObjectChange{account: &addr}) 393 } else { 394 self.journal.append(resetObjectChange{prev: prev}) 395 } 396 self.setStateObject(newobj) 397 return newobj, prev 398 } 399 400 // CreateAccount explicitly creates a state object. If a state object with the address 401 // already exists the balance is carried over to the new account. 402 // 403 // CreateAccount is called during the EVM CREATE operation. The situation might arise that 404 // a contract does the following: 405 // 406 // 1. sends funds to sha(account ++ (nonce + 1)) 407 // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) 408 // 409 // Carrying over the balance ensures that Ether doesn't disappear. 410 func (self *StateDB) CreateAccount(addr common.Address) { 411 new, prev := self.createObject(addr) 412 if prev != nil { 413 new.setBalance(prev.data.Balance) 414 } 415 } 416 417 func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) { 418 so := db.getStateObject(addr) 419 if so == nil { 420 return 421 } 422 423 // When iterating over the storage check the cache first 424 for h, value := range so.cachedStorage { 425 cb(h, value) 426 } 427 428 it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil)) 429 for it.Next() { 430 // ignore cached values 431 key := common.BytesToHash(db.trie.GetKey(it.Key)) 432 if _, ok := so.cachedStorage[key]; !ok { 433 cb(key, common.BytesToHash(it.Value)) 434 } 435 } 436 } 437 438 // Copy creates a deep, independent copy of the state. 439 // Snapshots of the copied state cannot be applied to the copy. 440 func (self *StateDB) Copy() *StateDB { 441 self.lock.Lock() 442 defer self.lock.Unlock() 443 444 // Copy all the basic fields, initialize the memory ones 445 state := &StateDB{ 446 db: self.db, 447 trie: self.db.CopyTrie(self.trie), 448 stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)), 449 stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)), 450 refund: self.refund, 451 logs: make(map[common.Hash][]*types.Log, len(self.logs)), 452 logSize: self.logSize, 453 preimages: make(map[common.Hash][]byte), 454 journal: newJournal(), 455 } 456 // Copy the dirty states, logs, and preimages 457 for addr := range self.journal.dirties { 458 // As documented [here](https://github.com/quickchainproject/quickchain/pull/16485#issuecomment-380438527), 459 // and in the Finalise-method, there is a case where an object is in the journal but not 460 // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for 461 // nil 462 if object, exist := self.stateObjects[addr]; exist { 463 state.stateObjects[addr] = object.deepCopy(state) 464 state.stateObjectsDirty[addr] = struct{}{} 465 } 466 } 467 // Above, we don't copy the actual journal. This means that if the copy is copied, the 468 // loop above will be a no-op, since the copy's journal is empty. 469 // Thus, here we iterate over stateObjects, to enable copies of copies 470 for addr := range self.stateObjectsDirty { 471 if _, exist := state.stateObjects[addr]; !exist { 472 state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state) 473 state.stateObjectsDirty[addr] = struct{}{} 474 } 475 } 476 477 for hash, logs := range self.logs { 478 state.logs[hash] = make([]*types.Log, len(logs)) 479 copy(state.logs[hash], logs) 480 } 481 for hash, preimage := range self.preimages { 482 state.preimages[hash] = preimage 483 } 484 return state 485 } 486 487 // Snapshot returns an identifier for the current revision of the state. 488 func (self *StateDB) Snapshot() int { 489 id := self.nextRevisionId 490 self.nextRevisionId++ 491 self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()}) 492 return id 493 } 494 495 // RevertToSnapshot reverts all state changes made since the given revision. 496 func (self *StateDB) RevertToSnapshot(revid int) { 497 // Find the snapshot in the stack of valid snapshots. 498 idx := sort.Search(len(self.validRevisions), func(i int) bool { 499 return self.validRevisions[i].id >= revid 500 }) 501 if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid { 502 panic(fmt.Errorf("revision id %v cannot be reverted", revid)) 503 } 504 snapshot := self.validRevisions[idx].journalIndex 505 506 // Replay the journal to undo changes and remove invalidated snapshots 507 self.journal.revert(self, snapshot) 508 self.validRevisions = self.validRevisions[:idx] 509 } 510 511 // GetRefund returns the current value of the refund counter. 512 func (self *StateDB) GetRefund() uint64 { 513 return self.refund 514 } 515 516 // Finalise finalises the state by removing the self destructed objects 517 // and clears the journal as well as the refunds. 518 func (s *StateDB) Finalise(deleteEmptyObjects bool) { 519 for addr := range s.journal.dirties { 520 stateObject, exist := s.stateObjects[addr] 521 if !exist { 522 // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 523 // That tx goes out of gas, and although the notion of 'touched' does not exist there, the 524 // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, 525 // it will persist in the journal even though the journal is reverted. In this special circumstance, 526 // it may exist in `s.journal.dirties` but not in `s.stateObjects`. 527 // Thus, we can safely ignore it here 528 continue 529 } 530 531 if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { 532 s.deleteStateObject(stateObject) 533 } else { 534 stateObject.updateRoot(s.db) 535 s.updateStateObject(stateObject) 536 } 537 s.stateObjectsDirty[addr] = struct{}{} 538 } 539 // Invalidate journal because reverting across transactions is not allowed. 540 s.clearJournalAndRefund() 541 } 542 543 // IntermediateRoot computes the current root hash of the state trie. 544 // It is called in between transactions to get the root hash that 545 // goes into transaction receipts. 546 func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { 547 s.Finalise(deleteEmptyObjects) 548 return s.trie.Hash() 549 } 550 551 // Prepare sets the current transaction hash and index and block hash which is 552 // used when the EVM emits new state logs. 553 func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { 554 self.thash = thash 555 self.bhash = bhash 556 self.txIndex = ti 557 } 558 559 func (s *StateDB) clearJournalAndRefund() { 560 s.journal = newJournal() 561 s.validRevisions = s.validRevisions[:0] 562 s.refund = 0 563 } 564 565 // Commit writes the state to the underlying in-memory trie database. 566 func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) { 567 defer s.clearJournalAndRefund() 568 569 for addr := range s.journal.dirties { 570 s.stateObjectsDirty[addr] = struct{}{} 571 } 572 // Commit objects to the trie. 573 for addr, stateObject := range s.stateObjects { 574 _, isDirty := s.stateObjectsDirty[addr] 575 switch { 576 case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()): 577 // If the object has been removed, don't bother syncing it 578 // and just mark it for deletion in the trie. 579 s.deleteStateObject(stateObject) 580 case isDirty: 581 // Write any contract code associated with the state object 582 if stateObject.code != nil && stateObject.dirtyCode { 583 s.db.TrieDB().Insert(common.BytesToHash(stateObject.CodeHash()), stateObject.code) 584 stateObject.dirtyCode = false 585 } 586 // Write any storage changes in the state object to its storage trie. 587 if err := stateObject.CommitTrie(s.db); err != nil { 588 return common.Hash{}, err 589 } 590 // Update the object in the main account trie. 591 s.updateStateObject(stateObject) 592 } 593 delete(s.stateObjectsDirty, addr) 594 } 595 // Write trie changes. 596 root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error { 597 var account Account 598 if err := rlp.DecodeBytes(leaf, &account); err != nil { 599 return nil 600 } 601 if account.Root != emptyState { 602 s.db.TrieDB().Reference(account.Root, parent) 603 } 604 code := common.BytesToHash(account.CodeHash) 605 if code != emptyCode { 606 s.db.TrieDB().Reference(code, parent) 607 } 608 return nil 609 }) 610 log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads()) 611 return root, err 612 }