github.com/theQRL/go-zond@v0.2.1/core/state/statedb.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 provides a caching layer atop the Ethereum state trie. 18 package state 19 20 import ( 21 "fmt" 22 "math/big" 23 "sort" 24 "time" 25 26 "github.com/theQRL/go-zond/common" 27 "github.com/theQRL/go-zond/core/rawdb" 28 "github.com/theQRL/go-zond/core/state/snapshot" 29 "github.com/theQRL/go-zond/core/types" 30 "github.com/theQRL/go-zond/crypto" 31 "github.com/theQRL/go-zond/log" 32 "github.com/theQRL/go-zond/metrics" 33 "github.com/theQRL/go-zond/params" 34 "github.com/theQRL/go-zond/trie" 35 "github.com/theQRL/go-zond/trie/trienode" 36 "github.com/theQRL/go-zond/trie/triestate" 37 ) 38 39 const ( 40 // storageDeleteLimit denotes the highest permissible memory allocation 41 // employed for contract storage deletion. 42 storageDeleteLimit = 512 * 1024 * 1024 43 ) 44 45 type revision struct { 46 id int 47 journalIndex int 48 } 49 50 // StateDB structs within the zond protocol are used to store anything 51 // within the merkle trie. StateDBs take care of caching and storing 52 // nested states. It's the general query interface to retrieve: 53 // 54 // * Contracts 55 // * Accounts 56 // 57 // Once the state is committed, tries cached in stateDB (including account 58 // trie, storage tries) will no longer be functional. A new state instance 59 // must be created with new root and updated database for accessing post- 60 // commit states. 61 type StateDB struct { 62 db Database 63 prefetcher *triePrefetcher 64 trie Trie 65 hasher crypto.KeccakState 66 snaps *snapshot.Tree // Nil if snapshot is not available 67 snap snapshot.Snapshot // Nil if snapshot is not available 68 69 // originalRoot is the pre-state root, before any changes were made. 70 // It will be updated when the Commit is called. 71 originalRoot common.Hash 72 73 // These maps hold the state changes (including the corresponding 74 // original value) that occurred in this **block**. 75 accounts map[common.Hash][]byte // The mutated accounts in 'slim RLP' encoding 76 storages map[common.Hash]map[common.Hash][]byte // The mutated slots in prefix-zero trimmed rlp format 77 accountsOrigin map[common.Address][]byte // The original value of mutated accounts in 'slim RLP' encoding 78 storagesOrigin map[common.Address]map[common.Hash][]byte // The original value of mutated slots in prefix-zero trimmed rlp format 79 80 // This map holds 'live' objects, which will get modified while processing 81 // a state transition. 82 stateObjects map[common.Address]*stateObject 83 stateObjectsPending map[common.Address]struct{} // State objects finalized but not yet written to the trie 84 stateObjectsDirty map[common.Address]struct{} // State objects modified in the current execution 85 stateObjectsDestruct map[common.Address]*types.StateAccount // State objects destructed in the block along with its previous value 86 87 // DB error. 88 // State objects are used by the consensus core and VM which are 89 // unable to deal with database-level errors. Any error that occurs 90 // during a database read is memoized here and will eventually be 91 // returned by StateDB.Commit. Notably, this error is also shared 92 // by all cached state objects in case the database failure occurs 93 // when accessing state of accounts. 94 dbErr error 95 96 // The refund counter, also used by state transitioning. 97 refund uint64 98 99 // The tx context and all occurred logs in the scope of transaction. 100 thash common.Hash 101 txIndex int 102 logs map[common.Hash][]*types.Log 103 logSize uint 104 105 // Preimages occurred seen by VM in the scope of block. 106 preimages map[common.Hash][]byte 107 108 // Per-transaction access list 109 accessList *accessList 110 111 // Journal of state modifications. This is the backbone of 112 // Snapshot and RevertToSnapshot. 113 journal *journal 114 validRevisions []revision 115 nextRevisionId int 116 117 // Measurements gathered during execution for debugging purposes 118 AccountReads time.Duration 119 AccountHashes time.Duration 120 AccountUpdates time.Duration 121 AccountCommits time.Duration 122 StorageReads time.Duration 123 StorageHashes time.Duration 124 StorageUpdates time.Duration 125 StorageCommits time.Duration 126 SnapshotAccountReads time.Duration 127 SnapshotStorageReads time.Duration 128 SnapshotCommits time.Duration 129 TrieDBCommits time.Duration 130 131 AccountUpdated int 132 StorageUpdated int 133 AccountDeleted int 134 StorageDeleted int 135 136 // Testing hooks 137 onCommit func(states *triestate.Set) // Hook invoked when commit is performed 138 } 139 140 // New creates a new state from a given trie. 141 func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) { 142 tr, err := db.OpenTrie(root) 143 if err != nil { 144 return nil, err 145 } 146 sdb := &StateDB{ 147 db: db, 148 trie: tr, 149 originalRoot: root, 150 snaps: snaps, 151 accounts: make(map[common.Hash][]byte), 152 storages: make(map[common.Hash]map[common.Hash][]byte), 153 accountsOrigin: make(map[common.Address][]byte), 154 storagesOrigin: make(map[common.Address]map[common.Hash][]byte), 155 stateObjects: make(map[common.Address]*stateObject), 156 stateObjectsPending: make(map[common.Address]struct{}), 157 stateObjectsDirty: make(map[common.Address]struct{}), 158 stateObjectsDestruct: make(map[common.Address]*types.StateAccount), 159 logs: make(map[common.Hash][]*types.Log), 160 preimages: make(map[common.Hash][]byte), 161 journal: newJournal(), 162 accessList: newAccessList(), 163 hasher: crypto.NewKeccakState(), 164 } 165 if sdb.snaps != nil { 166 sdb.snap = sdb.snaps.Snapshot(root) 167 } 168 return sdb, nil 169 } 170 171 // StartPrefetcher initializes a new trie prefetcher to pull in nodes from the 172 // state trie concurrently while the state is mutated so that when we reach the 173 // commit phase, most of the needed data is already hot. 174 func (s *StateDB) StartPrefetcher(namespace string) { 175 if s.prefetcher != nil { 176 s.prefetcher.close() 177 s.prefetcher = nil 178 } 179 if s.snap != nil { 180 s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace) 181 } 182 } 183 184 // StopPrefetcher terminates a running prefetcher and reports any leftover stats 185 // from the gathered metrics. 186 func (s *StateDB) StopPrefetcher() { 187 if s.prefetcher != nil { 188 s.prefetcher.close() 189 s.prefetcher = nil 190 } 191 } 192 193 // setError remembers the first non-nil error it is called with. 194 func (s *StateDB) setError(err error) { 195 if s.dbErr == nil { 196 s.dbErr = err 197 } 198 } 199 200 // Error returns the memorized database failure occurred earlier. 201 func (s *StateDB) Error() error { 202 return s.dbErr 203 } 204 205 func (s *StateDB) AddLog(log *types.Log) { 206 s.journal.append(addLogChange{txhash: s.thash}) 207 208 log.TxHash = s.thash 209 log.TxIndex = uint(s.txIndex) 210 log.Index = s.logSize 211 s.logs[s.thash] = append(s.logs[s.thash], log) 212 s.logSize++ 213 } 214 215 // GetLogs returns the logs matching the specified transaction hash, and annotates 216 // them with the given blockNumber and blockHash. 217 func (s *StateDB) GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log { 218 logs := s.logs[hash] 219 for _, l := range logs { 220 l.BlockNumber = blockNumber 221 l.BlockHash = blockHash 222 } 223 return logs 224 } 225 226 func (s *StateDB) Logs() []*types.Log { 227 var logs []*types.Log 228 for _, lgs := range s.logs { 229 logs = append(logs, lgs...) 230 } 231 return logs 232 } 233 234 // AddPreimage records a SHA3 preimage seen by the VM. 235 func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) { 236 if _, ok := s.preimages[hash]; !ok { 237 s.journal.append(addPreimageChange{hash: hash}) 238 pi := make([]byte, len(preimage)) 239 copy(pi, preimage) 240 s.preimages[hash] = pi 241 } 242 } 243 244 // Preimages returns a list of SHA3 preimages that have been submitted. 245 func (s *StateDB) Preimages() map[common.Hash][]byte { 246 return s.preimages 247 } 248 249 // AddRefund adds gas to the refund counter 250 func (s *StateDB) AddRefund(gas uint64) { 251 s.journal.append(refundChange{prev: s.refund}) 252 s.refund += gas 253 } 254 255 // SubRefund removes gas from the refund counter. 256 // This method will panic if the refund counter goes below zero 257 func (s *StateDB) SubRefund(gas uint64) { 258 s.journal.append(refundChange{prev: s.refund}) 259 if gas > s.refund { 260 panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund)) 261 } 262 s.refund -= gas 263 } 264 265 // Exist reports whether the given account address exists in the state. 266 // Notably this also returns true for self-destructed accounts. 267 func (s *StateDB) Exist(addr common.Address) bool { 268 return s.getStateObject(addr) != nil 269 } 270 271 // Empty returns whether the state object is either non-existent 272 // or empty according to the EIP161 specification (balance = nonce = code = 0) 273 func (s *StateDB) Empty(addr common.Address) bool { 274 so := s.getStateObject(addr) 275 return so == nil || so.empty() 276 } 277 278 // GetBalance retrieves the balance from the given address or 0 if object not found 279 func (s *StateDB) GetBalance(addr common.Address) *big.Int { 280 stateObject := s.getStateObject(addr) 281 if stateObject != nil { 282 return stateObject.Balance() 283 } 284 return common.Big0 285 } 286 287 // GetNonce retrieves the nonce from the given address or 0 if object not found 288 func (s *StateDB) GetNonce(addr common.Address) uint64 { 289 stateObject := s.getStateObject(addr) 290 if stateObject != nil { 291 return stateObject.Nonce() 292 } 293 294 return 0 295 } 296 297 // GetStorageRoot retrieves the storage root from the given address or empty 298 // if object not found. 299 func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash { 300 stateObject := s.getStateObject(addr) 301 if stateObject != nil { 302 return stateObject.Root() 303 } 304 return common.Hash{} 305 } 306 307 // TxIndex returns the current transaction index set by Prepare. 308 func (s *StateDB) TxIndex() int { 309 return s.txIndex 310 } 311 312 func (s *StateDB) GetCode(addr common.Address) []byte { 313 stateObject := s.getStateObject(addr) 314 if stateObject != nil { 315 return stateObject.Code() 316 } 317 return nil 318 } 319 320 func (s *StateDB) GetCodeSize(addr common.Address) int { 321 stateObject := s.getStateObject(addr) 322 if stateObject != nil { 323 return stateObject.CodeSize() 324 } 325 return 0 326 } 327 328 func (s *StateDB) GetCodeHash(addr common.Address) common.Hash { 329 stateObject := s.getStateObject(addr) 330 if stateObject == nil { 331 return common.Hash{} 332 } 333 return common.BytesToHash(stateObject.CodeHash()) 334 } 335 336 // GetState retrieves a value from the given account's storage trie. 337 func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { 338 stateObject := s.getStateObject(addr) 339 if stateObject != nil { 340 return stateObject.GetState(hash) 341 } 342 return common.Hash{} 343 } 344 345 // GetCommittedState retrieves a value from the given account's committed storage trie. 346 func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { 347 stateObject := s.getStateObject(addr) 348 if stateObject != nil { 349 return stateObject.GetCommittedState(hash) 350 } 351 return common.Hash{} 352 } 353 354 // Database retrieves the low level database supporting the lower level trie ops. 355 func (s *StateDB) Database() Database { 356 return s.db 357 } 358 359 /* 360 * SETTERS 361 */ 362 363 // AddBalance adds amount to the account associated with addr. 364 func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) { 365 stateObject := s.GetOrNewStateObject(addr) 366 if stateObject != nil { 367 stateObject.AddBalance(amount) 368 } 369 } 370 371 // SubBalance subtracts amount from the account associated with addr. 372 func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) { 373 stateObject := s.GetOrNewStateObject(addr) 374 if stateObject != nil { 375 stateObject.SubBalance(amount) 376 } 377 } 378 379 func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) { 380 stateObject := s.GetOrNewStateObject(addr) 381 if stateObject != nil { 382 stateObject.SetBalance(amount) 383 } 384 } 385 386 func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { 387 stateObject := s.GetOrNewStateObject(addr) 388 if stateObject != nil { 389 stateObject.SetNonce(nonce) 390 } 391 } 392 393 func (s *StateDB) SetCode(addr common.Address, code []byte) { 394 stateObject := s.GetOrNewStateObject(addr) 395 if stateObject != nil { 396 stateObject.SetCode(crypto.Keccak256Hash(code), code) 397 } 398 } 399 400 func (s *StateDB) SetState(addr common.Address, key, value common.Hash) { 401 stateObject := s.GetOrNewStateObject(addr) 402 if stateObject != nil { 403 stateObject.SetState(key, value) 404 } 405 } 406 407 // SetStorage replaces the entire storage for the specified account with given 408 // storage. This function should only be used for debugging and the mutations 409 // must be discarded afterwards. 410 func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { 411 // SetStorage needs to wipe existing storage. We achieve this by pretending 412 // that the account self-destructed earlier in this block, by flagging 413 // it in stateObjectsDestruct. The effect of doing so is that storage lookups 414 // will not hit disk, since it is assumed that the disk-data is belonging 415 // to a previous incarnation of the object. 416 // 417 // TODO(rjl493456442) this function should only be supported by 'unwritable' 418 // state and all mutations made should all be discarded afterwards. 419 if _, ok := s.stateObjectsDestruct[addr]; !ok { 420 s.stateObjectsDestruct[addr] = nil 421 } 422 stateObject := s.GetOrNewStateObject(addr) 423 for k, v := range storage { 424 stateObject.SetState(k, v) 425 } 426 } 427 428 // 429 // Setting, updating & deleting state object methods. 430 // 431 432 // updateStateObject writes the given object to the trie. 433 func (s *StateDB) updateStateObject(obj *stateObject) { 434 // Track the amount of time wasted on updating the account from the trie 435 if metrics.EnabledExpensive { 436 defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) 437 } 438 // Encode the account and update the account trie 439 addr := obj.Address() 440 if err := s.trie.UpdateAccount(addr, &obj.data); err != nil { 441 s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err)) 442 } 443 if obj.dirtyCode { 444 s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code) 445 } 446 // Cache the data until commit. Note, this update mechanism is not symmetric 447 // to the deletion, because whereas it is enough to track account updates 448 // at commit time, deletions need tracking at transaction boundary level to 449 // ensure we capture state clearing. 450 s.accounts[obj.addrHash] = types.SlimAccountRLP(obj.data) 451 452 // Track the original value of mutated account, nil means it was not present. 453 // Skip if it has been tracked (because updateStateObject may be called 454 // multiple times in a block). 455 if _, ok := s.accountsOrigin[obj.address]; !ok { 456 if obj.origin == nil { 457 s.accountsOrigin[obj.address] = nil 458 } else { 459 s.accountsOrigin[obj.address] = types.SlimAccountRLP(*obj.origin) 460 } 461 } 462 } 463 464 // deleteStateObject removes the given object from the state trie. 465 func (s *StateDB) deleteStateObject(obj *stateObject) { 466 // Track the amount of time wasted on deleting the account from the trie 467 if metrics.EnabledExpensive { 468 defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) 469 } 470 // Delete the account from the trie 471 addr := obj.Address() 472 if err := s.trie.DeleteAccount(addr); err != nil { 473 s.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err)) 474 } 475 } 476 477 // getStateObject retrieves a state object given by the address, returning nil if 478 // the object is not found or was deleted in this execution context. If you need 479 // to differentiate between non-existent/just-deleted, use getDeletedStateObject. 480 func (s *StateDB) getStateObject(addr common.Address) *stateObject { 481 if obj := s.getDeletedStateObject(addr); obj != nil && !obj.deleted { 482 return obj 483 } 484 return nil 485 } 486 487 // getDeletedStateObject is similar to getStateObject, but instead of returning 488 // nil for a deleted state object, it returns the actual object with the deleted 489 // flag set. This is needed by the state journal to revert to the correct s- 490 // destructed object instead of wiping all knowledge about the state object. 491 func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { 492 // Prefer live objects if any is available 493 if obj := s.stateObjects[addr]; obj != nil { 494 return obj 495 } 496 // If no live objects are available, attempt to use snapshots 497 var data *types.StateAccount 498 if s.snap != nil { 499 start := time.Now() 500 acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())) 501 if metrics.EnabledExpensive { 502 s.SnapshotAccountReads += time.Since(start) 503 } 504 if err == nil { 505 if acc == nil { 506 return nil 507 } 508 data = &types.StateAccount{ 509 Nonce: acc.Nonce, 510 Balance: acc.Balance, 511 CodeHash: acc.CodeHash, 512 Root: common.BytesToHash(acc.Root), 513 } 514 if len(data.CodeHash) == 0 { 515 data.CodeHash = types.EmptyCodeHash.Bytes() 516 } 517 if data.Root == (common.Hash{}) { 518 data.Root = types.EmptyRootHash 519 } 520 } 521 } 522 // If snapshot unavailable or reading from it failed, load from the database 523 if data == nil { 524 start := time.Now() 525 var err error 526 data, err = s.trie.GetAccount(addr) 527 if metrics.EnabledExpensive { 528 s.AccountReads += time.Since(start) 529 } 530 if err != nil { 531 s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err)) 532 return nil 533 } 534 if data == nil { 535 return nil 536 } 537 } 538 // Insert into the live set 539 obj := newObject(s, addr, data) 540 s.setStateObject(obj) 541 return obj 542 } 543 544 func (s *StateDB) setStateObject(object *stateObject) { 545 s.stateObjects[object.Address()] = object 546 } 547 548 // GetOrNewStateObject retrieves a state object or create a new state object if nil. 549 func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { 550 stateObject := s.getStateObject(addr) 551 if stateObject == nil { 552 stateObject, _ = s.createObject(addr) 553 } 554 return stateObject 555 } 556 557 // createObject creates a new state object. If there is an existing account with 558 // the given address, it is overwritten and returned as the second return value. 559 func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { 560 prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that! 561 newobj = newObject(s, addr, nil) 562 if prev == nil { 563 s.journal.append(createObjectChange{account: &addr}) 564 } else { 565 // The original account should be marked as destructed and all cached 566 // account and storage data should be cleared as well. Note, it must 567 // be done here, otherwise the destruction event of "original account" 568 // will be lost. 569 _, prevdestruct := s.stateObjectsDestruct[prev.address] 570 if !prevdestruct { 571 s.stateObjectsDestruct[prev.address] = prev.origin 572 } 573 // There may be some cached account/storage data already since IntermediateRoot 574 // will be called for each transaction before byzantium fork which will always 575 // cache the latest account/storage data. 576 prevAccount, ok := s.accountsOrigin[prev.address] 577 s.journal.append(resetObjectChange{ 578 account: &addr, 579 prev: prev, 580 prevdestruct: prevdestruct, 581 prevAccount: s.accounts[prev.addrHash], 582 prevStorage: s.storages[prev.addrHash], 583 prevAccountOriginExist: ok, 584 prevAccountOrigin: prevAccount, 585 prevStorageOrigin: s.storagesOrigin[prev.address], 586 }) 587 delete(s.accounts, prev.addrHash) 588 delete(s.storages, prev.addrHash) 589 delete(s.accountsOrigin, prev.address) 590 delete(s.storagesOrigin, prev.address) 591 } 592 593 newobj.created = true 594 595 s.setStateObject(newobj) 596 if prev != nil && !prev.deleted { 597 return newobj, prev 598 } 599 return newobj, nil 600 } 601 602 // CreateAccount explicitly creates a state object. If a state object with the address 603 // already exists the balance is carried over to the new account. 604 // 605 // CreateAccount is called during the ZVM CREATE operation. The situation might arise that 606 // a contract does the following: 607 // 608 // 1. sends funds to sha(account ++ (nonce + 1)) 609 // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) 610 // 611 // Carrying over the balance ensures that Ether doesn't disappear. 612 func (s *StateDB) CreateAccount(addr common.Address) { 613 newObj, prev := s.createObject(addr) 614 if prev != nil { 615 newObj.setBalance(prev.data.Balance) 616 } 617 } 618 619 // Copy creates a deep, independent copy of the state. 620 // Snapshots of the copied state cannot be applied to the copy. 621 func (s *StateDB) Copy() *StateDB { 622 // Copy all the basic fields, initialize the memory ones 623 state := &StateDB{ 624 db: s.db, 625 trie: s.db.CopyTrie(s.trie), 626 originalRoot: s.originalRoot, 627 accounts: make(map[common.Hash][]byte), 628 storages: make(map[common.Hash]map[common.Hash][]byte), 629 accountsOrigin: make(map[common.Address][]byte), 630 storagesOrigin: make(map[common.Address]map[common.Hash][]byte), 631 stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), 632 stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), 633 stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), 634 stateObjectsDestruct: make(map[common.Address]*types.StateAccount, len(s.stateObjectsDestruct)), 635 refund: s.refund, 636 logs: make(map[common.Hash][]*types.Log, len(s.logs)), 637 logSize: s.logSize, 638 preimages: make(map[common.Hash][]byte, len(s.preimages)), 639 journal: newJournal(), 640 hasher: crypto.NewKeccakState(), 641 642 // In order for the block producer to be able to use and make additions 643 // to the snapshot tree, we need to copy that as well. Otherwise, any 644 // block mined by ourselves will cause gaps in the tree, and force the 645 // miner to operate trie-backed only. 646 snaps: s.snaps, 647 snap: s.snap, 648 } 649 // Copy the dirty states, logs, and preimages 650 for addr := range s.journal.dirties { 651 // As documented [here](https://github.com/theQRL/go-zond/pull/16485#issuecomment-380438527), 652 // and in the Finalise-method, there is a case where an object is in the journal but not 653 // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for 654 // nil 655 if object, exist := s.stateObjects[addr]; exist { 656 // Even though the original object is dirty, we are not copying the journal, 657 // so we need to make sure that any side-effect the journal would have caused 658 // during a commit (or similar op) is already applied to the copy. 659 state.stateObjects[addr] = object.deepCopy(state) 660 661 state.stateObjectsDirty[addr] = struct{}{} // Mark the copy dirty to force internal (code/state) commits 662 state.stateObjectsPending[addr] = struct{}{} // Mark the copy pending to force external (account) commits 663 } 664 } 665 // Above, we don't copy the actual journal. This means that if the copy 666 // is copied, the loop above will be a no-op, since the copy's journal 667 // is empty. Thus, here we iterate over stateObjects, to enable copies 668 // of copies. 669 for addr := range s.stateObjectsPending { 670 if _, exist := state.stateObjects[addr]; !exist { 671 state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) 672 } 673 state.stateObjectsPending[addr] = struct{}{} 674 } 675 for addr := range s.stateObjectsDirty { 676 if _, exist := state.stateObjects[addr]; !exist { 677 state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) 678 } 679 state.stateObjectsDirty[addr] = struct{}{} 680 } 681 // Deep copy the destruction markers. 682 for addr, value := range s.stateObjectsDestruct { 683 state.stateObjectsDestruct[addr] = value 684 } 685 // Deep copy the state changes made in the scope of block 686 // along with their original values. 687 state.accounts = copySet(s.accounts) 688 state.storages = copy2DSet(s.storages) 689 state.accountsOrigin = copySet(state.accountsOrigin) 690 state.storagesOrigin = copy2DSet(state.storagesOrigin) 691 692 // Deep copy the logs occurred in the scope of block 693 for hash, logs := range s.logs { 694 cpy := make([]*types.Log, len(logs)) 695 for i, l := range logs { 696 cpy[i] = new(types.Log) 697 *cpy[i] = *l 698 } 699 state.logs[hash] = cpy 700 } 701 // Deep copy the preimages occurred in the scope of block 702 for hash, preimage := range s.preimages { 703 state.preimages[hash] = preimage 704 } 705 // Do we need to copy the access list? 706 // In practice: No. At the start of a transaction, these two lists are empty. 707 // In practice, we only ever copy state _between_ transactions/blocks, never 708 // in the middle of a transaction. However, it doesn't cost us much to copy 709 // empty lists, so we do it anyway to not blow up if we ever decide copy them 710 // in the middle of a transaction. 711 state.accessList = s.accessList.Copy() 712 713 // If there's a prefetcher running, make an inactive copy of it that can 714 // only access data but does not actively preload (since the user will not 715 // know that they need to explicitly terminate an active copy). 716 if s.prefetcher != nil { 717 state.prefetcher = s.prefetcher.copy() 718 } 719 return state 720 } 721 722 // Snapshot returns an identifier for the current revision of the state. 723 func (s *StateDB) Snapshot() int { 724 id := s.nextRevisionId 725 s.nextRevisionId++ 726 s.validRevisions = append(s.validRevisions, revision{id, s.journal.length()}) 727 return id 728 } 729 730 // RevertToSnapshot reverts all state changes made since the given revision. 731 func (s *StateDB) RevertToSnapshot(revid int) { 732 // Find the snapshot in the stack of valid snapshots. 733 idx := sort.Search(len(s.validRevisions), func(i int) bool { 734 return s.validRevisions[i].id >= revid 735 }) 736 if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { 737 panic(fmt.Errorf("revision id %v cannot be reverted", revid)) 738 } 739 snapshot := s.validRevisions[idx].journalIndex 740 741 // Replay the journal to undo changes and remove invalidated snapshots 742 s.journal.revert(s, snapshot) 743 s.validRevisions = s.validRevisions[:idx] 744 } 745 746 // GetRefund returns the current value of the refund counter. 747 func (s *StateDB) GetRefund() uint64 { 748 return s.refund 749 } 750 751 // Finalise finalises the state by removing the destructed objects and clears 752 // the journal as well as the refunds. Finalise, however, will not push any updates 753 // into the tries just yet. Only IntermediateRoot or Commit will do that. 754 func (s *StateDB) Finalise(deleteEmptyObjects bool) { 755 addressesToPrefetch := make([][]byte, 0, len(s.journal.dirties)) 756 for addr := range s.journal.dirties { 757 obj, exist := s.stateObjects[addr] 758 if !exist { 759 // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 760 // That tx goes out of gas, and although the notion of 'touched' does not exist there, the 761 // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, 762 // it will persist in the journal even though the journal is reverted. In this special circumstance, 763 // it may exist in `s.journal.dirties` but not in `s.stateObjects`. 764 // Thus, we can safely ignore it here 765 continue 766 } 767 if deleteEmptyObjects && obj.empty() { 768 obj.deleted = true 769 770 // We need to maintain account deletions explicitly (will remain 771 // set indefinitely). Note only the first occurred self-destruct 772 // event is tracked. 773 if _, ok := s.stateObjectsDestruct[obj.address]; !ok { 774 s.stateObjectsDestruct[obj.address] = obj.origin 775 } 776 // Note, we can't do this only at the end of a block because multiple 777 // transactions within the same block might self destruct and then 778 // resurrect an account; but the snapshotter needs both events. 779 delete(s.accounts, obj.addrHash) // Clear out any previously updated account data (may be recreated via a resurrect) 780 delete(s.storages, obj.addrHash) // Clear out any previously updated storage data (may be recreated via a resurrect) 781 delete(s.accountsOrigin, obj.address) // Clear out any previously updated account data (may be recreated via a resurrect) 782 delete(s.storagesOrigin, obj.address) // Clear out any previously updated storage data (may be recreated via a resurrect) 783 } else { 784 obj.finalise(true) // Prefetch slots in the background 785 } 786 obj.created = false 787 s.stateObjectsPending[addr] = struct{}{} 788 s.stateObjectsDirty[addr] = struct{}{} 789 790 // At this point, also ship the address off to the precacher. The precacher 791 // will start loading tries, and when the change is eventually committed, 792 // the commit-phase will be a lot faster 793 addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure 794 } 795 if s.prefetcher != nil && len(addressesToPrefetch) > 0 { 796 s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch) 797 } 798 // Invalidate journal because reverting across transactions is not allowed. 799 s.clearJournalAndRefund() 800 } 801 802 // IntermediateRoot computes the current root hash of the state trie. 803 // It is called in between transactions to get the root hash that 804 // goes into transaction receipts. 805 func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { 806 // Finalise all the dirty storage states and write them into the tries 807 s.Finalise(deleteEmptyObjects) 808 809 // If there was a trie prefetcher operating, it gets aborted and irrevocably 810 // modified after we start retrieving tries. Remove it from the statedb after 811 // this round of use. 812 // 813 // This is weird pre-byzantium since the first tx runs with a prefetcher and 814 // the remainder without, but pre-byzantium even the initial prefetcher is 815 // useless, so no sleep lost. 816 prefetcher := s.prefetcher 817 if s.prefetcher != nil { 818 defer func() { 819 s.prefetcher.close() 820 s.prefetcher = nil 821 }() 822 } 823 // Although naively it makes sense to retrieve the account trie and then do 824 // the contract storage and account updates sequentially, that short circuits 825 // the account prefetcher. Instead, let's process all the storage updates 826 // first, giving the account prefetches just a few more milliseconds of time 827 // to pull useful data from disk. 828 for addr := range s.stateObjectsPending { 829 if obj := s.stateObjects[addr]; !obj.deleted { 830 obj.updateRoot() 831 } 832 } 833 // Now we're about to start to write changes to the trie. The trie is so far 834 // _untouched_. We can check with the prefetcher, if it can give us a trie 835 // which has the same root, but also has some content loaded into it. 836 if prefetcher != nil { 837 if trie := prefetcher.trie(common.Hash{}, s.originalRoot); trie != nil { 838 s.trie = trie 839 } 840 } 841 usedAddrs := make([][]byte, 0, len(s.stateObjectsPending)) 842 for addr := range s.stateObjectsPending { 843 if obj := s.stateObjects[addr]; obj.deleted { 844 s.deleteStateObject(obj) 845 s.AccountDeleted += 1 846 } else { 847 s.updateStateObject(obj) 848 s.AccountUpdated += 1 849 } 850 usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure 851 } 852 if prefetcher != nil { 853 prefetcher.used(common.Hash{}, s.originalRoot, usedAddrs) 854 } 855 if len(s.stateObjectsPending) > 0 { 856 s.stateObjectsPending = make(map[common.Address]struct{}) 857 } 858 // Track the amount of time wasted on hashing the account trie 859 if metrics.EnabledExpensive { 860 defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) 861 } 862 return s.trie.Hash() 863 } 864 865 // SetTxContext sets the current transaction hash and index which are 866 // used when the ZVM emits new state logs. It should be invoked before 867 // transaction execution. 868 func (s *StateDB) SetTxContext(thash common.Hash, ti int) { 869 s.thash = thash 870 s.txIndex = ti 871 } 872 873 func (s *StateDB) clearJournalAndRefund() { 874 if len(s.journal.entries) > 0 { 875 s.journal = newJournal() 876 s.refund = 0 877 } 878 s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries 879 } 880 881 // fastDeleteStorage is the function that efficiently deletes the storage trie 882 // of a specific account. It leverages the associated state snapshot for fast 883 // storage iteration and constructs trie node deletion markers by creating 884 // stack trie with iterated slots. 885 func (s *StateDB) fastDeleteStorage(addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { 886 iter, err := s.snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{}) 887 if err != nil { 888 return false, 0, nil, nil, err 889 } 890 defer iter.Release() 891 892 var ( 893 size common.StorageSize 894 nodes = trienode.NewNodeSet(addrHash) 895 slots = make(map[common.Hash][]byte) 896 ) 897 stack := trie.NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) { 898 nodes.AddNode(path, trienode.NewDeleted()) 899 size += common.StorageSize(len(path)) 900 }) 901 for iter.Next() { 902 if size > storageDeleteLimit { 903 return true, size, nil, nil, nil 904 } 905 slot := common.CopyBytes(iter.Slot()) 906 if err := iter.Error(); err != nil { // error might occur after Slot function 907 return false, 0, nil, nil, err 908 } 909 size += common.StorageSize(common.HashLength + len(slot)) 910 slots[iter.Hash()] = slot 911 912 if err := stack.Update(iter.Hash().Bytes(), slot); err != nil { 913 return false, 0, nil, nil, err 914 } 915 } 916 if err := iter.Error(); err != nil { // error might occur during iteration 917 return false, 0, nil, nil, err 918 } 919 if stack.Hash() != root { 920 return false, 0, nil, nil, fmt.Errorf("snapshot is not matched, exp %x, got %x", root, stack.Hash()) 921 } 922 return false, size, slots, nodes, nil 923 } 924 925 // slowDeleteStorage serves as a less-efficient alternative to "fastDeleteStorage," 926 // employed when the associated state snapshot is not available. It iterates the 927 // storage slots along with all internal trie nodes via trie directly. 928 func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { 929 tr, err := s.db.OpenStorageTrie(s.originalRoot, addr, root) 930 if err != nil { 931 return false, 0, nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err) 932 } 933 it, err := tr.NodeIterator(nil) 934 if err != nil { 935 return false, 0, nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err) 936 } 937 var ( 938 size common.StorageSize 939 nodes = trienode.NewNodeSet(addrHash) 940 slots = make(map[common.Hash][]byte) 941 ) 942 for it.Next(true) { 943 if size > storageDeleteLimit { 944 return true, size, nil, nil, nil 945 } 946 if it.Leaf() { 947 slots[common.BytesToHash(it.LeafKey())] = common.CopyBytes(it.LeafBlob()) 948 size += common.StorageSize(common.HashLength + len(it.LeafBlob())) 949 continue 950 } 951 if it.Hash() == (common.Hash{}) { 952 continue 953 } 954 size += common.StorageSize(len(it.Path())) 955 nodes.AddNode(it.Path(), trienode.NewDeleted()) 956 } 957 if err := it.Error(); err != nil { 958 return false, 0, nil, nil, err 959 } 960 return false, size, slots, nodes, nil 961 } 962 963 // deleteStorage is designed to delete the storage trie of a designated account. 964 // It could potentially be terminated if the storage size is excessively large, 965 // potentially leading to an out-of-memory panic. The function will make an attempt 966 // to utilize an efficient strategy if the associated state snapshot is reachable; 967 // otherwise, it will resort to a less-efficient approach. 968 func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, map[common.Hash][]byte, *trienode.NodeSet, error) { 969 var ( 970 start = time.Now() 971 err error 972 aborted bool 973 size common.StorageSize 974 slots map[common.Hash][]byte 975 nodes *trienode.NodeSet 976 ) 977 // The fast approach can be failed if the snapshot is not fully 978 // generated, or it's internally corrupted. Fallback to the slow 979 // one just in case. 980 if s.snap != nil { 981 aborted, size, slots, nodes, err = s.fastDeleteStorage(addrHash, root) 982 } 983 if s.snap == nil || err != nil { 984 aborted, size, slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root) 985 } 986 if err != nil { 987 return false, nil, nil, err 988 } 989 if metrics.EnabledExpensive { 990 if aborted { 991 slotDeletionSkip.Inc(1) 992 } 993 n := int64(len(slots)) 994 995 slotDeletionMaxCount.UpdateIfGt(int64(len(slots))) 996 slotDeletionMaxSize.UpdateIfGt(int64(size)) 997 998 slotDeletionTimer.UpdateSince(start) 999 slotDeletionCount.Mark(n) 1000 slotDeletionSize.Mark(int64(size)) 1001 } 1002 return aborted, slots, nodes, nil 1003 } 1004 1005 // handleDestruction processes all destruction markers and deletes the account 1006 // and associated storage slots if necessary. There are four possible situations 1007 // here: 1008 // 1009 // - the account was not existent and be marked as destructed 1010 // 1011 // - the account was not existent and be marked as destructed, 1012 // however, it's resurrected later in the same block. 1013 // 1014 // - the account was existent and be marked as destructed 1015 // 1016 // - the account was existent and be marked as destructed, 1017 // however it's resurrected later in the same block. 1018 // 1019 // In case (a), nothing needs be deleted, nil to nil transition can be ignored. 1020 // 1021 // In case (b), nothing needs be deleted, nil is used as the original value for 1022 // newly created account and storages 1023 // 1024 // In case (c), **original** account along with its storages should be deleted, 1025 // with their values be tracked as original value. 1026 // 1027 // In case (d), **original** account along with its storages should be deleted, 1028 // with their values be tracked as original value. 1029 func (s *StateDB) handleDestruction(nodes *trienode.MergedNodeSet) (map[common.Address]struct{}, error) { 1030 // Short circuit if gzond is running with hash mode. This procedure can consume 1031 // considerable time and storage deletion isn't supported in hash mode, thus 1032 // preemptively avoiding unnecessary expenses. 1033 incomplete := make(map[common.Address]struct{}) 1034 if s.db.TrieDB().Scheme() == rawdb.HashScheme { 1035 return incomplete, nil 1036 } 1037 for addr, prev := range s.stateObjectsDestruct { 1038 // The original account was non-existing, and it's marked as destructed 1039 // in the scope of block. It can be case (a) or (b). 1040 // - for (a), skip it without doing anything. 1041 // - for (b), track account's original value as nil. It may overwrite 1042 // the data cached in s.accountsOrigin set by 'updateStateObject'. 1043 addrHash := crypto.Keccak256Hash(addr[:]) 1044 if prev == nil { 1045 if _, ok := s.accounts[addrHash]; ok { 1046 s.accountsOrigin[addr] = nil // case (b) 1047 } 1048 continue 1049 } 1050 // It can overwrite the data in s.accountsOrigin set by 'updateStateObject'. 1051 s.accountsOrigin[addr] = types.SlimAccountRLP(*prev) // case (c) or (d) 1052 1053 // Short circuit if the storage was empty. 1054 if prev.Root == types.EmptyRootHash { 1055 continue 1056 } 1057 // Remove storage slots belong to the account. 1058 aborted, slots, set, err := s.deleteStorage(addr, addrHash, prev.Root) 1059 if err != nil { 1060 return nil, fmt.Errorf("failed to delete storage, err: %w", err) 1061 } 1062 // The storage is too huge to handle, skip it but mark as incomplete. 1063 // For case (d), the account is resurrected might with a few slots 1064 // created. In this case, wipe the entire storage state diff because 1065 // of aborted deletion. 1066 if aborted { 1067 incomplete[addr] = struct{}{} 1068 delete(s.storagesOrigin, addr) 1069 continue 1070 } 1071 if s.storagesOrigin[addr] == nil { 1072 s.storagesOrigin[addr] = slots 1073 } else { 1074 // It can overwrite the data in s.storagesOrigin[addrHash] set by 1075 // 'object.updateTrie'. 1076 for key, val := range slots { 1077 s.storagesOrigin[addr][key] = val 1078 } 1079 } 1080 if err := nodes.Merge(set); err != nil { 1081 return nil, err 1082 } 1083 } 1084 return incomplete, nil 1085 } 1086 1087 // Commit writes the state to the underlying in-memory trie database. 1088 // Once the state is committed, tries cached in stateDB (including account 1089 // trie, storage tries) will no longer be functional. A new state instance 1090 // must be created with new root and updated database for accessing post- 1091 // commit states. 1092 // 1093 // The associated block number of the state transition is also provided 1094 // for more chain context. 1095 func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error) { 1096 // Short circuit in case any database failure occurred earlier. 1097 if s.dbErr != nil { 1098 return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) 1099 } 1100 // Finalize any pending changes and merge everything into the tries 1101 s.IntermediateRoot(deleteEmptyObjects) 1102 1103 // Commit objects to the trie, measuring the elapsed time 1104 var ( 1105 accountTrieNodesUpdated int 1106 accountTrieNodesDeleted int 1107 storageTrieNodesUpdated int 1108 storageTrieNodesDeleted int 1109 nodes = trienode.NewMergedNodeSet() 1110 codeWriter = s.db.DiskDB().NewBatch() 1111 ) 1112 // Handle all state deletions first 1113 incomplete, err := s.handleDestruction(nodes) 1114 if err != nil { 1115 return common.Hash{}, err 1116 } 1117 // Handle all state updates afterwards 1118 for addr := range s.stateObjectsDirty { 1119 obj := s.stateObjects[addr] 1120 if obj.deleted { 1121 continue 1122 } 1123 // Write any contract code associated with the state object 1124 if obj.code != nil && obj.dirtyCode { 1125 rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) 1126 obj.dirtyCode = false 1127 } 1128 // Write any storage changes in the state object to its storage trie 1129 set, err := obj.commit() 1130 if err != nil { 1131 return common.Hash{}, err 1132 } 1133 // Merge the dirty nodes of storage trie into global set. It is possible 1134 // that the account was destructed and then resurrected in the same block. 1135 // In this case, the node set is shared by both accounts. 1136 if set != nil { 1137 if err := nodes.Merge(set); err != nil { 1138 return common.Hash{}, err 1139 } 1140 updates, deleted := set.Size() 1141 storageTrieNodesUpdated += updates 1142 storageTrieNodesDeleted += deleted 1143 } 1144 } 1145 if codeWriter.ValueSize() > 0 { 1146 if err := codeWriter.Write(); err != nil { 1147 log.Crit("Failed to commit dirty codes", "error", err) 1148 } 1149 } 1150 // Write the account trie changes, measuring the amount of wasted time 1151 var start time.Time 1152 if metrics.EnabledExpensive { 1153 start = time.Now() 1154 } 1155 root, set, err := s.trie.Commit(true) 1156 if err != nil { 1157 return common.Hash{}, err 1158 } 1159 // Merge the dirty nodes of account trie into global set 1160 if set != nil { 1161 if err := nodes.Merge(set); err != nil { 1162 return common.Hash{}, err 1163 } 1164 accountTrieNodesUpdated, accountTrieNodesDeleted = set.Size() 1165 } 1166 if metrics.EnabledExpensive { 1167 s.AccountCommits += time.Since(start) 1168 1169 accountUpdatedMeter.Mark(int64(s.AccountUpdated)) 1170 storageUpdatedMeter.Mark(int64(s.StorageUpdated)) 1171 accountDeletedMeter.Mark(int64(s.AccountDeleted)) 1172 storageDeletedMeter.Mark(int64(s.StorageDeleted)) 1173 accountTrieUpdatedMeter.Mark(int64(accountTrieNodesUpdated)) 1174 accountTrieDeletedMeter.Mark(int64(accountTrieNodesDeleted)) 1175 storageTriesUpdatedMeter.Mark(int64(storageTrieNodesUpdated)) 1176 storageTriesDeletedMeter.Mark(int64(storageTrieNodesDeleted)) 1177 s.AccountUpdated, s.AccountDeleted = 0, 0 1178 s.StorageUpdated, s.StorageDeleted = 0, 0 1179 } 1180 // If snapshotting is enabled, update the snapshot tree with this new version 1181 if s.snap != nil { 1182 start := time.Now() 1183 // Only update if there's a state transition (skip empty Clique blocks) 1184 if parent := s.snap.Root(); parent != root { 1185 if err := s.snaps.Update(root, parent, s.convertAccountSet(s.stateObjectsDestruct), s.accounts, s.storages); err != nil { 1186 log.Warn("Failed to update snapshot tree", "from", parent, "to", root, "err", err) 1187 } 1188 // Keep 128 diff layers in the memory, persistent layer is 129th. 1189 // - head layer is paired with HEAD state 1190 // - head-1 layer is paired with HEAD-1 state 1191 // - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state 1192 if err := s.snaps.Cap(root, 128); err != nil { 1193 log.Warn("Failed to cap snapshot tree", "root", root, "layers", 128, "err", err) 1194 } 1195 } 1196 if metrics.EnabledExpensive { 1197 s.SnapshotCommits += time.Since(start) 1198 } 1199 s.snap = nil 1200 } 1201 if root == (common.Hash{}) { 1202 root = types.EmptyRootHash 1203 } 1204 origin := s.originalRoot 1205 if origin == (common.Hash{}) { 1206 origin = types.EmptyRootHash 1207 } 1208 if root != origin { 1209 start := time.Now() 1210 set := triestate.New(s.accountsOrigin, s.storagesOrigin, incomplete) 1211 if err := s.db.TrieDB().Update(root, origin, block, nodes, set); err != nil { 1212 return common.Hash{}, err 1213 } 1214 s.originalRoot = root 1215 if metrics.EnabledExpensive { 1216 s.TrieDBCommits += time.Since(start) 1217 } 1218 if s.onCommit != nil { 1219 s.onCommit(set) 1220 } 1221 } 1222 // Clear all internal flags at the end of commit operation. 1223 s.accounts = make(map[common.Hash][]byte) 1224 s.storages = make(map[common.Hash]map[common.Hash][]byte) 1225 s.accountsOrigin = make(map[common.Address][]byte) 1226 s.storagesOrigin = make(map[common.Address]map[common.Hash][]byte) 1227 s.stateObjectsDirty = make(map[common.Address]struct{}) 1228 s.stateObjectsDestruct = make(map[common.Address]*types.StateAccount) 1229 return root, nil 1230 } 1231 1232 // Prepare handles the preparatory steps for executing a state transition with. 1233 // This method must be invoked before state transition. 1234 // 1235 // Berlin fork: 1236 // - Add sender to access list (2929) 1237 // - Add destination to access list (2929) 1238 // - Add precompiles to access list (2929) 1239 // - Add the contents of the optional tx access list (2930) 1240 // 1241 // Potential EIPs: 1242 // - Reset access list (Berlin) 1243 // - Add coinbase to access list (EIP-3651) 1244 func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) { 1245 // Clear out any leftover from previous executions 1246 al := newAccessList() 1247 s.accessList = al 1248 1249 al.AddAddress(sender) 1250 if dst != nil { 1251 al.AddAddress(*dst) 1252 // If it's a create-tx, the destination will be added inside zvm.create 1253 } 1254 for _, addr := range precompiles { 1255 al.AddAddress(addr) 1256 } 1257 for _, el := range list { 1258 al.AddAddress(el.Address) 1259 for _, key := range el.StorageKeys { 1260 al.AddSlot(el.Address, key) 1261 } 1262 } 1263 al.AddAddress(coinbase) 1264 } 1265 1266 // AddAddressToAccessList adds the given address to the access list 1267 func (s *StateDB) AddAddressToAccessList(addr common.Address) { 1268 if s.accessList.AddAddress(addr) { 1269 s.journal.append(accessListAddAccountChange{&addr}) 1270 } 1271 } 1272 1273 // AddSlotToAccessList adds the given (address, slot)-tuple to the access list 1274 func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { 1275 addrMod, slotMod := s.accessList.AddSlot(addr, slot) 1276 if addrMod { 1277 // In practice, this should not happen, since there is no way to enter the 1278 // scope of 'address' without having the 'address' become already added 1279 // to the access list (via call-variant, create, etc). 1280 // Better safe than sorry, though 1281 s.journal.append(accessListAddAccountChange{&addr}) 1282 } 1283 if slotMod { 1284 s.journal.append(accessListAddSlotChange{ 1285 address: &addr, 1286 slot: &slot, 1287 }) 1288 } 1289 } 1290 1291 // AddressInAccessList returns true if the given address is in the access list. 1292 func (s *StateDB) AddressInAccessList(addr common.Address) bool { 1293 return s.accessList.ContainsAddress(addr) 1294 } 1295 1296 // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list. 1297 func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) { 1298 return s.accessList.Contains(addr, slot) 1299 } 1300 1301 // convertAccountSet converts a provided account set from address keyed to hash keyed. 1302 func (s *StateDB) convertAccountSet(set map[common.Address]*types.StateAccount) map[common.Hash]struct{} { 1303 ret := make(map[common.Hash]struct{}, len(set)) 1304 for addr := range set { 1305 obj, exist := s.stateObjects[addr] 1306 if !exist { 1307 ret[crypto.Keccak256Hash(addr[:])] = struct{}{} 1308 } else { 1309 ret[obj.addrHash] = struct{}{} 1310 } 1311 } 1312 return ret 1313 } 1314 1315 // copySet returns a deep-copied set. 1316 func copySet[k comparable](set map[k][]byte) map[k][]byte { 1317 copied := make(map[k][]byte, len(set)) 1318 for key, val := range set { 1319 copied[key] = common.CopyBytes(val) 1320 } 1321 return copied 1322 } 1323 1324 // copy2DSet returns a two-dimensional deep-copied set. 1325 func copy2DSet[k comparable](set map[k]map[common.Hash][]byte) map[k]map[common.Hash][]byte { 1326 copied := make(map[k]map[common.Hash][]byte, len(set)) 1327 for addr, subset := range set { 1328 copied[addr] = make(map[common.Hash][]byte, len(subset)) 1329 for key, val := range subset { 1330 copied[addr][key] = common.CopyBytes(val) 1331 } 1332 } 1333 return copied 1334 }