aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2018-04-11 17:00:17 +0800
committerGitHub <noreply@github.com>2018-04-11 17:00:17 +0800
commit5a79aca8b918a177d192299984d8f287dd6c1eb4 (patch)
tree14b188f6493703ef75110efa023e1e4a6f7b8d97
parente7cc5b41605f9145b2cb5755476456f30974a2c8 (diff)
parent0c7b99b8cc754a0045518ac12b8d1719c23b4181 (diff)
downloaddexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar.gz
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar.bz2
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar.lz
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar.xz
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.tar.zst
dexon-5a79aca8b918a177d192299984d8f287dd6c1eb4.zip
Merge pull request #16485 from holiman/fixcopycopy
core/state: fix bug in copy of copy State
-rw-r--r--core/state/statedb.go10
-rw-r--r--core/state/statedb_test.go16
2 files changed, 26 insertions, 0 deletions
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 08f18c2d2..97c6e4a01 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -474,6 +474,16 @@ func (self *StateDB) Copy() *StateDB {
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
state.stateObjectsDirty[addr] = struct{}{}
}
+ // Above, we don't copy the actual journal. This means that if the copy is copied, the
+ // loop above will be a no-op, since the copy's journal is empty.
+ // Thus, here we iterate over stateObjects, to enable copies of copies
+ for addr := range self.stateObjectsDirty {
+ if _, exist := state.stateObjects[addr]; !exist {
+ state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
+ state.stateObjectsDirty[addr] = struct{}{}
+ }
+ }
+
for hash, logs := range self.logs {
state.logs[hash] = make([]*types.Log, len(logs))
copy(state.logs[hash], logs)
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index 340c840f1..420ca745c 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -422,3 +422,19 @@ func (s *StateSuite) TestTouchDelete(c *check.C) {
c.Fatal("expected no dirty state object")
}
}
+
+// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
+// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
+func TestCopyOfCopy(t *testing.T) {
+ db, _ := ethdb.NewMemDatabase()
+ sdb, _ := New(common.Hash{}, NewDatabase(db))
+ addr := common.HexToAddress("aaaa")
+ sdb.SetBalance(addr, big.NewInt(42))
+
+ if got := sdb.Copy().GetBalance(addr).Uint64(); got != 42 {
+ t.Fatalf("1st copy fail, expected 42, got %v", got)
+ }
+ if got := sdb.Copy().Copy().GetBalance(addr).Uint64(); got != 42 {
+ t.Fatalf("2nd copy fail, expected 42, got %v", got)
+ }
+}