精通IPFS | IPFS 启动之 start 函数
-
首先,设置默认选项。
const libp2pDefaults = { datastore, peerInfo, peerBook, config: { peerDiscovery: { mdns: { enabled: get(options, 'config.Discovery.MDNS.Enabled', get(config, 'Discovery.MDNS.Enabled', true)) }, webRTCStar: { enabled: get(options, 'config.Discovery.webRTCStar.Enabled', get(config, 'Discovery.webRTCStar.Enabled', true)) }, bootstrap: { list: get(options, 'config.Bootstrap', get(config, 'Bootstrap', [])) } }, relay: { enabled: get(options, 'relay.enabled', get(config, 'relay.enabled', true)), hop: { enabled: get(options, 'relay.hop.enabled', get(config, 'relay.hop.enabled', false)), active: get(options, 'relay.hop.active', get(config, 'relay.hop.active', false)) } }, dht: { kBucketSize: get(options, 'dht.kBucketSize', 20), enabled: false, randomWalk: { enabled: false // disabled waiting for https://github.com/libp2p/js-libp2p-kad-dht/issues/86 }, validators: { ipns: ipnsUtils.validator }, selectors: { ipns: ipnsUtils.selector } }, EXPERIMENTAL: { pubsub: get(options, 'EXPERIMENTAL.pubsub', false) } }, connectionManager: get(options, 'connectionManager', { maxPeers: get(config, 'Swarm.ConnMgr.HighWater'), minPeers: get(config, 'Swarm.ConnMgr.LowWater') }) }
其中,
datastore
、peerInfo
、peerBook
、options
等来自于 IPFS 对象的相关私有属性,config
来自于最终生成的仓库的配置文件和用户指定的相关配置。 -
然后,调用
mergeOptions
方法,合并默认选项与用户指定的选项。const libp2pOptions = mergeOptions(libp2pDefaults, get(options, 'libp2p', {}))
</li> <li>
最后,加载
core/runtime/libp2p-nodejs.js
文件中定义的 Node 对象(继承于libp2p
库定义的对象),并调用其构造函数,生成 libp2p 对象。const Node = require('../runtime/libp2p-nodejs') return new Node(libp2pOptions)
<code>libp2p-nodejs.js</code>
文件中主要定义了创建 libp2p 对象的默认选项,并把前面生成的选项与默认选项进行合并,然后调用父类的构造来创建 对象。具体的默认选项为:
{ switch: { blacklistTTL: 2 * 60 * 1e3, // 2 minute base blackListAttempts: 5, // back off 5 times maxParallelDials: 150, maxColdCalls: 50, dialTimeout: 10e3 // Be strict with dial time }, modules: { transport: [ TCP, WS, wsstar ], streamMuxer: [ Multiplex ], connEncryption: [ SECIO ], peerDiscovery: [ MulticastDNS, Bootstrap, wsstar.discovery ], dht: KadDHT }, config: { peerDiscovery: { autoDial: true, mdns: { enabled: true }, bootstrap: { enabled: true }, websocketStar: { enabled: true } }, dht: { kBucketSize: 20, enabled: false, randomWalk: { enabled: false } }, EXPERIMENTAL: { pubsub: false } } }
</li> </ul>
通过以上代码,我们可以发现创建 libp2p 的过程是比较复杂的,libp2p 对象的实际类型为
libp2p
库中定义的对象。
因为 libp2p 是一个非常非常重要的组件/库,即可以使用在 IPFS/Filecoin 中,也可以有独立使用,或者在其他项目中使用,鉴于它是如此的重要,所以我们以后会专门来讲解它,这里只是简单涉及。libp2p 对象继承于
EventEmitter
类,所以可以触发事件,同时本身内部也有一个类型fsm-event
的状态变量,所以也可以认为是一个状态机对象。