Merge pull request #4536 from filecoin-project/zgfzgf-fix-chain-export

Small chain export optimization
This commit is contained in:
Łukasz Magiera 2020-10-22 17:35:58 +02:00 committed by GitHub
commit 6b9a4c4a34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 9 deletions

View File

@ -1312,12 +1312,14 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
var cids []cid.Cid var cids []cid.Cid
if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots { if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots {
if walked.Visit(b.Messages) {
mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages}) mcids, 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)
} }
cids = mcids cids = mcids
} }
}
if b.Height > 0 { if b.Height > 0 {
for _, p := range b.Parents { for _, p := range b.Parents {
@ -1331,6 +1333,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
out := cids out := cids
if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots { if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots {
if walked.Visit(b.ParentStateRoot) {
cids, err := recurseLinks(cs.bs, walked, 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)
@ -1338,6 +1341,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
out = append(out, cids...) out = append(out, cids...)
} }
}
for _, c := range out { for _, c := range out {
if seen.Visit(c) { if seen.Visit(c) {

View File

@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore" "github.com/filecoin-project/lotus/lib/blockstore"
@ -107,3 +108,60 @@ func TestChainExportImport(t *testing.T) {
t.Fatal("imported chain differed from exported chain") t.Fatal("imported chain differed from exported chain")
} }
} }
func TestChainExportImportFull(t *testing.T) {
cg, err := gen.NewGenerator()
if err != nil {
t.Fatal(err)
}
var last *types.TipSet
for i := 0; i < 100; i++ {
ts, err := cg.NextTipSet()
if err != nil {
t.Fatal(err)
}
last = ts.TipSet.TipSet()
}
buf := new(bytes.Buffer)
if err := cg.ChainStore().Export(context.TODO(), last, 100, false, buf); err != nil {
t.Fatal(err)
}
nbs := blockstore.NewTemporary()
cs := store.NewChainStore(nbs, datastore.NewMapDatastore(), nil, nil)
root, err := cs.Import(buf)
if err != nil {
t.Fatal(err)
}
err = cs.SetHead(last)
if err != nil {
t.Fatal(err)
}
if !root.Equals(last) {
t.Fatal("imported chain differed from exported chain")
}
sm := stmgr.NewStateManager(cs)
for i := 0; i < 100; i++ {
ts, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(i), nil, false)
if err != nil {
t.Fatal(err)
}
st, err := sm.ParentState(ts)
if err != nil {
t.Fatal(err)
}
// touches a bunch of actors
_, err = sm.GetCirculatingSupply(context.TODO(), abi.ChainEpoch(i), st)
if err != nil {
t.Fatal(err)
}
}
}