趣文网 > 作文大全

Filecoin 规范解读——系统节点

2020-11-24 00:20:01
相关推荐

节点类型

Filecoin 节点是符合 Filecoin 协议规范的完整软件和硬件系统。

节点基本数据结构定义如下:

type FilecoinNode struct { Node libp2p.Node // p2p节点

Repository repo.Repository // 资料库数据,存储区块链数据 FileStore filestore.FileStore // 本地文件存储库,暂存存储在Filecoin中的文件 Clock clock.UTCClock // 时钟

MessagePool message_pool.MessagePoolSubsystem // 消息池子系统,存储未上链消息}

Filecoin 网络存在各种类型的节点:

链验证节点

type ChainVerifierNode interface { FilecoinNode

systems.Blockchain}

客户端节点

type ClientNode struct { FilecoinNode

systems.Blockchain markets.StorageMarketClient markets.RetrievalMarketClient markets.MarketOrderBook markets.DataTransfers}

用于存储数据的客户使用。拥有区块链数据,存储市场客户端、索引市场客户端、市场订单表、数据传输等子系统。

存储矿工节点

type StorageMinerNode interface { FilecoinNode

systems.Blockchain systems.Mining markets.StorageMarketProvider markets.MarketOrderBook markets.DataTransfers}

用于存储数据的存储矿工使用。拥有区块链数据、挖矿、存储市场供应商、市场订单表、数据传输等子系统。

索引矿工节点

type RetrievalMinerNode interface { FilecoinNode

blockchain.Blockchain markets.RetrievalMarketProvider markets.MarketOrderBook markets.DataTransfers}

用于索引数据所需的索引矿工使用。拥有区块链数据、索引市场供应商、市场订单表、数据传输等子系统。

中继节点

type RelayerNode interface { FilecoinNode

blockchain.MessagePool markets.MarketOrderBook}

目前核心的是客户端节点和存储矿工节点。

数据仓库

数据仓库是用来本地存储 Filecoin 节点正常运行时所需要的数据。数据仓库采用 FileStore 存储节点的密钥、有状态对象的 IPLD 数据结构和节点配置。

type Repository struct { Config config.Config KeyStore key_store.KeyStore ChainStore ipld.GraphStore StateStore ipld.GraphStore}

节点配置

type ConfigKey stringtype ConfigVal Bytes

type Config struct { Get(k ConfigKey) union {c ConfigVal, e error} Put(k ConfigKey, v ConfigVal) error

Subconfig(k ConfigKey) Config}

节点配置可以根据 ConfigKey 获取和设置。

密钥存储

密钥存储用于存储与矿工地址对应的密钥对,节点安全基于这些密钥对的安全,所以建议把密钥对存放在另外的系统里。

type KeyStore struct { MinerAddress address.Address OwnerKey filcrypto.VRFKeyPair WorkerKey filcrypto.VRFKeyPair}

Filecoin 存储矿工依赖三个模块:

矿工地址调用存力共识子系统的 registerMiner()生成的唯一标识 ID。用于绑定矿工的存力和相关的密钥对。

所有者密钥对矿工注册时,公钥和矿工地址相关联的密钥对,矿工区块奖励等转账会转到这个公钥对应的地址。

工作者密钥对矿工可以选择和修改的密钥对,公钥关联矿工地址,用于签名交易等,必须是 BLS 密钥对。

矿工地址是唯一的,而多个矿工可以共享一个所有者密钥对和工作者密钥对。

在修改工作者密钥对时,会是两步过程。首先矿工向链上发送修改消息,当链上收到后,密钥对的修改会缓存随机性回溯参数数量的两倍时间进行更改,以防止进行自适应密钥选择攻击。每次查询工作者密钥对时,都会对延迟的更改进行延迟检查,并且可能会根据需要更新状态。

IPLD 数据结构

type Object interface { CID() cid.Cid

// Populate(v interface{}) error}

type GraphStore struct { // Retrieves a serialized value from the store by CID. Returns the value and whether it was found. Get(c cid.Cid) (util.Bytes, bool)

// Puts a serialized value in the store, returning the CID. Put(value util.Bytes) (c cid.Cid)}

Filecoin 数据结构是以 IPLD 格式存储,这是一种类似于 json 的数据格式,用于存储,检索和遍历散列链接的数据 DAG。

Filecoin 网络主要依赖两种 IPLD 数据:

ChainStore 存储了区块链数据,包括区块头,相关消息等。这是从其它节点下载而来,当有新区块产生或有新的最佳链,随时会更新。StateStore 存储了经过 Filecoin 虚拟机计算而来的区块链状态数据, 该状态数据由创世区块开始计算,当有新区块产生就会基于前一个区块状态计算出最新的状态。网络

Filecoin 节点使用 libp2p 协议发现节点、广播消息等。libp2p是一组点对点协议集合,节点通过该协议和其它节点通信,所有Filecoin协议会在 /fil/... 协议标识符下面。

以下是 Filecoin 使用到的 libp2p 协议:

Graphsync:用于传输区块链数据和用户数据,没有对应的协议标识符。Gossipsub:用于区块头部和消息的广播,节点可以订阅相关主题以获取该主题的消息,同时转发给其它订阅同一主题的节点。协议标识符为/fil/blocks/ 和 /fil/msgs/。KademliaDHT:用于发现节点的分布式哈希表,协议标识符为 /fil//kad/1.0.0。Bootstrap List:用于新节点连接入网络的初始化启动节点列表。Peer Exchange:可以帮助节点依据已连接节点的现有节点发现更多节点。Hello: 处理新连接的节点的寻找。协议标识符为 /fil/hello/1.0.0。以下以Hello协议为例:

hello协议包含两个过程:

hello_listen: 新建数据流 -> 从数据流中读取hello消息 -> 向数据流中写入延迟消息 -> 关闭数据流

hello_connect: 建立连接 -> 打开数据流 -> 向数据流中写入hello消息 -> 从数据流中读取延迟消息 -> 关闭数据流

这里数据流和连接操作都是标准 libp2p 操作。支持Hello协议的节点处理Hello消息并管理节点同步区块链。

消息数据结构:

import cid "github.com/ipfs/go-cid"

// HelloMessage 和其它节点共享当前节点信息type HelloMessage struct { HeaviestTipSet [cid.Cid] HeaviestTipSetWeight BigInt HeaviestTipSetHeight Int GenesisHash cid.Cid}

// LatencyMessage 和其他节点共享节点延迟type LatencyMessage struct { // Measured in unix nanoseconds TArrival Int // Measured in unix nanoseconds TSent Int}

当向数据流写入 HelloMessage 时, 节点检查当前最新区块以提供当前节点信息。当向数据流写入 LatencyMessage 时,节点设置接收时间戳 TArrival 和发送时间戳 TSent。

时钟

type UnixTime int64 // 时间戳

// UTCClock 是一个一般的系统时钟,保持和UTC时间同步,误差在1秒以内type UTCClock struct { NowUTCUnix() UnixTime}

// ChainEpoch 表示一个区块轮type ChainEpoch int64

// ChainEpochClock 是一个表示区块时间的时钟type ChainEpochClock struct { // GenesisTime 是第一个区块的出块时间 GenesisTime UnixTime

EpochAtTime(t UnixTime) ChainEpoch}package clock

import "time"

// UTCSyncPeriod 表示多久从可信赖的时间源同步时间var UTCSyncPeriod = time.Hour

// EpochDuration 表示一个区块时间var EpochDuration = UnixTime(25)

func (_ *UTCClock_I) NowUTCUnix() UnixTime {return UnixTime(time.Now().Unix())}

// EpochAtTime 返回当前时间对应的区块高度func (c *ChainEpochClock_I) EpochAtTime(t UnixTime) ChainEpoch {difference := t - c.GenesisTime()epochs := difference / EpochDurationreturn ChainEpoch(epochs)}

Filecoin 假定系统参与者之间的时钟同步较弱。也就是说,系统依赖于参与者可以使用全局同步时钟(可承受一定限度的误差)。

Filecoin 依靠此系统时钟来确保共识。具体来说,时间是支持验证规则所必需的,该验证规则可防止块生产者使用未来的时间戳来挖掘块,并且防止矿工的出块权的次数超出协议允许的范围。

时钟使用

Filecoin 系统时钟使用在以下场景:

用于验证同步到的区块的对应高度和系统时间是否吻合,这是基于每个高度都和创世区块的时间差相吻合。删除同步到的时间是未来的区块。如果当前高度没有区块产生,依据协议生成下一高度的区块,以保证网络协议稳定。为了完成以上需求,系统时钟需要:

相对与其它节点有足够低的时钟误差(小于1秒),以保证不会挖出未来的区块。预设高度值和系统时间戳的关系为epoch = Floor[(current_time - genesis_time) / epoch_time]。其他子系统将时钟子系统注册到 NewRound() 事件。

时钟需求

Filecoin 协议中使用的时钟应该保证 1 秒以内的同步误差,以完成需要的验证。

系统级别的时钟可以通过以下方式提高其误差率以保证其要求:

客户端需要查询NTP服务来校准时间,比如 pool.ntp.orgtime.cloudflare.com:1234time.google.comntp-b.nist.gov。客户端可以在大型采矿作业中使用铯钟实现精确时间同步。矿工应该防止他们的时钟向前偏离一个高度以上,以防止其提交的区块被网络拒绝。同样地,它们应该防止其时钟向后漂移超过一个高度,从而避免将自己与网络中的同步节点分叉。

后续

后续将会介绍 Filecoin 系统文件数据的规范。

End

非常感谢您对 IPFS&Filecoin 项目的持续支持。我们很高兴继续与您一起,为人类信息建立一个强大的,去中心化和高效的基础。

本文来源: 金色财经 / 作者:FilCloud

阅读剩余内容
网友评论
相关内容
延伸阅读
小编推荐

大家都在看

感动的作文 第一次作文 餐桌前的谈话600字作文 我的好朋友作文600字 以幸福为话题的作文 我爱我的祖国作文 关于旅游的作文 如何写好作文 我的春节作文 写秋天的作文 熊猫的作文 作文我的梦想 军训作文 材料作文 关于幸福的作文 关于亲情的作文500字 我想对你说作文400字 以劳动为主题的作文 关于宽容的作文 运动会作文600字 关于大自然的作文 我和我的祖国作文 关于冬天的作文 清洁工作文 状物作文 优秀作文开头 春的作文 感恩父母作文300字 三年级植物作文300字 我的家乡作文200字