此文中,我们会来看看同步以太坊节点过程中,到底会发生什么样的细节?
同步以太坊节点,对于很多人来说都是非常痛苦的事情。每个和以太坊接触的人都对这点感觉很不爽。
目前以太坊钱包默认的同步模式,叫做快速同步。和从创世区块开始,重新处理所有的转账不同(这会需要好几个星期),快速同步下载区块,然后只是验证和工作量证明相关的数据。下载所有区块是直截了当的,但是快速过程会相对快速地重新组成整个区块链。很多人错误地认为,因为他们有区块,所以在同步。
不幸地是,这不是问题的关键,因为没有任何转账被执行了(也就是说,为了验证区块链的有效性,没有转账进行),所以我们没有任何账户的状态(也就是,余额,记录,智能合约代码以及数据)。这些需求被分开下载,而且会和最新的区块交叉检测。这个部分叫做状态前缀树的下载,而且它实际上和区块下载同时运行;同时它比下载区块要花费更长的时间。
所以,什么是状态前缀树?在以太坊主网中,有无数的账户,这些会追踪每个用户的余额,数据等等,
这些账户本身是不足够去运行节点,他们需要和每个区块进行加密连接,从而节点能够验证账户没有被欺诈。这个加密连接是通过在账户上创建树状的数据结构来完成的,每个层级都和下面的层级连接,然后和更小的层级连接,直到你达到单个根数据。这种庞大的数据结构包含了所有账户和中间的加密证明,被称为状态前缀树。
那么为什么要提出这个问题?这种树状的数据结构是几百万个很小的加密证明相连接的、为了获得同步节点,你需要下载所有账户的数据,同时这些加密证明也会验证网络中没有任何东西尝试去欺骗你。这本身已经是非常夸张的数据了。它变得更加混乱的部分是这个数据不断地变化:每个区块(15秒),大约有1000个节点会从树状结构中删除,然后大约有2000个新节点会添加。这意味着需要同步数据库的节点正在以每秒200次的速度改变。最差的部分是让你在同步的时候,网络还在往前推进,并且你开始下载的状态也许会在你下载的时候小时,所以你的节点需要一直跟着网络进行,同时还需要获得所有最近的数据。但是当你实际上获得所有数据的时候,你的本地节点不能使用,因为它不能加密证明任何账户的任何信息。
如果你看到主网后面有64个区块,你还没有完全同步,甚至还差的很远。你只是完成了区块下载的部分,仍然在进行状态的下载。你可以通过无穷无尽的Imported state entries [...] ,来看到你自己的状态。当你的节点在线之前,你也需要等到它们出来。
Q:节点只是取决于输入的状态?
A: 节点不会暂停,它只是不会提前知道整个状态前缀树有多大,所以它会一直进行直到发现和下载了整个数据。
原因是以太坊区块中只有状态根部,根节点的单个哈希。当节点开始同步,它会完全直到1个节点,并且尝试下载。那个节点,可以对标高达16个新节点,并且尝试下载那些。随着我们继续进行下载,大多数的节点会和新的节点对标,而且我们那时候还不知道它们。这就是为什么你需要想想,为什么它会卡在同样的数字。随着时间,节点是在发现和下载树状数据。
Q: 我卡在了主网后的64个区块?
A: 就像上面解释的,你不是卡主了,是刚刚完成了区块下载阶段,正在等待状态下载完成。这部分花费的时间,比下载区块要长很多。
Q:为什么下载状态需要花费这么长时间,我有很高的带宽?
A: 状态同步是受制于磁盘输入输出,而不是带宽。
以太坊的状态前缀树包含了几百万个节点,大多数会是按照单个哈希对应至多16个其他哈希。在磁盘上,这是很恐怖的存储方式,因为其中几乎没有结构,只是随机的数字来反应甚至更多的随机数字。这会让底层数据库变得混乱,因为它不能优化存储以及使用任何有意义的方式来寻找数据。
不仅存储数据是非常不理想的,而且由于每秒200次的改变以及对过去数据的修改,我们甚至不能下载,这是一个正确的预处理方法,使它更快地导入,而底层数据库不太多。最终的结果甚至是快速的更新导致很高的磁盘输入输出费用,这对于机械硬盘来说,是非常大的挑战。
Q:这么说,我不能用硬盘驱动器来运行全节点?
A: 很不幸地是,确实不可以。在硬盘驱动器上进行快速同步,比起你等待目前的数据,会花费更多时间。尽管你确实等待了,硬盘驱动器也不能跟上主网转账处理的读写需求。
但是,你应该能够使用硬盘驱动器在轻客户端使用,因为会最小化对系统资源的影响。如果你想要运行全节点,那么固态硬盘就是唯一的选择。