Merge pull request #1193 from tgerring/hotbackup
Improve export command
This commit is contained in:
commit
0f1cdfa53a
@ -26,6 +26,12 @@ var (
|
|||||||
Action: exportChain,
|
Action: exportChain,
|
||||||
Name: "export",
|
Name: "export",
|
||||||
Usage: `export blockchain into file`,
|
Usage: `export blockchain into file`,
|
||||||
|
Description: `
|
||||||
|
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.
|
||||||
|
`,
|
||||||
}
|
}
|
||||||
upgradedbCommand = cli.Command{
|
upgradedbCommand = cli.Command{
|
||||||
Action: upgradeDB,
|
Action: upgradeDB,
|
||||||
@ -63,12 +69,30 @@ func importChain(ctx *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func exportChain(ctx *cli.Context) {
|
func exportChain(ctx *cli.Context) {
|
||||||
if len(ctx.Args()) != 1 {
|
if len(ctx.Args()) < 1 {
|
||||||
utils.Fatalf("This command requires an argument.")
|
utils.Fatalf("This command requires an argument.")
|
||||||
}
|
}
|
||||||
chain, _, _, _ := utils.MakeChain(ctx)
|
chain, _, _, _ := utils.MakeChain(ctx)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if err := utils.ExportChain(chain, ctx.Args().First()); err != nil {
|
|
||||||
|
var err error
|
||||||
|
fp := ctx.Args().First()
|
||||||
|
if len(ctx.Args()) < 3 {
|
||||||
|
err = utils.ExportChain(chain, fp)
|
||||||
|
} else {
|
||||||
|
// This can be improved to allow for numbers larger than 9223372036854775807
|
||||||
|
first, ferr := strconv.ParseInt(ctx.Args().Get(1), 10, 64)
|
||||||
|
last, lerr := strconv.ParseInt(ctx.Args().Get(2), 10, 64)
|
||||||
|
if ferr != nil || lerr != nil {
|
||||||
|
utils.Fatalf("Export error in parsing parameters: block number not an integer\n")
|
||||||
|
}
|
||||||
|
if first < 0 || last < 0 {
|
||||||
|
utils.Fatalf("Export error: block number must be greater than 0\n")
|
||||||
|
}
|
||||||
|
err = utils.ExportAppendChain(chain, fp, uint64(first), uint64(last))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
utils.Fatalf("Export error: %v\n", err)
|
utils.Fatalf("Export error: %v\n", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Export done in %v", time.Since(start))
|
fmt.Printf("Export done in %v", time.Since(start))
|
||||||
|
@ -268,3 +268,18 @@ func ExportChain(chainmgr *core.ChainManager, fn string) error {
|
|||||||
glog.Infoln("Exported blockchain to", fn)
|
glog.Infoln("Exported blockchain to", fn)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExportAppendChain(chainmgr *core.ChainManager, fn string, first uint64, last uint64) error {
|
||||||
|
glog.Infoln("Exporting blockchain to", fn)
|
||||||
|
// TODO verify mode perms
|
||||||
|
fh, err := os.OpenFile(fn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
if err := chainmgr.ExportN(fh, first, last); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
glog.Infoln("Exported blockchain to", fn)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -347,13 +347,24 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) {
|
|||||||
|
|
||||||
// Export writes the active chain to the given writer.
|
// Export writes the active chain to the given writer.
|
||||||
func (self *ChainManager) Export(w io.Writer) error {
|
func (self *ChainManager) Export(w io.Writer) error {
|
||||||
|
if err := self.ExportN(w, uint64(0), self.currentBlock.NumberU64()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportN writes a subset of the active chain to the given writer.
|
||||||
|
func (self *ChainManager) ExportN(w io.Writer, first uint64, last uint64) error {
|
||||||
self.mu.RLock()
|
self.mu.RLock()
|
||||||
defer self.mu.RUnlock()
|
defer self.mu.RUnlock()
|
||||||
glog.V(logger.Info).Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
|
|
||||||
|
|
||||||
last := self.currentBlock.NumberU64()
|
if first > last {
|
||||||
|
return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
|
||||||
|
}
|
||||||
|
|
||||||
for nr := uint64(1); nr <= last; nr++ {
|
glog.V(logger.Info).Infof("exporting %d blocks...\n", last-first+1)
|
||||||
|
|
||||||
|
for nr := first; nr <= last; nr++ {
|
||||||
block := self.GetBlockByNumber(nr)
|
block := self.GetBlockByNumber(nr)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return fmt.Errorf("export failed on #%d: not found", nr)
|
return fmt.Errorf("export failed on #%d: not found", nr)
|
||||||
|
Loading…
Reference in New Issue
Block a user