Filecoin系统启动篇教程

当用户以守护进程模式启动 filecoin 时,最终执行的命令位于 commands/daemon.go 文件,它的 Run 方法直接调用同文件中的 daemonRun 函数进行处理。这个函数的处理如下:调用 getRepo,获得本地仓库 <code

当用户以守护进程模式启动 filecoin 时,最终执行的命令位于 commands/daemon.go 文件,它的 Run 方法直接调用同文件中的 daemonRun 函数进行处理。这个函数的处理如下:

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

声明:本文来自比特币网平台用户投稿,观点仅代表作者本人,不代表【比特币网-www.5898.com.cn】立场,文章内容仅供参考,如若转载请标注文章来源:【当前页面链接】

区块链相关

区块链媒体相关

区块链技术相关

挖矿相关

比特币相关