Skip to content

Commit aa37bd0

Browse files
authored
cmd, tests: fix snapshot dump and export-preimages (#32650)
Address #32646
1 parent ada2db4 commit aa37bd0

File tree

4 files changed

+67
-23
lines changed

4 files changed

+67
-23
lines changed

cmd/geth/snapshot.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -561,17 +561,11 @@ func dumpState(ctx *cli.Context) error {
561561
triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false)
562562
defer triedb.Close()
563563

564-
snapConfig := snapshot.Config{
565-
CacheSize: 256,
566-
Recovery: false,
567-
NoBuild: true,
568-
AsyncBuild: false,
569-
}
570-
snaptree, err := snapshot.New(snapConfig, db, triedb, root)
564+
stateIt, err := utils.NewStateIterator(triedb, db, root)
571565
if err != nil {
572566
return err
573567
}
574-
accIt, err := snaptree.AccountIterator(root, common.BytesToHash(conf.Start))
568+
accIt, err := stateIt.AccountIterator(root, common.BytesToHash(conf.Start))
575569
if err != nil {
576570
return err
577571
}
@@ -605,7 +599,7 @@ func dumpState(ctx *cli.Context) error {
605599
if !conf.SkipStorage {
606600
da.Storage = make(map[common.Hash]string)
607601

608-
stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
602+
stIt, err := stateIt.StorageIterator(root, accIt.Hash(), common.Hash{})
609603
if err != nil {
610604
return err
611605
}
@@ -658,17 +652,11 @@ func snapshotExportPreimages(ctx *cli.Context) error {
658652
}
659653
root = headBlock.Root()
660654
}
661-
snapConfig := snapshot.Config{
662-
CacheSize: 256,
663-
Recovery: false,
664-
NoBuild: true,
665-
AsyncBuild: false,
666-
}
667-
snaptree, err := snapshot.New(snapConfig, chaindb, triedb, root)
655+
stateIt, err := utils.NewStateIterator(triedb, chaindb, root)
668656
if err != nil {
669657
return err
670658
}
671-
return utils.ExportSnapshotPreimages(chaindb, snaptree, ctx.Args().First(), root)
659+
return utils.ExportSnapshotPreimages(chaindb, stateIt, ctx.Args().First(), root)
672660
}
673661

674662
// checkAccount iterates the snap data layers, and looks up the given account

cmd/utils/cmd.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import (
4848
"github.com/ethereum/go-ethereum/node"
4949
"github.com/ethereum/go-ethereum/params"
5050
"github.com/ethereum/go-ethereum/rlp"
51+
"github.com/ethereum/go-ethereum/triedb"
5152
"github.com/urfave/cli/v2"
5253
)
5354

@@ -567,9 +568,64 @@ func ExportPreimages(db ethdb.Database, fn string) error {
567568
return nil
568569
}
569570

571+
// StateIterator is a temporary structure for traversing state in order. It serves
572+
// as an aggregator for both path scheme and hash scheme implementations and should
573+
// be removed once the hash scheme is fully deprecated.
574+
type StateIterator struct {
575+
scheme string
576+
root common.Hash
577+
triedb *triedb.Database
578+
snapshots *snapshot.Tree
579+
}
580+
581+
// NewStateIterator constructs the state iterator with the specific root.
582+
func NewStateIterator(triedb *triedb.Database, db ethdb.Database, root common.Hash) (*StateIterator, error) {
583+
if triedb.Scheme() == rawdb.PathScheme {
584+
return &StateIterator{
585+
scheme: rawdb.PathScheme,
586+
root: root,
587+
triedb: triedb,
588+
}, nil
589+
}
590+
config := snapshot.Config{
591+
CacheSize: 256,
592+
Recovery: false,
593+
NoBuild: true,
594+
AsyncBuild: false,
595+
}
596+
snapshots, err := snapshot.New(config, db, triedb, root)
597+
if err != nil {
598+
return nil, err
599+
}
600+
return &StateIterator{
601+
scheme: rawdb.HashScheme,
602+
root: root,
603+
triedb: triedb,
604+
snapshots: snapshots,
605+
}, nil
606+
}
607+
608+
// AccountIterator creates a new account iterator for the specified root hash and
609+
// seeks to a starting account hash.
610+
func (it *StateIterator) AccountIterator(root common.Hash, start common.Hash) (snapshot.AccountIterator, error) {
611+
if it.scheme == rawdb.PathScheme {
612+
return it.triedb.AccountIterator(root, start)
613+
}
614+
return it.snapshots.AccountIterator(root, start)
615+
}
616+
617+
// StorageIterator creates a new storage iterator for the specified root hash and
618+
// account. The iterator will be moved to the specific start position.
619+
func (it *StateIterator) StorageIterator(root common.Hash, accountHash common.Hash, start common.Hash) (snapshot.StorageIterator, error) {
620+
if it.scheme == rawdb.PathScheme {
621+
return it.triedb.StorageIterator(root, accountHash, start)
622+
}
623+
return it.snapshots.StorageIterator(root, accountHash, start)
624+
}
625+
570626
// ExportSnapshotPreimages exports the preimages corresponding to the enumeration of
571627
// the snapshot for a given root.
572-
func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn string, root common.Hash) error {
628+
func ExportSnapshotPreimages(chaindb ethdb.Database, stateIt *StateIterator, fn string, root common.Hash) error {
573629
log.Info("Exporting preimages", "file", fn)
574630

575631
fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
@@ -602,7 +658,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn
602658
)
603659
go func() {
604660
defer close(hashCh)
605-
accIt, err := snaptree.AccountIterator(root, common.Hash{})
661+
accIt, err := stateIt.AccountIterator(root, common.Hash{})
606662
if err != nil {
607663
log.Error("Failed to create account iterator", "error", err)
608664
return
@@ -619,7 +675,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn
619675
hashCh <- hashAndPreimageSize{Hash: accIt.Hash(), Size: common.AddressLength}
620676

621677
if acc.Root != (common.Hash{}) && acc.Root != types.EmptyRootHash {
622-
stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
678+
stIt, err := stateIt.StorageIterator(root, accIt.Hash(), common.Hash{})
623679
if err != nil {
624680
log.Error("Failed to create storage iterator", "error", err)
625681
return

tests/state_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) {
156156
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
157157
var result error
158158
test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, state *StateTestState) {
159-
if state.Snapshots != nil && state.StateDB != nil {
160-
if _, err := state.Snapshots.Journal(state.StateDB.IntermediateRoot(false)); err != nil {
159+
if state.TrieDB != nil && state.StateDB != nil {
160+
if err := state.TrieDB.Journal(state.StateDB.IntermediateRoot(false)); err != nil {
161161
result = err
162162
return
163163
}

tests/state_test_util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
523523

524524
// If snapshot is requested, initialize the snapshotter and use it in state.
525525
var snaps *snapshot.Tree
526-
if snapshotter {
526+
if snapshotter && scheme == rawdb.HashScheme {
527527
snapconfig := snapshot.Config{
528528
CacheSize: 1,
529529
Recovery: false,

0 commit comments

Comments
 (0)