节点类型 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?string type?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/<network-name> 和 /fil/msgs/<network-name>。 KademliaDHT:用于发现节点的分布式哈希表,协议标识符为 /fil/<network-name>/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?/?EpochDuration return?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 帮你迅速了解 IPFS 领域的热点技术和应用公众号:filcloud —- 编译者/作者:FilCloud 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
Filecoin规范解读--系统节点
2020-07-30 FilCloud 来源:区块链网络
LOADING...
相关阅读:
- 标题中包含Key(Mykey)会带来什么效果2020-08-02
- 黑莓副总裁表示,加密劫持攻击被大大低估了2020-08-02
- 倾听是新兴市场创新的强大催化剂2020-08-02
- 价格上涨带来越来越多的比特币百万富翁2020-08-02
- 矿工和主节点:达世币的两层区块链架构2020-08-02