@cryptotaxi247 / kubo / commits / ed514b917

Invert constructor config handling

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Apr 29, 2019 at 23:37 UTC ed514b91774de87fb1c96f878943e78db0f17fc9
9 files changed +399 -334
core/core.go
+2 -2
@@ -71,13 +71,13 @@ type IpfsNode struct {
71 // Local node
72 Pinning pin.Pinner // the pinning manager
73 Mounts Mounts `optional:"true"` // current mount state, if any.
74 - PrivateKey ic.PrivKey // the local node's private Key
74 + PrivateKey ic.PrivKey `optional:"true"` // the local node's private Key
75 PNetFingerprint libp2p.PNetFingerprint `optional:"true"` // fingerprint of private network
76
77 // Services
78 Peerstore pstore.Peerstore `optional:"true"` // storage for other Peer instances
79 Blockstore bstore.GCBlockstore // the block store (lower level)
80 - Filestore *filestore.Filestore // the filestore blockstore
80 + Filestore *filestore.Filestore `optional:"true"` // the filestore blockstore
81 BaseBlocks node.BaseBlocks // the raw blockstore, no filestore wrapping
82 GCLocker bstore.GCLocker // the locker used to protect the blockstore during gc
83 Blocks bserv.BlockService // the block service, get/add blocks.
core/node/groups.go
+221 -47
@@ -2,72 +2,187 @@ package node
2
3 import (
4 "context"
5 + "errors"
6 + "fmt"
7 + "time"
8 +
9 + blockstore "github.com/ipfs/go-ipfs-blockstore"
10 + "github.com/ipfs/go-ipfs-config"
11 + util "github.com/ipfs/go-ipfs-util"
12 + peer "github.com/libp2p/go-libp2p-peer"
13 + "github.com/libp2p/go-libp2p-peerstore/pstoremem"
14 + pubsub "github.com/libp2p/go-libp2p-pubsub"
15
16 "github.com/ipfs/go-ipfs/core/node/libp2p"
17 "github.com/ipfs/go-ipfs/p2p"
18 "github.com/ipfs/go-ipfs/provider"
19 + "github.com/ipfs/go-ipfs/reprovide"
20
21 offline "github.com/ipfs/go-ipfs-exchange-offline"
22 offroute "github.com/ipfs/go-ipfs-routing/offline"
12 - uio "github.com/ipfs/go-unixfs/io"
23 "github.com/ipfs/go-path/resolver"
24 + uio "github.com/ipfs/go-unixfs/io"
25 "go.uber.org/fx"
26 )
27
28 var BaseLibP2P = fx.Options(
18 - fx.Provide(libp2p.AddrFilters),
19 - fx.Provide(libp2p.BandwidthCounter),
29 fx.Provide(libp2p.PNet),
21 - fx.Provide(libp2p.AddrsFactory),
30 fx.Provide(libp2p.ConnectionManager),
23 - fx.Provide(libp2p.NatPortMap),
24 - fx.Provide(libp2p.Relay),
25 - fx.Provide(libp2p.AutoRealy),
31 fx.Provide(libp2p.DefaultTransports),
27 - fx.Provide(libp2p.QUIC),
32
33 fx.Provide(libp2p.Host),
34
35 fx.Provide(libp2p.DiscoveryHandler),
36
33 - fx.Invoke(libp2p.AutoNATService),
37 fx.Invoke(libp2p.PNetChecker),
35 - fx.Invoke(libp2p.StartListening),
36 - fx.Invoke(libp2p.SetupDiscovery),
38 )
39
39 -func LibP2P(cfg *BuildCfg) fx.Option {
40 +func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option {
41 +
42 + // parse ConnMgr config
43 +
44 + grace := config.DefaultConnMgrGracePeriod
45 + low := config.DefaultConnMgrHighWater
46 + high := config.DefaultConnMgrHighWater
47 +
48 + connmgr := fx.Options()
49 +
50 + if cfg.Swarm.ConnMgr.Type != "none" {
51 + switch cfg.Swarm.ConnMgr.Type {
52 + case "":
53 + // 'default' value is the basic connection manager
54 + break
55 + case "basic":
56 + var err error
57 + grace, err = time.ParseDuration(cfg.Swarm.ConnMgr.GracePeriod)
58 + if err != nil {
59 + return fx.Error(fmt.Errorf("parsing Swarm.ConnMgr.GracePeriod: %s", err))
60 + }
61 +
62 + low = cfg.Swarm.ConnMgr.LowWater
63 + high = cfg.Swarm.ConnMgr.HighWater
64 + default:
65 + return fx.Error(fmt.Errorf("unrecognized ConnMgr.Type: %q", cfg.Swarm.ConnMgr.Type))
66 + }
67 +
68 + connmgr = fx.Provide(libp2p.ConnectionManager(low, high, grace))
69 + }
70 +
71 + // parse PubSub config
72 +
73 + ps := fx.Options()
74 + if bcfg.getOpt("pubsub") || bcfg.getOpt("ipnsps") {
75 + var pubsubOptions []pubsub.Option
76 + if cfg.Pubsub.DisableSigning {
77 + pubsubOptions = append(pubsubOptions, pubsub.WithMessageSigning(false))
78 + }
79 +
80 + if cfg.Pubsub.StrictSignatureVerification {
81 + pubsubOptions = append(pubsubOptions, pubsub.WithStrictSignatureVerification(true))
82 + }
83 +
84 + switch cfg.Pubsub.Router {
85 + case "":
86 + fallthrough
87 + case "floodsub":
88 + ps = fx.Provide(libp2p.FloodSub(pubsubOptions...))
89 + case "gossipsub":
90 + ps = fx.Provide(libp2p.GossipSub(pubsubOptions...))
91 + default:
92 + return fx.Error(fmt.Errorf("unknown pubsub router %s", cfg.Pubsub.Router))
93 + }
94 + }
95 +
96 + // Gather all the options
97 +
98 opts := fx.Options(
99 BaseLibP2P,
100
43 - fx.Provide(libp2p.Security(!cfg.DisableEncryptedConnections)),
44 - maybeProvide(libp2p.Pubsub, cfg.getOpt("pubsub") || cfg.getOpt("ipnsps")),
101 + fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)),
102 + fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled, cfg.Discovery.MDNS.Interval)),
103 + fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.NoAnnounce)),
104 + fx.Provide(libp2p.SmuxTransport(bcfg.getOpt("mplex"))),
105 + fx.Provide(libp2p.Relay(cfg.Swarm.DisableRelay, cfg.Swarm.EnableRelayHop)),
106 + fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)),
107 +
108 + fx.Provide(libp2p.Security(!bcfg.DisableEncryptedConnections, cfg.Experimental.PreferTLS)),
109
46 - fx.Provide(libp2p.SmuxTransport(cfg.getOpt("mplex"))),
110 fx.Provide(libp2p.Routing),
111 fx.Provide(libp2p.BaseRouting),
49 - maybeProvide(libp2p.PubsubRouter, cfg.getOpt("ipnsps")),
112 + maybeProvide(libp2p.PubsubRouter, bcfg.getOpt("ipnsps")),
113 +
114 + maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics),
115 + maybeProvide(libp2p.NatPortMap, !cfg.Swarm.DisableNatPortMap),
116 + maybeProvide(libp2p.AutoRealy, cfg.Swarm.EnableAutoRelay),
117 + maybeProvide(libp2p.QUIC, cfg.Experimental.QUIC),
118 + maybeProvide(libp2p.AutoNATService(cfg.Experimental.QUIC), cfg.Swarm.EnableAutoNATService),
119 + connmgr,
120 + ps,
121 )
122
123 return opts
124 }
125
126 // Storage groups units which setup datastore based persistence and blockstore layers
56 -func Storage(cfg *BuildCfg) fx.Option {
127 +func Storage(bcfg *BuildCfg, cfg *config.Config) fx.Option {
128 + cacheOpts := blockstore.DefaultCacheOpts()
129 + cacheOpts.HasBloomFilterSize = cfg.Datastore.BloomFilterSize
130 + if !bcfg.Permanent {
131 + cacheOpts.HasBloomFilterSize = 0
132 + }
133 +
134 + finalBstore := fx.Provide(GcBlockstoreCtor)
135 + if cfg.Experimental.FilestoreEnabled || cfg.Experimental.UrlstoreEnabled {
136 + finalBstore = fx.Provide(FilestoreBlockstoreCtor)
137 + }
138 +
139 return fx.Options(
140 fx.Provide(RepoConfig),
141 fx.Provide(Datastore),
60 - fx.Provide(BaseBlockstoreCtor(cfg.Permanent, cfg.NilRepo)),
61 - fx.Provide(GcBlockstoreCtor),
142 + fx.Provide(BaseBlockstoreCtor(cacheOpts, bcfg.NilRepo, cfg.Datastore.HashOnRead)),
143 + finalBstore,
144 )
145 }
146
147 // Identity groups units providing cryptographic identity
66 -var Identity = fx.Options(
67 - fx.Provide(PeerID),
68 - fx.Provide(PrivateKey),
69 - fx.Provide(libp2p.Peerstore),
70 -)
148 +func Identity(cfg *config.Config) fx.Option {
149 + // PeerID
150 +
151 + cid := cfg.Identity.PeerID
152 + if cid == "" {
153 + return fx.Error(errors.New("identity was not set in config (was 'ipfs init' run?)"))
154 + }
155 + if len(cid) == 0 {
156 + return fx.Error(errors.New("no peer ID in config! (was 'ipfs init' run?)"))
157 + }
158 +
159 + id, err := peer.IDB58Decode(cid)
160 + if err != nil {
161 + return fx.Error(fmt.Errorf("peer ID invalid: %s", err))
162 + }
163 +
164 + // Private Key
165 +
166 + if cfg.Identity.PrivKey == "" {
167 + return fx.Options( // No PK (usually in tests)
168 + fx.Provide(PeerID(id)),
169 + fx.Provide(pstoremem.NewPeerstore),
170 + )
171 + }
172 +
173 + sk, err := cfg.Identity.DecodePrivateKey("passphrase todo!")
174 + if err != nil {
175 + return fx.Error(err)
176 + }
177 +
178 + return fx.Options( // Full identity
179 + fx.Provide(PeerID(id)),
180 + fx.Provide(PrivateKey(sk)),
181 + fx.Provide(pstoremem.NewPeerstore),
182 +
183 + fx.Invoke(libp2p.PstoreAddSelfKeys),
184 + )
185 +}
186
187 // IPNS groups namesys related units
188 var IPNS = fx.Options(
@@ -75,33 +190,97 @@ var IPNS = fx.Options(
190 )
191
192 // Providers groups units managing provider routing records
78 -var Providers = fx.Options(
79 - fx.Provide(ProviderQueue),
80 - fx.Provide(ProviderCtor),
81 - fx.Provide(ReproviderCtor),
193 +func Providers(cfg *config.Config) fx.Option {
194 + reproviderInterval := kReprovideFrequency
195 + if cfg.Reprovider.Interval != "" {
196 + dur, err := time.ParseDuration(cfg.Reprovider.Interval)
197 + if err != nil {
198 + return fx.Error(err)
199 + }
200 +
201 + reproviderInterval = dur
202 + }
203
83 - fx.Invoke(Reprovider),
84 -)
204 + var keyProvider fx.Option
205 + switch cfg.Reprovider.Strategy {
206 + case "all":
207 + fallthrough
208 + case "":
209 + keyProvider = fx.Provide(reprovide.NewBlockstoreProvider)
210 + case "roots":
211 + keyProvider = fx.Provide(reprovide.NewPinnedProvider(true))
212 + case "pinned":
213 + keyProvider = fx.Provide(reprovide.NewPinnedProvider(false))
214 + default:
215 + return fx.Error(fmt.Errorf("unknown reprovider strategy '%s'", cfg.Reprovider.Strategy))
216 + }
217 +
218 + return fx.Options(
219 + fx.Provide(ProviderQueue),
220 + fx.Provide(ProviderCtor),
221 + fx.Provide(ReproviderCtor(reproviderInterval)),
222 + keyProvider,
223 +
224 + fx.Invoke(Reprovider),
225 + )
226 +}
227
228 // Online groups online-only units
87 -func Online(cfg *BuildCfg) fx.Option {
229 +func Online(bcfg *BuildCfg, cfg *config.Config) fx.Option {
230 +
231 + // Namesys params
232 +
233 + ipnsCacheSize := cfg.Ipns.ResolveCacheSize
234 + if ipnsCacheSize == 0 {
235 + ipnsCacheSize = DefaultIpnsCacheSize
236 + }
237 + if ipnsCacheSize < 0 {
238 + return fx.Error(fmt.Errorf("cannot specify negative resolve cache size"))
239 + }
240 +
241 + // Republisher params
242 +
243 + var repubPeriod, recordLifetime time.Duration
244 +
245 + if cfg.Ipns.RepublishPeriod != "" {
246 + d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod)
247 + if err != nil {
248 + return fx.Error(fmt.Errorf("failure to parse config setting IPNS.RepublishPeriod: %s", err))
249 + }
250 +
251 + if !util.Debug && (d < time.Minute || d > (time.Hour*24)) {
252 + return fx.Error(fmt.Errorf("config setting IPNS.RepublishPeriod is not between 1min and 1day: %s", d))
253 + }
254 +
255 + repubPeriod = d
256 + }
257 +
258 + if cfg.Ipns.RecordLifetime != "" {
259 + d, err := time.ParseDuration(cfg.Ipns.RecordLifetime)
260 + if err != nil {
261 + return fx.Error(fmt.Errorf("failure to parse config setting IPNS.RecordLifetime: %s", err))
262 + }
263 +
264 + recordLifetime = d
265 + }
266 +
267 return fx.Options(
268 fx.Provide(OnlineExchange),
90 - fx.Provide(OnlineNamesys),
269 + fx.Provide(Namesys(ipnsCacheSize)),
270
92 - fx.Invoke(IpnsRepublisher),
271 + fx.Invoke(IpnsRepublisher(repubPeriod, recordLifetime)),
272
273 fx.Provide(p2p.New),
274
96 - LibP2P(cfg),
97 - Providers,
275 + LibP2P(bcfg, cfg),
276 + Providers(cfg),
277 )
278 }
279
280 // Offline groups offline alternatives to Online units
281 var Offline = fx.Options(
282 fx.Provide(offline.Exchange),
104 - fx.Provide(OfflineNamesys),
283 + fx.Provide(Namesys(0)),
284 fx.Provide(offroute.NewOfflineRouter),
285 fx.Provide(provider.NewOfflineProvider),
286 )
@@ -115,9 +294,9 @@ var Core = fx.Options(
294 fx.Provide(Files),
295 )
296
118 -func Networked(cfg *BuildCfg) fx.Option {
119 - if cfg.Online {
120 - return Online(cfg)
297 +func Networked(bcfg *BuildCfg, cfg *config.Config) fx.Option {
298 + if bcfg.Online {
299 + return Online(bcfg, cfg)
300 }
301 return Offline
302 }
@@ -136,20 +315,15 @@ func IPFS(ctx context.Context, bcfg *BuildCfg) fx.Option {
315 // TEMP: setting global sharding switch here
316 uio.UseHAMTSharding = cfg.Experimental.ShardingEnabled
317
139 -
140 -
141 -
142 -
143 -
318 return fx.Options(
319 bcfgOpts,
320
321 fx.Provide(baseProcess),
322
149 - Storage(bcfg),
150 - Identity,
323 + Storage(bcfg, cfg),
324 + Identity(cfg),
325 IPNS,
152 - Networked(bcfg),
326 + Networked(bcfg, cfg),
327
328 Core,
329 )
core/node/identity.go
+14 -35
@@ -1,50 +1,29 @@
1 package node
2
3 import (
4 - "errors"
4 "fmt"
5
7 - "github.com/ipfs/go-ipfs-config"
6 "github.com/libp2p/go-libp2p-crypto"
7 "github.com/libp2p/go-libp2p-peer"
8 )
9
12 -// PeerID loads peer identity form config
13 -func PeerID(cfg *config.Config) (peer.ID, error) {
14 - cid := cfg.Identity.PeerID
15 - if cid == "" {
16 - return "", errors.New("identity was not set in config (was 'ipfs init' run?)")
10 +func PeerID(id peer.ID) func() peer.ID {
11 + return func() peer.ID {
12 + return id
13 }
18 - if len(cid) == 0 {
19 - return "", errors.New("no peer ID in config! (was 'ipfs init' run?)")
20 - }
21 -
22 - id, err := peer.IDB58Decode(cid)
23 - if err != nil {
24 - return "", fmt.Errorf("peer ID invalid: %s", err)
25 - }
26 -
27 - return id, nil
14 }
15
16 // PrivateKey loads the private key from config
31 -func PrivateKey(cfg *config.Config, id peer.ID) (crypto.PrivKey, error) {
32 - if cfg.Identity.PrivKey == "" {
33 - return nil, nil
34 - }
35 -
36 - sk, err := cfg.Identity.DecodePrivateKey("passphrase todo!")
37 - if err != nil {
38 - return nil, err
39 - }
40 -
41 - id2, err := peer.IDFromPrivateKey(sk)
42 - if err != nil {
43 - return nil, err
44 - }
45 -
46 - if id2 != id {
47 - return nil, fmt.Errorf("private key in config does not match id: %s != %s", id, id2)
17 +func PrivateKey(sk crypto.PrivKey) func(id peer.ID) (crypto.PrivKey, error) {
18 + return func(id peer.ID) (crypto.PrivKey, error) {
19 + id2, err := peer.IDFromPrivateKey(sk)
20 + if err != nil {
21 + return nil, err
22 + }
23 +
24 + if id2 != id {
25 + return nil, fmt.Errorf("private key in config does not match id: %s != %s", id, id2)
26 + }
27 + return sk, nil
28 }
49 - return sk, nil
29 }
core/node/ipns.go
+16 -35
@@ -4,7 +4,6 @@ import (
4 "fmt"
5 "time"
6
7 - "github.com/ipfs/go-ipfs-config"
7 "github.com/ipfs/go-ipfs-util"
8 "github.com/ipfs/go-ipns"
9 "github.com/libp2p/go-libp2p-crypto"
@@ -27,49 +26,31 @@ func RecordValidator(ps peerstore.Peerstore) record.Validator {
26 }
27 }
28
30 -// OfflineNamesys creates namesys setup for offline operation
31 -func OfflineNamesys(rt routing.IpfsRouting, repo repo.Repo) (namesys.NameSystem, error) {
32 - return namesys.NewNameSystem(rt, repo.Datastore(), 0), nil
33 -}
34 -
35 -// OnlineNamesys createn new namesys setup for online operation
36 -func OnlineNamesys(rt routing.IpfsRouting, repo repo.Repo, cfg *config.Config) (namesys.NameSystem, error) {
37 - cs := cfg.Ipns.ResolveCacheSize
38 - if cs == 0 {
39 - cs = DefaultIpnsCacheSize
29 +// Namesys creates new name system
30 +func Namesys(cacheSize int) func(rt routing.IpfsRouting, repo repo.Repo) (namesys.NameSystem, error) {
31 + return func(rt routing.IpfsRouting, repo repo.Repo) (namesys.NameSystem, error) {
32 + return namesys.NewNameSystem(rt, repo.Datastore(), cacheSize), nil
33 }
41 - if cs < 0 {
42 - return nil, fmt.Errorf("cannot specify negative resolve cache size")
43 - }
44 - return namesys.NewNameSystem(rt, repo.Datastore(), cs), nil
34 }
35
36 // IpnsRepublisher runs new IPNS republisher service
48 -func IpnsRepublisher(lc lcProcess, cfg *config.Config, namesys namesys.NameSystem, repo repo.Repo, privKey crypto.PrivKey) error {
49 - repub := republisher.NewRepublisher(namesys, repo.Datastore(), privKey, repo.Keystore())
37 +func IpnsRepublisher(repubPeriod time.Duration, recordLifetime time.Duration) func(lcProcess, namesys.NameSystem, repo.Repo, crypto.PrivKey) error {
38 + return func(lc lcProcess, namesys namesys.NameSystem, repo repo.Repo, privKey crypto.PrivKey) error {
39 + repub := republisher.NewRepublisher(namesys, repo.Datastore(), privKey, repo.Keystore())
40
51 - if cfg.Ipns.RepublishPeriod != "" {
52 - d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod)
53 - if err != nil {
54 - return fmt.Errorf("failure to parse config setting IPNS.RepublishPeriod: %s", err)
55 - }
41 + if repubPeriod != 0 {
42 + if !util.Debug && (repubPeriod < time.Minute || repubPeriod > (time.Hour*24)) {
43 + return fmt.Errorf("config setting IPNS.RepublishPeriod is not between 1min and 1day: %s", repubPeriod)
44 + }
45
57 - if !util.Debug && (d < time.Minute || d > (time.Hour*24)) {
58 - return fmt.Errorf("config setting IPNS.RepublishPeriod is not between 1min and 1day: %s", d)
46 + repub.Interval = repubPeriod
47 }
48
61 - repub.Interval = d
62 - }
63 -
64 - if cfg.Ipns.RecordLifetime != "" {
65 - d, err := time.ParseDuration(cfg.Ipns.RecordLifetime)
66 - if err != nil {
67 - return fmt.Errorf("failure to parse config setting IPNS.RecordLifetime: %s", err)
49 + if recordLifetime != 0 {
50 + repub.RecordLifetime = recordLifetime
51 }
52
70 - repub.RecordLifetime = d
53 + lc.Append(repub.Run)
54 + return nil
55 }
72 -
73 - lc.Append(repub.Run)
74 - return nil
56 }
core/node/libp2p/discovery.go
+15 -14
@@ -4,12 +4,12 @@ import (
4 "context"
5 "time"
6
7 - "github.com/ipfs/go-ipfs-config"
8 - "github.com/ipfs/go-ipfs/core/node/helpers"
7 "github.com/libp2p/go-libp2p-host"
8 "github.com/libp2p/go-libp2p-peerstore"
9 "github.com/libp2p/go-libp2p/p2p/discovery"
10 "go.uber.org/fx"
11 +
12 + "github.com/ipfs/go-ipfs/core/node/helpers"
13 )
14
15 const discoveryConnTimeout = time.Second * 30
@@ -35,18 +35,19 @@ func DiscoveryHandler(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host)
35 }
36 }
37
38 -func SetupDiscovery(mctx helpers.MetricsCtx, lc fx.Lifecycle, cfg *config.Config, host host.Host, handler *discoveryHandler) error {
39 - if cfg.Discovery.MDNS.Enabled {
40 - mdns := cfg.Discovery.MDNS
41 - if mdns.Interval == 0 {
42 - mdns.Interval = 5
43 - }
44 - service, err := discovery.NewMdnsService(helpers.LifecycleCtx(mctx, lc), host, time.Duration(mdns.Interval)*time.Second, discovery.ServiceTag)
45 - if err != nil {
46 - log.Error("mdns error: ", err)
47 - return nil
38 +func SetupDiscovery(mdns bool, mdnsInterval int) func(helpers.MetricsCtx, fx.Lifecycle, host.Host, *discoveryHandler) error {
39 + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, handler *discoveryHandler) error {
40 + if mdns {
41 + if mdnsInterval == 0 {
42 + mdnsInterval = 5
43 + }
44 + service, err := discovery.NewMdnsService(helpers.LifecycleCtx(mctx, lc), host, time.Duration(mdnsInterval)*time.Second, discovery.ServiceTag)
45 + if err != nil {
46 + log.Error("mdns error: ", err)
47 + return nil
48 + }
49 + service.RegisterNotifee(handler)
50 }
49 - service.RegisterNotifee(handler)
51 + return nil
52 }
51 - return nil
53 }
core/node/libp2p/libp2p.go
+91 -138
@@ -11,7 +11,6 @@ import (
11 "time"
12
13 "github.com/ipfs/go-datastore"
14 - "github.com/ipfs/go-ipfs-config"
14 nilrouting "github.com/ipfs/go-ipfs-routing/none"
15 logging "github.com/ipfs/go-log"
16 "github.com/libp2p/go-libp2p"
@@ -25,7 +24,6 @@ import (
24 "github.com/libp2p/go-libp2p-metrics"
25 "github.com/libp2p/go-libp2p-peer"
26 "github.com/libp2p/go-libp2p-peerstore"
28 - "github.com/libp2p/go-libp2p-peerstore/pstoremem"
27 "github.com/libp2p/go-libp2p-pnet"
28 "github.com/libp2p/go-libp2p-pubsub"
29 "github.com/libp2p/go-libp2p-pubsub-router"
@@ -87,38 +85,30 @@ var DHTOption RoutingOption = constructDHTRouting
85 var DHTClientOption RoutingOption = constructClientDHTRouting
86 var NilRouterOption RoutingOption = nilrouting.ConstructNilRouting
87
90 -func Peerstore(id peer.ID, sk crypto.PrivKey) (peerstore.Peerstore, error) {
91 - ps := pstoremem.NewPeerstore()
92 -
93 - if sk != nil {
94 - if err := ps.AddPubKey(id, sk.GetPublic()); err != nil {
95 - return nil, err
96 - }
97 - if err := ps.AddPrivKey(id, sk); err != nil {
98 - return nil, err
99 - }
88 +func PstoreAddSelfKeys(id peer.ID, sk crypto.PrivKey, ps peerstore.Peerstore) error {
89 + if err := ps.AddPubKey(id, sk.GetPublic()); err != nil {
90 + return err
91 }
92
102 - return ps, nil
93 + return ps.AddPrivKey(id, sk)
94 }
95
105 -func AddrFilters(cfg *config.Config) (opts Libp2pOpts, err error) {
106 - for _, s := range cfg.Swarm.AddrFilters {
107 - f, err := mamask.NewMask(s)
108 - if err != nil {
109 - return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s)
96 +func AddrFilters(filters []string) func() (opts Libp2pOpts, err error) {
97 + return func() (opts Libp2pOpts, err error) {
98 + for _, s := range filters {
99 + f, err := mamask.NewMask(s)
100 + if err != nil {
101 + return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s)
102 + }
103 + opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f))
104 }
111 - opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f))
105 + return opts, nil
106 }
113 - return opts, nil
107 }
108
116 -func BandwidthCounter(cfg *config.Config) (opts Libp2pOpts, reporter metrics.Reporter) {
109 +func BandwidthCounter() (opts Libp2pOpts, reporter metrics.Reporter) {
110 reporter = metrics.NewBandwidthCounter()
118 -
119 - if !cfg.Swarm.DisableBandwidthMetrics {
120 - opts.Opts = append(opts.Opts, libp2p.BandwidthReporter(reporter))
121 - }
111 + opts.Opts = append(opts.Opts, libp2p.BandwidthReporter(reporter))
112 return opts, reporter
113 }
114
@@ -183,9 +173,9 @@ func PNetChecker(repo repo.Repo, ph host.Host, lc fx.Lifecycle) error {
173 return nil
174 }
175
186 -func makeAddrsFactory(cfg config.Addresses) (p2pbhost.AddrsFactory, error) {
176 +func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFactory, error) {
177 var annAddrs []ma.Multiaddr
188 - for _, addr := range cfg.Announce {
178 + for _, addr := range announce {
179 maddr, err := ma.NewMultiaddr(addr)
180 if err != nil {
181 return nil, err
@@ -195,7 +185,7 @@ func makeAddrsFactory(cfg config.Addresses) (p2pbhost.AddrsFactory, error) {
185
186 filters := mafilter.NewFilters()
187 noAnnAddrs := map[string]bool{}
198 - for _, addr := range cfg.NoAnnounce {
188 + for _, addr := range noAnnounce {
189 f, err := mamask.NewMask(addr)
190 if err == nil {
191 filters.AddDialFilter(f)
@@ -229,41 +219,23 @@ func makeAddrsFactory(cfg config.Addresses) (p2pbhost.AddrsFactory, error) {
219 }, nil
220 }
221
232 -func AddrsFactory(cfg *config.Config) (opts Libp2pOpts, err error) {
233 - addrsFactory, err := makeAddrsFactory(cfg.Addresses)
234 - if err != nil {
235 - return opts, err
222 +func AddrsFactory(announce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) {
223 + return func() (opts Libp2pOpts, err error) {
224 + addrsFactory, err := makeAddrsFactory(announce, noAnnounce)
225 + if err != nil {
226 + return opts, err
227 + }
228 + opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory))
229 + return
230 }
237 - opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory))
238 - return
231 }
232
241 -func ConnectionManager(cfg *config.Config) (opts Libp2pOpts, err error) {
242 - grace := config.DefaultConnMgrGracePeriod
243 - low := config.DefaultConnMgrHighWater
244 - high := config.DefaultConnMgrHighWater
245 -
246 - switch cfg.Swarm.ConnMgr.Type {
247 - case "":
248 - // 'default' value is the basic connection manager
233 +func ConnectionManager(low, high int, grace time.Duration) func() (opts Libp2pOpts, err error) {
234 + return func() (opts Libp2pOpts, err error) {
235 + cm := connmgr.NewConnManager(low, high, grace)
236 + opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm))
237 return
250 - case "none":
251 - return opts, nil
252 - case "basic":
253 - grace, err = time.ParseDuration(cfg.Swarm.ConnMgr.GracePeriod)
254 - if err != nil {
255 - return opts, fmt.Errorf("parsing Swarm.ConnMgr.GracePeriod: %s", err)
256 - }
257 -
258 - low = cfg.Swarm.ConnMgr.LowWater
259 - high = cfg.Swarm.ConnMgr.HighWater
260 - default:
261 - return opts, fmt.Errorf("unrecognized ConnMgr.Type: %q", cfg.Swarm.ConnMgr.Type)
238 }
263 -
264 - cm := connmgr.NewConnManager(low, high, grace)
265 - opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm))
266 - return
239 }
240
241 func makeSmuxTransportOption(mplexExp bool) libp2p.Option {
@@ -315,32 +287,29 @@ func SmuxTransport(mplex bool) func() (opts Libp2pOpts, err error) {
287 }
288 }
289
318 -func NatPortMap(cfg *config.Config) (opts Libp2pOpts, err error) {
319 - if !cfg.Swarm.DisableNatPortMap {
320 - opts.Opts = append(opts.Opts, libp2p.NATPortMap())
321 - }
290 +func NatPortMap() (opts Libp2pOpts, err error) {
291 + opts.Opts = append(opts.Opts, libp2p.NATPortMap())
292 return
293 }
294
325 -func Relay(cfg *config.Config) (opts Libp2pOpts, err error) {
326 - if cfg.Swarm.DisableRelay {
327 - // Enabled by default.
328 - opts.Opts = append(opts.Opts, libp2p.DisableRelay())
329 - } else {
330 - relayOpts := []relay.RelayOpt{relay.OptDiscovery}
331 - if cfg.Swarm.EnableRelayHop {
332 - relayOpts = append(relayOpts, relay.OptHop)
295 +func Relay(disable, enableHop bool) func() (opts Libp2pOpts, err error) {
296 + return func() (opts Libp2pOpts, err error) {
297 + if disable {
298 + // Enabled by default.
299 + opts.Opts = append(opts.Opts, libp2p.DisableRelay())
300 + } else {
301 + relayOpts := []relay.RelayOpt{relay.OptDiscovery}
302 + if enableHop {
303 + relayOpts = append(relayOpts, relay.OptHop)
304 + }
305 + opts.Opts = append(opts.Opts, libp2p.EnableRelay(relayOpts...))
306 }
334 - opts.Opts = append(opts.Opts, libp2p.EnableRelay(relayOpts...))
307 + return
308 }
336 - return
309 }
310
339 -func AutoRealy(cfg *config.Config) (opts Libp2pOpts, err error) {
340 - // enable autorelay
341 - if cfg.Swarm.EnableAutoRelay {
342 - opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay())
343 - }
311 +func AutoRealy() (opts Libp2pOpts, err error) {
312 + opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay())
313 return
314 }
315
@@ -349,14 +318,12 @@ func DefaultTransports() (opts Libp2pOpts, err error) {
318 return
319 }
320
352 -func QUIC(cfg *config.Config) (opts Libp2pOpts, err error) {
353 - if cfg.Experimental.QUIC {
354 - opts.Opts = append(opts.Opts, libp2p.Transport(libp2pquic.NewTransport))
355 - }
321 +func QUIC() (opts Libp2pOpts, err error) {
322 + opts.Opts = append(opts.Opts, libp2p.Transport(libp2pquic.NewTransport))
323 return
324 }
325
359 -func Security(enabled bool) interface{} {
326 +func Security(enabled, preferTLS bool) interface{} {
327 if !enabled {
328 return func() (opts Libp2pOpts) {
329 // TODO: shouldn't this be Errorf to guarantee visibility?
@@ -366,8 +333,8 @@ func Security(enabled bool) interface{} {
333 return opts
334 }
335 }
369 - return func(cfg *config.Config) (opts Libp2pOpts) {
370 - if cfg.Experimental.PreferTLS {
336 + return func() (opts Libp2pOpts) {
337 + if preferTLS {
338 opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(tls.ID, tls.New), libp2p.Security(secio.ID, secio.New)))
339 } else {
340 opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(secio.ID, secio.New), libp2p.Security(tls.ID, tls.New)))
@@ -524,58 +491,42 @@ func PubsubRouter(mctx helpers.MetricsCtx, lc fx.Lifecycle, in p2pPSRoutingIn) (
491 }, psRouter
492 }
493
527 -func AutoNATService(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, cfg *config.Config, host host.Host) error {
528 - if !cfg.Swarm.EnableAutoNATService {
529 - return nil
530 - }
494 +func AutoNATService(quic bool) func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error {
495 + return func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error {
496 + // collect private net option in case swarm.key is presented
497 + opts, _, err := PNet(repo)
498 + if err != nil {
499 + // swarm key exists but was failed to decode
500 + return err
501 + }
502
532 - // collect private net option in case swarm.key is presented
533 - opts, _, err := PNet(repo)
534 - if err != nil {
535 - // swarm key exists but was failed to decode
536 - return err
537 - }
503 + if quic {
504 + opts.Opts = append(opts.Opts, libp2p.DefaultTransports, libp2p.Transport(libp2pquic.NewTransport))
505 + }
506
539 - if cfg.Experimental.QUIC {
540 - opts.Opts = append(opts.Opts, libp2p.DefaultTransports, libp2p.Transport(libp2pquic.NewTransport))
507 + _, err = autonat.NewAutoNATService(helpers.LifecycleCtx(mctx, lc), host, opts.Opts...)
508 + return err
509 }
542 -
543 - _, err = autonat.NewAutoNATService(helpers.LifecycleCtx(mctx, lc), host, opts.Opts...)
544 - return err
510 }
511
547 -func Pubsub(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, cfg *config.Config) (service *pubsub.PubSub, err error) {
548 - var pubsubOptions []pubsub.Option
549 - if cfg.Pubsub.DisableSigning {
550 - pubsubOptions = append(pubsubOptions, pubsub.WithMessageSigning(false))
512 +func FloodSub(pubsubOptions ...pubsub.Option) interface{} {
513 + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) {
514 + return pubsub.NewFloodSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
515 }
516 +}
517
553 - if cfg.Pubsub.StrictSignatureVerification {
554 - pubsubOptions = append(pubsubOptions, pubsub.WithStrictSignatureVerification(true))
555 - }
556 -
557 - switch cfg.Pubsub.Router {
558 - case "":
559 - fallthrough
560 - case "floodsub":
561 - service, err = pubsub.NewFloodSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
562 -
563 - case "gossipsub":
564 - service, err = pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
565 -
566 - default:
567 - err = fmt.Errorf("Unknown pubsub router %s", cfg.Pubsub.Router)
518 +func GossipSub(pubsubOptions ...pubsub.Option) interface{} {
519 + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) {
520 + return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...)
521 }
569 -
570 - return service, err
522 }
523
573 -func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
524 +func listenAddresses(addresses []string) ([]ma.Multiaddr, error) {
525 var listen []ma.Multiaddr
575 - for _, addr := range cfg.Addresses.Swarm {
526 + for _, addr := range addresses {
527 maddr, err := ma.NewMultiaddr(addr)
528 if err != nil {
578 - return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", cfg.Addresses.Swarm)
529 + return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", addresses)
530 }
531 listen = append(listen, maddr)
532 }
@@ -583,22 +534,24 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
534 return listen, nil
535 }
536
586 -func StartListening(host host.Host, cfg *config.Config) error {
587 - listenAddrs, err := listenAddresses(cfg)
588 - if err != nil {
589 - return err
590 - }
537 +func StartListening(addresses []string) func(host host.Host) error {
538 + return func(host host.Host) error {
539 + listenAddrs, err := listenAddresses(addresses)
540 + if err != nil {
541 + return err
542 + }
543
592 - // Actually start listening:
593 - if err := host.Network().Listen(listenAddrs...); err != nil {
594 - return err
595 - }
544 + // Actually start listening:
545 + if err := host.Network().Listen(listenAddrs...); err != nil {
546 + return err
547 + }
548
597 - // list out our addresses
598 - addrs, err := host.Network().InterfaceListenAddresses()
599 - if err != nil {
600 - return err
549 + // list out our addresses
550 + addrs, err := host.Network().InterfaceListenAddresses()
551 + if err != nil {
552 + return err
553 + }
554 + log.Infof("Swarm listening at: %s", addrs)
555 + return nil
556 }
602 - log.Infof("Swarm listening at: %s", addrs)
603 - return nil
557 }
core/node/provider.go
+3 -29
@@ -2,16 +2,12 @@ package node
2
3 import (
4 "context"
5 - "fmt"
5 "time"
6
8 - "github.com/ipfs/go-ipfs-config"
9 - "github.com/ipfs/go-ipld-format"
7 "github.com/libp2p/go-libp2p-routing"
8 "go.uber.org/fx"
9
10 "github.com/ipfs/go-ipfs/core/node/helpers"
14 - "github.com/ipfs/go-ipfs/pin"
11 "github.com/ipfs/go-ipfs/provider"
12 "github.com/ipfs/go-ipfs/repo"
13 "github.com/ipfs/go-ipfs/reprovide"
@@ -42,32 +38,10 @@ func ProviderCtor(mctx helpers.MetricsCtx, lc fx.Lifecycle, queue *provider.Queu
38 }
39
40 // ReproviderCtor creates new reprovider
45 -func ReproviderCtor(mctx helpers.MetricsCtx, lc fx.Lifecycle, cfg *config.Config, bs BaseBlocks, ds format.DAGService, pinning pin.Pinner, rt routing.IpfsRouting) (*reprovide.Reprovider, error) {
46 - var keyProvider reprovide.KeyChanFunc
47 -
48 - reproviderInterval := kReprovideFrequency
49 - if cfg.Reprovider.Interval != "" {
50 - dur, err := time.ParseDuration(cfg.Reprovider.Interval)
51 - if err != nil {
52 - return nil, err
53 - }
54 -
55 - reproviderInterval = dur
56 - }
57 -
58 - switch cfg.Reprovider.Strategy {
59 - case "all":
60 - fallthrough
61 - case "":
62 - keyProvider = reprovide.NewBlockstoreProvider(bs)
63 - case "roots":
64 - keyProvider = reprovide.NewPinnedProvider(pinning, ds, true)
65 - case "pinned":
66 - keyProvider = reprovide.NewPinnedProvider(pinning, ds, false)
67 - default:
68 - return nil, fmt.Errorf("unknown reprovider strategy '%s'", cfg.Reprovider.Strategy)
41 +func ReproviderCtor(reproviderInterval time.Duration) func(helpers.MetricsCtx, fx.Lifecycle, routing.IpfsRouting, reprovide.KeyChanFunc) (*reprovide.Reprovider, error) {
42 + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, rt routing.IpfsRouting, keyProvider reprovide.KeyChanFunc) (*reprovide.Reprovider, error) {
43 + return reprovide.NewReprovider(helpers.LifecycleCtx(mctx, lc), reproviderInterval, rt, keyProvider), nil
44 }
70 - return reprovide.NewReprovider(helpers.LifecycleCtx(mctx, lc), reproviderInterval, rt, keyProvider), nil
45 }
46
47 // Reprovider runs the reprovider service
core/node/storage.go
+18 -17
@@ -42,8 +42,8 @@ func Datastore(repo repo.Repo) datastore.Datastore {
42 type BaseBlocks blockstore.Blockstore
43
44 // BaseBlockstoreCtor creates cached blockstore backed by the provided datastore
45 -func BaseBlockstoreCtor(permanent bool, nilRepo bool) func(mctx helpers.MetricsCtx, repo repo.Repo, cfg *config.Config, lc fx.Lifecycle) (bs BaseBlocks, err error) {
46 - return func(mctx helpers.MetricsCtx, repo repo.Repo, cfg *config.Config, lc fx.Lifecycle) (bs BaseBlocks, err error) {
45 +func BaseBlockstoreCtor(cacheOpts blockstore.CacheOpts, nilRepo bool, hashOnRead bool) func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) {
46 + return func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) {
47 rds := &retrystore.Datastore{
48 Batching: repo.Datastore(),
49 Delay: time.Millisecond * 200,
@@ -54,12 +54,6 @@ func BaseBlockstoreCtor(permanent bool, nilRepo bool) func(mctx helpers.MetricsC
54 bs = blockstore.NewBlockstore(rds)
55 bs = &verifbs.VerifBS{Blockstore: bs}
56
57 - opts := blockstore.DefaultCacheOpts()
58 - opts.HasBloomFilterSize = cfg.Datastore.BloomFilterSize
59 - if !permanent {
60 - opts.HasBloomFilterSize = 0
61 - }
62 -
57 if !nilRepo {
58 ctx, cancel := context.WithCancel(mctx)
59
@@ -69,7 +63,7 @@ func BaseBlockstoreCtor(permanent bool, nilRepo bool) func(mctx helpers.MetricsC
63 return nil
64 },
65 })
72 - bs, err = blockstore.CachedBlockstore(ctx, bs, opts)
66 + bs, err = blockstore.CachedBlockstore(ctx, bs, cacheOpts)
67 if err != nil {
68 return nil, err
69 }
@@ -78,7 +72,7 @@ func BaseBlockstoreCtor(permanent bool, nilRepo bool) func(mctx helpers.MetricsC
72 bs = blockstore.NewIdStore(bs)
73 bs = cidv0v1.NewBlockstore(bs)
74
81 - if cfg.Datastore.HashOnRead { // TODO: review: this is how it was done originally, is there a reason we can't just pass this directly?
75 + if hashOnRead { // TODO: review: this is how it was done originally, is there a reason we can't just pass this directly?
76 bs.HashOnRead(true)
77 }
78
@@ -87,16 +81,23 @@ func BaseBlockstoreCtor(permanent bool, nilRepo bool) func(mctx helpers.MetricsC
81 }
82
83 // GcBlockstoreCtor wraps the base blockstore with GC and Filestore layers
90 -func GcBlockstoreCtor(repo repo.Repo, bb BaseBlocks, cfg *config.Config) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) {
84 +func GcBlockstoreCtor(bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore) {
85 gclocker = blockstore.NewGCLocker()
86 gcbs = blockstore.NewGCBlockstore(bb, gclocker)
87
94 - if cfg.Experimental.FilestoreEnabled || cfg.Experimental.UrlstoreEnabled {
95 - // hash security
96 - fstore = filestore.NewFilestore(bb, repo.FileManager()) // TODO: mark optional
97 - gcbs = blockstore.NewGCBlockstore(fstore, gclocker)
98 - gcbs = &verifbs.VerifBSGC{GCBlockstore: gcbs}
99 - }
88 + bs = gcbs
89 + return
90 +}
91 +
92 +// GcBlockstoreCtor wraps GcBlockstore and adds Filestore support
93 +func FilestoreBlockstoreCtor(repo repo.Repo, bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) {
94 + gclocker, gcbs, bs = GcBlockstoreCtor(bb)
95 +
96 + // hash security
97 + fstore = filestore.NewFilestore(bb, repo.FileManager())
98 + gcbs = blockstore.NewGCBlockstore(fstore, gclocker)
99 + gcbs = &verifbs.VerifBSGC{GCBlockstore: gcbs}
100 +
101 bs = gcbs
102 return
103 }
reprovide/providers.go
+19 -17
@@ -20,27 +20,29 @@ func NewBlockstoreProvider(bstore blocks.Blockstore) KeyChanFunc {
20 }
21
22 // NewPinnedProvider returns provider supplying pinned keys
23 -func NewPinnedProvider(pinning pin.Pinner, dag ipld.DAGService, onlyRoots bool) KeyChanFunc {
24 - return func(ctx context.Context) (<-chan cid.Cid, error) {
25 - set, err := pinSet(ctx, pinning, dag, onlyRoots)
26 - if err != nil {
27 - return nil, err
28 - }
23 +func NewPinnedProvider(onlyRoots bool) func(pinning pin.Pinner, dag ipld.DAGService) KeyChanFunc {
24 + return func(pinning pin.Pinner, dag ipld.DAGService) KeyChanFunc {
25 + return func(ctx context.Context) (<-chan cid.Cid, error) {
26 + set, err := pinSet(ctx, pinning, dag, onlyRoots)
27 + if err != nil {
28 + return nil, err
29 + }
30
30 - outCh := make(chan cid.Cid)
31 - go func() {
32 - defer close(outCh)
33 - for c := range set.New {
34 - select {
35 - case <-ctx.Done():
36 - return
37 - case outCh <- c:
31 + outCh := make(chan cid.Cid)
32 + go func() {
33 + defer close(outCh)
34 + for c := range set.New {
35 + select {
36 + case <-ctx.Done():
37 + return
38 + case outCh <- c:
39 + }
40 }
39 - }
41
41 - }()
42 + }()
43
43 - return outCh, nil
44 + return outCh, nil
45 + }
46 }
47 }
48