Copy creates a deep, independent copy of the state. Snapshots of the copied state cannot be applied to the copy.
()
| 454 | // Copy creates a deep, independent copy of the state. |
| 455 | // Snapshots of the copied state cannot be applied to the copy. |
| 456 | func (self *StateDB) Copy() *StateDB { |
| 457 | self.lock.Lock() |
| 458 | defer self.lock.Unlock() |
| 459 | |
| 460 | // Copy all the basic fields, initialize the memory ones |
| 461 | state := &StateDB{ |
| 462 | db: self.db, |
| 463 | trie: self.db.CopyTrie(self.trie), |
| 464 | stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)), |
| 465 | stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)), |
| 466 | refund: self.refund, |
| 467 | logs: make(map[common.Hash][]*types.Log, len(self.logs)), |
| 468 | logSize: self.logSize, |
| 469 | preimages: make(map[common.Hash][]byte), |
| 470 | journal: newJournal(), |
| 471 | } |
| 472 | // Copy the dirty states, logs, and preimages |
| 473 | for addr := range self.journal.dirties { |
| 474 | // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), |
| 475 | // and in the Finalise-method, there is a case where an object is in the journal but not |
| 476 | // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for |
| 477 | // nil |
| 478 | if object, exist := self.stateObjects[addr]; exist { |
| 479 | state.stateObjects[addr] = object.deepCopy(state) |
| 480 | state.stateObjectsDirty[addr] = struct{}{} |
| 481 | } |
| 482 | } |
| 483 | // Above, we don't copy the actual journal. This means that if the copy is copied, the |
| 484 | // loop above will be a no-op, since the copy's journal is empty. |
| 485 | // Thus, here we iterate over stateObjects, to enable copies of copies |
| 486 | for addr := range self.stateObjectsDirty { |
| 487 | if _, exist := state.stateObjects[addr]; !exist { |
| 488 | state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state) |
| 489 | state.stateObjectsDirty[addr] = struct{}{} |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | for hash, logs := range self.logs { |
| 494 | state.logs[hash] = make([]*types.Log, len(logs)) |
| 495 | copy(state.logs[hash], logs) |
| 496 | } |
| 497 | for hash, preimage := range self.preimages { |
| 498 | state.preimages[hash] = preimage |
| 499 | } |
| 500 | return state |
| 501 | } |
| 502 | |
| 503 | // Snapshot returns an identifier for the current revision of the state. |
| 504 | func (self *StateDB) Snapshot() int { |