Skip to content

Commit 903bf51

Browse files
committed
core/state: better randomized testing (postcheck) on journalling
1 parent 4f4f9d8 commit 903bf51

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

core/state/access_list.go

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

1919
import (
20+
"fmt"
2021
"maps"
22+
"slices"
23+
"strings"
2124

2225
"github.com/ethereum/go-ethereum/common"
2326
)
@@ -130,3 +133,34 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
130133
func (al *accessList) DeleteAddress(address common.Address) {
131134
delete(al.addresses, address)
132135
}
136+
137+
// Equal returns true if the two access lists are identical
138+
func (al *accessList) Equal(other *accessList) bool {
139+
if !maps.Equal(al.addresses, other.addresses) {
140+
return false
141+
}
142+
return slices.EqualFunc(al.slots, other.slots,
143+
func(m map[common.Hash]struct{}, m2 map[common.Hash]struct{}) bool {
144+
return maps.Equal(m, m2)
145+
})
146+
}
147+
148+
func (al *accessList) PrettyPrint() string {
149+
out := new(strings.Builder)
150+
var sortedAddrs []common.Address
151+
for addr, _ := range al.addresses {
152+
sortedAddrs = append(sortedAddrs, addr)
153+
}
154+
slices.SortFunc(sortedAddrs, common.Address.Cmp)
155+
for _, addr := range sortedAddrs {
156+
idx := al.addresses[addr]
157+
fmt.Fprintf(out, "%#x : (idx %d)\n", addr, idx)
158+
if idx >= 0 {
159+
slotmap := al.slots[idx]
160+
for h, _ := range slotmap {
161+
fmt.Fprintf(out, " %#x\n", h)
162+
}
163+
}
164+
}
165+
return out.String()
166+
}

core/state/statedb_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/binary"
2222
"errors"
2323
"fmt"
24+
"maps"
2425
"math"
2526
"math/rand"
2627
"reflect"
@@ -609,11 +610,29 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
609610
return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
610611
})
611612
}
613+
// Check transient storage.
614+
{
615+
have := state.transientStorage
616+
want := checkstate.transientStorage
617+
eq := maps.EqualFunc(have, want,
618+
func(a Storage, b Storage) bool {
619+
return maps.Equal(a, b)
620+
})
621+
if !eq {
622+
return fmt.Errorf("transient storage differs ,have\n%v\nwant\n%v",
623+
have.PrettyPrint(),
624+
want.PrettyPrint())
625+
}
626+
}
612627
if err != nil {
613628
return err
614629
}
615630
}
616-
631+
if !checkstate.accessList.Equal(state.accessList) { // Check access lists
632+
return fmt.Errorf("AccessLists are wrong, have \n%v\nwant\n%v",
633+
checkstate.accessList.PrettyPrint(),
634+
state.accessList.PrettyPrint())
635+
}
617636
if state.GetRefund() != checkstate.GetRefund() {
618637
return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
619638
state.GetRefund(), checkstate.GetRefund())

core/state/transient_storage.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
package state
1818

1919
import (
20+
"fmt"
21+
"slices"
22+
"strings"
23+
2024
"github.com/ethereum/go-ethereum/common"
2125
)
2226

@@ -30,10 +34,19 @@ func newTransientStorage() transientStorage {
3034

3135
// Set sets the transient-storage `value` for `key` at the given `addr`.
3236
func (t transientStorage) Set(addr common.Address, key, value common.Hash) {
33-
if _, ok := t[addr]; !ok {
34-
t[addr] = make(Storage)
37+
if value == (common.Hash{}) { // this is a 'delete'
38+
if _, ok := t[addr]; ok {
39+
delete(t[addr], key)
40+
if len(t[addr]) == 0 {
41+
delete(t, addr)
42+
}
43+
}
44+
} else {
45+
if _, ok := t[addr]; !ok {
46+
t[addr] = make(Storage)
47+
}
48+
t[addr][key] = value
3549
}
36-
t[addr][key] = value
3750
}
3851

3952
// Get gets the transient storage for `key` at the given `addr`.
@@ -53,3 +66,26 @@ func (t transientStorage) Copy() transientStorage {
5366
}
5467
return storage
5568
}
69+
70+
func (t transientStorage) PrettyPrint() string {
71+
out := new(strings.Builder)
72+
var sortedAddrs []common.Address
73+
for addr := range t {
74+
sortedAddrs = append(sortedAddrs, addr)
75+
slices.SortFunc(sortedAddrs, common.Address.Cmp)
76+
}
77+
78+
for _, addr := range sortedAddrs {
79+
fmt.Fprintf(out, "%#x:", addr)
80+
var sortedKeys []common.Hash
81+
storage := t[addr]
82+
for key := range storage {
83+
sortedKeys = append(sortedKeys, key)
84+
}
85+
slices.SortFunc(sortedKeys, common.Hash.Cmp)
86+
for _, key := range sortedKeys {
87+
fmt.Fprintf(out, " %X : %X\n", key, storage[key])
88+
}
89+
}
90+
return out.String()
91+
}

0 commit comments

Comments
 (0)