---
title: 快照核查
---

## 面临的问题

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

## 解决方案

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

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

为了验证快照，我们进行以下工作：

在非零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](https://link.springer.com/content/pdf/10.1007%2F3-540-45708-9_19.pdf)\]

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

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