2020-09-09 05:14:01 +00:00
|
|
|
package chain
|
|
|
|
|
|
|
|
import (
|
2021-04-26 10:50:29 +00:00
|
|
|
"context"
|
2020-09-09 05:14:01 +00:00
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
)
|
|
|
|
|
2021-04-26 10:50:29 +00:00
|
|
|
func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error {
|
2020-09-09 05:14:01 +00:00
|
|
|
if tsk == types.EmptyTSK {
|
|
|
|
return xerrors.Errorf("called with empty tsk")
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:03:00 +00:00
|
|
|
ts, err := syncer.ChainStore().LoadTipSet(ctx, tsk)
|
2020-09-09 05:14:01 +00:00
|
|
|
if err != nil {
|
2021-04-26 10:50:29 +00:00
|
|
|
tss, err := syncer.Exchange.GetBlocks(ctx, tsk, 1)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("failed to fetch tipset: %w", err)
|
|
|
|
} else if len(tss) != 1 {
|
|
|
|
return xerrors.Errorf("expected 1 tipset, got %d", len(tss))
|
|
|
|
}
|
|
|
|
ts = tss[0]
|
2020-09-09 05:14:01 +00:00
|
|
|
}
|
|
|
|
|
2021-04-28 19:49:21 +00:00
|
|
|
if err := syncer.switchChain(ctx, ts); err != nil {
|
|
|
|
return xerrors.Errorf("failed to switch chain when syncing checkpoint: %w", err)
|
2020-09-09 05:14:01 +00:00
|
|
|
}
|
2021-04-28 19:49:21 +00:00
|
|
|
|
2021-12-11 21:03:00 +00:00
|
|
|
if err := syncer.ChainStore().SetCheckpoint(ctx, ts); err != nil {
|
2021-04-28 19:49:21 +00:00
|
|
|
return xerrors.Errorf("failed to set the chain checkpoint: %w", err)
|
2020-09-09 05:14:01 +00:00
|
|
|
}
|
|
|
|
|
2021-04-28 19:49:21 +00:00
|
|
|
return nil
|
|
|
|
}
|
2021-04-26 10:50:29 +00:00
|
|
|
|
2021-04-28 19:49:21 +00:00
|
|
|
func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error {
|
|
|
|
hts := syncer.ChainStore().GetHeaviestTipSet()
|
|
|
|
if hts.Equals(ts) {
|
|
|
|
return nil
|
2020-09-09 05:14:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-11 21:03:00 +00:00
|
|
|
if anc, err := syncer.store.IsAncestorOf(ctx, ts, hts); err == nil && anc {
|
2021-04-28 19:49:21 +00:00
|
|
|
return nil
|
2020-09-09 05:14:01 +00:00
|
|
|
}
|
|
|
|
|
2021-04-28 19:49:21 +00:00
|
|
|
// Otherwise, sync the chain and set the head.
|
|
|
|
if err := syncer.collectChain(ctx, ts, hts, true); err != nil {
|
|
|
|
return xerrors.Errorf("failed to collect chain for checkpoint: %w", err)
|
|
|
|
}
|
2020-09-09 05:14:01 +00:00
|
|
|
|
2021-12-11 21:03:00 +00:00
|
|
|
if err := syncer.ChainStore().SetHead(ctx, ts); err != nil {
|
2021-04-28 19:49:21 +00:00
|
|
|
return xerrors.Errorf("failed to set the chain head: %w", err)
|
|
|
|
}
|
2020-09-09 05:14:01 +00:00
|
|
|
return nil
|
|
|
|
}
|