feat: allow injecting custom path resolvers (#9750)
In order to make it possible to easily-overwrite the path Resolvers (i.e. via plugins), this creates resolvers as part of the Node rather than creating them ad-hoc.
Hector Sanjuan committed
Apr 4, 2023 at 19:11 UTC
027c5b1a09f79ce029286a8a8f0fe63d3a6aec32
6 files changed
+62
-32
core/core.go
+15
-12
@@ -21,6 +21,7 @@ import (
21
exchange "github.com/ipfs/boxo/exchange"
22
"github.com/ipfs/boxo/fetcher"
23
mfs "github.com/ipfs/boxo/mfs"
24
+ pathresolver "github.com/ipfs/boxo/path/resolver"
25
provider "github.com/ipfs/boxo/provider"
26
"github.com/ipfs/go-graphsync"
27
ipld "github.com/ipfs/go-ipld-format"
@@ -87,18 +88,20 @@ type IpfsNode struct {
88
RecordValidator record.Validator
89
90
// Online
90
- PeerHost p2phost.Host `optional:"true"` // the network host (server+client)
91
- Peering *peering.PeeringService `optional:"true"`
92
- Filters *ma.Filters `optional:"true"`
93
- Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper
94
- Routing irouting.ProvideManyRouter `optional:"true"` // the routing system. recommend ipfs-dht
95
- DNSResolver *madns.Resolver // the DNS resolver
96
- Exchange exchange.Interface // the block exchange + strategy (bitswap)
97
- Namesys namesys.NameSystem // the name system, resolves paths to hashes
98
- Provider provider.System // the value provider system
99
- IpnsRepub *ipnsrp.Republisher `optional:"true"`
100
- GraphExchange graphsync.GraphExchange `optional:"true"`
101
- ResourceManager network.ResourceManager `optional:"true"`
91
+ PeerHost p2phost.Host `optional:"true"` // the network host (server+client)
92
+ Peering *peering.PeeringService `optional:"true"`
93
+ Filters *ma.Filters `optional:"true"`
94
+ Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper
95
+ Routing irouting.ProvideManyRouter `optional:"true"` // the routing system. recommend ipfs-dht
96
+ DNSResolver *madns.Resolver // the DNS resolver
97
+ IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"` // The IPLD path resolver
98
+ UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"` // The UnixFS path resolver
99
+ Exchange exchange.Interface // the block exchange + strategy (bitswap)
100
+ Namesys namesys.NameSystem // the name system, resolves paths to hashes
101
+ Provider provider.System // the value provider system
102
+ IpnsRepub *ipnsrp.Republisher `optional:"true"`
103
+ GraphExchange graphsync.GraphExchange `optional:"true"`
104
+ ResourceManager network.ResourceManager `optional:"true"`
105
106
PubSub *pubsub.PubSub `optional:"true"`
107
PSRouter *psrouter.PubsubValueStore `optional:"true"`
core/coreapi/coreapi.go
+15
-10
@@ -26,6 +26,7 @@ import (
26
offlinexch "github.com/ipfs/boxo/exchange/offline"
27
"github.com/ipfs/boxo/fetcher"
28
dag "github.com/ipfs/boxo/ipld/merkledag"
29
+ pathresolver "github.com/ipfs/boxo/path/resolver"
30
pin "github.com/ipfs/boxo/pinning/pinner"
31
provider "github.com/ipfs/boxo/provider"
32
offlineroute "github.com/ipfs/boxo/routing/offline"
@@ -65,9 +66,11 @@ type CoreAPI struct {
66
recordValidator record.Validator
67
exchange exchange.Interface
68
68
- namesys namesys.NameSystem
69
- routing routing.Routing
70
- dnsResolver *madns.Resolver
69
+ namesys namesys.NameSystem
70
+ routing routing.Routing
71
+ dnsResolver *madns.Resolver
72
+ ipldPathResolver pathresolver.Resolver
73
+ unixFSPathResolver pathresolver.Resolver
74
75
provider provider.System
76
@@ -179,13 +182,15 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e
182
ipldFetcherFactory: n.IPLDFetcherFactory,
183
unixFSFetcherFactory: n.UnixFSFetcherFactory,
184
182
- peerstore: n.Peerstore,
183
- peerHost: n.PeerHost,
184
- namesys: n.Namesys,
185
- recordValidator: n.RecordValidator,
186
- exchange: n.Exchange,
187
- routing: n.Routing,
188
- dnsResolver: n.DNSResolver,
185
+ peerstore: n.Peerstore,
186
+ peerHost: n.PeerHost,
187
+ namesys: n.Namesys,
188
+ recordValidator: n.RecordValidator,
189
+ exchange: n.Exchange,
190
+ routing: n.Routing,
191
+ dnsResolver: n.DNSResolver,
192
+ ipldPathResolver: n.IPLDPathResolver,
193
+ unixFSPathResolver: n.UnixFSPathResolver,
194
195
provider: n.Provider,
196
core/coreapi/path.go
+3
-5
@@ -13,7 +13,6 @@ import (
13
14
coreiface "github.com/ipfs/boxo/coreiface"
15
path "github.com/ipfs/boxo/coreiface/path"
16
- "github.com/ipfs/boxo/fetcher"
16
ipfspath "github.com/ipfs/boxo/path"
17
ipfspathresolver "github.com/ipfs/boxo/path/resolver"
18
"github.com/ipfs/go-cid"
@@ -63,13 +62,12 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved
62
return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace())
63
}
64
66
- var dataFetcher fetcher.Factory
65
+ var resolver ipfspathresolver.Resolver
66
if ipath.Segments()[0] == "ipld" {
68
- dataFetcher = api.ipldFetcherFactory
67
+ resolver = api.ipldPathResolver
68
} else {
70
- dataFetcher = api.unixFSFetcherFactory
69
+ resolver = api.unixFSPathResolver
70
}
72
- resolver := ipfspathresolver.NewBasicResolver(dataFetcher)
71
72
node, rest, err := resolver.ResolveToLastNode(ctx, ipath)
73
if err != nil {
core/node/core.go
+27
-3
@@ -13,6 +13,7 @@ import (
13
"github.com/ipfs/boxo/ipld/merkledag"
14
"github.com/ipfs/boxo/ipld/unixfs"
15
"github.com/ipfs/boxo/mfs"
16
+ pathresolver "github.com/ipfs/boxo/path/resolver"
17
pin "github.com/ipfs/boxo/pinning/pinner"
18
"github.com/ipfs/boxo/pinning/pinner/dspinner"
19
"github.com/ipfs/go-cid"
@@ -83,14 +84,22 @@ func (s *syncDagService) Session(ctx context.Context) format.NodeGetter {
84
return merkledag.NewSession(ctx, s.DAGService)
85
}
86
86
-type fetchersOut struct {
87
+// FetchersOut allows injection of fetchers.
88
+type FetchersOut struct {
89
fx.Out
90
IPLDFetcher fetcher.Factory `name:"ipldFetcher"`
91
UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"`
92
}
93
94
+// FetchersIn allows using fetchers for other dependencies.
95
+type FetchersIn struct {
96
+ fx.In
97
+ IPLDFetcher fetcher.Factory `name:"ipldFetcher"`
98
+ UnixfsFetcher fetcher.Factory `name:"unixfsFetcher"`
99
+}
100
+
101
// FetcherConfig returns a fetcher config that can build new fetcher instances
93
-func FetcherConfig(bs blockservice.BlockService) fetchersOut {
102
+func FetcherConfig(bs blockservice.BlockService) FetchersOut {
103
ipldFetcher := bsfetcher.NewFetcherConfig(bs)
104
ipldFetcher.PrototypeChooser = dagpb.AddSupportToChooser(func(lnk ipld.Link, lnkCtx ipld.LinkContext) (ipld.NodePrototype, error) {
105
if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok {
@@ -100,7 +109,22 @@ func FetcherConfig(bs blockservice.BlockService) fetchersOut {
109
})
110
111
unixFSFetcher := ipldFetcher.WithReifier(unixfsnode.Reify)
103
- return fetchersOut{IPLDFetcher: ipldFetcher, UnixfsFetcher: unixFSFetcher}
112
+ return FetchersOut{IPLDFetcher: ipldFetcher, UnixfsFetcher: unixFSFetcher}
113
+}
114
+
115
+// PathResolversOut allows injection of path resolvers
116
+type PathResolversOut struct {
117
+ fx.Out
118
+ IPLDPathResolver pathresolver.Resolver `name:"ipldPathResolver"`
119
+ UnixFSPathResolver pathresolver.Resolver `name:"unixFSPathResolver"`
120
+}
121
+
122
+// PathResolverConfig creates path resolvers with the given fetchers.
123
+func PathResolverConfig(fetchers FetchersIn) PathResolversOut {
124
+ return PathResolversOut{
125
+ IPLDPathResolver: pathresolver.NewBasicResolver(fetchers.IPLDFetcher),
126
+ UnixFSPathResolver: pathresolver.NewBasicResolver(fetchers.UnixfsFetcher),
127
+ }
128
}
129
130
// Dag creates new DAGService
core/node/groups.go
+1
@@ -334,6 +334,7 @@ var Core = fx.Options(
334
fx.Provide(BlockService),
335
fx.Provide(Dag),
336
fx.Provide(FetcherConfig),
337
+ fx.Provide(PathResolverConfig),
338
fx.Provide(Pinning),
339
fx.Provide(Files),
340
)
fuse/readonly/readonly_unix.go
+1
-2
@@ -17,7 +17,6 @@ import (
17
ft "github.com/ipfs/boxo/ipld/unixfs"
18
uio "github.com/ipfs/boxo/ipld/unixfs/io"
19
path "github.com/ipfs/boxo/path"
20
- "github.com/ipfs/boxo/path/resolver"
20
"github.com/ipfs/go-cid"
21
ipld "github.com/ipfs/go-ipld-format"
22
logging "github.com/ipfs/go-log"
@@ -69,7 +68,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
68
return nil, fuse.ENOENT
69
}
70
72
- nd, ndLnk, err := resolver.NewBasicResolver(s.Ipfs.UnixFSFetcherFactory).ResolvePath(ctx, p)
71
+ nd, ndLnk, err := s.Ipfs.UnixFSPathResolver.ResolvePath(ctx, p)
72
if err != nil {
73
// todo: make this error more versatile.
74
return nil, fuse.ENOENT