|
|
|
@ -40,11 +40,6 @@ 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), |
|
|
|
@ -100,6 +95,34 @@ Requires a first argument of the file to write to. |
|
|
|
|
Optional second and third arguments control the first and |
|
|
|
|
last block to write. In this mode, the file will be appended |
|
|
|
|
if already existing.`, |
|
|
|
|
} |
|
|
|
|
importPreimagesCommand = cli.Command{ |
|
|
|
|
Action: utils.MigrateFlags(importPreimages), |
|
|
|
|
Name: "import-preimages", |
|
|
|
|
Usage: "Import the preimage database from an RLP stream", |
|
|
|
|
ArgsUsage: "<datafile>", |
|
|
|
|
Flags: []cli.Flag{ |
|
|
|
|
utils.DataDirFlag, |
|
|
|
|
utils.CacheFlag, |
|
|
|
|
utils.LightModeFlag, |
|
|
|
|
}, |
|
|
|
|
Category: "BLOCKCHAIN COMMANDS", |
|
|
|
|
Description: ` |
|
|
|
|
The import-preimages command imports hash preimages from an RLP encoded stream.`, |
|
|
|
|
} |
|
|
|
|
exportPreimagesCommand = cli.Command{ |
|
|
|
|
Action: utils.MigrateFlags(exportPreimages), |
|
|
|
|
Name: "export-preimages", |
|
|
|
|
Usage: "Export the preimage database into an RLP stream", |
|
|
|
|
ArgsUsage: "<dumpfile>", |
|
|
|
|
Flags: []cli.Flag{ |
|
|
|
|
utils.DataDirFlag, |
|
|
|
|
utils.CacheFlag, |
|
|
|
|
utils.LightModeFlag, |
|
|
|
|
}, |
|
|
|
|
Category: "BLOCKCHAIN COMMANDS", |
|
|
|
|
Description: ` |
|
|
|
|
The export-preimages command export hash preimages to an RLP encoded stream`, |
|
|
|
|
} |
|
|
|
|
copydbCommand = cli.Command{ |
|
|
|
|
Action: utils.MigrateFlags(copyDb), |
|
|
|
@ -146,34 +169,6 @@ 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
|
|
|
|
@ -332,7 +327,39 @@ func exportChain(ctx *cli.Context) error { |
|
|
|
|
if err != nil { |
|
|
|
|
utils.Fatalf("Export error: %v\n", err) |
|
|
|
|
} |
|
|
|
|
fmt.Printf("Export done in %v", time.Since(start)) |
|
|
|
|
fmt.Printf("Export done in %v\n", time.Since(start)) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// importPreimages imports preimage data from the specified file.
|
|
|
|
|
func importPreimages(ctx *cli.Context) error { |
|
|
|
|
if len(ctx.Args()) < 1 { |
|
|
|
|
utils.Fatalf("This command requires an argument.") |
|
|
|
|
} |
|
|
|
|
stack := makeFullNode(ctx) |
|
|
|
|
diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase) |
|
|
|
|
|
|
|
|
|
start := time.Now() |
|
|
|
|
if err := utils.ImportPreimages(diskdb, ctx.Args().First()); err != nil { |
|
|
|
|
utils.Fatalf("Export error: %v\n", err) |
|
|
|
|
} |
|
|
|
|
fmt.Printf("Export done in %v\n", time.Since(start)) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// exportPreimages dumps the preimage data to specified json file in streaming way.
|
|
|
|
|
func exportPreimages(ctx *cli.Context) error { |
|
|
|
|
if len(ctx.Args()) < 1 { |
|
|
|
|
utils.Fatalf("This command requires an argument.") |
|
|
|
|
} |
|
|
|
|
stack := makeFullNode(ctx) |
|
|
|
|
diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase) |
|
|
|
|
|
|
|
|
|
start := time.Now() |
|
|
|
|
if err := utils.ExportPreimages(diskdb, ctx.Args().First()); err != nil { |
|
|
|
|
utils.Fatalf("Export error: %v\n", err) |
|
|
|
|
} |
|
|
|
|
fmt.Printf("Export done in %v\n", time.Since(start)) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -439,86 +466,6 @@ 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) |
|
|
|
|