forked from cerc-io/plugeth
cmd: implement preimage dump and import cmds
This commit is contained in:
parent
933972d139
commit
b6b6f52ec8
@ -40,6 +40,11 @@ import (
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
// secureKeyPrefix is the database key prefix used to store trie node preimages.
|
||||
secureKeyPrefix = []byte("secure-key-")
|
||||
)
|
||||
|
||||
var (
|
||||
initCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(initGenesis),
|
||||
@ -141,6 +146,34 @@ Remove blockchain and state databases`,
|
||||
The arguments are interpreted as block numbers or hashes.
|
||||
Use "ethereum dump 0" to dump the genesis block.`,
|
||||
}
|
||||
preimageDumpCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(dumpPreimage),
|
||||
Name: "preimagedump",
|
||||
Usage: "Dump the preimage database in json format",
|
||||
ArgsUsage: "<dumpfile>",
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.CacheFlag,
|
||||
utils.LightModeFlag,
|
||||
},
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
Description: `
|
||||
Dump the preimage database in json format`,
|
||||
}
|
||||
preimageImportCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(importPreimage),
|
||||
Name: "preimageimport",
|
||||
Usage: "Import the preimage data from the specified file",
|
||||
ArgsUsage: "<datafile>",
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.CacheFlag,
|
||||
utils.LightModeFlag,
|
||||
},
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
Description: `
|
||||
Import the preimage data from the specified file`,
|
||||
}
|
||||
)
|
||||
|
||||
// initGenesis will initialise the given JSON format genesis file and writes it as
|
||||
@ -406,6 +439,86 @@ func dump(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreimageEntry represents a map between preimage and hash.
|
||||
type PreimageEntry struct {
|
||||
Hash string `json:"hash"`
|
||||
Preimage string `json:"preimage"`
|
||||
}
|
||||
|
||||
// dumpPreimage dumps the preimage data to specified json file in streaming way.
|
||||
func dumpPreimage(ctx *cli.Context) error {
|
||||
// Make sure the export json file has been specified.
|
||||
if len(ctx.Args()) < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
|
||||
// Encode preimage data to json file in streaming way.
|
||||
file, err := os.Create(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encoder := json.NewEncoder(file)
|
||||
|
||||
stack := makeFullNode(ctx)
|
||||
db := utils.MakeChainDatabase(ctx, stack)
|
||||
|
||||
// Dump all preimage entries.
|
||||
it := db.(*ethdb.LDBDatabase).NewIteratorByPrefix(secureKeyPrefix)
|
||||
for it.Next() {
|
||||
hash := it.Key()[len(secureKeyPrefix):]
|
||||
if err := encoder.Encode(PreimageEntry{common.Bytes2Hex(hash), common.Bytes2Hex(it.Value())}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// importPreimages imports preimage data from the specified file.
|
||||
func importPreimage(ctx *cli.Context) error {
|
||||
// Make sure the export json file has been specified.
|
||||
if len(ctx.Args()) < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
|
||||
// Decode the preimage data in streaming way.
|
||||
file, err := os.Open(ctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
decoder := json.NewDecoder(file)
|
||||
|
||||
stack := makeFullNode(ctx)
|
||||
db := utils.MakeChainDatabase(ctx, stack)
|
||||
|
||||
var (
|
||||
entry PreimageEntry
|
||||
preimages = make(map[common.Hash][]byte)
|
||||
)
|
||||
|
||||
for decoder.More() {
|
||||
if err := decoder.Decode(&entry); err != nil {
|
||||
return err
|
||||
}
|
||||
preimages[common.HexToHash(entry.Hash)] = common.Hex2Bytes(entry.Preimage)
|
||||
// Flush to database in batch
|
||||
if len(preimages) > 1024 {
|
||||
err := core.WritePreimages(db, 0, preimages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
preimages = make(map[common.Hash][]byte)
|
||||
}
|
||||
}
|
||||
// Flush the last batch preimage data
|
||||
if len(preimages) > 0 {
|
||||
err := core.WritePreimages(db, 0, preimages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// hashish returns true for strings that look like hashes.
|
||||
func hashish(x string) bool {
|
||||
_, err := strconv.Atoi(x)
|
||||
|
@ -158,6 +158,8 @@ func init() {
|
||||
copydbCommand,
|
||||
removedbCommand,
|
||||
dumpCommand,
|
||||
preimageDumpCommand,
|
||||
preimageImportCommand,
|
||||
// See monitorcmd.go:
|
||||
monitorCommand,
|
||||
// See accountcmd.go:
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||
"github.com/syndtr/goleveldb/leveldb/iterator"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
var OpenFileLimit = 64
|
||||
@ -121,6 +122,11 @@ func (db *LDBDatabase) NewIterator() iterator.Iterator {
|
||||
return db.db.NewIterator(nil, nil)
|
||||
}
|
||||
|
||||
// NewIteratorByPrefix returns a iterator to iterate over subset of database content with a particular prefix.
|
||||
func (db *LDBDatabase) NewIteratorByPrefix(prefix []byte) iterator.Iterator {
|
||||
return db.db.NewIterator(util.BytesPrefix(prefix), nil)
|
||||
}
|
||||
|
||||
func (db *LDBDatabase) Close() {
|
||||
// Stop the metrics collection to avoid internal database races
|
||||
db.quitLock.Lock()
|
||||
|
Loading…
Reference in New Issue
Block a user