82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package chain
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
"github.com/ipfs/go-datastore"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
var CheckpointKey = datastore.NewKey("/chain/checks")
|
|
|
|
func loadCheckpoint(ds dtypes.MetadataDS) (types.TipSetKey, error) {
|
|
haveChks, err := ds.Has(CheckpointKey)
|
|
if err != nil {
|
|
return types.EmptyTSK, err
|
|
}
|
|
|
|
if !haveChks {
|
|
return types.EmptyTSK, nil
|
|
}
|
|
|
|
tskBytes, err := ds.Get(CheckpointKey)
|
|
if err != nil {
|
|
return types.EmptyTSK, err
|
|
}
|
|
|
|
var tsk types.TipSetKey
|
|
err = json.Unmarshal(tskBytes, &tsk)
|
|
if err != nil {
|
|
return types.EmptyTSK, err
|
|
}
|
|
|
|
return tsk, err
|
|
}
|
|
|
|
func (syncer *Syncer) SetCheckpoint(tsk types.TipSetKey) error {
|
|
if tsk == types.EmptyTSK {
|
|
return xerrors.Errorf("called with empty tsk")
|
|
}
|
|
|
|
syncer.checkptLk.Lock()
|
|
defer syncer.checkptLk.Unlock()
|
|
|
|
ts, err := syncer.ChainStore().LoadTipSet(tsk)
|
|
if err != nil {
|
|
return xerrors.Errorf("cannot find tipset: %w", err)
|
|
}
|
|
|
|
hts := syncer.ChainStore().GetHeaviestTipSet()
|
|
anc, err := syncer.ChainStore().IsAncestorOf(ts, hts)
|
|
if err != nil {
|
|
return xerrors.Errorf("cannot determine whether checkpoint tipset is in main-chain: %w", err)
|
|
}
|
|
|
|
if !hts.Equals(ts) && !anc {
|
|
return xerrors.Errorf("cannot mark tipset as checkpoint, since it isn't in the main-chain: %w", err)
|
|
}
|
|
|
|
tskBytes, err := json.Marshal(tsk)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = syncer.ds.Put(CheckpointKey, tskBytes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
syncer.checkpt = tsk
|
|
|
|
return nil
|
|
}
|
|
|
|
func (syncer *Syncer) GetCheckpoint() types.TipSetKey {
|
|
syncer.checkptLk.Lock()
|
|
defer syncer.checkptLk.Unlock()
|
|
return syncer.checkpt
|
|
}
|