Skip to main content

快照核查

面临的问题#

当验证节点从快照启动时,它需要一种方法来验证账户集与网络其他部分所看到的快速匹配。 潜在的攻击者可以给验证节点一个不正确的状态,然后试图说服它接受一个本来会被拒绝的交易。

解决方案#

目前,银行哈希值是通过对一个插槽中账户的差异状态进行哈希,然后与之前的银行哈希值相结合而得出的。 这样做的问题是,哈希值列表将按链处理的插槽数顺序增长,成为传输和验证成功的负担。

另一种原始的方法可以是创建一个账户状态的哈希树。 这样做的缺点是,每次账户更新,都要从系统中所有活账户的整个账户状态中重新计算出哈希树。

为了验证快照,我们进行以下工作:

在非零lamport账户的账户存储中,我们对以下数据进行哈希处理:

  • 帐户所有者
  • 账户数据
  • 帐户公钥
  • 账户余额
  • 帐户存储分叉

使用这个产生的哈希值作为一个扩展函数的输入,该函数将哈希值扩展为一个图像值。 该函数将创建一个440字节的数据块,其中前32个字节是哈希值,接下来的440-32个字节由Chacha RNG以哈希值为种子生成。

然后用xor结合账户图像。 前一个账户值将被xored到状态,新的账户值也被xored到状态。

投票和sysvar哈希值与产生的完整映像值的哈希值一起发生。

在验证节点启动时,当它从快照加载时,它会用设置的账户验证哈希值。 然后,它将使用SPV来显示投票支持所给哈希值的网络百分比。

由此产生的值可以被验证节点验证为所有当前账户状态一起xoring的结果。

在创建之前和验证过程中,必须清除零lamport账户的快照,因为零lamport账户不会影响哈希值,但可能会导致验证节点银行读到一个账户不存在,而它确实应该存在。

可以对xor状态进行攻击来影响它的值:

因此,440字节的图像大小来自于这篇论文,避免xor与0的碰撞(或因此任何其他给定的比特模式):[https://link.springer.com/content/pdf/10.1007%2F3-540-45708-9_19.pdf]

在这种情况下,数学提供了128位的安全性。

O(k * 2^(n/(1+lg(k)))
k=2^40 accounts
n=440
2^(40) * 2^(448 * 8 / 41) ~= O(2^(128))