mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
core/state: better randomized testing (postcheck) on journalling
This commit is contained in:
parent
4f4f9d88d3
commit
903bf512a9
3 changed files with 93 additions and 4 deletions
|
|
@ -17,7 +17,10 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
|
@ -130,3 +133,34 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
|
|||
func (al *accessList) DeleteAddress(address common.Address) {
|
||||
delete(al.addresses, address)
|
||||
}
|
||||
|
||||
// Equal returns true if the two access lists are identical
|
||||
func (al *accessList) Equal(other *accessList) bool {
|
||||
if !maps.Equal(al.addresses, other.addresses) {
|
||||
return false
|
||||
}
|
||||
return slices.EqualFunc(al.slots, other.slots,
|
||||
func(m map[common.Hash]struct{}, m2 map[common.Hash]struct{}) bool {
|
||||
return maps.Equal(m, m2)
|
||||
})
|
||||
}
|
||||
|
||||
func (al *accessList) PrettyPrint() string {
|
||||
out := new(strings.Builder)
|
||||
var sortedAddrs []common.Address
|
||||
for addr, _ := range al.addresses {
|
||||
sortedAddrs = append(sortedAddrs, addr)
|
||||
}
|
||||
slices.SortFunc(sortedAddrs, common.Address.Cmp)
|
||||
for _, addr := range sortedAddrs {
|
||||
idx := al.addresses[addr]
|
||||
fmt.Fprintf(out, "%#x : (idx %d)\n", addr, idx)
|
||||
if idx >= 0 {
|
||||
slotmap := al.slots[idx]
|
||||
for h, _ := range slotmap {
|
||||
fmt.Fprintf(out, " %#x\n", h)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"math"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
|
|
@ -609,11 +610,29 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
|
|||
return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value)
|
||||
})
|
||||
}
|
||||
// Check transient storage.
|
||||
{
|
||||
have := state.transientStorage
|
||||
want := checkstate.transientStorage
|
||||
eq := maps.EqualFunc(have, want,
|
||||
func(a Storage, b Storage) bool {
|
||||
return maps.Equal(a, b)
|
||||
})
|
||||
if !eq {
|
||||
return fmt.Errorf("transient storage differs ,have\n%v\nwant\n%v",
|
||||
have.PrettyPrint(),
|
||||
want.PrettyPrint())
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !checkstate.accessList.Equal(state.accessList) { // Check access lists
|
||||
return fmt.Errorf("AccessLists are wrong, have \n%v\nwant\n%v",
|
||||
checkstate.accessList.PrettyPrint(),
|
||||
state.accessList.PrettyPrint())
|
||||
}
|
||||
if state.GetRefund() != checkstate.GetRefund() {
|
||||
return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
|
||||
state.GetRefund(), checkstate.GetRefund())
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
|
|
@ -30,11 +34,20 @@ func newTransientStorage() transientStorage {
|
|||
|
||||
// Set sets the transient-storage `value` for `key` at the given `addr`.
|
||||
func (t transientStorage) Set(addr common.Address, key, value common.Hash) {
|
||||
if value == (common.Hash{}) { // this is a 'delete'
|
||||
if _, ok := t[addr]; ok {
|
||||
delete(t[addr], key)
|
||||
if len(t[addr]) == 0 {
|
||||
delete(t, addr)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if _, ok := t[addr]; !ok {
|
||||
t[addr] = make(Storage)
|
||||
}
|
||||
t[addr][key] = value
|
||||
}
|
||||
}
|
||||
|
||||
// Get gets the transient storage for `key` at the given `addr`.
|
||||
func (t transientStorage) Get(addr common.Address, key common.Hash) common.Hash {
|
||||
|
|
@ -53,3 +66,26 @@ func (t transientStorage) Copy() transientStorage {
|
|||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
func (t transientStorage) PrettyPrint() string {
|
||||
out := new(strings.Builder)
|
||||
var sortedAddrs []common.Address
|
||||
for addr := range t {
|
||||
sortedAddrs = append(sortedAddrs, addr)
|
||||
slices.SortFunc(sortedAddrs, common.Address.Cmp)
|
||||
}
|
||||
|
||||
for _, addr := range sortedAddrs {
|
||||
fmt.Fprintf(out, "%#x:", addr)
|
||||
var sortedKeys []common.Hash
|
||||
storage := t[addr]
|
||||
for key := range storage {
|
||||
sortedKeys = append(sortedKeys, key)
|
||||
}
|
||||
slices.SortFunc(sortedKeys, common.Hash.Cmp)
|
||||
for _, key := range sortedKeys {
|
||||
fmt.Fprintf(out, " %X : %X\n", key, storage[key])
|
||||
}
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue