精通IPFS:系统启动篇
commands/daemon.go
文件,它的
Run
方法直接调用同文件中的
daemonRun
函数进行处理。这个函数的处理如下:
getRepo
,获得本地仓库
repo.Repo 接口
对象。这个方法内部调用仓库的
OpenFSRepo
函数,生成并初始化仓库对象,它的流程如下:
repo.FSRepo 对象
。
repo.lock
文件,并设置仓库对象的
lockfile
属性,从而确保同时只有一个全节点可以使用仓库,以便维护仓库的完整性。
loadFromDisk
方法,从磁盘上加载仓库的各种数据,并同继续完善仓库对象。这个方法的流程如下:
这个方法会生成仓库存储对象,并保存在仓库对象的
readVersion
方法,从仓库文件中读取仓库的版本号,并与仓库对象自身的版本号进行比较。如果不匹配,则抛出错误。
loadConfig
方法,加载仓库的配置文件
config.json
。
openDatastore
方法,加载仓库的数据存储文件。默认情况下,数据存储类型为
badgerds
,所以加载的文件目录为仓库下的这个目录。这个方法会生成仓库存储对象,并保存在仓库对象的
ds
属性。
openKeystore
方法,打开仓库的
keystore
文件。这个方法会生成私钥存储对象,并保存在仓库对象的
keystore
属性。
openWalletDatastore
方法,打开钱包数据存储。这个方法会生成仓库存储对象,并保存在仓库对象的
walletDs
属性。这次对象对应的目录为
wallet
。
openChainDatastore
方法,打开区块链数据存储。这个方法会生成仓库存储对象,并保存在仓库对象的
chainDs
属性。这次对象对应的目录为
chain
。
openDealsDatastore
方法,打开交易数据存储。
dealsDs
属性。这次对象对应的目录为
deals
。
New
方法,创建一个节点。首先,生成一个配置对象,使用前面几步形成的选项参数和仓库对象来设置配置对象;然后调用配置对象的
Build
方法,构建一个 Filecoin 节点。当我们不带参数启动时,配置对象中只有仓库对象会被设置。
Build
函数执行流程如下:
buildHost
方法,生成 libp2p Host 对象'。
buildHost
方法调用 libp2p 的
New
方法,这个方法最终调用
config/config.go
中定义的
NewNode
方法,这个方法:
NewSwarm
方法创建一个 swarm对象。
basic_host.go
中定义的
NewHost
来创建 host 对象。在创建 host 对象过程中,把 swarm 对象保存为 host 对象的网络对象,同时设置 swarm 的连接处理器和流处理器分别为 host 对象的
newConnHandler
和
newStreamHandler
两个方法。
AddTransport
方法,添加指定的传输协义。
Listen
方法,开始监听指定的地址。
readGenesisCid
函数,获取创世区块的 CID''。
powerTable
对象,类型为 consensus.MarketView 对象。
consensus/processor.go
的
NewDefaultProcessor
函数,生成共识器;否则,调用
NewConfiguredProcessor
函数,生成共识器。两个函数都生成 consensus.DefaultProcessor 对象,区块在于它们的属性。
consensus/NewExpected.go
的
NewExpected
函数,生成 consensus.Protocol 接口 节点共识consensus.Expected 对象。根据配置对象是否有 proofs.Verifier 接口对象,在生成过程中会使用不同的参数。
NewFloodSub
函数,生成一个 发布/订阅pubsub.PubSub 对象
fsub
,监听自身的所有消息。
walletDs
属性作为钱包后端,生成钱包wallet.Wallet 对象。
chain/syncer.go
的
NewSyncer
函数,生成区块链chain.Syncer 同步对象。
/fil/msgs/devnet-3
,它会在这个主题上发布消息。在全节点的启动方法中通过,通过调用 porcelain.API 对象的
PubSubSubscribe
方法,订阅这个主题的消息通知。
MessageSend
方法发送消息时,内部调用本对象的
Send
方法,进行发送。发送方法最终调用消息发布对象的
Publish
,把经过签名之后的消息发布到相应的主题上。当消息发送之后,别的全节点对象因为订阅了消息主题,所以会调用全节点的
processMessage
的方法进行处理。具体见全节点启动过程。
runAPIAndWait
,启动全节点。
Start
方法,启动 Filecon 节点''。
Load
方法,加载本地已有区块。
miningAddress
方法,获取矿工地址;如果配置了矿工地址,则调用node.Node 全节点对象的
setupMining
方法,设置挖矿。这个方法调用
initSectorBuilderForNode
函数,初始化初始化扇区生成器,并保存在全节点对象的
sectorBuilder
属性上。
syncCallBack
同步回调函数对象,用于处理区块同步。
protocol/hello/hello.go
文件的
New
函数,进行 Hello 消息处理设置这个方法内部处理如下:
HelloSvc
属性。
/fil/hello/1.0.0
协义处理器为protocol.hello.Handler 对象 的
handleNewStream
方法。
setupProtocols
方法,设置各种协义。这个方法内部处理如下:
BlockMiningAPI
属性。
protocol/retrieval/api.go
文件的
NewAPI
函数,生成protocol.retrieval.API 对象,并促为全节点对象的
RetrievalAPI
属性。
protocol/storage/api.go
文件的
NewAPI
函数,生成protocol.storage.API 对象,并促为全节点对象的
StorageAPI
属性。
protocol/retrieval/NewMiner.go
的
NewMiner
函数,生成一个检索矿工,并为设置全节点对象的
RetrievalMiner
属性。这个函数首先生成一个检索矿工,然后调用全节点对象的 libp2p Host 对象的
SetStreamHandler
方法,设置
/fil/retrieval/free/0.0.0
协议的处理器为检索矿工的
handleRetrievePieceForFree
方法,最后返回检索矿工。
PubSubSubscribe
方法,订阅
/fil/blocks/devnet-3
主题的区块通知,并设置为全节点的
BlockSub
属性。
PubSubSubscribe
方法,订阅
/fil/msgs/devnet-3
主题的消息通知,并设置为全节点的
MessageSub
属性。
handleSubscription
方法,处理区块通知。这个方法主体是一个无限循环。它从参数指定的主题中读取主题,并调用参数指定的方法进行处理。区块通知订阅的是
/fil/blocks/devnet-3
,它的处理方法是全节点的
processBlock
方法。
handleSubscription
方法,处理消息通知。消息通知订阅的是
/fil/msgs/devnet-3
,它的处理方法是全节点的
processMessage
方法。这个方法把收到的消息进行反序列化,然后调用 core.Inbox 对象的
Add
方法,把消息对象保存在 core.MessagePool 对象中。
HeadEvents
方法,使用其返回的发布/订阅对象的
Sub
方法,订阅新区块头部主题
new-head
。
ChainHead
方法,返回处理区块链头部的函数,在一个协程中调用全节点的
handleNewHeaviestTipSet
方法,处理区块链头部消息。
Connected
方法,从而向远程节点发送自身的顶层区块信息,而远程节点也会向我们发送它的顶层区块信息,从而开启区块同步过程。
ServeMux
处理器对象,设置它处理
/debug/pprof/
请求的对象为 Go 自身的
DefaultServeMux
;处理
/api/
请求的 go-ipfs-cmds 类库的
handler
对象。
handler
对象持有上面生成的环境变量、服务器配置变量等。