allow snapshot importing

This commit is contained in:
whyrusleeping 2020-09-01 20:12:21 -07:00 committed by Łukasz Magiera
parent 09ebd1a557
commit 2b16e69e90
3 changed files with 29 additions and 12 deletions

View File

@ -1114,7 +1114,7 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
return cs.LoadTipSet(lbts.Parents()) return cs.LoadTipSet(lbts.Parents())
} }
func recurseLinks(bs bstore.Blockstore, seen *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) { func recurseLinks(bs bstore.Blockstore, walked *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) {
if root.Prefix().Codec != cid.DagCBOR { if root.Prefix().Codec != cid.DagCBOR {
return in, nil return in, nil
} }
@ -1132,13 +1132,13 @@ func recurseLinks(bs bstore.Blockstore, seen *cid.Set, root cid.Cid, in []cid.Ci
} }
// traversed this already... // traversed this already...
if !seen.Visit(c) { if !walked.Visit(c) {
return return
} }
in = append(in, c) in = append(in, c)
var err error var err error
in, err = recurseLinks(bs, seen, c, in) in, err = recurseLinks(bs, walked, c, in)
if err != nil { if err != nil {
rerr = err rerr = err
} }
@ -1156,6 +1156,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
} }
seen := cid.NewSet() seen := cid.NewSet()
walked := cid.NewSet()
h := &car.CarHeader{ h := &car.CarHeader{
Roots: ts.Cids(), Roots: ts.Cids(),
@ -1187,7 +1188,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err) return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err)
} }
cids, err := recurseLinks(cs.bs, seen, b.Messages, []cid.Cid{b.Messages}) cids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages})
if err != nil { if err != nil {
return xerrors.Errorf("recursing messages failed: %w", err) return xerrors.Errorf("recursing messages failed: %w", err)
} }
@ -1204,7 +1205,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
out := cids out := cids
if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots { if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots {
cids, err := recurseLinks(cs.bs, seen, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot}) cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
if err != nil { if err != nil {
return xerrors.Errorf("recursing genesis state failed: %w", err) return xerrors.Errorf("recursing genesis state failed: %w", err)
} }

View File

@ -41,7 +41,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
var st power.State var st power.State
if err := cst.Get(ctx, act.Head, &st); err != nil { if err := cst.Get(ctx, act.Head, &st); err != nil {
return types.NewInt(0), xerrors.Errorf("get power actor head: %w", err) return types.NewInt(0), xerrors.Errorf("get power actor head (%s, height=%d): %w", act.Head, ts.Height(), err)
} }
tpow = st.TotalQualityAdjPower // TODO: REVIEW: Is this correct? tpow = st.TotalQualityAdjPower // TODO: REVIEW: Is this correct?
} }

View File

@ -102,6 +102,10 @@ var DaemonCmd = &cli.Command{
Name: "import-chain", Name: "import-chain",
Usage: "on first run, load chain from given file", Usage: "on first run, load chain from given file",
}, },
&cli.StringFlag{
Name: "checkpoint",
Usage: "import chain state from a given chain export file",
},
&cli.BoolFlag{ &cli.BoolFlag{
Name: "halt-after-import", Name: "halt-after-import",
Usage: "halt the process after importing chain from file", Usage: "halt the process after importing chain from file",
@ -191,13 +195,23 @@ var DaemonCmd = &cli.Command{
} }
chainfile := cctx.String("import-chain") chainfile := cctx.String("import-chain")
if chainfile != "" { snapshot := cctx.String("checkpoint")
if chainfile != "" || snapshot != "" {
if chainfile != "" && snapshot != "" {
return fmt.Errorf("cannot specify both 'snapshot' and 'import-chain'")
}
var ischeckpoint bool
if chainfile == "" {
chainfile = snapshot
ischeckpoint = true
}
chainfile, err := homedir.Expand(chainfile) chainfile, err := homedir.Expand(chainfile)
if err != nil { if err != nil {
return err return err
} }
if err := ImportChain(r, chainfile); err != nil { if err := ImportChain(r, chainfile, ischeckpoint); err != nil {
return err return err
} }
if cctx.Bool("halt-after-import") { if cctx.Bool("halt-after-import") {
@ -312,7 +326,7 @@ func importKey(ctx context.Context, api api.FullNode, f string) error {
return nil return nil
} }
func ImportChain(r repo.Repo, fname string) error { func ImportChain(r repo.Repo, fname string, snapshot bool) error {
fi, err := os.Open(fname) fi, err := os.Open(fname)
if err != nil { if err != nil {
return err return err
@ -357,10 +371,12 @@ func ImportChain(r repo.Repo, fname string) error {
stm := stmgr.NewStateManager(cst) stm := stmgr.NewStateManager(cst)
if !snapshot {
log.Infof("validating imported chain...") log.Infof("validating imported chain...")
if err := stm.ValidateChain(context.TODO(), ts); err != nil { if err := stm.ValidateChain(context.TODO(), ts); err != nil {
return xerrors.Errorf("chain validation failed: %w", err) return xerrors.Errorf("chain validation failed: %w", err)
} }
}
log.Info("accepting %s as new head", ts.Cids()) log.Info("accepting %s as new head", ts.Cids())
if err := cst.SetHead(ts); err != nil { if err := cst.SetHead(ts); err != nil {