core: call dht bootstrap
Juan Batiz-Benet committed
Jan 18, 2015 at 00:56 UTC
ec848c486b5f8fd45e20983a1b0767558103922b
2 files changed
+53
-35
core/bootstrap.go
+12
-11
@@ -31,6 +31,8 @@ func superviseConnections(parent context.Context,
31
store peer.Peerstore,
32
peers []peer.PeerInfo) error {
33
34
+ var dhtAlreadyBootstrapping bool
35
+
36
for {
37
ctx, _ := context.WithTimeout(parent, connectiontimeout)
38
// TODO get config from disk so |peers| always reflects the latest
@@ -38,6 +40,14 @@ func superviseConnections(parent context.Context,
40
if err := bootstrap(ctx, h, route, store, peers); err != nil {
41
log.Error(err)
42
}
43
+
44
+ if !dhtAlreadyBootstrapping {
45
+ dhtAlreadyBootstrapping = true // only call dht.Bootstrap once.
46
+ if _, err := route.Bootstrap(); err != nil {
47
+ log.Error(err)
48
+ }
49
+ }
50
+
51
select {
52
case <-parent.Done():
53
return parent.Err()
@@ -56,7 +66,7 @@ func bootstrap(ctx context.Context,
66
connectedPeers := h.Network().Peers()
67
if len(connectedPeers) >= recoveryThreshold {
68
log.Event(ctx, "bootstrapSkip", h.ID())
59
- log.Debugf("%s bootstrap skipped -- connected to %d (> %d) nodes",
69
+ log.Debugf("%s core bootstrap skipped -- connected to %d (> %d) nodes",
70
h.ID(), len(connectedPeers), recoveryThreshold)
71
72
return nil
@@ -64,7 +74,7 @@ func bootstrap(ctx context.Context,
74
numCxnsToCreate := recoveryThreshold - len(connectedPeers)
75
76
log.Event(ctx, "bootstrapStart", h.ID())
67
- log.Debugf("%s bootstrapping to %d more nodes", h.ID(), numCxnsToCreate)
77
+ log.Debugf("%s core bootstrapping to %d more nodes", h.ID(), numCxnsToCreate)
78
79
var notConnected []peer.PeerInfo
80
for _, p := range bootstrapPeers {
@@ -83,15 +93,6 @@ func bootstrap(ctx context.Context,
93
return err
94
}
95
}
86
-
87
- // we can try running dht bootstrap even if we're connected to all bootstrap peers.
88
- if len(h.Network().Conns()) > 0 {
89
- if _, err := r.Bootstrap(); err != nil {
90
- // log this as Info. later on, discern better between errors.
91
- log.Infof("dht bootstrap err: %s", err)
92
- return nil
93
- }
94
- }
96
return nil
97
}
98
core/core.go
+41
-24
@@ -235,29 +235,17 @@ func (n *IpfsNode) StartOnlineServices(ctx context.Context) error {
235
// TODO implement an offline namesys that serves only local names.
236
n.Namesys = namesys.NewNameSystem(n.Routing)
237
238
- // TODO consider moving connection supervision into the Network. We've
239
- // discussed improvements to this Node constructor. One improvement
240
- // would be to make the node configurable, allowing clients to inject
241
- // an Exchange, Network, or Routing component and have the constructor
242
- // manage the wiring. In that scenario, this dangling function is a bit
243
- // awkward.
244
- var bootstrapPeers []peer.PeerInfo
245
- for _, bootstrap := range n.Repo.Config().Bootstrap {
246
- p, err := toPeer(bootstrap)
247
- if err != nil {
248
- log.Event(ctx, "bootstrapError", n.Identity, lgbl.Error(err))
249
- log.Errorf("%s bootstrap error: %s", n.Identity, err)
250
- return err
251
- }
252
- bootstrapPeers = append(bootstrapPeers, p)
253
- }
254
-
255
- go superviseConnections(ctx, n.PeerHost, dhtRouting, n.Peerstore, bootstrapPeers)
256
-
238
n.Reprovider = rp.NewReprovider(n.Routing, n.Blockstore)
239
go n.Reprovider.ProvideEvery(ctx, kReprovideFrequency)
240
260
- return nil
241
+ // prepare bootstrap peers from config
242
+ bpeers, err := n.loadBootstrapPeers()
243
+ if err != nil {
244
+ log.Event(ctx, "bootstrapError", n.Identity, lgbl.Error(err))
245
+ log.Errorf("%s bootstrap error: %s", n.Identity, err)
246
+ return debugerror.Wrap(err)
247
+ }
248
+ return n.Bootstrap(ctx, bpeers)
249
}
250
251
// teardown closes owned children. If any errors occur, this function returns
@@ -310,11 +298,28 @@ func (n *IpfsNode) Bootstrap(ctx context.Context, peers []peer.PeerInfo) error {
298
299
// TODO what should return value be when in offlineMode?
300
313
- if n.Routing != nil {
314
- if dht, ok := n.Routing.(*dht.IpfsDHT); ok {
315
- return bootstrap(ctx, n.PeerHost, dht, n.Peerstore, peers)
316
- }
301
+ if n.Routing == nil {
302
+ return nil
303
+ }
304
+
305
+ // TODO what bootstrapping should happen if there is no DHT? i.e. we could
306
+ // continue connecting to our bootstrap peers, but for what purpose?
307
+ dhtRouting, ok := n.Routing.(*dht.IpfsDHT)
308
+ if !ok {
309
+ return nil
310
}
311
+
312
+ // TODO consider moving connection supervision into the Network. We've
313
+ // discussed improvements to this Node constructor. One improvement
314
+ // would be to make the node configurable, allowing clients to inject
315
+ // an Exchange, Network, or Routing component and have the constructor
316
+ // manage the wiring. In that scenario, this dangling function is a bit
317
+ // awkward.
318
+
319
+ // spin off the node's connection supervisor.
320
+ // TODO, clean up how this thing works. Make the superviseConnections thing
321
+ // work like the DHT.Bootstrap.
322
+ go superviseConnections(ctx, n.PeerHost, dhtRouting, n.Peerstore, peers)
323
return nil
324
}
325
@@ -355,6 +360,18 @@ func (n *IpfsNode) loadPrivateKey() error {
360
return nil
361
}
362
363
+func (n *IpfsNode) loadBootstrapPeers() ([]peer.PeerInfo, error) {
364
+ var peers []peer.PeerInfo
365
+ for _, bootstrap := range n.Repo.Config().Bootstrap {
366
+ p, err := toPeer(bootstrap)
367
+ if err != nil {
368
+ return nil, err
369
+ }
370
+ peers = append(peers, p)
371
+ }
372
+ return peers, nil
373
+}
374
+
375
// SetupOfflineRouting loads the local nodes private key and
376
// uses it to instantiate a routing system in offline mode.
377
// This is primarily used for offline ipns modifications.