一、比特币时间同步
比特币采用Pow共识机制,即不断调整Nonce值,对区块头做双重SHA256哈希运算,使得结果满足给定数量前导0的哈希值的过程。其中前导0的个数,取决于挖矿难度,前导0的个数越多,挖矿难度越大。
具体流程如下:
首先,生成铸币交易,并与其它所有准备打包进区块的交易组成交易列表,生成Merkle根哈希值;
其次,将Merkle根哈希值,与区块头其它字段组成区块头,80字节长度的区块头作为Pow算法的输入;
再次,不断变更区块头的随机数Nonce,对变更后的区块头做SHA256哈希运算,与当前难度的目标值做对比,如果小于目标难度,即Pow完成;
最后,Pow完成的区块向全网广播,其它节点将验证其是否符合规则,如果验证有效,其它节点将接收此区块,并附加在已有区块链之后;
之后,将进入下一轮挖矿。
当新的区块产生或者其他节点发送过来一个新的区块时(generateBlocks/net_processing),都会进行如下校验:
1 CheckBlock区块校验
1.1 范围检查(Check range)
validation.processNewBlock() –> validation.checkBlock() –> CheckProofOfWork
首先将难度编码为指定大数类型(arith_uint256),判断编码过程中是否有溢出,负数,或难度小于当前链的最低难度情况,如果存在,返回false
1.2 工作量证明(Check proof of work matches claimed amount)
将hash转换为指定的大数类型(arith_uint256),与块头难度编码后的值进行比较。如果大于块头难度,返回false。否则返回true。该函数用来判断:块头哈希与块中声明的难度是否吻合(即该区块的工作量是否正确,独立于上下文)。
2 尝试把区块信息写入硬盘内(Store to disk)
在写入之前再校验一次区块头中的时间戳。
2.1 比较当前产生区块的时间戳blockTime与前nMedianTimeSpan(默认11)个区块时间排序的中位值medianTime
这里有两个问题要注意:
1,当前产生的区块的时间戳blockTime并不是直接取本地系统时间,而是当前时间+偏移量(可以理解成网络延迟)。
偏移量的计算方法:
◎取网络上其他节点的系统时间x(建立节点时发出version请求)
◎计算出x与本地系统时间的差值的绝对值=y
◎取n个y并排序,n的值在5-200中间
◎取上述排序的中位数即为偏移量(网络延迟)
◎其他节点数量小于5个则取本地时间
2,比较的时间并不是上一个区块结束的时间,而是中位数时间,因为每一个块的时间是矿工随意填写的一个值,所以取到这 11 个块之后,进行一次排序,取第 6 个块的时间来作为真正需要去比较的时间,6个块的时候,这个链就处于一个稳定的状态,所以,这种方式能够有效的降低随意性。
如果当前区块的时间戳blockTime小于等于上述中位值medianTime的话,校验不通过,返回false:block’s timestamp is too early.
2.2 当前产生区块时间戳blockTime与最大允许时间误差MAX_FUTURE_BLOCK_TIME(默认26060,可以自定义)进行比较
如果当前区块时间大于系统时间+最大允许误差时间时,校验不通过,返回false:block timestamp too far in the future.
比特币的共识机制是POW,通过算力竞赛选择出块的节点。出块时,区块时间戳设置为当前时间加上网络延迟时间,并且要求大于之前的11个区块按时间戳排序后的中间的那个区块的时间戳。出块后其它节点验证Pow、MerkleRoot和交易。每隔2016个区块,系统会调整挖矿难度,使得每个块的生产时间约为10分钟。
version
节点通过发送version消息连接到一个对等节点。消息version 包含了节点的版本信息、块信息和时间戳。这个消息被对等节点收到,如果它愿意建立对等关系,它将发送自己的version消息。
一旦建立对等关系,节点可以向远程节点发送getaddr和addr消息来获得其它的对等节点信息。为了维持与对等节点的连接,节点默认情况下每30分钟内会给对等节点至少发送一次信息。如果超过90分钟没有收到回复,节点会认为连接已经断开。
version内容:
一个节点收到连接请求时,它立即宣告其版本。在通信双方都得到对方版本之前,不会有其他通信。
字段尺寸 | 描述 | 数据类型 | 说明 | |
---|---|---|---|---|
4 | version | uint32_t | 节点使用的协议版本标识 | |
8 | services | uint64_t | 该连接允许的特性(bitfield) | |
8 | timestamp | uint64_t | 以秒计算的标准UNIX时间戳 | |
26 | addr_me | net_addr | 生成此消息的节点的网络地址 | |
version >= 106 | ||||
26 | addr_you | net_addr | 接收此消息的节点的网络地址 | |
8 | nonce | uint64_t | 节点的随机id,用于侦测这个连接 | |
? | sub_version_num | var_str | 辅助版本信息 | |
version >= 209 | ||||
4 | start_height | uint32_t | 发送节点接收到的最新block | |
https://zh-cn.bitcoin.it/wiki/%E5%8D%8F%E8%AE%AE%E8%AF%B4%E6%98%8E#version
二、以太坊时间同步
1,以太坊中区块的时间戳由矿工填写,取的是矿工的本地系统时间tstamp。
◎如果tstamp小于或等于上一区块时间戳时:取上一区块时间戳+1作为tstamp。
◎如果tstamp大于本地系统时间+1时:一直等待到系统时间到达tstamp时,才会打包并广播区块。
这种机制保证了当用户的系统时间太超前时,本地挖矿将延迟处理。
2,其他节点在验证矿工发送过来的新区块时,如果区块时间晚于本地时间则不处理,这意味着矿工的日期如果设置的太超前,将得不到有效的确认数。
3,另外如果矿工的本区块时间戳如果太接近上一区块时间戳甚至等于或早于上一区块时间戳的话也不会被接受,因此矿工日期如果设置的太落后或者恶意填写时间戳的话也得不到有效的确认数,从而失去本区块的记账权。
由此不难发现,以太坊鼓励用户将系统时间调整至系统运行的标准时间,否则挖矿也将会以失败告终。
三、比特股时间同步
比特股的共识机制是DPOS,全网投票产生101个出块节点,依次出块,每隔一段时间101个出块节点重新排序。出块时,block interval是一个slot对应的时间段,区块时间戳是block interval的整数倍。如果某slot,对应的scheduled witness未出块,则跳过该块。出块后其它节点会校验区块时间,校验条件为(now-timestamp)/1000 > -5000,其中校验节点的当前时间为now,收到的区块时间戳为timestamp,单位为ms。
DPOS算法分为两部分:投票选出一组区块生产者和调度生产。
1,投票
出块节点由持币用户选举投票产生,每个用户的投票权重则按照用户持币占系统总量比例计算。全网持有代币的人可以通过投票系统来选择区块生产者,一旦当选任何人都可以参与区块的生产。
优点:投票的人是最终受益人;
缺点:选举流程是否保证权益所有者最终控制网络存疑。
2,正常流程
在正常情况下,区块生产者轮流每3秒产生一个区块。任何时刻,只有一个生产者被授权产生区块。如果在某个时间内没有成功出块,则跳过该块。
DPOS的基本规则是我们总是应该选择最长的区块链。任何时候,一个诚实的节点看到另一个合法的且更长的区块链,它应该总是切换到那个更长的额分支上。
假设没有生产者错过自己顺序,那么他们生产的链条势必是最长的链条。在区块生产者在非指定时间生产区块会被认为是无效的。
注:无法超前出块攻击,因为某一时刻,只有一个生产者被网络授权产生区块,其它生产者产生的区块视为无效。
在正常情况下,DPOS块链不会经历任何叉,因为块生产者合作生产区块而不是竞争。如果有区块分叉,共识将自动切换到最长的链条。具有更多生产者的区块链长度将比具有较少生产者的区块链增长速度更快。此外,没有块生产者应该同时在两个区块链分叉上生产块。如果一个块生产者发现这么做了,就可能被投票出局。
,3,少数群体的分叉
可以允许少数出块节点是恶意或者故障,从而导致出现分叉。在这种情况下,少数分支长度小于大多数分支。
4,隔离环境下的重复块生产
少数群体可能尝试一个无限数量的分叉,但所有分支都将比主链短,因为少数群体在链的成长上更慢。
5,网络碎片
网络非常有可能碎片到,没有哪一个链上的区块生产者占到了所有区块生产者中的大多数。在此情景下,最长的哪个链将变成最大的少数群体。当网络连接恢复正常后,相对较小的那些群体将自然的切换到最长的链,从而将恢复明确的共识。
还有一种非常可能的情况是,三个分支中,最大的两个分支一样大。此时,将由相对更小的第三个分支加入网络时来打破僵局。存在奇数个区块生产者,所以僵局一般不会持续很久。
另外,区块生产者每隔一段时间,会随机生成顺序,以保证即使两个分支具有相同数量的生产者,分支也将以不同的长度爆发增长,最后一个分支最终接管另一个分支。
6,少数群体重复生产
在这种情况下,少数群体在自己可以生产的时间节点,同时创建两条,或多条区块链。下一个执行的生产者,将选择可选链中的任一条。该生产者选中的这条链将成为最长的链。
7,最后的不可逆区块
在网络碎片的情况下,多个分叉可能持续较长时间的隔离。长远来看,最长的链将最终受到认可。但观察者需要一种手段来确定某个块是否是在最长链条的一部分。这可以通过大多数区块生产者是否对某个块有确认。如果大多数生产者都已经确认了。由此可以认为不可能存在更长的链了。因为大多数链是诚实的。
8,不足法定区块生产者
在一些不太可能的情况下,生产者没有明确达到法定人数,少数人可能继续生产块。在继续生产的区块中,利益相关者可以包含一些改变投票的交易。这些交易会选举一组新的区块生产者,并将区块生产者参与度恢复到法定人数。一旦发生这种情况,少数人链最终会成为最长的链。
在这个流程发生时,所有的观察者必须要明白整个网络处于不稳定的状态,知道多于67%参与者出现后才会稳定下来。
注:这种情况下,需要发起交易的人明白其中的风险,知道生产者不足,网络不稳定。
优点:DPOS可以在大多数生产者失败的情况下,继续工作。在这种情况下,社区可以投票来替换失效的生产者,直到恢复到法定数量的生产者。
9,大多数区块生产者的腐败
如果大多数区块生产者合谋变得腐败,他们制造无限数量的分支,每一个分支都有大多数的签名。在这样的场景里,最后不可逆转块算法退化为最长链算法。此时最长的,获得了最大的群体认证的,将由少数的诚实节点的加入来确定。这样的情形不会持续很久,因为利益相关者会最终投票换掉这些区块生产者。
注:大多数区块生产者作恶将转化为最长链算法,依赖少数诚实节点最终确定最长链。
10,生产者的顺序是随机的
生产者集合每N个块就将随机一次,其中N是生产者的数量。
注:节点随机排序,可以防止DOS攻击。
转载请注明来源