diff options
author | Martin Holst Swende <martin@swende.se> | 2018-08-12 05:03:54 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-09-18 18:08:28 +0800 |
commit | 58374e28d95c03d8b0e6d9035c0fb92fad3e865e (patch) | |
tree | 25fd00dc4619e39cabdeb39e8b4417c31ad1136a /core/state | |
parent | b8aa5980cf28313f36af9090c1491eb3fd0e1507 (diff) | |
download | go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar.gz go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar.bz2 go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar.lz go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar.xz go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.tar.zst go-tangerine-58374e28d95c03d8b0e6d9035c0fb92fad3e865e.zip |
core, state: initial implementation of Eip-1283
Diffstat (limited to 'core/state')
-rw-r--r-- | core/state/state_object.go | 15 | ||||
-rw-r--r-- | core/state/statedb.go | 11 |
2 files changed, 24 insertions, 2 deletions
diff --git a/core/state/state_object.go b/core/state/state_object.go index 091d24184..0b72d0114 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -79,7 +79,7 @@ type stateObject struct { cachedStorage Storage // Storage entry cache to avoid duplicate reads dirtyStorage Storage // Storage entries that need to be flushed to disk - + originalValue Storage // Map of original storage values, at the beginning of current call context // Cache flags. // When an object is marked suicided it will be delete from the trie // during the "update" phase of the state transition. @@ -117,6 +117,7 @@ func newObject(db *StateDB, address common.Address, data Account) *stateObject { data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), + originalValue: make(Storage), } } @@ -184,11 +185,16 @@ func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { // SetState updates a value in account storage. func (self *stateObject) SetState(db Database, key, value common.Hash) { + prev := self.GetState(db, key) self.db.journal.append(storageChange{ account: &self.address, key: key, - prevalue: self.GetState(db, key), + prevalue: prev, }) + if _, isSet := self.originalValue[key]; !isSet { + // original value has not been set, so set it now + self.originalValue[key] = prev + } self.setState(key, value) } @@ -210,6 +216,10 @@ func (self *stateObject) updateTrie(db Database) Trie { v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) self.setError(tr.TryUpdate(key[:], v)) } + // Clean the map containing 'original' value of storage entries + for k, _ := range self.originalValue { + delete(self.originalValue, k) + } return tr } @@ -280,6 +290,7 @@ func (self *stateObject) deepCopy(db *StateDB) *stateObject { stateObject.code = self.code stateObject.dirtyStorage = self.dirtyStorage.Copy() stateObject.cachedStorage = self.dirtyStorage.Copy() + stateObject.originalValue = self.originalValue.Copy() stateObject.suicided = self.suicided stateObject.dirtyCode = self.dirtyCode stateObject.deleted = self.deleted diff --git a/core/state/statedb.go b/core/state/statedb.go index 101b03a12..d9300012d 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -169,11 +169,22 @@ func (self *StateDB) Preimages() map[common.Hash][]byte { return self.preimages } +// AddRefund adds gas to the refund counter func (self *StateDB) AddRefund(gas uint64) { self.journal.append(refundChange{prev: self.refund}) self.refund += gas } +// SubRefund removes gas from the refund counter. +// This method will panic if the refund counter goes below zero +func (self *StateDB) SubRefund(gas uint64) { + self.journal.append(refundChange{prev: self.refund}) + if gas > self.refund { + panic("Refund counter below zero") + } + self.refund -= gas +} + // Exist reports whether the given account address exists in the state. // Notably this also returns true for suicided accounts. func (self *StateDB) Exist(addr common.Address) bool { |