MCPcopy Create free account
hub / github.com/CPChain/chain / Copy

Method Copy

core/state/statedb.go:456–501  ·  view source on GitHub ↗

Copy creates a deep, independent copy of the state. Snapshots of the copied state cannot be applied to the copy.

()

Source from the content-addressed store, hash-verified

454// Copy creates a deep, independent copy of the state.
455// Snapshots of the copied state cannot be applied to the copy.
456func (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.
504func (self *StateDB) Snapshot() int {

Callers 5

OpenTrieMethod · 0.45
CopyTrieMethod · 0.45
ManageStateFunction · 0.45
TestCopyFunction · 0.45
TestCopyOfCopyFunction · 0.45

Calls 5

newJournalFunction · 0.85
LockMethod · 0.80
UnlockMethod · 0.80
deepCopyMethod · 0.80
CopyTrieMethod · 0.65

Tested by 2

TestCopyFunction · 0.36
TestCopyOfCopyFunction · 0.36