mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd/evm, core/state: add callback to blockrunner, fix dump with missing 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,
```
This commit is contained in:
parent
984f82629c
commit
7df4ebd5ec
4 changed files with 25 additions and 10 deletions
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
|
|
@ -85,7 +86,13 @@ func blockTestCmd(ctx *cli.Context) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
test := tests[name]
|
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)
|
return fmt.Errorf("test %v: %w", name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ type DumpAccount struct {
|
||||||
|
|
||||||
// Dump represents the full dump in a collected format, as one large map.
|
// Dump represents the full dump in a collected format, as one large map.
|
||||||
type Dump struct {
|
type Dump struct {
|
||||||
Root string `json:"root"`
|
Root string `json:"root"`
|
||||||
Accounts map[common.Address]DumpAccount `json:"accounts"`
|
Accounts map[string]DumpAccount `json:"accounts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnRoot implements DumpCollector interface
|
// OnRoot implements DumpCollector interface
|
||||||
|
|
@ -73,8 +73,11 @@ func (d *Dump) OnRoot(root common.Hash) {
|
||||||
|
|
||||||
// OnAccount implements DumpCollector interface
|
// OnAccount implements DumpCollector interface
|
||||||
func (d *Dump) OnAccount(addr *common.Address, account DumpAccount) {
|
func (d *Dump) OnAccount(addr *common.Address, account DumpAccount) {
|
||||||
|
if addr == nil {
|
||||||
|
d.Accounts[fmt.Sprintf("pre(%s)", account.SecureKey)] = account
|
||||||
|
}
|
||||||
if addr != nil {
|
if addr != nil {
|
||||||
d.Accounts[*addr] = account
|
d.Accounts[(*addr).String()] = account
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +226,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
|
||||||
// RawDump returns the entire state an a single large object
|
// RawDump returns the entire state an a single large object
|
||||||
func (s *StateDB) RawDump(opts *DumpConfig) Dump {
|
func (s *StateDB) RawDump(opts *DumpConfig) Dump {
|
||||||
dump := &Dump{
|
dump := &Dump{
|
||||||
Accounts: make(map[common.Address]DumpAccount),
|
Accounts: make(map[string]DumpAccount),
|
||||||
}
|
}
|
||||||
s.DumpToCollector(dump, opts)
|
s.DumpToCollector(dump, opts)
|
||||||
return *dump
|
return *dump
|
||||||
|
|
|
||||||
|
|
@ -74,19 +74,19 @@ func TestExecutionSpec(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func execBlockTest(t *testing.T, bt *testMatcher, test *BlockTest) {
|
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)
|
t.Errorf("test in hash mode without snapshotter failed: %v", err)
|
||||||
return
|
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)
|
t.Errorf("test in hash mode with snapshotter failed: %v", err)
|
||||||
return
|
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)
|
t.Errorf("test in path mode without snapshotter failed: %v", err)
|
||||||
return
|
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)
|
t.Errorf("test in path mode with snapshotter failed: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ type btHeaderMarshaling struct {
|
||||||
ExcessBlobGas *math.HexOrDecimal64
|
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]
|
config, ok := Forks[t.json.Network]
|
||||||
if !ok {
|
if !ok {
|
||||||
return UnsupportedForkError{t.json.Network}
|
return UnsupportedForkError{t.json.Network}
|
||||||
|
|
@ -158,6 +158,11 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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()
|
cmlast := chain.CurrentBlock().Hash()
|
||||||
if common.Hash(t.json.BestBlock) != cmlast {
|
if common.Hash(t.json.BestBlock) != cmlast {
|
||||||
return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast)
|
return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue