Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/evm, core/state: fix post-exec dump of state (statetests, blockchaintests) #28504

Merged
merged 11 commits into from
Nov 28, 2023
Next Next commit
cmd/evm, core/state: add callback to blockrunner, fix dump with missi…
…ng preimages

This changes makes it so that the block test executor takes a callback, just like
the state test executor already does. This callback can be used to examine the
post-execution state, e.g. to aid debugging of test failures.

This change also modifies the mechanics of Dump: previously, all accounts for which
we did not have the preimage (address) were silently discarded.

Now they are output instead like this:
```
{
    "root": "3ef447699d08e3160c448903e77bd092c67ce3faeba773a3f83c500ab80f2400",
    "accounts": {
        "pre(0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b)": {
            "balance": "10780210",
            "nonce": 1,
```
  • Loading branch information
holiman committed Nov 15, 2023
commit 7df4ebd5eceae62004b86c8ea68734a5cceff7bf
9 changes: 8 additions & 1 deletion cmd/evm/blockrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"regexp"
"sort"

"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
Expand Down Expand Up @@ -85,7 +86,13 @@ func blockTestCmd(ctx *cli.Context) error {
continue
}
test := tests[name]
if err := test.Run(false, rawdb.HashScheme, tracer); err != nil {
if err := test.Run(false, rawdb.HashScheme, tracer, func(res error, chain *core.BlockChain) {
if ctx.Bool(DumpFlag.Name) {
if state, _ := chain.State(); state != nil {
fmt.Println(string(state.Dump(nil)))
}
}
}); err != nil {
return fmt.Errorf("test %v: %w", name, err)
}
}
Expand Down
11 changes: 7 additions & 4 deletions core/state/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ type DumpAccount struct {

// Dump represents the full dump in a collected format, as one large map.
type Dump struct {
Root string `json:"root"`
Accounts map[common.Address]DumpAccount `json:"accounts"`
Root string `json:"root"`
Accounts map[string]DumpAccount `json:"accounts"`
}

// OnRoot implements DumpCollector interface
Expand All @@ -73,8 +73,11 @@ func (d *Dump) OnRoot(root common.Hash) {

// OnAccount implements DumpCollector interface
func (d *Dump) OnAccount(addr *common.Address, account DumpAccount) {
if addr == nil {
d.Accounts[fmt.Sprintf("pre(%s)", account.SecureKey)] = account
holiman marked this conversation as resolved.
Show resolved Hide resolved
}
if addr != nil {
d.Accounts[*addr] = account
d.Accounts[(*addr).String()] = account
}
}

Expand Down Expand Up @@ -223,7 +226,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
// RawDump returns the entire state an a single large object
func (s *StateDB) RawDump(opts *DumpConfig) Dump {
dump := &Dump{
Accounts: make(map[common.Address]DumpAccount),
Accounts: make(map[string]DumpAccount),
}
s.DumpToCollector(dump, opts)
return *dump
Expand Down
8 changes: 4 additions & 4 deletions tests/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@ func TestExecutionSpec(t *testing.T) {
}

func execBlockTest(t *testing.T, bt *testMatcher, test *BlockTest) {
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil, nil)); err != nil {
t.Errorf("test in hash mode without snapshotter failed: %v", err)
return
}
if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil)); err != nil {
if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil, nil)); err != nil {
t.Errorf("test in hash mode with snapshotter failed: %v", err)
return
}
if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil)); err != nil {
if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil, nil)); err != nil {
t.Errorf("test in path mode without snapshotter failed: %v", err)
return
}
if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil)); err != nil {
if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil, nil)); err != nil {
t.Errorf("test in path mode with snapshotter failed: %v", err)
return
}
Expand Down
7 changes: 6 additions & 1 deletion tests/block_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type btHeaderMarshaling struct {
ExcessBlobGas *math.HexOrDecimal64
}

func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger) error {
func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger, postCheck func(error, *core.BlockChain)) (result error) {
config, ok := Forks[t.json.Network]
if !ok {
return UnsupportedForkError{t.json.Network}
Expand Down Expand Up @@ -158,6 +158,11 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger) er
if err != nil {
return err
}
// Import succeeded: regardless of whether the _test_ succeeds or not, schedule
// the post-check to run
defer func() {
postCheck(result, chain)
}()
cmlast := chain.CurrentBlock().Hash()
if common.Hash(t.json.BestBlock) != cmlast {
return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast)
Expand Down