Skip to content

Commit cde06b4

Browse files
fjlGustav Simonsson
authored and
Gustav Simonsson
committed
Merge pull request ethereum#1781 from Gustav-Simonsson/state_object_copy
core/state: deleted field in StateObject Copy() and unit test (cherry picked from commit 90f1fe0)
1 parent 5876692 commit cde06b4

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

core/state/state_object.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ func (self *StateObject) Copy() *StateObject {
263263
stateObject.gasPool.Set(self.gasPool)
264264
stateObject.remove = self.remove
265265
stateObject.dirty = self.dirty
266+
stateObject.deleted = self.deleted
266267

267268
return stateObject
268269
}

core/state/state_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package state
1818

1919
import (
20+
"bytes"
2021
"math/big"
2122
"testing"
2223

@@ -117,3 +118,106 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
117118

118119
c.Assert(data1, checker.DeepEquals, res)
119120
}
121+
122+
// use testing instead of checker because checker does not support
123+
// printing/logging in tests (-check.vv does not work)
124+
func TestSnapshot2(t *testing.T) {
125+
db, _ := ethdb.NewMemDatabase()
126+
state := New(common.Hash{}, db)
127+
128+
stateobjaddr0 := toAddr([]byte("so0"))
129+
stateobjaddr1 := toAddr([]byte("so1"))
130+
var storageaddr common.Hash
131+
132+
data0 := common.BytesToHash([]byte{17})
133+
data1 := common.BytesToHash([]byte{18})
134+
135+
state.SetState(stateobjaddr0, storageaddr, data0)
136+
state.SetState(stateobjaddr1, storageaddr, data1)
137+
138+
// db, trie are already non-empty values
139+
so0 := state.GetStateObject(stateobjaddr0)
140+
so0.balance = big.NewInt(42)
141+
so0.nonce = 43
142+
so0.gasPool = big.NewInt(44)
143+
so0.code = []byte{'c', 'a', 'f', 'e'}
144+
so0.codeHash = so0.CodeHash()
145+
so0.remove = true
146+
so0.deleted = false
147+
so0.dirty = false
148+
state.SetStateObject(so0)
149+
150+
// and one with deleted == true
151+
so1 := state.GetStateObject(stateobjaddr1)
152+
so1.balance = big.NewInt(52)
153+
so1.nonce = 53
154+
so1.gasPool = big.NewInt(54)
155+
so1.code = []byte{'c', 'a', 'f', 'e', '2'}
156+
so1.codeHash = so1.CodeHash()
157+
so1.remove = true
158+
so1.deleted = true
159+
so1.dirty = true
160+
state.SetStateObject(so1)
161+
162+
so1 = state.GetStateObject(stateobjaddr1)
163+
if so1 != nil {
164+
t.Fatalf("deleted object not nil when getting")
165+
}
166+
167+
snapshot := state.Copy()
168+
state.Set(snapshot)
169+
170+
so0Restored := state.GetStateObject(stateobjaddr0)
171+
so1Restored := state.GetStateObject(stateobjaddr1)
172+
// non-deleted is equal (restored)
173+
compareStateObjects(so0Restored, so0, t)
174+
// deleted should be nil, both before and after restore of state copy
175+
if so1Restored != nil {
176+
t.Fatalf("deleted object not nil after restoring snapshot")
177+
}
178+
}
179+
180+
func compareStateObjects(so0, so1 *StateObject, t *testing.T) {
181+
if so0.address != so1.address {
182+
t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address)
183+
}
184+
if so0.balance.Cmp(so1.balance) != 0 {
185+
t.Fatalf("Balance mismatch: have %v, want %v", so0.balance, so1.balance)
186+
}
187+
if so0.nonce != so1.nonce {
188+
t.Fatalf("Nonce mismatch: have %v, want %v", so0.nonce, so1.nonce)
189+
}
190+
if !bytes.Equal(so0.codeHash, so1.codeHash) {
191+
t.Fatalf("CodeHash mismatch: have %v, want %v", so0.codeHash, so1.codeHash)
192+
}
193+
if !bytes.Equal(so0.code, so1.code) {
194+
t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code)
195+
}
196+
if !bytes.Equal(so0.initCode, so1.initCode) {
197+
t.Fatalf("InitCode mismatch: have %v, want %v", so0.initCode, so1.initCode)
198+
}
199+
200+
for k, v := range so1.storage {
201+
if so0.storage[k] != v {
202+
t.Fatalf("Storage key %s mismatch: have %v, want %v", k, so0.storage[k], v)
203+
}
204+
}
205+
for k, v := range so0.storage {
206+
if so1.storage[k] != v {
207+
t.Fatalf("Storage key %s mismatch: have %v, want none.", k, v)
208+
}
209+
}
210+
211+
if so0.gasPool.Cmp(so1.gasPool) != 0 {
212+
t.Fatalf("GasPool mismatch: have %v, want %v", so0.gasPool, so1.gasPool)
213+
}
214+
if so0.remove != so1.remove {
215+
t.Fatalf("Remove mismatch: have %v, want %v", so0.remove, so1.remove)
216+
}
217+
if so0.deleted != so1.deleted {
218+
t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted)
219+
}
220+
if so0.dirty != so1.dirty {
221+
t.Fatalf("Dirty mismatch: have %v, want %v", so0.dirty, so1.dirty)
222+
}
223+
}

0 commit comments

Comments
 (0)