aboutsummaryrefslogtreecommitdiffstats
path: root/core/state/statedb.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2017-02-02 05:36:51 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2017-05-18 15:05:58 +0800
commit10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9 (patch)
tree170eb09bf51c802894d9335570d7319a2f86ef15 /core/state/statedb.go
parenta2f23ca9b181fa4409fdee3076316f3127038b9b (diff)
downloaddexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar.gz
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar.bz2
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar.lz
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar.xz
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.tar.zst
dexon-10a57fc3d45cbc59d6c8eeb0f7f2b93a71e8f4c9.zip
consensus, core/*, params: metropolis preparation refactor
This commit is a preparation for the upcoming metropolis hardfork. It prepares the state, core and vm packages such that integration with metropolis becomes less of a hassle. * Difficulty calculation requires header instead of individual parameters * statedb.StartRecord renamed to statedb.Prepare and added Finalise method required by metropolis, which removes unwanted accounts from the state (i.e. selfdestruct) * State keeps record of destructed objects (in addition to dirty objects) * core/vm pre-compiles may now return errors * core/vm pre-compiles gas check now take the full byte slice as argument instead of just the size * core/vm now keeps several hard-fork instruction tables instead of a single instruction table and removes the need for hard-fork checks in the instructions * core/vm contains a empty restruction function which is added in preparation of metropolis write-only mode operations * Adds the bn256 curve * Adds and sets the metropolis chain config block parameters (2^64-1)
Diffstat (limited to 'core/state/statedb.go')
-rw-r--r--core/state/statedb.go91
1 files changed, 57 insertions, 34 deletions
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 3b753a2e6..8e4ba21c0 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -62,8 +62,9 @@ type StateDB struct {
codeSizeCache *lru.Cache
// This map holds 'live' objects, which will get modified while processing a state transition.
- stateObjects map[common.Address]*stateObject
- stateObjectsDirty map[common.Address]struct{}
+ stateObjects map[common.Address]*stateObject
+ stateObjectsDirty map[common.Address]struct{}
+ stateObjectsDestructed map[common.Address]struct{}
// The refund counter, also used by state transitioning.
refund *big.Int
@@ -92,14 +93,15 @@ func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
}
csc, _ := lru.New(codeSizeCacheSize)
return &StateDB{
- db: db,
- trie: tr,
- codeSizeCache: csc,
- stateObjects: make(map[common.Address]*stateObject),
- stateObjectsDirty: make(map[common.Address]struct{}),
- refund: new(big.Int),
- logs: make(map[common.Hash][]*types.Log),
- preimages: make(map[common.Hash][]byte),
+ db: db,
+ trie: tr,
+ codeSizeCache: csc,
+ stateObjects: make(map[common.Address]*stateObject),
+ stateObjectsDirty: make(map[common.Address]struct{}),
+ stateObjectsDestructed: make(map[common.Address]struct{}),
+ refund: new(big.Int),
+ logs: make(map[common.Hash][]*types.Log),
+ preimages: make(map[common.Hash][]byte),
}, nil
}
@@ -114,14 +116,15 @@ func (self *StateDB) New(root common.Hash) (*StateDB, error) {
return nil, err
}
return &StateDB{
- db: self.db,
- trie: tr,
- codeSizeCache: self.codeSizeCache,
- stateObjects: make(map[common.Address]*stateObject),
- stateObjectsDirty: make(map[common.Address]struct{}),
- refund: new(big.Int),
- logs: make(map[common.Hash][]*types.Log),
- preimages: make(map[common.Hash][]byte),
+ db: self.db,
+ trie: tr,
+ codeSizeCache: self.codeSizeCache,
+ stateObjects: make(map[common.Address]*stateObject),
+ stateObjectsDirty: make(map[common.Address]struct{}),
+ stateObjectsDestructed: make(map[common.Address]struct{}),
+ refund: new(big.Int),
+ logs: make(map[common.Hash][]*types.Log),
+ preimages: make(map[common.Hash][]byte),
}, nil
}
@@ -138,6 +141,7 @@ func (self *StateDB) Reset(root common.Hash) error {
self.trie = tr
self.stateObjects = make(map[common.Address]*stateObject)
self.stateObjectsDirty = make(map[common.Address]struct{})
+ self.stateObjectsDestructed = make(map[common.Address]struct{})
self.thash = common.Hash{}
self.bhash = common.Hash{}
self.txIndex = 0
@@ -173,12 +177,6 @@ func (self *StateDB) pushTrie(t *trie.SecureTrie) {
}
}
-func (self *StateDB) StartRecord(thash, bhash common.Hash, ti int) {
- self.thash = thash
- self.bhash = bhash
- self.txIndex = ti
-}
-
func (self *StateDB) AddLog(log *types.Log) {
self.journal = append(self.journal, addLogChange{txhash: self.thash})
@@ -510,21 +508,25 @@ func (self *StateDB) Copy() *StateDB {
// Copy all the basic fields, initialize the memory ones
state := &StateDB{
- db: self.db,
- trie: self.trie,
- pastTries: self.pastTries,
- codeSizeCache: self.codeSizeCache,
- stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
- stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)),
- refund: new(big.Int).Set(self.refund),
- logs: make(map[common.Hash][]*types.Log, len(self.logs)),
- logSize: self.logSize,
- preimages: make(map[common.Hash][]byte),
+ db: self.db,
+ trie: self.trie,
+ pastTries: self.pastTries,
+ codeSizeCache: self.codeSizeCache,
+ stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
+ stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)),
+ stateObjectsDestructed: make(map[common.Address]struct{}, len(self.stateObjectsDestructed)),
+ refund: new(big.Int).Set(self.refund),
+ logs: make(map[common.Hash][]*types.Log, len(self.logs)),
+ logSize: self.logSize,
+ preimages: make(map[common.Hash][]byte),
}
// Copy the dirty states, logs, and preimages
for addr := range self.stateObjectsDirty {
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty)
state.stateObjectsDirty[addr] = struct{}{}
+ if self.stateObjects[addr].suicided {
+ state.stateObjectsDestructed[addr] = struct{}{}
+ }
}
for hash, logs := range self.logs {
state.logs[hash] = make([]*types.Log, len(logs))
@@ -590,6 +592,27 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
return s.trie.Hash()
}
+// Prepare sets the current transaction hash and index and block hash which is
+// used when the EVM emits new state logs.
+func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
+ self.thash = thash
+ self.bhash = bhash
+ self.txIndex = ti
+}
+
+// Finalise finalises the state by removing the self destructed objects
+// in the current stateObjectsDestructed buffer and clears the journal
+// as well as the refunds.
+//
+// Please note that Finalise is used by EIP#98 and is used instead of
+// IntermediateRoot.
+func (s *StateDB) Finalise() {
+ for addr := range s.stateObjectsDestructed {
+ s.deleteStateObject(s.stateObjects[addr])
+ }
+ s.clearJournalAndRefund()
+}
+
// DeleteSuicides flags the suicided objects for deletion so that it
// won't be referenced again when called / queried up on.
//