Burrow, Dump & Restore
Dump
Dump will create a dump file of burrow state.
Dump local
create a dump from local Burrow directory
burrow dump --verbose local
It will create a burrow kernel locally from the burrow state DB, then make a dumper which start a goroutine for feeding state data.
// Return a Source that is a Pipe fed from this Dumper's Transmit function
func (ds *Dumper) Source(startHeight, endHeight uint64, options Option) Source {
p := make(Pipe)
go func() {
err := ds.Transmit(p, startHeight, endHeight, options)
if err != nil {
p <- msg{err: err}
}
close(p)
}()
return p
}
Accounts | Names | Events can be dumpped.
Dump remote
pull a dump from a remote Burrow node
burrow dump --verbose remote -c 127.0.0.1:10997
Similarly it will dial to a gRPC dump server, and start streaming the state data.
func (c *dumpClient) GetDump(ctx context.Context, in *GetDumpParam, opts ...grpc.CallOption) (Dump_GetDumpClient, error) {
stream, err := c.cc.NewStream(ctx, &_Dump_serviceDesc.Streams[0], "/rpcdump.Dump/GetDump", opts...)
if err != nil {
return nil, err
}
x := &dumpGetDumpClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
func (x *dumpGetDumpClient) Recv() (*dump.Dump, error) {
m := new(dump.Dump)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
Restore
Restore from a dump file.
burrow restore
// LoadDump restores chain state from the given dump file
func (kern *Kernel) LoadDump(genesisDoc *genesis.GenesisDoc, restoreFile string, silent bool) (err error) {
var exists bool
if kern.Blockchain, exists, err = bcm.LoadOrNewBlockchain(kern.database, genesisDoc, kern.Logger); err != nil {
return fmt.Errorf("error creating or loading blockchain state: %v", err)
}
if exists {
if silent {
kern.Logger.InfoMsg("State already exists, skipping...")
return nil
}
return fmt.Errorf("existing state found, please remove before restoring")
}
kern.Blockchain.SetBlockStore(bcm.NewBlockStore(store.NewBlockStore(kern.database)))
if kern.State, err = state.MakeGenesisState(kern.database, genesisDoc); err != nil {
return fmt.Errorf("could not build genesis state: %v", err)
}
if len(genesisDoc.AppHash) == 0 {
return fmt.Errorf("AppHash is required when restoring chain")
}
reader, err := dump.NewFileReader(restoreFile)
if err != nil {
return err
}
err = dump.Load(reader, kern.State)
if err != nil {
return err
}
if !bytes.Equal(kern.State.Hash(), kern.Blockchain.GenesisDoc().AppHash) {
return fmt.Errorf("restore produced a different apphash expect 0x%x got 0x%x",
kern.Blockchain.GenesisDoc().AppHash, kern.State.Hash())
}
err = kern.Blockchain.CommitWithAppHash(kern.State.Hash())
if err != nil {
return fmt.Errorf("unable to commit %v", err)
}
kern.Logger.InfoMsg("State restore successful",
"state_hash", kern.State.Hash())
return nil
}