@cryptotaxi247 / kubo / commits / cc8ed14e7

bootstrap: update bootstrapping process.

Note: the dht-specific part of the bootstrap function was only there to make sure to call `dht.Update(ctx, npeer)`. This already happens on all new connections made by the network, as the dht is signed up for notifications.

Juan Batiz-Benet committed Feb 5, 2015 at 07:53 UTC cc8ed14e7a3b012ef7e08682529240953662a0e9
2 files changed +40 -40
core/bootstrap.go
+15 -34
@@ -4,7 +4,6 @@ import (
4 "errors"
5 "fmt"
6 "io"
7 - "io/ioutil"
7 "math/rand"
8 "sync"
9 "time"
@@ -13,7 +12,6 @@ import (
12 inet "github.com/jbenet/go-ipfs/p2p/net"
13 peer "github.com/jbenet/go-ipfs/p2p/peer"
14 config "github.com/jbenet/go-ipfs/repo/config"
16 - dht "github.com/jbenet/go-ipfs/routing/dht"
15 math2 "github.com/jbenet/go-ipfs/thirdparty/math2"
16 lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
17
@@ -76,15 +74,6 @@ func BootstrapConfigWithPeers(pis []peer.PeerInfo) BootstrapConfig {
74 // bootstrapping (i.e. routing).
75 func Bootstrap(n *IpfsNode, cfg BootstrapConfig) (io.Closer, error) {
76
79 - // TODO what bootstrapping should happen if there is no DHT? i.e. we could
80 - // continue connecting to our bootstrap peers, but for what purpose? for now
81 - // simply exit without connecting to any of them. When we introduce another
82 - // routing system that uses bootstrap peers we can change this.
83 - thedht, ok := n.Routing.(*dht.IpfsDHT)
84 - if !ok {
85 - return ioutil.NopCloser(nil), nil
86 - }
87 -
77 // make a signal to wait for one bootstrap round to complete.
78 doneWithRound := make(chan struct{})
79
@@ -93,7 +82,7 @@ func Bootstrap(n *IpfsNode, cfg BootstrapConfig) (io.Closer, error) {
82 ctx := procctx.WithProcessClosing(context.Background(), worker)
83 defer log.EventBegin(ctx, "periodicBootstrap", n.Identity).Done()
84
96 - if err := bootstrapRound(ctx, n.PeerHost, thedht, n.Peerstore, cfg); err != nil {
85 + if err := bootstrapRound(ctx, n.PeerHost, cfg); err != nil {
86 log.Event(ctx, "bootstrapError", n.Identity, lgbl.Error(err))
87 log.Debugf("%s bootstrap error: %s", n.Identity, err)
88 }
@@ -105,25 +94,21 @@ func Bootstrap(n *IpfsNode, cfg BootstrapConfig) (io.Closer, error) {
94 proc := periodicproc.Tick(cfg.Period, periodic)
95 proc.Go(periodic) // run one right now.
96
108 - // kick off dht bootstrapping.
109 - dbproc, err := thedht.BootstrapWithConfig(dht.DefaultBootstrapConfig)
110 - if err != nil {
111 - proc.Close()
112 - return nil, err
97 + // kick off Routing.Bootstrap
98 + if n.Routing != nil {
99 + ctx := procctx.WithProcessClosing(context.Background(), proc)
100 + if err := n.Routing.Bootstrap(ctx); err != nil {
101 + proc.Close()
102 + return nil, err
103 + }
104 }
105
115 - // add dht bootstrap proc as a child, so it is closed automatically when we are.
116 - proc.AddChild(dbproc)
106 doneWithRound <- struct{}{}
107 close(doneWithRound) // it no longer blocks periodic
108 return proc, nil
109 }
110
122 -func bootstrapRound(ctx context.Context,
123 - host host.Host,
124 - route *dht.IpfsDHT,
125 - peerstore peer.Peerstore,
126 - cfg BootstrapConfig) error {
111 +func bootstrapRound(ctx context.Context, host host.Host, cfg BootstrapConfig) error {
112
113 ctx, _ = context.WithTimeout(ctx, cfg.ConnectionTimeout)
114 id := host.ID()
@@ -161,16 +146,13 @@ func bootstrapRound(ctx context.Context,
146
147 defer log.EventBegin(ctx, "bootstrapStart", id).Done()
148 log.Debugf("%s bootstrapping to %d nodes: %s", id, numToDial, randSubset)
164 - if err := bootstrapConnect(ctx, peerstore, route, randSubset); err != nil {
149 + if err := bootstrapConnect(ctx, host, randSubset); err != nil {
150 return err
151 }
152 return nil
153 }
154
170 -func bootstrapConnect(ctx context.Context,
171 - ps peer.Peerstore,
172 - route *dht.IpfsDHT,
173 - peers []peer.PeerInfo) error {
155 +func bootstrapConnect(ctx context.Context, ph host.Host, peers []peer.PeerInfo) error {
156 if len(peers) < 1 {
157 return ErrNotEnoughBootstrapPeers
158 }
@@ -187,12 +169,11 @@ func bootstrapConnect(ctx context.Context,
169 wg.Add(1)
170 go func(p peer.PeerInfo) {
171 defer wg.Done()
190 - defer log.EventBegin(ctx, "bootstrapDial", route.LocalPeer(), p.ID).Done()
191 - log.Debugf("%s bootstrapping to %s", route.LocalPeer(), p.ID)
172 + defer log.EventBegin(ctx, "bootstrapDial", ph.ID(), p.ID).Done()
173 + log.Debugf("%s bootstrapping to %s", ph.ID(), p.ID)
174
193 - ps.AddAddrs(p.ID, p.Addrs, peer.PermanentAddrTTL)
194 - err := route.Connect(ctx, p.ID)
195 - if err != nil {
175 + ph.Peerstore().AddAddrs(p.ID, p.Addrs, peer.PermanentAddrTTL)
176 + if err := ph.Connect(ctx, p); err != nil {
177 log.Event(ctx, "bootstrapDialFailed", p.ID)
178 log.Debugf("failed to bootstrap with %v: %s", p.ID, err)
179 errs <- err
routing/dht/dht_bootstrap.go
+25 -6
@@ -4,7 +4,6 @@ package dht
4
5 import (
6 "crypto/rand"
7 - "errors"
7 "fmt"
8 "sync"
9 "time"
@@ -45,17 +44,37 @@ var DefaultBootstrapConfig = BootstrapConfig{
44 Timeout: time.Duration(20 * time.Second),
45 }
46
48 -func (dht *IpfsDHT) Bootstrap(context.Context) error {
49 - // Bootstrap satisfies the routing interface
50 - return errors.New("TODO: perform DHT bootstrap")
47 +// Bootstrap ensures the dht routing table remains healthy as peers come and go.
48 +// it builds up a list of peers by requesting random peer IDs. The Bootstrap
49 +// process will run a number of queries each time, and run every time signal fires.
50 +// These parameters are configurable.
51 +//
52 +// As opposed to BootstrapWithConfig, Bootstrap satisfies the routing interface
53 +func (dht *IpfsDHT) Bootstrap(ctx context.Context) error {
54 + proc, err := dht.BootstrapWithConfig(DefaultBootstrapConfig)
55 + if err != nil {
56 + return err
57 + }
58 +
59 + // wait till ctx or dht.Context exits.
60 + // we have to do it this way to satisfy the Routing interface (contexts)
61 + go func() {
62 + defer proc.Close()
63 + select {
64 + case <-ctx.Done():
65 + case <-dht.Context().Done():
66 + }
67 + }()
68 +
69 + return nil
70 }
71
53 -// Bootstrap ensures the dht routing table remains healthy as peers come and go.
72 +// BootstrapWithConfig ensures the dht routing table remains healthy as peers come and go.
73 // it builds up a list of peers by requesting random peer IDs. The Bootstrap
74 // process will run a number of queries each time, and run every time signal fires.
75 // These parameters are configurable.
76 //
58 -// Bootstrap returns a process, so the user can stop it.
77 +// BootstrapWithConfig returns a process, so the user can stop it.
78 func (dht *IpfsDHT) BootstrapWithConfig(config BootstrapConfig) (goprocess.Process, error) {
79 sig := time.Tick(config.Period)
80 return dht.BootstrapOnSignal(config, sig)