-
Notifications
You must be signed in to change notification settings - Fork 93
/
chainsync.go
74 lines (65 loc) · 1.85 KB
/
chainsync.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package chainsync
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/api/apistruct"
"github.com/filecoin-project/lotus/chain/types"
)
const (
hcApply = "apply"
// For completeness:
// hcRevert = "revert"
// hcCurrent = "current"
)
// ChainSync provides methods to resolve chain syncing situations
type ChainSync struct {
api *apistruct.FullNodeStruct
}
// New returns a new ChainSync
func New(api *apistruct.FullNodeStruct) *ChainSync {
return &ChainSync{
api: api,
}
}
// Precedes returns true if from and to don't live in different chain forks, and
// from is at a lower epoch than to.
func (cs *ChainSync) Precedes(ctx context.Context, from, to types.TipSetKey) (bool, error) {
fpath, err := cs.api.ChainGetPath(ctx, from, to)
if err != nil {
return false, fmt.Errorf("getting path from %v to %v: %s", from.Cids(), to.Cids(), err)
}
if len(fpath) == 0 {
return true, nil
}
norevert := fpath[0].Type == hcApply
return norevert, nil
}
// ResolveBase returns the base TipSetKey that both left and right TipSetKey share,
// plus a Revert/Apply set of operations to get from last to new.
func ResolveBase(ctx context.Context, api *apistruct.FullNodeStruct, left *types.TipSetKey, right types.TipSetKey) (*types.TipSetKey, []*types.TipSet, error) {
var path []*types.TipSet
if left == nil {
genesis, err := api.ChainGetGenesis(ctx)
if err != nil {
return nil, nil, fmt.Errorf("getting genesis tipset: %s", err)
}
path = append(path, genesis)
gtsk := types.NewTipSetKey(genesis.Cids()...)
left = >sk
}
fpath, err := api.ChainGetPath(ctx, *left, right)
if err != nil {
return nil, nil, err
}
var base *types.TipSetKey
for _, ts := range fpath {
if ts.Type == hcApply {
if base == nil {
b := types.NewTipSetKey(ts.Val.Blocks()[0].Parents...)
base = &b
}
path = append(path, ts.Val)
}
}
return base, path, nil
}