如何处理 Solana 上的 Blockhash 错误

  • 想样
  • 更新于 1天前
  • 阅读 73

什么是区块哈希?要理解什么是区块哈希,您必须理解什么是槽和区块。slot是验证者可以生成区块的时间段区块是验证器处理的交易+元数据的集合。每个区块中的元数据将其与前一个区块链接起来,形成一个链条。重要的是要了解时隙持续时间为400到600毫秒,并且在每个时隙中,验证者可

<!--StartFragment-->

什么是区块哈希?

要理解什么是区块哈希,您必须理解什么是槽和区块。

  • slot 是验证者可以生成区块的时间段 
  • 区块是验证器处理的交易 + 元数据的集合。每个区块中的元数据将其与前一个区块链接起来,形成一个链条。

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

好的,那么什么是区块哈希?区块哈希是在一个时间段内创建的所有区块链账本条目的唯一哈希值。[这是根据区块的最后一个条目 ID 计算得出的]。每个生成的区块结果都是正在创建的唯一区块哈希。这些区块哈希用作时间戳。

Solana 的承诺水平是多少?

另一个需要理解的重要概念是[承诺级别]。这些承诺级别衡量特定区块的网络确认。三个选项分别是处理、确认和最终确定。

当验证者将区块提交到链中时,该区块将处于已处理状态。一旦所需数量的验证者([66% 的验证者])投票支持包含该区块,该区块就会被添加到链中,承诺级别将变为已确认。一旦在此区块上构建了另外 31 个区块,承诺级别将变为已完成。

<!--EndFragment-->

QQ20241226-182216.png <!--StartFragment-->

为什么会发生Blockhash错误?

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

<!--EndFragment--> <!--StartFragment-->

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

当验证器处理交易时,如果交易中包含的区块哈希不被视为有效,则会出现 “[未找到区块哈希”错误。这可能是因为它太旧,或者在某些情况下太新。]

此错误的最常见原因是,交易中包含的区块哈希未出现在验证器将与之比较的最后 300 个区块哈希的队列中。这将导致[未找到区块哈希错误]。当在规定时间内创建和处理交易时,可能会发生交易过期。这可能是因为用户花了很长时间签署交易。还可能存在这样的情况:提交了有效交易但未包含在当前区块中,而当它可以包含在后续区块中时,交易的区块哈希太旧了。

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

另一种可能导致“未找到区块哈希错误”的情况是,当交易的区块哈希比用于检查该交易到期日期的区块哈希新时。这有点令人困惑,因此这里有一个例子:您创建一个交易并包含特定区块(假设是区块 1000)的区块哈希,然后立即将其发送到 RPC,RPC 可能会获取前一个区块的区块哈希,在本例中可能是区块 999(由于 RPC 使用更高的承诺级别,或者 RPC 节点落后于网络)。因此,将找不到交易中的区块哈希。这是一种奇怪的情况,但它可能发生在两种情况下:

  1. 创建交易时,使用已确认的承诺级别,但当 RPC 计算其有效性时,它默认使用最终承诺。这可能会导致区块哈希比交易的区块哈希更旧,因为最终区块比最新区块“落后” 31 个区块。

    1. 如果使用已处理的承诺级别来获取最终被删除的少数分叉上的交易的块哈希,则该块哈希将无效,并且在处理过程中不会被找到。
  2. 如果使用两个不同的 RPC 来获取区块哈希和发送交易,则发送交易的 RPC 所经历的任何延迟都可能导致其用于检查有效性的区块比创建交易时使用的区块更旧。

<!--EndFragment--> <!--StartFragment-->

如何处理 Blockhash 错误

针对上述每种情况,需要采取一些步骤。

  1. 确保提交的交易的区块哈希不是太旧:

    • 在获取交易的区块哈希时使用“已确认”的承诺级别,因为这可以确保与“**最终确定**”的承诺级别相比包含较新的区块哈希。
    • 您还可以对稍新的区块哈希使用“已处理”承诺级别,但[大约 5% 的已处理区块]尚未由集群最终确定。这意味着交易的区块哈希将属于已丢弃的分叉,并且不再有效。
  2. 确保交易的区块哈希不比用于检查交易有效性的区块哈希新:

    • 始终将preflightCommitment(即使使用 skipPreflight)设置为用于获取交易块哈希的相同承诺级别。这将帮助您避免交易的块哈希比用于检查交易有效性的块哈希更新。

    • 为了解决发送交易时 RPC 节点滞后的问题,应不断向 RPC 重新发送转换。这可以按设定的时间间隔进行,这样,如果 RPC 滞后,它最终会赶上并检测到交易的到期时间。

      • 如果使用simulateTransaction请求,则应设置replaceRecentBlockhash参数。此标志指示RPC用始终对模拟有效的块哈希替换模拟交易的块哈希。
  3. 当区块哈希有效时继续重试交易:

    • 当创建交易并获取最新的区块哈希时,您应该记下该区块哈希的 lastValidBlockHeight。然后,您可以继续使用该区块哈希重试交易,直到当前区块高度超过交易的有效区块高度。可以使用 getBlockHeight RPC 调用不断检查交易是否仍然有效。一旦当前区块高度高于交易的 lastValidBlock 高度,就应该获取并使用新的区块哈希。

<!--EndFragment--> 作者:GTokenTool 来源:https://www.gtokentool.com

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

0 条评论

请先 登录 后评论
想样
想样
江湖只有他的大名,没有他的介绍。