Skip to content

Commit 54d7d56

Browse files
committed
test: GetExtra() after StateDB.Copy() and writes to original
1 parent 679a10c commit 54d7d56

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

core/state/state.libevm_test.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package state_test
1818

1919
import (
2020
"fmt"
21+
"reflect"
2122
"testing"
2223

2324
"github.com/google/go-cmp/cmp"
@@ -35,25 +36,34 @@ import (
3536
)
3637

3738
func TestGetSetExtra(t *testing.T) {
39+
type accountExtra struct {
40+
// Data is a pointer to test deep copying.
41+
Data *[]byte // MUST be exported; I spent 20 minutes investigating failing tests because I'm an idiot
42+
}
43+
3844
types.TestOnlyClearRegisteredExtras()
3945
t.Cleanup(types.TestOnlyClearRegisteredExtras)
40-
payloads := types.RegisterExtras[[]byte]()
46+
// Just as its Data field is a pointer, the registered type is a pointer to
47+
// test deep copying.
48+
payloads := types.RegisterExtras[*accountExtra]()
4149

4250
rng := ethtest.NewPseudoRand(42)
4351
addr := rng.Address()
4452
nonce := rng.Uint64()
4553
balance := rng.Uint256()
46-
extra := rng.Bytes(8)
54+
buf := rng.Bytes(8)
55+
extra := &accountExtra{Data: &buf}
4756

4857
views := newWithSnaps(t)
4958
stateDB := views.newStateDB(t, types.EmptyRootHash)
59+
5060
assert.Nilf(t, state.GetExtra(stateDB, payloads, addr), "state.GetExtra() returns zero-value %T if before account creation", extra)
5161
stateDB.CreateAccount(addr)
5262
stateDB.SetNonce(addr, nonce)
5363
stateDB.SetBalance(addr, balance)
5464
assert.Nilf(t, state.GetExtra(stateDB, payloads, addr), "state.GetExtra() returns zero-value %T if after account creation but before SetExtra()", extra)
5565
state.SetExtra(stateDB, payloads, addr, extra)
56-
assert.Equal(t, extra, state.GetExtra(stateDB, payloads, addr), "state.GetExtra() immediately after SetExtra()")
66+
require.Equal(t, extra, state.GetExtra(stateDB, payloads, addr), "state.GetExtra() immediately after SetExtra()")
5767

5868
root, err := stateDB.Commit(1, false) // arbitrary block number
5969
require.NoErrorf(t, err, "%T.Commit(1, false)", stateDB)
@@ -99,15 +109,32 @@ func TestGetSetExtra(t *testing.T) {
99109
snap := s.Snapshot()
100110

101111
oldExtra := extra
102-
newExtra := rng.Bytes(16)
103-
assert.NotEqual(t, oldExtra, newExtra, "new extra payload is different to old one")
112+
buf := append(*oldExtra.Data, rng.Bytes(8)...)
113+
newExtra := &accountExtra{Data: &buf}
104114

105115
state.SetExtra(s, payloads, addr, newExtra)
106116
assert.Equalf(t, newExtra, state.GetExtra(s, payloads, addr), "state.GetExtra() after overwriting with new value")
107-
108117
s.RevertToSnapshot(snap)
109118
assert.Equalf(t, oldExtra, state.GetExtra(s, payloads, addr), "state.GetExtra() after reverting to snapshot")
110119
})
120+
121+
t.Run(fmt.Sprintf("%T.Copy()", stateDB), func(t *testing.T) {
122+
require.Equalf(t, reflect.Pointer, reflect.TypeOf(extra).Kind(), "extra-payload type")
123+
require.Equalf(t, reflect.Pointer, reflect.TypeOf(extra.Data).Kind(), "extra-payload field")
124+
125+
orig := views.newStateDB(t, root)
126+
cp := orig.Copy()
127+
128+
oldExtra := extra
129+
buf := append(*oldExtra.Data, rng.Bytes(8)...)
130+
newExtra := &accountExtra{Data: &buf}
131+
132+
assert.Equalf(t, oldExtra, state.GetExtra(orig, payloads, addr), "GetExtra([original %T]) before setting", orig)
133+
assert.Equalf(t, oldExtra, state.GetExtra(cp, payloads, addr), "GetExtra([copy of %T]) returns the same payload", orig)
134+
state.SetExtra(orig, payloads, addr, newExtra)
135+
assert.Equalf(t, newExtra, state.GetExtra(orig, payloads, addr), "GetExtra([original %T]) returns overwritten payload", orig)
136+
assert.Equalf(t, oldExtra, state.GetExtra(cp, payloads, addr), "GetExtra([copy of %T]) returns original payload despite overwriting on original", orig)
137+
})
111138
}
112139

113140
// stateViews are different ways to access the same data.

0 commit comments

Comments
 (0)