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