V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BlockHeader
V2EX  ›  区块链

Filecoin 逻辑梳理及源代码导读

  •  
  •   BlockHeader · 2019-03-29 23:23:54 +08:00 · 1686 次点击
    这是一个创建于 2073 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Filecoin 的源代码可以从 Github 下载: https://github.com/filecoin-project/go-filecoin。

    在阅读源代码之前,强烈建议看两份对阅读代码有益的文档:

    Filecoin 的设计文档

    https://github.com/filecoin-project/specs

    设计文档,从设计的角度,分别介绍数据结构,挖矿机制,共识机制,支付方式,虚拟机执行,状态机,存储角色等等。

    CODEWALK.md

    https://github.com/filecoin-project/go-filecoin/blob/master/CODEWALK.md

    CODEWALK 也是高屋建瓴的讲述了 Filecoin 的代码历史,框架,以及各个模块的功能。

    总的来说,这两份文档篇幅都不长,对理解 Filecoin 的项目以及代码很有帮助。建议大家有空看看。注意的是,这些文档也不是实时更新,和代码有些出入的。闲话不多说,我整理了一下 Filecoin 源代码的一些理解,方便对 Filecoin 代码感兴趣的小伙伴,可以更快的理解 Filecoin 的设计以及现状。文章比较长,请耐心阅读 :)

    在该导读中使用的 Filecoin 代码的最后一个 commit 信息如下:

    commit c293e9032505fce2f89575846dcf5491b7b0fe92 (HEAD -> master, origin/master, origin/HEAD)

    Author: Richard Littauer [email protected]

    Date: Mon Feb 18 19:22:47 2019 +0200

    docs: Add dual license
    
    Missing it in the manifest. Not sure if this is how GX reads it (cc @whyrusleeping), but I'm going off of this example from @kemitchell.
    

    01 Filecoin 的几个基本概念 Filecoin State Machine (Filecoin 状态机):

    Filecoin 的状态机,主要是维护如下一些状态信息:支付情况,存储市场情况,各个节点的 Power (算力)等等。

    Actor:

    Filecoin 网络中的 Actor 可以类比以太坊网络中的账户(一般账户或者智能合约账户)。每个 Actor 有自己的地址,余额,也可以维护自己的状态,同时 Actor 提供一些函数调用(也正是这些函数调用触发 Actor 的状态变化)。Filecoin 的状态机,包括所有 Actor 的状态。

    Actor 的状态,包括:账户信息( Balance ),类型( Code ),以及序号( Nonce )。Actor 的定义在 actor/actor.go 中。

    Message:

    Filecoin 网络中的区块是由一个个的 Message 组成。你可以把 Message 想象成以太坊的交易。一个 Message 由发起地址,目标地址,金额,调用的函数以及参数组成。所有 Message 的执行的结果就是状态机的全局状态。Filecoin 网络的全局状态就是映射表:Actor 的地址和 Actor 的状态 /信息。以太坊的全局信息是通过 leveldb 数据库存储。Filecoin 的全局状态是使用 IPLD HAMT(Hash-Array Mapped Trie) 存储。

    Message 的定义在 types/message.go 中。

    FIL & AttoFIL:

    FIL 是 Filecoin 项目的代币。AttoFIL 是 FIL 代币的最小单位,1 AttoFIL = 10^(-18) FIL。

    Gas 费用:

    和以太坊网络类似,执行 Actor 的函数需要消耗 Gas。Actor 的函数调用有两种方式:1/ 用户发起签名后的 Message (指定调用某个 Actor 的某个函数),并支付矿工 Gas 费用(类似以太坊的 Gas 费用)。2/ Actor 之间调用。Actor 之间调用也必须是用户发起。

    区块( Block & TipSet ):

    Block 是一个区块,定义在 types/block.go 文件中:

    一个区块的信息主要包括:

    打包者的地址信息

    区块的高度 /权重信息

    区块中包括的交易信息 /更新后新的 Root 信息

    Ticket 信息以及 Ticket 的 PoSt 的证明信息

    一个 Tip,就是一个区块。一个 TipSet,就是多个区块信息的集合,这些区块拥有同一个父亲区块。所谓的 TipSet,就是一个区块的多个子区块,定义在 types/tipset.go 文件中:

    目前 Filecoin 的代码中,每个区块的生成时间设置为 30 秒。

    02 Filecoin 地址生成逻辑

    在深入其他逻辑之前,先介绍一下 Filecoin 网络中的地址生成逻辑。Filecoin 的地址总共为 41 个字节,比如 fcqphnea72vq5yynshuur33pfnnksjsn5sle75rxc。fc 代表是主网,tf 代表是测试网络。

    详细的代码在 address/address.go ,核心逻辑在 encode 函数。 在 address/constants.go 文件中定义了一些参数,并预制了一些固定地址:Filecoin 的铸币地址,存储市场地址,支付通道地址等等。

    03 Filecoin 的整体框架

    所有的交易在节点间同步到每个节点的“ Message Pool ”中。经过“ Expected Consensus ”共识机制,当选为 Leader 的一个或者多个节点从“ Message Pool ”中挑选 Message,并打包。被打包的区块,会同步给其他节点。打包的区块中的交易( Message )会被 Filecoin 虚拟机执行,更新各个 Actor 的状态。所有的区块数据,Actor 的状态是通过 IPFS/IPLD 进行存储。

    04 Filecoin 虚拟机以及 Gas 计算 Filecoin 虚拟机比较简单,在 Filecoin 虚拟机执行具体某个 Message 的时候( Actor 的某个 Method ),会准备 VMContext,提供 Actor 的执行环境:

    Filecoin 虚拟机相关的代码在 vm 的目录下。所有的区块数据以及 Actor 状态数据存储是通过 IPFS/IPLD 实现。

    Message ()函数提供了当前交易 Message 的信息

    BlockHeight ()函数提供了当前区块高度信息

    Stoage/ReadStorage/WriteStorage 提供对当前目标地址的存储访问信息

    Charge()函数提供油费耗费的调用

    CreateNewActor/AddressForNewActor/IsFromAcccountActor 函数提供了对 Actor 地址的创建以及基本查询功能

    Rand 函数提供了随机数能力

    Send 函数提供了调用其他 Actor 函数的能力

    05 Expected Consensus - EC 共识机制 Filecoin 的共识算法叫 Expected Consensus,简称 EC 共识机制。Expected Consensus 实现的相关代码在 consensus 目录。除了区块链数据外,Expected Consensus 每一轮会生成一个 Ticket,每个节点通过一定的计算,确定是否是该轮的 Leader。如果选为 Leader,节点可以打包区块。也就是说,每一轮可能没有 Leader (所有节点都不符合 Leader 的条件),或者多个 Leader (有多个节点符合 Leader )。Filecoin 使用 TipSet 的概念,表明一轮中多个 Leader 产生的指向同一个父亲区块的区块集合。

    Ticket 的生成:

    下一轮的 Ticket 是通过前一轮的区块的 Proof 以及节点的地址的 Hash 计算的结果,具体看 consensus/expected.go 中的 CreateTicket 函数。

    Leader 的选择:

    在每个 Ticket 生成的基础上,进行 Leader 的选择,具体查看 consensus/expected.go 中的 IsWinningTicket 函数。也就是说,如果 Ticket 的数值小于当前节点的有效存储的比例的话,该节点在该轮就是 Leader。

    Weight 的计算:

    当多个 Leader 打包,形成多个 TipSet 时,通过计算 TipSet 的 Weight 的计算确定“主链”。具体查看 consensus/expected.go 中的 Weight 函数。如下图,在高度 n+1,存在两个合法的 TipSet,如何选择 TipSet 作为主链:计算 Weight。

    每个区块的 Weight 的计算公式如下:

    Weight = ParentWeight + ECV + ECPrM * ratio 
    

    目前,ECV 设置为 10,ECPrM 设置为 100,Ratio 是当前节点的存储有效率(节点存储的容量 /所有节点的存储容量)。在目前的算法下,也就是说,节点的 ratio 高,Weight 就高。

    一个 TipSet 的 Weight 等于 TipSet 中所有区块的 Weight 的总和。Weight 大的 TipSet 认为是主链。当两个 TipSet 的 Weight 一样大的时候,取 Ticket 较小者。

    06 Filecoin 协议层 在区块链的基础上,Filecoin 设计了几个协议:hello 协议,storage 协议以及 retrieval 协议。协议层在区块链数据之上,通过 Message 驱动区块链状态转移。Hello 协议负责 TipSet 的区块同步,storage 协议负责存储需求双方的撮合,retrieval 协议负责文件的检索以及读取服务。协议层的代码在 protocol 目录中。

    以 storage 协议为例,讲解一些协议层的主要逻辑:

    Miner (紫红色)就是平时所说的存储矿工,通过 createMiner 创建 Miner Actor。使用 Miner Actor 的 addAsk 提供存储服务。存储需求方,也就是 Client,通过 getAsks 获取所有 Miner Actor 的存储服务,并在这些服务中确定相应的存储矿工。在确定存储矿工的基础上,使用 createChannel 创建支付通道,并和存储矿工进行数据的传输。存储矿工在存储数据后,定期向 Miner Actor 报告存储证明( submitPoSt )。存储矿工通过 FPS ( Filecon Proving Subsystem )实现数据的存储以及存储证明:SectorBase 提供存储接口,Storage Proof 提供 PoRep 以及 PoSt 的存储证明。PoRep 以及 PoSt 的存储证明逻辑可以查看:IPFS & FileCoin - PoRep 和 PoSt 算法。其他协议逻辑类似,感兴趣的小伙伴可以自行查看源代码。

    总结:Filecoin 是由区块链以及上层协议构成的存储系统。Filecoin 有自己的一套术语:Message,Block,TipSet,Actor,Ticket,GAS。Filecoin 的状态由多个 Actor 的状态组成。Filecoin 区块链的区块数据以及 Actor 的状态数据通过 IPFS/IPLD 进行存储。Filecoin 采用 EC 共识机制,通过 TipSet 的 Weight 确定主链。Filecoin 目前实现三个上层协议:Hello,Storage (存储协议)以及 Retrieval (检索协议)。目前的代码还在迭代中,代码中有很多 TODO,也有一些和设计文档不一致的地方。

    V2EX 的文章不能贴图,查看原文,请关注公众号:星想法。

    BlockHeader
        1
    BlockHeader  
    OP
       2019-03-29 23:25:09 +08:00
    V2EX,不能贴图,好多代码逻辑不太好表达。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1591 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:00 · PVG 01:00 · LAX 09:00 · JFK 12:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.