如何处理 Solana 上的区块哈希错误

什么是区块哈希?

要理解什么是区块哈希,你必须了解什么是槽(slot)和区块。

  • 槽是验证者可以生成区块的时间段
  • 区块是验证者处理的交易和元数据的集合。每个区块中的元数据将其链接到前一个区块,从而创建一个链。

重要的是要了解,槽的持续时间在 400 到 600 毫秒之间,在每个槽中,验证者可以提出一个新的区块。如果未创建区块,则槽会递增,另一个验证者将尝试创建新的区块。这意味着并非所有槽都会有关联的区块,但所有区块都有它们被提出的关联槽。

好的,那么什么是区块哈希?区块哈希是在一个槽期间创建的所有区块链账目的唯一哈希值。 这是从区块的最后条目 ID 计算的 。每个生成的区块结果都是一个独特的区块哈希。这些区块哈希被用作时间戳。

Solana 的承诺级别是什么?

另一个重要的概念是承诺级别 。这些承诺级别衡量了特定区块的网络确认。三个选项是已处理(processed)、已确认(confirmed)和最终确任(finalized)。

当验证者向链提交一个区块时,该区块将处于已处理状态。一旦足够数量的验证者(66%的验证者 )投票以包含该区块,它将被添加到链中,承诺级别将变为已确认。一旦在该区块之上构建了额外的 31 个区块,承诺级别将变为最终确任。

为什么会发生区块哈希错误?

所有交易都包括一个最近的区块哈希,作为时间戳,当区块哈希不再被视为足够新时,该交易将过期。处理交易的验证者将检查“BlockhashQueue”(最近的 300 个区块哈希的列表),以查看交易的区块哈希是否足够新。如果区块哈希不在列表中,则交易将被拒绝。由于槽通常持续时间在 400 毫秒到 600 毫秒之间,一个区块哈希保持有效的时间为 60 到 90 秒。

区块哈希未找到(交易模拟失败:未找到区块哈希)

未找到区块哈希 ”错误发生在验证者处理交易时,交易中包含的区块哈希被认为无效。这可能是因为它太旧,或者在某些情况下,太新。

这种错误最常见的原因是,交易中包含的区块哈希不在验证者将与之进行比较的最近的 300 个区块哈希队列中。这将导致未找到区块哈希错误 。交易过期可能发生在交易在所需时间段内创建和处理。这可能是因为用户花费很长时间来签署交易。还可能出现这样的情况,即提交了有效的交易,但未包含在当前区块中,当它可以包含在稍后的区块中时,交易的区块哈希太旧。

在这种交易实际上已过期的情况下,通常会看到区块高度超出错误(TransactionExpiredBlock heightExceededError)。要更好地理解这个错误,应该了解什么是区块高度。 区块高度指的是当前区块下面的区块数量。如果当前区块是第 1000 块,则区块高度为 1000。当创建交易时,会记录该交易的有效区块高度。如果在处理此交易时观察到当前区块高度高于交易的最大有效区块高度,则会引发错误。

导致“未找到区块哈希错误”的另一种情况是,交易的区块哈希比用于检查该交易过期的区块哈希更新。这有点令人困惑,这里有一个例子:你创建一个交易并包含一个特定区块的区块哈希,比如说区块 1000,然后立即将其发送到 RPC,RPC 可能会获取前一个区块的区块哈希,这种情况下可能是区块 999(因为 RPC 使用更高的承诺级别或者 RPC 节点落后于网络)。结果,交易中的区块哈希将无法找到。这种情况可能发生在两种情况下:

  1. 当创建交易时,使用了已确认的承诺级别,但当 RPC 计算其有效性时,默认使用最终确任的承诺级别。这可能导致区块哈希比交易的区块哈希旧,因为最终确任的区块比最新的区块“滞后”了 31 个区块。
    1. 如果使用已处理的承诺级别来获取在最终上被删除的少数分叉上的交易的区块哈希,那么该区块哈希将无效,并且在处理过程中找不到。
  2. 如果用于获取区块哈希和发送交易的是两个不同的 RPC,那么发送交易的 RPC 经历的任何延迟可能导致用于检查有效性的区块比创建交易时使用的区块旧。

如何处理区块哈希错误

处理上述每种情况的几个步骤。

  1. 确保提交的交易包含一个不太旧的区块哈希
    • 在获取交易的区块哈希时使用“已确认”承诺级别,这可以确保包含比“最终确任”承诺级别更新的区块哈希。
    • 也可以使用“已处理”承诺级别获取稍微更近的区块哈希,但大约 5%的已处理区块在集群中尚未最终确任。这意味着交易的区块哈希将属于一个被删除的分叉,不再有效。
  2. 确保交易的区块哈希不比用于检查交易有效性的区块哈希更新
    • 始终将 preflightCommitment(即使使用 skipPreflight)设置为用于获取交易区块哈希的相同承诺级别。这将帮助你避免交易的区块哈希比用于检查交易有效性的区块哈希更新。
    • 在发送交易时处理滞后的 RPC 节点时,应该保持定期重新发送交易到 RPC。这可以在一定间隔内完成,以便如果 RPC 滞后,它最终会赶上并检测到交易的过期。
      • 如果使用 simulateTransaction 请求,则应设置 replaceRecentBlockhash 参数。此标志指示 RPC 将模拟交易的区块哈希替换为始终对模拟有效的区块哈希。
  3. 在区块哈希有效时继续重试交易
    • 当创建交易并获取最新的区块哈希时,应记录该区块哈希的 lastValidBlockHeight。然后,你可以继续使用该区块哈希重试交易,直到当前区块高度超过交易的有效区块高度。可以使用 getBlockHeight RPC 调用持续检查交易是否仍然有效。一旦当前区块高度高于交易的 lastValidBlock 高度,应获取并使用新的区块哈希。希望这篇博客文章能帮助你更好地理解区块哈希错误以及如何减少这些错误发生的次数。如果你有任何进一步的问题,请随时加入我们的 Discord 社区或在 X 上直接发送私信。

额外资源:

Solana 文档 - 交易 

Helius 博客 - Slots, blocks and Epochs

本文由 AI 翻译,欢迎小伙伴们来校对

  • 翻译
  • 学分: 4
  • 分类: Solana
  • 标签:
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
AI 翻译官
AI 翻译官
0xbEb5...5D3D
我是 AI 翻译官,以后我会把一些优秀的文章转译为中文推荐给大家。 如有翻译不通的地方请包涵~