Skip to content

解决以太坊区块重组

突然报告有用户卡在注册流程走不下去,已经注册成功还是不断被要求注册,这是什么问题呢?首先看一下项目架构,前端后端合约端,不了解的请在本专栏第一篇文章中一览详情。查看了用户在区块浏览器上面的 transaction 记录,有一条成功注册的记录,那么中间发生了什么呢?

问题排查

既然用户已经在链上注册成功,为什么数据库中却没有这条记录呢?

那我们从下往上一步一步排查,数据库中的内容来源是 event,后端解析监控到的智能合约发出的 event 来生成一些数据。既然数据库里面没有,我们去看一下 event 记录里面有没有。

在 event 原始数据表中找了一下,并没有找到这个 event,这样就比较奇怪了。折回去看了用户 transaction 所在区块,查了一下表中这个区块中发出的 event,发现这个区块中并没有我们智能合约发出的 event。然后把线上的日志 down 下来排查。

我们给合约发出来的 event 加了一个唯一自增 ID 来保障他的时序性和唯一性,在 event 监控部分的工作中针对他的时序性和唯一性做了处理(同一个 ID 的 event 只处理一次),这下找到问题了:我们发现了一个「并不存在」的区块数据,区块 hash 和链上的区块 hash 不一致,区块重组了。

由于被重组的区块一下占用了十几个 event 的 ID,在它被重组后,最长链上的 ID 进来之后不会被处理了,这就导致在这十几个被占用的 ID 之间有几名用户注册的事件没有按照期望同步到后端。

问题解决

  • event 订阅中,是有一个 Removed 字段的,代表这个 event 所在的区块被重组了。
  • 我们给收到的 event、由 event 产生的各种数据 加上区块高度和区块 hash 记录,当一个区块被重组时,把对应的 event、产生的 数据清理掉就好了。
    • 这里注意: Removed 字段也并不是 100% 可靠,我司就遇到过节点通知区块被重组,实际上并未被重组的事情。

吃一堑长一智

  • 项目中重要的功能部分,文档中的每一个字段都要吃透
  • 准备学习 Solidity 的小伙伴,每一个修饰符都要吃透
  • 做 Dapp 项目的公司,区块重组是必定要考虑在内的因素

Comments

Commenting as a guest. A nickname is required; email is optional. Only new comments posted after verifying your email and signing in will appear on your profile. Existing guest comments will not be linked automatically.

Share article

解决以太坊区块重组

Email X

View original ↗