-
Notifications
You must be signed in to change notification settings - Fork 0
/
retriever.go
78 lines (68 loc) · 2.11 KB
/
retriever.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
75
76
77
78
package jiffy
import (
"context"
"io"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-shipyard/boostly"
)
var (
_ Retriever = (*httpPieceRetriever)(nil)
)
type (
Retriever interface {
Retrieve(context.Context, abi.PieceInfo) (io.ReadSeekCloser, error)
}
httpPieceRetriever struct {
j *Jiffy
}
)
// TODO implement chained retriever where it returns things in this order:
// 1. well-known pieces like the empty carv1 header segment
// 2. local copy (via headless car segmentor)
// 3. remote HTTP piece retrieval by piece CID.
// Note for other protocols we need CIDs from the CAR sections.
// This basically means we either store segments as unixfs file and keep hold of the root
// or store the CARv2 index of the CAR sections.
// Other techniques include nested CAR in sections which has its own headaches.
// For now, require SPs to support HTTP piece retrieval.
//lint:ignore U1000 WIP
func newHttpPieceRetriever(j *Jiffy) (*httpPieceRetriever, error) {
return &httpPieceRetriever{j: j}, nil
}
func (s *httpPieceRetriever) Retrieve(ctx context.Context, pi abi.PieceInfo) (io.ReadSeekCloser, error) {
// TODO add built-in rule for well known piece infos like emptyHeaderV1Segment
replicas, err := s.j.replicator.GetReplicas(ctx, pi)
if err != nil {
return nil, err
}
if len(replicas) == 0 {
return nil, nil
}
// Pick a replica as candidate to retrieve from
for range replicas {
// TODO for each replica check status and pick an active one.
}
var sp address.Address
info, err := s.j.fil.StateMinerInfo(ctx, sp)
if err != nil {
return nil, err
}
if err = s.j.h.Connect(ctx, *info); err != nil {
return nil, err
}
// Check what transports the SP supports
transports, err := boostly.QueryTransports(ctx, s.j.h, info.ID)
if err != nil {
return nil, err
}
for _, protocol := range transports.Protocols {
//lint:ignore SA9003 WIP
if protocol.Name == "http" {
// might support /ipfs trustless gateway
// might suport /piece
}
}
// TODO implement the rest of remote retrieval
return nil, nil
}