@cryptotaxi247 / kubo / commits / 1fa14335b

core: rearranged initialization a bit

Juan Batiz-Benet committed Jan 2, 2015 at 05:40 UTC 1fa14335b95c622fa0347f92a3a4da78d225ab54
2 files changed +104 -75
core/core.go
+100 -75
@@ -57,6 +57,7 @@ type IpfsNode struct {
57 PeerHost p2phost.Host // the network host (server+client)
58 Routing routing.IpfsRouting // the routing system. recommend ipfs-dht
59 Exchange exchange.Interface // the block exchange + strategy (bitswap)
60 + Blockstore bstore.Blockstore // the block store (lower level)
61 Blocks *bserv.BlockService // the block service, get/add blocks.
62 DAG merkledag.DAGService // the merkle dag service, get/add objects.
63 Resolver *path.Resolver // the path resolution system
@@ -94,87 +95,39 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
95 n.ContextGroup = ctxgroup.WithContextAndTeardown(ctx, n.teardown)
96 ctx = n.ContextGroup.Context()
97
98 + // setup Peerstore
99 + n.Peerstore = peer.NewPeerstore()
100 +
101 // setup datastore.
102 if n.Datastore, err = makeDatastore(cfg.Datastore); err != nil {
103 return nil, debugerror.Wrap(err)
104 }
105
102 - // setup local peer identity
103 - n.Identity, n.PrivateKey, err = initIdentity(&n.Config.Identity, online)
104 - if err != nil {
105 - return nil, debugerror.Wrap(err)
106 + // setup local peer ID (private key is loaded in online setup)
107 + if err := n.loadID(); err != nil {
108 + return nil, err
109 }
110
108 - // setup Peerstore
109 - n.Peerstore = peer.NewPeerstore()
110 - if n.PrivateKey != nil {
111 - n.Peerstore.AddPrivKey(n.Identity, n.PrivateKey)
111 + n.Blockstore, err = bstore.WriteCached(bstore.NewBlockstore(n.Datastore), kSizeBlockstoreWriteCache)
112 + if err != nil {
113 + return nil, debugerror.Wrap(err)
114 }
115
114 - blockstore, err := bstore.WriteCached(bstore.NewBlockstore(n.Datastore), kSizeBlockstoreWriteCache)
115 - n.Exchange = offline.Exchange(blockstore)
116 -
116 // setup online services
117 if online {
119 -
120 - // setup the network
121 - listenAddrs, err := listenAddresses(cfg)
122 - if err != nil {
123 - return nil, debugerror.Wrap(err)
124 - }
125 -
126 - network, err := swarm.NewNetwork(ctx, listenAddrs, n.Identity, n.Peerstore)
127 - if err != nil {
128 - return nil, debugerror.Wrap(err)
129 - }
130 - n.AddChildGroup(network.CtxGroup())
131 - n.PeerHost = p2pbhost.New(network)
132 -
133 - // explicitly set these as our listen addrs.
134 - // (why not do it inside inet.NewNetwork? because this way we can
135 - // listen on addresses without necessarily advertising those publicly.)
136 - addrs, err := n.PeerHost.Network().InterfaceListenAddresses()
137 - if err != nil {
138 - return nil, debugerror.Wrap(err)
118 + if err := n.StartOnlineServices(); err != nil {
119 + return nil, err // debugerror.Wraps.
120 }
140 -
141 - n.Peerstore.AddAddresses(n.Identity, addrs)
142 -
143 - // setup diagnostics service
144 - n.Diagnostics = diag.NewDiagnostics(n.Identity, n.PeerHost)
145 -
146 - // setup routing service
147 - dhtRouting := dht.NewDHT(ctx, n.PeerHost, n.Datastore)
148 - dhtRouting.Validators[IpnsValidatorTag] = namesys.ValidateIpnsRecord
149 -
150 - // TODO(brian): perform this inside NewDHT factory method
151 - n.Routing = dhtRouting
152 - n.AddChildGroup(dhtRouting)
153 -
154 - // setup exchange service
155 - const alwaysSendToPeer = true // use YesManStrategy
156 - bitswapNetwork := bsnet.NewFromIpfsHost(n.PeerHost, n.Routing)
157 -
158 - n.Exchange = bitswap.New(ctx, n.Identity, bitswapNetwork, blockstore, alwaysSendToPeer)
159 -
160 - // TODO consider moving connection supervision into the Network. We've
161 - // discussed improvements to this Node constructor. One improvement
162 - // would be to make the node configurable, allowing clients to inject
163 - // an Exchange, Network, or Routing component and have the constructor
164 - // manage the wiring. In that scenario, this dangling function is a bit
165 - // awkward.
166 - go superviseConnections(ctx, n.PeerHost, dhtRouting, n.Peerstore, n.Config.Bootstrap)
121 + } else {
122 + n.Exchange = offline.Exchange(n.Blockstore)
123 }
124
169 - // TODO(brian): when offline instantiate the BlockService with a bitswap
170 - // session that simply doesn't return blocks
171 - n.Blocks, err = bserv.New(blockstore, n.Exchange)
125 + n.Blocks, err = bserv.New(n.Blockstore, n.Exchange)
126 if err != nil {
127 return nil, debugerror.Wrap(err)
128 }
129
130 n.DAG = merkledag.NewDAGService(n.Blocks)
177 - n.Namesys = namesys.NewNameSystem(n.Routing)
131 n.Pinning, err = pin.LoadPinner(n.Datastore, n.DAG)
132 if err != nil {
133 n.Pinning = pin.NewPinner(n.Datastore, n.DAG)
@@ -185,6 +138,67 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
138 return n, nil
139 }
140
141 +func (n *IpfsNode) StartOnlineServices() error {
142 + ctx := n.Context()
143 +
144 + if n.PeerHost != nil { // already online.
145 + return debugerror.New("node already online")
146 + }
147 +
148 + // load private key
149 + if err := n.loadPrivateKey(); err != nil {
150 + return err
151 + }
152 +
153 + // setup the network
154 + listenAddrs, err := listenAddresses(n.Config)
155 + if err != nil {
156 + return debugerror.Wrap(err)
157 + }
158 + network, err := swarm.NewNetwork(ctx, listenAddrs, n.Identity, n.Peerstore)
159 + if err != nil {
160 + return debugerror.Wrap(err)
161 + }
162 + n.AddChildGroup(network.CtxGroup())
163 + n.PeerHost = p2pbhost.New(network)
164 +
165 + // explicitly set these as our listen addrs.
166 + // (why not do it inside inet.NewNetwork? because this way we can
167 + // listen on addresses without necessarily advertising those publicly.)
168 + addrs, err := n.PeerHost.Network().InterfaceListenAddresses()
169 + if err != nil {
170 + return debugerror.Wrap(err)
171 + }
172 + n.Peerstore.AddAddresses(n.Identity, addrs)
173 +
174 + // setup diagnostics service
175 + n.Diagnostics = diag.NewDiagnostics(n.Identity, n.PeerHost)
176 +
177 + // setup routing service
178 + dhtRouting := dht.NewDHT(ctx, n.PeerHost, n.Datastore)
179 + dhtRouting.Validators[IpnsValidatorTag] = namesys.ValidateIpnsRecord
180 + n.Routing = dhtRouting
181 + n.AddChildGroup(dhtRouting)
182 +
183 + // setup exchange service
184 + const alwaysSendToPeer = true // use YesManStrategy
185 + bitswapNetwork := bsnet.NewFromIpfsHost(n.PeerHost, n.Routing)
186 + n.Exchange = bitswap.New(ctx, n.Identity, bitswapNetwork, n.Blockstore, alwaysSendToPeer)
187 +
188 + // setup name system
189 + // TODO implement an offline namesys that serves only local names.
190 + n.Namesys = namesys.NewNameSystem(n.Routing)
191 +
192 + // TODO consider moving connection supervision into the Network. We've
193 + // discussed improvements to this Node constructor. One improvement
194 + // would be to make the node configurable, allowing clients to inject
195 + // an Exchange, Network, or Routing component and have the constructor
196 + // manage the wiring. In that scenario, this dangling function is a bit
197 + // awkward.
198 + go superviseConnections(ctx, n.PeerHost, dhtRouting, n.Peerstore, n.Config.Bootstrap)
199 + return nil
200 +}
201 +
202 func (n *IpfsNode) teardown() error {
203 if err := n.Datastore.Close(); err != nil {
204 return err
@@ -196,29 +210,40 @@ func (n *IpfsNode) OnlineMode() bool {
210 return n.onlineMode
211 }
212
199 -func initIdentity(cfg *config.Identity, online bool) (peer.ID, ic.PrivKey, error) {
200 -
201 - if cfg.PeerID == "" {
202 - return "", nil, debugerror.New("Identity was not set in config (was ipfs init run?)")
213 +func (n *IpfsNode) loadID() error {
214 + if n.Identity != "" {
215 + return debugerror.New("identity already loaded")
216 }
217
205 - if len(cfg.PeerID) == 0 {
206 - return "", nil, debugerror.New("No peer ID in config! (was ipfs init run?)")
218 + cid := n.Config.Identity.PeerID
219 + if cid == "" {
220 + return debugerror.New("Identity was not set in config (was ipfs init run?)")
221 + }
222 + if len(cid) == 0 {
223 + return debugerror.New("No peer ID in config! (was ipfs init run?)")
224 }
225
209 - id := peer.ID(b58.Decode(cfg.PeerID))
226 + n.Identity = peer.ID(b58.Decode(cid))
227 + return nil
228 +}
229
211 - // when not online, don't need to parse private keys (yet)
212 - if !online {
213 - return id, nil, nil
230 +func (n *IpfsNode) loadPrivateKey() error {
231 + if n.Identity == "" || n.Peerstore == nil {
232 + return debugerror.New("loaded private key out of order.")
233 }
234
216 - sk, err := loadPrivateKey(cfg, id)
235 + if n.PrivateKey != nil {
236 + return debugerror.New("private key already loaded")
237 + }
238 +
239 + sk, err := loadPrivateKey(&n.Config.Identity, n.Identity)
240 if err != nil {
218 - return "", nil, err
241 + return err
242 }
243
221 - return id, sk, nil
244 + n.PrivateKey = sk
245 + n.Peerstore.AddPrivKey(n.Identity, n.PrivateKey)
246 + return nil
247 }
248
249 func loadPrivateKey(cfg *config.Identity, id peer.ID) (ic.PrivKey, error) {
namesys/routing.go
+4
@@ -23,6 +23,10 @@ type routingResolver struct {
23 // NewRoutingResolver constructs a name resolver using the IPFS Routing system
24 // to implement SFS-like naming on top.
25 func NewRoutingResolver(route routing.IpfsRouting) Resolver {
26 + if route == nil {
27 + panic("attempt to create resolver with nil routing system")
28 + }
29 +
30 return &routingResolver{routing: route}
31 }
32