什么是PoH
- 通过SHA256之类的Hash加密函数,来计算生成序列,提供验证两个事件(这里可以理解为两个区块生成)之间的时间流逝。
- 创世区块中,第一笔交易Hash函数的输入是一个随机值,然后该函数的输出,将是下一次Hash函数计算的输入参数之一:
PoH序列 |
|
|
Index |
Operation |
Output Hash |
1 |
sha256(“any random starting value”) |
hash1 |
2 |
sha256(hash1) |
hash2 |
3 |
sha256(hash2) |
hash3 |
自此以下,上一笔的hash函数输出,都会是下一笔hash函数的输入实参之一。 |
|
|
- 不用每个序列(区块)的Hash及其索引,PoH Generator都要发给下游的Validators;而是每隔一段时间才发:
PoH序列 |
|
|
Index |
Operation |
Output Hash |
1 |
sha256(“any random starting value”) |
hash1 |
200 |
sha256(hash199) |
hash200 |
300 |
sha256(hash299) |
hash300 |
- 这个PoH可证明的序列,在技术实现上应注意两个关键点:
- Hash函数要是抗碰撞的,因为一旦可以发生碰撞,就会出现Hash值相同,从而无法区分序列;
- 该Hash的计算应在单核上,以单线程的方式来计算,因为该Hash的计算是依次顺序依赖上一次Hash计算输出的。
- 最终,基于PoH生成的链式证明如下:
将外部事件的时间戳囊括进来
- 只是纯粹地生成序列(区块),是没有意义的,该区块里应还能承载外部的事件(Events)。
- combine函数将把现实世界关联的数据,与当前序列的Index和Hash结合起来,再通过hash函数计算,产生不同于上节所述的序列(包含了外部信息),也同样可以挂载可证明的链上的,比如从Solana链下来了一张照片:
PoH Sequence With Data |
|
|
Index |
Operation |
Output Hash |
1 |
sha256(“any random starting value”) |
hash1 |
200 |
sha256(hash199) |
hash200 |
300 |
sha256(hash299) |
hash300 |
336 |
sha256(append(hash335, photograph sha256)) |
hash336 |
-
combine函数可以是如上表中的hash拼接,也可以是任何其他抗碰撞的操作;此时序列的生成就如下图:
-
任何拿到此类带Events的序列,也是可复现这个序列的;而这个证明过程则可并执行的。
如何证明所生成的历史证明
- 可以将PoH序列切割成多个片段,然后交给多个核来证明或验算:
Core 1 |
|
|
Index |
Data |
Output Hash |
200 |
sha256(hash199) |
hash200 |
300 |
sha256(hash299) |
hash300 |
Core 2 |
|
|
Index |
Data |
Output Hash |
300 |
sha256(hash299) |
hash300 |
400 |
sha256(hash399) |
hash400 |
|
|
|
显然,多个核的并发处理肯定要更快,这也是PoH按顺序输出带来的一个福利吧。 |
|
|
- 理论情况下,一个序列被证明所要花费的最短时间为:
Solana网络如何横向扩展规模
- 从上节,我们了解了Verifying的动作是可以并发的,所以这个证明工作的横向扩展是没有问题的。
- 但PoH Generating的动作,则是串行、单线程的,它该如何扩展,以便扩充Solana网络的处理能力?
- 集群划分片区,独立提供服务,肯定是可以提高吞吐量的,但这种分区是完全割裂的,实际上是两条独立的Solana区块链网络;
- 混入两个PoH生成器生成的Hash,可以保障时间序列证明链的同时,也可以让不同PoH生成器,去各自承担一部分外部的Event:
- 要注意的一点,这种扩充规模的方式,是1+1 < 2的,是要损失若干性能的:
PoH Generator A |
|
|
PoH Generator B |
|
|
Index |
Hash |
Data |
Index |
Hash |
Data |
1 |
hash1a |
|
1 |
hash1b |
|
2 |
hash2a |
hash1b |
2 |
hash2b |
hash1a |
3 |
hash3a |
|
3 |
hash3b |
|
4 |
hash4a |
|
4 |
hash4b |
|
- 通信没有100%的正确率,多次交互叠加一起,会让错误率更大:
假设10gbps的网络的可靠性达到了0.999,但经过10次通信叠加后,这个可靠性只有0.99910=0.99。
如何保障一致性
- 当存在恶意的PoH Generator,可能会生成与正常序列不一致的序列:
PoH Generator A |
|
|
PoH Generator B |
|
|
Index |
Data |
Output Hash |
Index |
Data |
Output Hash |
10 |
|
hash10a |
10 |
|
hash10b |
20 |
Event1 |
hash20a |
20 |
Event3 |
hash20b |
30 |
Event2 |
hash30a |
30 |
Event2 |
hash30b |
40 |
Event3 |
hash40a |
40 |
Event1 |
hash40b |
- 面对两个序列,都包含了关心的Events,但存放在链上的顺序不同,我们该信谁?
- 交由用户来裁决:客户端会把它所认可的最新的序列的Hash,与它的event绑定,生成新的Event,而用这个Event来作为此次Hash生成的输入参数之一。
PoH Generator A |
|
|
Index |
Data |
Output Hash |
10 |
|
hash10a |
20 |
|
hash20a |
30 |
|
hash30a |
40 |
|
hash40a |
- 这样,上上张表中的恶意PoH Generator,如果作恶,用户从他绑定的Event里,就很容易被发现其序列的顺序有误,从而不被认可;由于没有人认可,所以它造再多的恶也没有用。
- 为了防止恶意Generator拿到了用户原始内容event,引入不合规的hash来生成Event,进而作恶,客户端可以,并且实际上提交的是敏感信息的签名,如下表:
PoH Generator A |
|
|
Index |
Data |
Output Hash |
10 |
|
hash10a |
20 |
Event1 = sign(append(event1 data, hash10a), Client Private Key) |
hash20a |
30 |
Event2 = sign(append(event2 data, hash20a), Client Private Key) |
hash30a |
40 |
Event3 = sign(append(event3 data, hash30a), Client Private Key) |
hash40a |
- 到现在,序列的生成和序列就成下图所示的样子了:
生成PoH后会带来哪些开销
以每秒4000个hash来算:
- ⽣成额外的 160 KB 数据。
- 具有 4000 个内核的GPU花费⼤约 0.25-0.75 毫秒的时间来验证。
PoH会有哪些风险点,如何防御
逆序攻击( Reversal)
- 什么是逆序攻击?
就是攻击节点,针对PoH序列中第二个Event开始(第一个Event是随机种子的导入),就可能编排入恶意的序列。
- 允许其它节点从创世序列来延续后续的Events。
- 在前面保持链网络系统 一致性,我们提到,PoH的生成,是允许客户端选择它认可的前导Event,并它混入自己的Event里,通过这些信息,就可以很容易地找出恶意序列与攻击切入点。
抢跑攻击(Speed)
- 什么是抢跑攻击?
恶意节点的具有高性能的配置(计算速度快,网络带宽高等),理论上存在拥有PoH Generating的权利,并创建有利于自己的最长序列(链的验证者(Validators)一般都会采取贪婪算法,以便获得更多奖励,因此这种最长序列,理论上最易被共识认识)。如何防御这种攻击?
- 让所有正常的节点,都升级,让作恶者的高性能优势荡然无存;但费用太高。
- Solana推荐采用多个PoH Generator混合的方式,以更小的成本来阻止此类攻击的发生:
- 一个generator计算能力弱些,但带宽高,因此可以接收较多的Events,并将它们排序好就可;
- 另一个generator则带宽低,但计算能力强,它周期性地混入上面节点Events序列;
- 后一个generator可以计算得到第二个序列:Data序列;
- 而这第二序列将是比较长的,从而会使得恶意节点的抢跑,变得无效。
可以看到它,这种多节点混合的方式,将以更小的平均成本,有效地防御那些高性能的恶意节点。
长程攻击(Long Range attack)
- 什么是长程攻击?
采用PoS共识机制的链会比较容易受到此类攻击,因为攻击都拿到最多的股权质押,就可以通过不断地共识,在经历较长序列后,理论上是有可能制造出有利于自己的最长序列(链)。
- Solana区块链网络中的节点的私钥采用了密钥演化算法,会自动更新;恶意节点拿到老旧的私钥期间,整个区块链的长度肯定会去增长;当恶意节点成为Leader,拥有PoH Generating的权利时,它要作恶,就必须生成同样或超过正常链长的节点数量。
- 但在正常Leader生成链块时,已通过PoRep协议,将这些正常链块复制给了Verifiers,那作恶节点成为Leader生成的伪造区块,也将得不到Verifiers的共识或认同。
注:针对长程攻击,是结合PoH和PoRep来防御的。