2.4blockchain Cn

2021/06/25

2.4 Blockchain

Filecoin区块链是一个分布式虚拟机,在Filecoin协议中实现共识、处理信息、核算存储和维护安全。它是连接Filecoin系统中各种行为者的主要接口。

Filecoin区块链系统包括:

  • 一个消息池系统,节点用来跟踪和传播矿工宣布要纳入区块链的消息
  • 一个虚拟机子系统,用于解释和执行信息,以更新系统状态。
  • 一个状态树子系统,管理状态树(系统状态)的创建和维护,这些状态树是由vm从一个给定的子链中确定性地生成的。
  • 一个链同步(ChainSync)子系统跟踪和传播经过验证的消息块,维护矿工可以开采的候选链集,并对进入的块进行语法验证。
  • 一个存储算力共识子系统,它跟踪给定链的存储状态(即存储子系统),并帮助区块链系统选择子链来扩展和区块来包括在其中。

区块链系统还包括:

  • 链管理器,维护一个给定的链的状态,为其他区块链子系统提供设施,这些子系统将查询关于最新的链的状态,以便运行,并确保传入的区块在纳入链之前得到语义验证。
  • 区块生产者,在领导者选举成功的情况下被调用,以产生一个新的区块,在将其转发给同步器传播之前,将扩展当前最重的链。

在高层次上,Filecoin区块链通过连续几轮领导人选举而成长,其中一些矿工被选举产生一个区块,该区块被纳入链中将为他们赢得区块奖励。Filecoin的区块链依靠存储能力运行。也就是说,它的共识算法,即矿工同意开采哪个子链,是以支持该子链的存储量为前提的。在高层次上,存储算力共识子系统维护一个算力表,跟踪存储矿工演员通过扇区承诺和时空证明对网络贡献的存储量。

2.4.1 Blocks

区块是Filecoin区块链的主要单位,大多数其他区块链也是如此。区块信息与Tipsets直接相关,Tipsets是由区块信息组成的组,本节后面将详细介绍。在下文中,我们将讨论区块信息的主要结构以及在Filecoin区块链中验证区块信息的过程。

2.4.1.1 Block

区块是Filecoin区块链的主要单位。

Filecoin区块链中的区块结构由以下部分组成:i)区块头,ii)区块内的信息列表,以及iii)已签署的信息。这在FullBlock的抽象中得到了体现。这些消息表明,为了达到链的确定状态,需要应用的一组变化。

该区块的Lotus实现有以下结构:

type FullBlock struct {
	Header        *BlockHeader
	BlsMessages   []*Message
	SecpkMessages []*SignedMessage
}

备注:一个区块在功能上与Filecoin协议中的区块头是一样的。虽然区块头包含完整的系统状态、消息和消息收据的Merkle链接,但一个区块可以被认为是这些信息的完整集合(不仅仅是Merkle根,而是状态树、消息树、收据树等的完整数据)。因为一个完整的区块大小很大,所以Filecoin区块链由区块头而不是完整的区块组成。我们经常交替使用区块和区块头这两个术语。

BlockHeader是一个区块的典型代表。BlockHeaders在矿工节点之间传播。从BlockHeader消息中,矿工拥有应用相关FullBlock的状态和更新链的所有必要信息。为了能够做到这一点,需要包含在BlockHeader中的最小信息项目集如下所示,其中包括:矿工的地址、Ticket、SpaceTime证明、IPLD DAG中该区块演化而来的父类的CID,以及消息本身的CID。

Lotus实现的区块头有以下结构:

type BlockHeader struct {
	Miner                 address.Address    // 0 unique per block/miner
	Ticket                *Ticket            // 1 unique per block/miner: should be a valid VRF
	ElectionProof         *ElectionProof     // 2 unique per block/miner: should be a valid VRF
	BeaconEntries         []BeaconEntry      // 3 identical for all blocks in same tipset
	WinPoStProof          []proof2.PoStProof // 4 unique per block/miner
	Parents               []cid.Cid          // 5 identical for all blocks in same tipset
	ParentWeight          BigInt             // 6 identical for all blocks in same tipset
	Height                abi.ChainEpoch     // 7 identical for all blocks in same tipset
	ParentStateRoot       cid.Cid            // 8 identical for all blocks in same tipset
	ParentMessageReceipts cid.Cid            // 9 identical for all blocks in same tipset
	Messages              cid.Cid            // 10 unique per block
	BLSAggregate          *crypto.Signature  // 11 unique per block: aggrregate of BLS messages from above
	Timestamp             uint64             // 12 identical for all blocks in same tipset / hard-tied to the value of Height above
	BlockSig              *crypto.Signature  // 13 unique per block/miner: miner signature
	ForkSignaling         uint64             // 14 currently unused/undefined
	ParentBaseFee         abi.TokenAmount    // 15 identical for all blocks in same tipset: the base fee after executing parent tipset

	validated bool // internal, true if the signature has been validated
}
type Ticket struct {
	VRFProof []byte
}
type ElectionProof struct {
	WinCount int64
	VRFProof []byte
}
type BeaconEntry struct {
	Round uint64
	Data  []byte
}

BlockHeader结构必须引用当前轮次的TicketWinner,以确保正确的赢家被传递给ChainSync。

Message 结构必须包括源(From)和目的(To)地址、Nonce和GasPrice。

Lotus实现的消息有以下结构:

type Message struct {
	Version uint64

	To   address.Address
	From address.Address

	Nonce uint64

	Value abi.TokenAmount

	GasLimit   int64
	GasFeeCap  abi.TokenAmount
	GasPremium abi.TokenAmount

	Method abi.MethodNum
	Params []byte
}

消息在传递给链同步逻辑之前也会被验证。

func (m *Message) ValidForBlockInclusion(minGas int64, version network.Version) error {
	if m.Version != 0 {
		return xerrors.New("'Version' unsupported")
	}

	if m.To == address.Undef {
		return xerrors.New("'To' address cannot be empty")
	}

	if m.To == build.ZeroAddress && version >= network.Version7 {
		return xerrors.New("invalid 'To' address")
	}

	if m.From == address.Undef {
		return xerrors.New("'From' address cannot be empty")
	}

	if m.Value.Int == nil {
		return xerrors.New("'Value' cannot be nil")
	}

	if m.Value.LessThan(big.Zero()) {
		return xerrors.New("'Value' field cannot be negative")
	}

	if m.Value.GreaterThan(TotalFilecoinInt) {
		return xerrors.New("'Value' field cannot be greater than total filecoin supply")
	}

	if m.GasFeeCap.Int == nil {
		return xerrors.New("'GasFeeCap' cannot be nil")
	}

	if m.GasFeeCap.LessThan(big.Zero()) {
		return xerrors.New("'GasFeeCap' field cannot be negative")
	}

	if m.GasPremium.Int == nil {
		return xerrors.New("'GasPremium' cannot be nil")
	}

	if m.GasPremium.LessThan(big.Zero()) {
		return xerrors.New("'GasPremium' field cannot be negative")
	}

	if m.GasPremium.GreaterThan(m.GasFeeCap) {
		return xerrors.New("'GasFeeCap' less than 'GasPremium'")
	}

	if m.GasLimit > build.BlockGasLimit {
		return xerrors.New("'GasLimit' field cannot be greater than a block's gas limit")
	}

	// since prices might vary with time, this is technically semantic validation
	if m.GasLimit < minGas {
		return xerrors.Errorf("'GasLimit' field cannot be less than the cost of storing a message on chain %d < %d", m.GasLimit, minGas)
	}

	return nil
}

2.4.1.2 Tipset

预期共识在每个纪元中以概率方式选出多个领导者,这意味着一个Filecoin链在每个纪元可能包含零个或多个区块(每个当选的矿工一个)。来自同一纪元的区块被组装成tipset。虚拟解释器通过执行一个区块中的所有信息(在去除包含在一个以上区块中的相同信息后)来修改Filecoin状态树。

每个区块都引用一个父tipset,并验证该tipset的状态,同时提出当前纪元要包括的消息。一个新区块的信息所适用的状态,在该区块被纳入一个tipset之前,是无法知道的。因此,孤立地执行单个区块的消息是没有意义的:只有当该区块的tipset中的所有消息被执行后,才会知道新的状态树。

一个有效的tipset包含一个非空的区块集合,这些区块有不同的矿工,并且都指定了相同的内容。

  • Epoch
  • Parents
  • ParentWeight
  • StateRoot
  • ReceiptsRoot

一个tipset中的区块是通过每个区块的票据中的字节的词法排序的,与区块本身的CID的字节打破联系。

由于网络传播的延迟,在纪元N+1的矿工有可能从他们的父tipset中省略在纪元N开采的有效块。这不会使新产生的区块无效,但它确实减少了它的权重和成为协议中典型链的一部分的机会,如EC的链选择功能所定义。

区块生产者应协调他们如何选择纳入区块的消息,以避免重复,从而最大限度地提高他们从消息费中获得的预期收益(见消息池)。

Lotus实现中的主要Tipset结构包括以下内容:

type TipSet struct {
	cids   []cid.Cid
	blks   []*BlockHeader
	height abi.ChainEpoch
}

tipset 语义监测:

  • 一个提示集至少由一个块组成。(由于我们对每个提示集的块数不固定,由随机性决定,我们不强加一个上限)。
  • 所有区块都有相同的高度。
  • 所有的块都有相同的父母(相同的数量和匹配的CIDs)。

2.4.1.3 Chain Manager

链管理器是区块链系统中的一个中心组件。它跟踪和更新特定节点收到的竞争子链,以选择适当的区块链头:它所知道的系统中最重的子链的最新块。

在这样做的过程中,链管理器是中央子系统,为Filecoin节点中的众多其他系统处理簿记,并暴露出方便的方法供这些系统使用,例如,使系统能够从链中抽出随机性,或看到哪个区块最近被最终确定。

对于每一个传入的区块,即使传入的区块没有被添加到当前权重最高的tipset中,链管理者也应该将其添加到它所追踪的适当的子链中,或者独立追踪它,直到以下两种情况之一。

  • 通过接收该子链中的另一个区块,它能够添加到当前最重的子链中
  • 它能够丢弃该区块,因为该区块是在最后阶段被开采的

值得注意的是,在最终结果之前,一个给定的子链可能会被放弃,以换取在某一轮中开采的另一个更重的子链。为了迅速适应这种情况,链管理者必须维护和更新所有正在考虑的子链,直到最终结果。

链的选择是Filecoin区块链工作方式的一个重要组成部分。简而言之,每条链都有一个相关的权重,占其上开采的区块的数量,因此它们追踪的算力(存储)。选择工作的全部细节在链选择部分提供。

  • 为了使某些验证检查更简单,块应该按高度和父集进行索引。这样,具有给定高度和共同父本的块的集合可以被快速查询。
  • 计算并缓存这些集合中的块的总状态可能也是有用的,这可以在检查一个块有多个父代时从哪个状态根开始时节省额外的状态计算。
  • 建议将块保存在本地数据存储中,无论它们是否被理解为此时的最佳提示–这是为了避免将来不得不重新获取相同的块。

The Chain Tips Manager is a subcomponent of Filecoin consensus that is responsible for tracking all live tips of the Filecoin blockchain, and tracking what the current ‘best’ tipset is.

链上tip管理器是Filecoin共识的一个子组件,负责跟踪Filecoin区块链的所有实时tip,并跟踪当前 “最佳 “tipset是什么。

2.4.1.4 Block Producer

在存储能力行动者处注册的矿工,如果证明其存储能力符合最小矿工规模的阈值要求,就可以开始生成和检查选举票。

为了做到这一点,矿工必须运行链验证,并跟踪最近收到的区块。矿工的新区块将基于上一个纪元的父母。

2.4.1.4.1 Block Creation

产生一个纪元H的区块需要等待该纪元的信标条目并使用它来运行GenerateElectionProof。如果WinCount≥1(即当矿工当选时),同一信标条目被用来运行WinningPoSt。在ElectionProof票(GenerateElectionProof的输出)和WinningPoSt证明的支持下,矿工可以产生一个新区块。

关于父tipset评估的细节,见VM解释器,关于有效区块头值的约束,见Block。

为了创建一个区块,合格的矿工必须计算几个字段。

  • Parents - 父tipset的区块的CIDs
  • ParentWeight - 父链的权重
  • ParentState - 来自父tipset状态评估的状态根的CID
  • ParentMessageReceipts - 包含计算ParentState时产生的收据的AMT的根的CID
  • Epoch - 该块的纪元,由Parents的纪元和生成该块所花的纪元数得出
  • Timestamp - Unix时间戳,以秒为单位,在块创建时产生
  • BeaconEntries - 一组自上一个区块产生的drand条目
  • Ticket - 从上一个纪元中产生的新票据
  • Miner - 区块生产者的矿工地址
  • Messages - TxMeta对象的CID,该对象包含建议纳入新区块的消息。
    • 从mempool中选择一组消息包含在区块中,满足区块大小和gas limit
    • 将消息分离成BLS签名的消息和secpk签名的消息
    • TxMeta.BLSMessages: 一个AMT的根的CID,包括裸露的UnsignedMessages
    • TxMeta.SECPMessages: AMT根部的CID,包括签名信息。
  • BeaconEntries: 一个信标条目的列表,用于导出随机性
  • BLSAggregate - 该区块中所有使用BLS签名的消息的集合签名
  • Signature - 用矿工的工人账户私钥(也必须与票据签名相匹配)在区块头的序列化表示上签名(有空签名)
  • ForkSignaling - 作为分叉信号的一部分使用的一个uint64标志。默认情况下应设置为0

请注意,为了产生一个有效的区块,不需要对区块中包含的消息进行评估。矿工可能希望对信息进行投机性评估,以优化包括将成功执行并支付最多气体的信息。

区块奖励在产生区块时不被评估。它是在区块被包含在下一个纪元的提示集中时支付的。

区块的签名确保了传播后区块的完整性,因为与许多PoW区块链不同,中奖票是独立于区块生成的。

符合条件的矿工使用GossipSub /fil/blocks 主题将完成的区块传播给网络,假设一切操作正确,网络将接受它,其他矿工将在它上面挖矿,为矿工赚取区块奖励。

矿工应该在他们的有效区块产生后立即输出,否则他们有可能在EPOCH_CUTOFF后被其他矿工接收到区块而不包括在当前纪元中。

2.4.2 Message Pool

消息池,或mpool或mempool是Filecoin协议中的一个消息池。它作为Filecoin节点和用于链外消息传播的其他节点的点对点网络之间的接口。消息池被节点用来维护一组他们想传送到Filecoin VM并添加到链上的消息(即添加到 “链上 “执行)。

为了让一个消息最终出现在区块链中,它首先必须在消息池中。在现实中,至少在Filecoin的Lotus实现中,没有中央的消息池存储在某个地方。相反,消息池是一个抽象概念,并被实现为网络中每个节点保存的消息列表。因此,当一个节点在消息池中放入一个新消息时,这个消息会通过libp2p的pubsub协议GossipSub传播到网络的其他部分。节点需要订阅相应的pubsub主题,以便接收消息。

使用GossipSub的消息传播不会立即发生,因此,在不同节点的消息池能够同步之前,会有一些滞后。在实践中,考虑到不断有消息被添加到消息池中,以及传播消息的延迟,消息池在网络中的所有节点上从未同步。这不是系统的缺陷,因为消息池不需要在整个网络中同步。

消息池应该有一个最大尺寸的定义,以避免DoS攻击,即节点被发送垃圾邮件并耗尽内存。建议消息池的大小为5000条消息。

2.4.2.1 Message Propagation

消息池必须与libp2p pubsub GossipSub协议接口。这是因为消息是通过GossipSub传播相应的 /fil/msgs/ 主题。每个消息都由参与网络的任何节点在相应的 /fil/msgs/ 主题中公布。

有两个与消息和区块有关的主要pubsub主题:i)携带消息的/fil/msgs/主题和,ii)携带区块的/fil/blocks/主题。/fil/msgs/主题被链接到mpool。这个过程如下。

  • 当客户想要在Filecoin网络中发送消息时,他们将消息发布到 /fil/msgs/ 主题。
  • 该消息使用GossipSub传播到网络中的所有其他节点,并最终在所有矿工的mpool中结束。
  • 根据加密经济规则,一些矿工最终会从mpool中挑选消息(与其他消息一起)并将其纳入一个区块。 矿工在/fil/blocks/pubsub主题中发布新开采的区块,该区块会传播到网络中的所有节点(包括发布该区块所含消息的节点)。

节点必须检查传入的消息是否有效,也就是说,它们有一个有效的签名。如果消息是无效的,它应该被丢弃,不得转发。

GossipSub协议的更新、加固版本包括一些攻击缓解策略。例如,当一个节点收到一个无效的消息时,它会给发送方的对等体分配一个负分。对等体的分数不与其他节点共享,而是由每个对等体在本地为所有与之互动的其他对等体保存。如果一个对等体的分数下降到某个阈值以下,它就会被排除在评分对等体的网状结构之外。我们在GossipSub部分讨论这些设置的更多细节。完整的细节可以在GossipSub规范中找到。

笔记:

  • 资金检查。值得注意的是,mpool逻辑并不检查消息发布者的账户中是否有足够的资金。这是由矿工在将消息纳入区块之前检查的。
  • 消息排序。消息在矿工的mpool中根据矿工所遵循的加密经济规则进行排序,并按照矿工的顺序组成下一个区块。

2.4.3 ChainSync

区块链同步(”sync”)是区块链系统的一个关键部分。它处理区块和消息的检索和传播,因此负责分布式状态复制。因此,这个过程是安全的关键–状态复制的问题会对区块链的运行产生严重的影响。

当一个节点第一次加入网络时,它发现了对等体(通过上面讨论的对等体发现)并加入了 /fil/blocks/fil/msgs GossipSub主题。它监听由其他节点传播的新区块。它挑选一个区块作为BestTargetHead,并开始从TrustedCheckpoint(默认为GenesisBlock或GenesisCheckpoint)将区块链同步到这个高度。为了挑选BestTargetHead,对等人正在比较高度和重量的组合–这些值越高,区块在主链上的机会就越大。如果有两个高度相同的区块,对等体应该选择权重较高的那个。一旦对等体选择了BestTargetHead,它就会使用BlockSync协议来获取区块并达到当前的高度。从那时起,它就处于CHAIN_FOLLOW模式,它使用GossipSub来接收新的区块,或者如果它听说有一个区块没有通过GossipSub收到,就使用Bitswap。

2.4.3.1 ChainSync Overview

ChainSync是Filecoin用来同步其区块链的协议。它是针对Filecoin在状态表示和共识规则方面的选择,但其通用性足以让它为其他区块链服务。ChainSync是一组较小的协议,它们处理同步过程的不同部分。

通常在以下情况下需要进行链式同步:

  1. 当一个节点第一次加入网络,需要在验证或扩展链之前达到当前状态。
  2. 当一个节点失去同步时,例如,由于短暂的断开连接。
  3. 在正常运行期间,为了跟上最新的消息和区块。

有三种主要协议用于实现这三种情况下的同步:

  • GossipSub是用于传播消息和区块的libp2p pubsub协议。它主要用于上述第三个过程,当一个节点需要与正在产生和传播的新块保持同步。
  • BlockSync用于同步链的特定部分,即从和到一个特定的高度。
  • hello协议,在两个对等体第一次 “见面”(即第一次相互连接)时使用。根据该协议,他们交换他们的链头。

此外,Bitswap用于请求和接收区块,当一个节点被同步化(”赶上”),但GossipSub未能向一个节点交付一些区块。最后,GraphSync可以用来获取区块链的一部分,作为Bitswap的一个更有效的版本。

Filecoin节点是libp2p节点,因此可以运行各种其他协议。与Filecoin中的其他东西一样,节点可以选择使用额外的协议来实现结果。也就是说,节点必须实现本规范中描述的ChainSync版本,才能被认为是Filecoin的实现。

2.4.3.2 Terms and Concepts

  • LastCheckpoint是ChainSync所知道的最后一个面向社会共识的硬性检查点。这个共识检查点定义了最低限度的最终结果,以及最低限度的历史基础。ChainSync相信LastCheckpoint,并建立在它的基础上,从不脱离它的历史。
  • TargetHeads是一个BlockCIDs列表,代表处于区块生产边缘的区块。这些是ChainSync知道的最新最好的区块。它们是 “目标 “头,因为ChainSync会尝试与它们同步。这个列表是按照 “成为最佳链的可能性 “来排序的。在这一点上,这只是通过ChainWeight来实现。
  • BestTargetHead 试图同步到的单个最佳链头BlockCID。这是TargetHeads的第一个元素。

2.4.3.3 ChainSync State Machine

在一个较高的水平上,ChainSync做了以下工作。

  • 第1部分:验证内部状态(初始化下列的状态)
    • 应该验证数据结构和验证本地链
    • 耗费大量资源的验证可能会被跳过,风险由节点自己承担
  • 第2部分:启动到网络(BOOTSTRAP)
    • 步骤1:启动到网络,并获得一套 “足够安全 “的对等体
    • 步骤2:引导到GossipSub通道
  • 第3部分:同步可信的检查点状态(SYNC_CHECKPOINT)
    • 步骤1:从一个受信任的检查点开始(默认为GenesisCheckpoint)。TrustedCheckpoint不应该在软件中进行验证,应该由操作人员进行验证。
    • 步骤2:获取它所指向的区块,以及该区块的父类。
    • 步骤3:获得 StateTree
  • 第四部分:追赶链(CHAIN_CATCHUP)
    • 步骤1:维护一组TargetHeads(BlockCIDs),并从中选择 BestTargetHead
    • 步骤2:同步到最新观察到的头,向它们验证区块(请求中间点)
    • 步骤3:随着验证的进行,TargetHeads和BestTargetHead可能会发生变化,因为生产边缘的新块会到达,一些目标头或通往它们的路径可能无法验证。
    • 步骤4:当节点 “赶上” BestTargetHead(检索所有状态,链接到本地链,验证所有区块,等等)时完成。
  • 第五部分:保持同步,并参与区块传播(CHAIN_FOLLOW)
    • 步骤1:如果安全条件发生变化,回到第四部分(CHAIN_CATCHUP)。
    • 步骤2:接收、验证和传播收到的区块
    • 步骤3:现在有了更大的把握拥有最佳的链,最终确定Tipsets,并推进链的状态

ChainSync使用以下概念性的状态机。由于这是一个概念性的状态机,实现者可能会偏离这些状态的精确实现,或者严格划分这些状态。实现可以模糊这些状态之间的界限。如果是这样,实现者必须确保改变后的协议的安全性。

2.4.3.4 Peer Discovery

对等体发现是整个架构的一个关键部分。错了这一点会给协议的运行带来严重后果。新节点在加入网络时最初连接的对等体集合可能会完全支配节点对其他对等体的认识,从而支配节点对网络状态的看法。

对等体的发现可以由任意的外部手段驱动,并被推到ChainSync所涉及的协议(即GossipSub、Bitswap、BlockSync)的核心功能之外。这使得正交的、应用驱动的开发和协议实现没有外部依赖性。尽管如此,GossipSub协议支持:i)对等交换,以及ii)明确的对等协议。

对等体交换允许应用程序从已知的对等体集合中启动,而不需要外部对等体发现机制。这个过程可以通过引导节点或其他正常对等体来实现。引导节点必须由系统运营商维护,并且必须正确配置。它们必须是稳定的,并且独立于协议结构运行,例如GossipSub网状结构,也就是说,引导节点不维护与网状结构的连接。

有了明确的对等协议,操作者必须指定一个节点在加入时应连接的对等体列表。该协议必须有可用的选项来指定这些。对于每一个明确的对等体,路由器必须建立并保持双向(对等)连接。

2.4.3.5 Progressive Block Validation

  • 块可以在渐进阶段进行验证,以尽量减少资源支出。
  • 验证的计算量很大,是一个严重的DOS攻击载体。
  • 安全的实现必须仔细安排验证,并尽量减少在没有完全验证的情况下修剪区块所做的工作。
  • ChainSync应该保留一个未验证区块的缓存(最好是按属于链的可能性排序),并在FinalityTipset通过后或ChainSync处于重大资源负荷时删除未验证的区块。
  • 这些阶段可以部分地用于候选链中的许多区块,以便在实际进行昂贵的验证工作之前,修剪出明显的坏区块。

  • 区块验证的渐进阶段
    • BV0 - 语法。序列化、类型化、价值范围。
    • BV1 - 合理的共识。合理的矿工、权重和纪元值(例如链状态从 b.ChainEpoch - consensus.LookbackParameter)。
    • BV2 - 区块签名
    • BV3 - 信标条目。有效的随机信标条目已被插入区块中(见信标条目验证)。
    • BV4 - ElectionProof。一个有效的选举证明已经产生。
    • BV5 - WinningPoSt。产生了正确的PoSt。
    • BV6 - Chain ancestry and finality。验证区块链接回到可信链,而不是在最终性之前。
    • BV7 - 消息签名。
    • BV8 - 状态树。父提示集消息的执行产生声称的状态树根和收据。

2.4.4 Storage Power Consensus

存储算力共识(SPC)子系统是使得Filecoin节点能够就系统的状态达成一致的主要接口。存储算力共识在算力表中说明了个别存储矿工在特定链中对共识的有效算力。它还运行预期共识(Filecoin使用的底层共识算法),使存储矿工能够运行领导者选举并产生新的区块,更新Filecoin系统的状态。

简而言之,SPC子系统提供以下服务:

  • 访问每个子链的算力表,说明单个存储矿工的算力和链上的总算力
  • 访问单个存储矿工的预期共识,使之成为可能:
    • 访问可验证的随机性门票,正如drand为协议的其余部分提供的那样
    • 运行领导者选举以产生新区块
    • 使用EC的加权功能在各子链上运行链选择
    • 识别最近完成的tipset,供所有协议参与者使用

2.4.4.1 Distinguishing between storage miners and block miners

在Filecoin网络中,有两种方式可以赚取Filecoin代币:

  • 通过作为存储供应商参与存储市场,并由客户为文件存储交易付费
  • 通过挖掘新的区块,扩展区块链,确保Filecoin共识机制的安全,并作为存储矿工运行智能合约来执行状态更新

有两种类型的 “矿工”(存储和区块矿工)需要区分。Filecoin的领导者选举是以矿工的存储能力为前提的。因此,虽然所有区块矿工都是存储矿工,但反过来也不一定是对的。

然而,鉴于Filecoin的 “有用的Proof-of-Work “是通过文件存储实现的(PoRep和PoSt),存储矿工参与领袖选举的开销成本很小。这样的存储矿工行为体只需要在存储算力行为体中注册,就可以参与预期共识和开采区块。

2.4.2.2 On Power

质量调整后的算力被分配给每个扇区,作为其扇区质量的静态函数,其中包括:i) 扇区时空,这是扇区大小和承诺存储时间的乘积;ii) 交易权重,将交易占用的时空转换为共识算力;iii) 交易质量乘数,取决于在扇区上完成的交易类型(即 CC、普通交易或验证客户交易),以及最后,iv)扇区质量乘数,这是一个交易质量乘数的平均值,由每种类型的交易在扇区中占据的时空量加权。

扇区质量是一个衡量标准,它将一个扇区的容量、持续时间和在其生命周期中的活跃交易类型与它对权力和奖励分配的影响相映射。

一个扇区的质量取决于在该扇区内的数据上进行的交易。通常有三种类型的交易:承诺容量(CC),实际上没有交易,矿工在扇区内存储任意数据;常规交易,矿工和客户在市场上商定价格;验证客户交易,给扇区更多权力。我们请读者参阅扇区和扇区质量部分,以了解扇区类型和扇区质量的详情,验证客户部分,以了解什么是验证客户的详情,以及CryptoEconomics部分,以了解交易权重和质量乘数的具体参数值。

质量调整后的权力是矿工在秘密领导人选举中拥有的投票数,并被定义为与矿工承诺给网络的有用存储量呈线性增长。

更确切地说,我们有以下定义:

  • Raw-byte power:一个扇区的大小,以字节为单位
  • Quality-adjusted power:网络上存储数据的共识算力,等于原始字节算力乘以扇区质量乘数

2.4.4.3 Beacon Entries

Filecoin协议使用由drand 信标产生的随机性来播种无偏的随机性种子,以便在链中使用(见随机性)。

这些随机性种子被以下角色使用:

  • sector_sealer作为SealSeeds,将扇区承诺绑定到一个给定的子链上
  • Post_generator作为PoStChallenges来证明扇区在给定的区块上仍然是承诺的
  • 存储算力子系统作为秘密领导人选举中的随机性,以确定矿工被选中开采新区块的频率

这种随机性可以由使用它们的各自协议根据其安全要求从各种Filecoin链纪元中提取。

需要注意的是,一个给定的Filecoin网络和一个给定的drand网络不需要有相同的轮回时间,也就是说,区块由Filecoin生成的速度可能比随机性由drand生成的速度快或慢。例如,如果drand信标产生随机性的速度是Filecoin产生区块的两倍,我们可能期望在一个Filecoin纪元中产生两个随机值,相反,如果Filecoin网络的速度是drand的两倍,我们可能期望每隔一个Filecoin纪元产生一个随机值。因此,根据两个网络的配置,某些Filecoin块可能包含多个或没有drand条目。此外,必须是在中断期间对drand网络的任何调用以获得新的随机性条目都应该是阻塞的,正如下面的drand.Public()调用所指出的。在所有情况下,Filecoin区块必须包括区块头的BeaconEntries字段中自上个纪元以来产生的所有drand信标输出。任何使用特定Filecoin纪元的随机性都应该使用Filecoin区块中包含的最后一个有效的drand条目。这显示在下面。

2.4.4.4 Tickets

Filecoin区块头也包含一个由其纪元的信标条目生成的单一 “票”。票据用于打破分叉选择规则中的平局,用于同等重量的分叉。

当在Filecoin中比较票据时,比较的是票据的VRF摘要的字节数。

在Filecoin的一个纪元n,使用纪元n的适当信标条目生成一个新票据。

矿工通过一个可验证的随机函数(VRF)运行信标条目,以获得一个新的唯一票据。该信标条目以票域分离标签为前缀,并与矿工行为人地址相连接(以确保使用相同工人密钥的矿工获得不同的票)。

randSeed = GetRandomnessFromBeacon(n)
newTicketRandomness = VRF_miner(H(TicketProdDST || index || Serialization(randSeed, minerActorAddress)))

每张票据都应从VRF链中的前一张票据生成,并进行相应的验证。

2.4.4.5 Minimum Miner Size

为了确保存储算力共识,系统定义了参与共识所需的最小矿工规模。

具体来说,矿工必须至少拥有 MIN_MINER_SIZE_STOR 的算力(即目前用于存储交易的存储算力),才能参与领袖选举。如果没有矿工拥有MIN_MINER_SIZE_STOR或更多的算力,那么拥有至少与矿工前几名 MIN_MINER_SIZE_TARG(按存储能力排序)中最小的矿工一样多的算力的矿工将能够参与领袖选举。通俗地说,以MIN_MINER_SIZE_TARG=3为例,这意味着至少拥有与第三大矿工一样多的算力的矿工将有资格参与共识。

小于此数的矿工不能在网络中开采区块并获得区块奖励。他们的算力仍将被计入网络总的(原始或声称的)存储算力,尽管他们的算力不会被计入领袖选举的投票。然而,需要注意的是,这样的矿工仍然可以让他们的算力出现故障并受到相应的惩罚。

因此,为了启动网络,创世区块必须包括矿工,可能只是CommittedCapacity sectors,以启动网络。

MIN_MINER_SIZE_TARG条件不会被用于任何矿工拥有超过MIN_MINER_SIZE_STOR算力的网络中。然而,它的定义是为了确保小型网络的活泼性(例如,在接近创世的时候或在大量算力下降之后)。

2.4.4.6 Storage Power Actor

2.4.4.6.3 The Power Table

一个给定的矿工在EC中通过领袖选举产生的区块部分(因此他们获得的区块奖励)与他们在一段时间内的 Quality-Adjusted Power Fraction 正比。也就是说,一个矿工的质量调整算力占网络上总质量调整算力的1%,他应该在预期中开采1%的区块。

SPC提供了一个算力表抽象,它跟踪矿工的算力(即矿工存储与网络存储的关系),随着时间的推移。算力表在新的sector承诺(增加矿工算力)、失败的PoSts(减少矿工算力)或其他存储和共识故障时被更新。

扇区证明承诺(ProveCommit)是第一次向网络证明算力,因此算力在扇区证明承诺成功后首先被添加。当一个扇区被宣布为已恢复时,也会增加算力。矿工们应该证明他们所有的扇区,这些扇区对他们的算力有贡献。

当一个扇区过期时,当一个扇区被宣布或检测到有问题时,或者当它通过矿工的调用被终止时,算力就会被减去。矿工也可以通过ExtendSectorExpiration延长一个扇区的寿命。

算力表中的矿工生命周期应该大致如下:

  • 矿工注册。一个新的矿工与一个相关的工人公钥和地址被存储采矿子系统在算力表中注册,以及他们相关的扇区大小(每个工人只有一个)。
  • UpdatePower:这些算力增量和减量是由不同的存储角色调用的(因此必须由网络上的每一个完整的节点进行验证)。具体来说。
    • 算力在ProveCommit时被增加,作为miner.ProveCommitSector或miner.ProveCommitAggregate的一个子调用
    • 在错过WindowPoSt(DetectedFault)后,分区的算力会立即被递减。
    • 当一个特定的扇区通过Declared Faults或Skipped Faults进入故障状态时,该扇区的算力将被减去。
    • 在宣布恢复并经PoSt证明后,一个特定扇区的算力被添加回来。
    • 当某一扇区过期或因矿工干预而终止时,该扇区的算力将被移除。

总而言之,只有处于活跃状态的区块才会获得算力。当一个矿区在ProveCommit时被添加,它就成为活跃状态。当它进入故障状态时,算力会立即被减去。当其声明的恢复被证明时,算力将被恢复。当一个扇区过期或通过矿工干预而终止时,该扇区的算力将被移除。

Search

    Table of Contents