当前位置:主页 > 列表页 > 正文

通告 | 伦敦升级 Ropsten 测试网事故回顾

2021-07-30 00:30 | 出处: EthFans


Ropsten 共识问题


概述

2021年 7 月 21 日,OpenEthereum 团队注意到他们在 Ropsten 上的节点卡在了区块 10679538 处。人们原以为这是 OpenEthereum 的问题。其实,问题真正出在 go-ethereum 实现检查 1559 交易发送方余额的方式上。一个无效交易(发送方余额只够支付交易实际使用的 gas,而非交易指定的 maxFeePerGas 总额)被打包进了区块。由于 Ropsten 矿工运行的都是 go-ethereum,这个区块随后又被其它 go-ethereum 矿工接受,但是被网络中的其它一些客户端拒绝了。具体来说,OpenEthereum 和 Besu 拒绝了这个交易/区块,Nethermind、go-ethereum 和 Erigon(这些客户端实现的部分代码来自 go-ethereum 代码)接受了它。问题的根源已经找到,相关客户端已经在新的版本中修复了该问题:


问题区块的信息

eth.getBlock("0x1252a34c4f2b061adc609e909d958c02e1ac39043e2e60c0ec47e565e3f625f1"){  baseFeePerGas: 11,  difficulty: 1124214874,  extraData: "0 xd883010a05846765746888676f312e31352e36856c696e7578",  gasLimit: 8000000,  gasUsed: 1762587,  hash: "0 x1252a34c4f2b061adc609e909d958c02e1ac39043e2e60c0ec47e565e3f625f1",  logsBloom: "0 x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",  miner: "0 xfbb61b8b98a59fbc4bd79c23212addbefaeb289f",  mixHash: "0 x178c542ebd5b730aa141b3e07fce663b81d7f5485011cca55b5cd55dc39b2550",  nonce: "0 x98728302c513a677",  number: 10679538,  parentHash: "0 xe936ee0e5a915b9c163a7a1ff67269dd5f1ccb981f91b269a2130711e6a62598",  receiptsRoot: "0 x09a6eb2bf38000dd934b2cdc66f7f7923397ddd6d9cd1ac69379aaed73d00f1e",  sha3Uncles: "0 x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",  size: 5175,stateRoot: "0 xa942f7462d923a5e292627b**e1b20cc314bac31f7e72ecb02b65d954d12f758",  timestamp: 1626863988,  totalDifficulty: 34224959923696599,  transactions: ["0 x07ca8f5634d634e2eb67a9af6f9d510d73d3c2f0393f0e0490e7c0b4c18fdf0e", "0 x9dbef6da5331b085d1dcc70eaa028376fd0452c49992e5ddccc132f4d42467cc", "0 xdfa858a98cab341e540fc2da8abfd0b298df22a9ee9eff0c6e1edf4828ab9b84", "0 x01bdfaba318f4c0b2878db0d413a20d3a2669ebbaa5c4e8f6901bdc9a01a99ec", "0 xd9d2aa19f747b04863eb13a2698cd8a3c96b2463d2cf7eb60d7ca3ea8e2d45e3", "0 xf5ee17e9bf8bc4fe3325860d91535d1eb98bc1d83f39fe998e0b6c4706c581c5"],transactionsRoot: "0 x6e6f39318ad2e60969e2422977deffd42dc34ac7bdbb6fb1934541c044f18774",uncles: []}

测试网事故的时间线

(注:所有时间已转换成北京时间)。
2021 年 7月 21日
2021年 7月22 日
2021 年 7 月 23日


纠正措施建议


提高规范中断言(assertion)的清晰度

该提交新增了关于 EIP 1559 类型交易有效性的断言。具体来说,在第 217 行代码新增了以下断言:
assert sender.balance >= gasLimit * transaction.max_fee_per_gas
另外还要注意的是,在前几行代码(第 207 行)中,sender.balance 被修改成了减去交易量之后的部分(sender.balance -= transaction.amount)。这个参数引发了混乱,因为一些客户端团队在检查第 217 行定义的断言时使用的是全部 sender.balance(即,没有减去transactiion.amount 的发送者地址余额),而非更新后的值。


Go-Ethereum 恢复


@holiman 关于 go-ethereum 恢复的说明:


节点同步时跟随错误的链

假设你正在运行 geth,并处于同步中。区块 X 上发生了分叉。你的节点跟随了总难度较高的错误的链。在区块 Z,你停止了节点并将其更新至修复后版本。
问题描述:节点依然在 “错误” 的链上。
解决方案:执行 debug.setHead{X-1) 回到分叉发生之前。这会将节点倒回区块 X 之前的某个状态,不一定是区块 X-1 的状态,因为 geth 不一定有区块 X-1 的完整状态,但是会有其它某个区块的完整状态。通常情况下,geth 大约每隔 1 万个区块(1 小时)和/或宕机时会将状态刷到磁盘。如果 geth 在 gcmode=archive 下运行,就会将每个区块都刷到磁盘。


当错误的链总难度较高时进行同步

假设你正在同步一个 geth 节点,区块 X 上发生了分叉。由于分叉已经发生了,再加上错误的链总难度更高,你很可能会同步错误的链,pivot 区块是 X+M。在这种情况下,由于你没有区块 X+M 之前的状态,无法执行 debug.setHead 来解决这个问题。
这种情况需要重新同步。但是,你需要防止 geth 同步错误的那条分叉链。这可以通过 whitelist 命令行参数实现。
 geth -h | grep white  --whitelist value                   Comma separated block number-to-hash mappings to enforce (<number>=<hash>) 
因此,你需要执行 geth --whitelist 123123=0 x2342fafa9af9af9af9af9af9
所谓的白名单,就是一个 geth 节点在与另一个对等节点连接时会向对方请求区块 123123 的数据。如果该 geth 节点收到的区块头中的哈希与白名单中的不符,就会与之断开连接。这就意味着,节点将排斥错误的链上的对等节点,只与较短(但是正确的)链上的对等节点连接。


原文链接:

https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/retrospectives/london.md

作者: Tim Beiko

翻译&校对: 闵敏 & 阿剑
作者郑重申明:截至发文时,作者与文中提及项目存在利益关系,特此告知。利益关系包括但不限于下述情况:本人为项目团队成员、本人是项目团队成员的直系亲属或配偶、参与投资该项目、持有该项目发行的股份或通证、参与做空或做多该项目、收取回报进行有偿撰文等。
相关文章