星际联盟计划提供对Filecoin Spec 的全文翻译,便于Filecoin项目广大中国参与者理解Filecoin的深层原理。文章将定期更新章节,请持续关注"IPFS星际联盟"&"星际联盟Filecoin"公众号。
2.1.3 网络接口
import libp2p "github.com/filecoin-project/specs/libraries/libp2p"
type Node libp2p.Node
Filecoin节点使用libp2p协议进行节点发现,节点路由和消息多播等。 Libp2p是一组点对点网络堆栈通用的模块化协议。 节点彼此之间打开连接,并在同一连接上挂载不同的协议或流。 在最初的握手中,节点交换它们各自支持的协议,并且所有与Filecoin相关的协议都将安装在/fil/…
协议标识符下。
Filecoin使用的libp2p协议列表如下:
- Graphsync:
- Graphsync用于传输区块链和用户数据
- 草案细则
- 没有对协议ID进行特定于Filecoin的修改。
- Gossipsub:
- 区块头和消息都通过Gossip PubSub协议进行广播,节点可以订阅区块链数据的主题并在这些主题中接收消息。当接收到与某个主题相关的消息时,节点将处理该消息,并将其转发给同样订阅了该主题的节点。
- 查看细则
- 没有对协议ID进行特定于Filecoin的修改。但是,主题标识符必须为
fil/blocks/
,<network-name>
fil/msgs/
格式<network-name>
- KademliaDHT:
- Kademlia DHT是一个分布式哈希表,对特定节点的最大查找次数有一个对数级的限制。 Kad DHT主要用于Filecoin协议中的节点路由与节点发现。
- 细则:待完成 (参考实现)
- 协议ID必须为
fil/<网络名称>/kad/1.0.0
格式
- Bootstrap列表
- Bootstrap是新节点加入网络后尝试连接的节点列表。Bootstrap节点列表以及节点的地址由用户定义。
- 节点交换
- 节点交换是一种发现协议,它使得节点能够针对其现有节点,创建和发出对所需节点的查询
- 细则: 待完成
- 没有对协议ID进行特定于Filecoin的修改。
- DNS发现:实现之前需要设计和规范
- HTTP发现:实现之前需要设计和规范
- Hello:
- Hello协议将处理与Filecoin节点的新连接,以促进发现
- 协议字符串为
fil/hello/1.0.0
。
2.1.3.1 Hello协议细则
2.1.3.1.1 协议流程
fil/hello
是基于libp2p堆栈的filecoin特定协议。 它有两个概念性的程序:hello_connect
和hello_listen
。
hello_listen: on new stream -> read peer hello msg from stream ->
write latency message to stream -> close stream
hello_connect: on connected -> open stream -> write own hello msg to
stream -> read peer latency msg from stream -> close stream
其中流和连接操作都是标准的libp2p操作。 运行Hello协议的节点应该使用传入的Hello消息,并使用它来帮助管理节点以及同步链。
2.1.3.1.2 消息
import cid "github.com/ipfs/go-cid"
// HelloMessage shares information about a peer's chain head
type HelloMessage struct {
HeaviestTipSet [cid.Cid]
HeaviestTipSetWeight BigInt
HeaviestTipSetHeight Int
GenesisHash cid.Cid
}
// LatencyMessage shares information about a peer's network latency
type LatencyMessage struct {
// Measured in unix nanoseconds
TArrival Int
// Measured in unix nanoseconds
TSent Int
}
当将HelloMessage
写入流时,节点必须检查其当前头以提供准确的信息。 当将LatencyMessage
写入流时,节点应在收到消息后立即设置TArrival
,并在将消息写入流之前立即设置TSent
。
2.1.4 时钟
type UnixTime int64 // unix timestamp
// UTCClock is a normal, system clock reporting UTC time.
// It should be kept in sync, with drift less than 1 second.
type UTCClock struct {
NowUTCUnix() UnixTime
}
// ChainEpoch represents a round of a blockchain protocol.
type ChainEpoch int64
// ChainEpochClock is a clock that represents epochs of the protocol.
type ChainEpochClock struct {
// GenesisTime is the time of the first block. EpochClock counts
// up from there.
GenesisTime UnixTime
EpochAtTime(t UnixTime) ChainEpoch
}
package clock
import "time"
// UTCSyncPeriod notes how often to sync the UTC clock with an authoritative
// source, such as NTP, or a very precise hardware clock.
var UTCSyncPeriod = time.Hour
// EpochDuration is a constant that represents the duration in seconds
// of a blockchain epoch.
var EpochDuration = UnixTime(15)
func (_ *UTCClock_I) NowUTCUnix() UnixTime {
return UnixTime(time.Now().Unix())
}
// EpochAtTime returns the ChainEpoch corresponding to time `t`.
// It first subtracts GenesisTime, then divides by EpochDuration
// and returns the resulting number of epochs.
func (c *ChainEpochClock_I) EpochAtTime(t UnixTime) ChainEpoch {
difference := t - c.GenesisTime()
epochs := difference / EpochDuration
return ChainEpoch(epochs)
}
Filecoin假定系统中参与者之间的时钟同步较弱。 也就是说,系统依赖于能够访问全局同步时钟的参与者(承受一定限度的偏移)。
Filecoin依靠此系统时钟来确保共识。 具体来说,时钟是支持验证规则所必需的,它可以防止区块产出者使用未来的时间戳挖矿,从而防止领导人选举的频率超出协议所允许的范围。
2.1.4.0.1 时钟用途
Filecoin系统时钟用于:
- 通过同步节点来验证传入的区块是否已在给定时间戳的适当时期内被挖出 (请参阅Block Validation(区块验证))。 这是可能的,因为系统时钟始终将时间映射到唯一的时期号,该时期号完全由创世区块中的创建时间确定。
- 通过同步节点删除来自未来时期的区块
- 通过允许参与者在下一轮尝试领导人选举(如果本轮没有人产出区块)的方式来挖掘节点,以保持协议的活跃性 (请参阅Storage Power Consensus(存储算力共识))。
为了允许矿工执行上述操作,系统时钟必须:
- 相对于其他节点必须具有足够低的时钟偏移(sub 1s),以便从其他节点的角度出发,不在被认为是未来时期的时期中开采区块 (在按照validation rules](验证规则)) 确定适当的时期/时间之前,这些块不应当被验证)。
- 将节点初始化上的时期数值设置为
epoch = floor[(current_time -genesis_time)/ epoch_time]
预期其他子系统将从时钟子系统注册到NewRound()事件。
2.1.4.0.1 时钟要求
时钟作为Filecoin协议的一部分应保持同步,且偏移值应少于1秒,以便进行适当的验证。
计算机级时钟晶体的偏移速率预计约为1ppm(即每秒1微秒或每周0.6秒),因此,为了满足上述要求,
- 客户端应每小时查询NTP服务器(建议使用
pool.ntp.org
)以调整时钟偏斜。- 我们建议使用以下之一:
pool.ntp.org
(可查询特定时区参见 specific zone)time.cloudflare.com:1234
(更多服务信息参见Cloudflare time services)- time.google.com(参见Google Public NTP)
- ntp-b.nist.gov(NIST服务器需要注册使用
- 我们进一步建议对时钟进行3次测量,以便通过使用网络丢弃异常值来进行丢弃
- 看看以太坊是如何激发灵感的
- 我们建议使用以下之一:
- 客户端可以考虑使用铯钟代替大型挖矿作业中的精确同步
操作挖矿有很强的诱因来防止他们的时钟向前偏移一个时期以上的时间,以防止提交的区块被拒绝。 同样,他们也有诱因来防止其时钟向后漂移超过一个时期,从而避免将自己与网络中的同步节点分开。
2.1.4.0.1 未来的工作
如果以上任一指标显示随时间推移出现明显的网络偏斜,则在Filecoin的未来版本可能会在定期间隙中添加潜在的时间戳/时间校正。
当从异常链网络暂停中断中恢复时(例如,所有给定的区块的implementations panic),网络可能会选择针对每个中断的“死区”规则,禁止在中断时期内编写区块,以防止在链重启时受到未挖掘时期相关的攻击向量。
Filecoin协议的未来版本可能会使用可验证延迟功能(VDFs)来强制执行区块时间并满足此leader选举要求;我们选择显式地假定时钟同步,直到硬件VDF的安全性得到更广泛的证明为止。