本文档描述了 Engine API 的测试用例,这些测试用例都是从合并后的世界开始的,即 Genesis 是一个终端PoW块。
本文档中描述的所有测试用例都始于合并后的世界,即 Genesis 是一个最终的 PoW 区块。
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
[x] [Hive] 无效的 block_hash
<details>
<summary>点击查看详情</summary>
SYNCING 状态以及不在 SYNCING 状态时 block_hash 的验证,以确保同步不会影响验证block_hash 所有可能的不一致情况,这些情况很容易发生,例如随机哈希、如果区块是有效的 PoW 区块时的哈希等{status: INVALID_BLOCK_HASH, latestValidHash: null, validationError: errorMessage | null}</details>
[x] [Hive] VALID 规范 链 payload
<details>
<summary>点击查看详情</summary>
P 是扩展规范链的 VALID payloadnewPayload(P){status: VALID, latestValidHash: payload.blockHash, validationError: null}P 的父级)forkchoiceUpdated(headBlock: P){payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}P</details>
[x] [Hive PR] 不一致的 ForkchoiceState
<details>
<summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3,B: Genesis <- P1' <- P2' <- P3'A 和 B 启动forkchoiceUpdated(finalized: A.P1, safe: A.P2, head: A.P3)A.P3,finalized 和 safe 区块符合预期forkchoiceUpdated(finalized: A.P1, safe: A.P2, head: B.P3')forkchoiceUpdated(finalized: A.P1, safe: B.P2', head: A.P3)forkchoiceUpdated(finalized: B.P1', safe: A.P2, head: A.P3){error: {code: -38002, message: "Invalid forkchoice state"}}forkchoiceUpdated(finalized: B.P1', safe: B.P2', head: B.P3')B.P3,finalized 和 safe 区块符合预期</details>
[x] [Hive] INVALID 规范 链 payload
<details>
<summary>点击查看详情</summary>
INV_P 是扩展规范链的 INVALID payloadINV_P 具有有效的 block_hash,但由于以下无效属性而被无效:stateRoot 无效receiptsRoot 无效blockNumber 小于或等于 parent.blockNumber 或大于 parent.blockNumber+1gasLimit 大于 parent.gasLimit + parent.gasLimit / 1024 或小于 parent.gasLimit - parent.gasLimit / 1024gasUsed 不等于包含的交易使用的 gastimestamp 小于或等于 parent.timestampbaseFeePerGas 与 parent.baseFeePerGas 和 parent.gasUsed 不一致transactions 具有以下任一情况:
newPayload(INV_P){status: INVALID, latestValidHash: P.parentHash, validationError: errorMessage | null}eth_getBlockByHash 访问 INV_P</details>
[x] [Hive] 具有未知父级的 Payload <details> <summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3,B: Genesis <- P1' <- P2' <- P3'Genesis 区块和状态启动forkchoiceUpdated(A.P1){status: SYNCING}newPayload(A.P1) + forkchoiceUpdated(A.P1)forkchoiceUpdated(A.P1),直到它响应 {status: VALID},head 设置为 A.P1newPayload(B.P2'){status: SYNCING}newPayload(B.P1') + newPayload(B.P2') + forkchoiceUpdated(B.P2')forkchoiceUpdated(B.P2'),直到它响应 {status: VALID},head 设置为 B.P2'forkchoiceUpdated(A.P1)A.P1newPayload(A.P3){status: SYNCING}newPayload(A.P2) + newPayload(A.P3) + forkchoiceUpdated(A.P3)forkchoiceUpdated(A.P3),直到它响应 {status: VALID},head 设置为 A.P3'</details>
[x] [Hive] SYNCING 具有无效链
<details>
<summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3 <- P4,B: Genesis <- P1' <- INV_P2' <- P3' <- P4',INV_P2' 是无效的 payloadINV_P2' 具有有效的 block_hash,但由于以下无效属性而被无效:stateRoot 无效receiptsRoot 无效blockNumber 小于或等于 parent.blockNumber 或大于 parent.blockNumber+1gasLimit 大于 parent.gasLimit + parent.gasLimit / 1024 或小于 parent.gasLimit - parent.gasLimit / 1024gasUsed 不等于包含的交易使用的 gastimestamp 小于或等于 parent.timestampbaseFeePerGas 与 parent.baseFeePerGas 和 parent.gasUsed 不一致transactions 具有以下任一情况:
A: P4 区块和状态启动newPayload(INV_P2') + forkchoiceUpdated(head: INV_P2'){status: SYNCING, latestValidHash: null, validationError: null}P1'newPayload(P3')newPayload(P3'),直到响应为 INVALID,且 latestValidHash: P1'.blockHashfinalized、safe 和 head 区块没有改变,即来自 A 链newPayload(P2') + forkchoiceUpdated(head: P2')P1'forkchoiceUpdated(P2'),直到响应为 INVALID,且 latestValidHash: P1'.blockHash</details>
[x] [Hive] 构建一个 payload <details> <summary>点击查看详情</summary>
Genesis <- P1Genesis 区块和状态启动newPayload(P1)getPayload(payloaId: random){error: {code: -38001, message: "Unknown payload"}}forkchoiceUpdated(P1, payloadAttributes: {validTimestamp, validPrevRandao, validFeeRecipient})existingPayloadIdgetPayload(payloaId: random){error: {code: -38001, message: "Unknown payload"}}getPayload(payloaId: existingPayloadId)returnedPayloadnewPayload(returnedPayload){status: VALID}forkchoiceUpdated(returnedPayload){status: VALID},returnedPayload 变为 headforkchoiceUpdated(returnedPayload, payloadAttributes: {validTimestamp, validPrevRandao, validFeeRecipient})existingPayloadId2getPayload(payloaId: existingPayloadId2)returnedPayload2newPayload(returnedPayload2){status: VALID}returnedPayload 仍为 headgetPayload(payloaId: existingPayloadId2){error: {code: -38001, message: "Unknown payload"}}</details>
[x] [Hive] 无效的 PayloadAttributes
<details>
<summary>点击查看详情</summary>
Genesis <- P1Genesis 区块和状态启动newPayload(P1)forkchoiceUpdated(P1, payloadAttributes: {timestamp: 0, validPrevRandao, validFeeRecipient}){error: {code: -38003, message: "Invalid payload attributes"}}P1</details>
[x] [Hive] VALID 侧 链 payload
<details>
<summary>点击查看详情</summary>
P' 是扩展侧链的 VALID payloadP 和 P' 包含相同的交易,该交易使用 PREVRANDAO 来修改存储P 和 P' 具有不同的 prevRandao 值newPayload(P')ACCEPTED 或 VALIDforkchoiceUpdated(headBlock: P'){payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}P'P'.prevRandao 正确更新</details>
[x] [Hive] 更新规范链上的 finalized 和 safe 区块 <details> <summary>点击查看详情</summary>
Genesis <- P1 <- P2 <- P3 <- P4 是扩展规范链的有效 payload 的子链newPayload(P1) + forkchoiceUpdated(finalized: Genesis, safe: Genesis, head: P1)newPayload(P2) + forkchoiceUpdated(finalized: Genesis, safe: P1, head: P2)safe 设置为 P1,将 head 设置为 P2,finalized == GenesisnewPayload(P3) + forkchoiceUpdated(finalized: P1, safe: P2, head: P3)finalized 设置为 P1,将 safe 设置为 P2,将 head 设置为 P3newPayload(P4) + forkchoiceUpdated(finalized: P2, safe: P3, head: P4)finalized 设置为 P2,将 safe 设置为 P3,将 head 设置为 P4</details>
[x] [Hive] 更新侧链上的 safe 区块 <details> <summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3 是扩展规范链的有效 payload 的子链,B: Genesis <- P1 <- P2' <- P3' 是扩展侧链的有效 payload 的子链A 并调用 forkchoiceUpdated(finalized: P1, safe: P2, head: P3)finalized 设置为 P1,将 safe 设置为 P2,将 head 设置为 P3newPayload(P2') + newPayload(P3') 导入 B 并调用 forkchoiceUpdated(finalized: P1, safe: P2', head: P3')forkchoiceUpdated 轮询,因为 EL 可能会响应正在同步finalized 设置为 P1,将 safe 设置为 P2',将 head 设置为 P3'</details>
[x] [Hive] SYNCING 具有有效链
<details>
<summary>点击查看详情</summary>
Genesis <- P1 <- P2 <- P3 <- ... <- PnGenesis 区块和状态启动newPayload(Pn) + forkchoiceUpdated(head: Pn){status: SYNCING, latestValidHash: null, validationError: null}P1 <- P2 <- P3 <- ... <- Pn-1 并成功完成同步过程newPayload(Pn+1) + forkchoiceUpdated(head: Pn+1)newPayload + forkchoiceUpdated,直到响应为 VALIDfinalized、safe 和 head 区块已相应设置</details>
[x] [Hive PR] 在 SYNCING 时重新组织回规范链
<details>
<summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3 <- P4, B: Genesis <- P1' <- P2' <- P3' <- P4'A.P3 区块,即 A.P3 是 headnewPayload(B.P4') + forkchoiceUpdated(head: B.P4'){status: SYNCING, latestValidHash: null, validationError: null}B 链的其余部分应不可用,以使 EL 无法完成其同步过程newPayload(A.P4) + forkchoiceUpdated(A.P4)forkchoiceUpdated(finalized: P2, safe: P3, head: P4),直到响应为 VALIDfinalized、safe 和 head 区块已相应设置</details>
[x] [Hive] 重新组织为删除交易的侧链 <details> <summary>点击查看详情</summary>
A: Genesis <- P1,B: Genesis <- P1'P1 和 P1' 是有效的 payloadP1 包含交易 Tx1,而 P1' 不包含任何交易newPayload(A.P1) + forkchoiceUpdated(head: A.P1){status: VALID, latestValidHash: A.P1, validationError: null}Tx1 收据Tx1 收据newPayload(B.P1') + forkchoiceUpdated(head: B.P1'){status: VALID, latestValidHash: B.P1', validationError: null}Tx1 收据Tx1 收据</details>
[x] [Hive] 具有现有规范链 payload 的 newPayload
<details>
<summary>点击查看详情</summary>
Genesis <- P1 <- P2 <- P3 <- ... <- PnnewPayload(P1) + forkchoiceUpdated(head: P1) 到 newPayload(Pn) + forkchoiceUpdated(head: Pn)PnnewPayload(P1) 到 newPayload(Pn)VALID 且没有错误newPayload(Pn+1) + forkchoiceUpdated(head: Pn+1)</details>
[x] [Hive] 导入并重新组织到先前验证的 payload <details> <summary>点击查看详情</summary>
Genesis <- P1 <- P2 <- P3 <- P4head: P4, safe: P3, finalized: P2 启动newPayload(P3){status: VALID, latestValidHash: P3.blockHash}forkchoiceUpdated(head: P3, safe: P2, finalized: P1){status: VALID, latestValidHash: P3.blockHash}</details>
[x] [Hive] 导入并重新组织到侧链上先前验证的 payload <details> <summary>点击查看详情</summary>
A: Genesis <- P1 <- P2 <- P3 <- P4,B: Genesis <- P1 <- P2 <- P3 <- P4A 和 B 链以及作为 head 的 A.P4 启动newPayload(B.P3){status: VALID, latestValidHash: B.P3.blockHash}forkchoiceUpdated(head: B.P3, payloadAttributes: buildProcessAttributes)payloadStatus: {status: VALID, latestValidHash: B.P3.blockHash}, payloadId: buildProcessIdgetPayload(payloadId: buildProcessId)builtPayloadnewPayload(builtPayload){status: VALID, latestValidHash: builtPayload.blockHash}</details>
[x] [Hive] QUANTITY 字段值已正确编码
<details>
<summary>点击查看详情</summary>
P1 具有大于 255 的所有 QUANTITY 字段值BeaconBlock(P1)P1 QUANTITY 字段都是大端序</details>
[x] [Hive] INVALID 规范 链 payload
<details>
<summary>点击查看详情</summary>
INV_P 是扩展规范链的 INVALID payloadBeaconBlock(INV_P)INVALIDGET /eth/v1/beacon/headers/{block_id} 访问 BeaconBlock(INV_P)</details>
[x] [Hive] 无效的 Timestamp
<details>
<summary>点击查看详情</summary>
INV_P 是由 EL 生成的扩展规范链的 INVALID payload,其中 timestamp 值超出当前 slot 时间范围INV_P</details>
[x] [Hive] 无效的 PrevRandao
<details>
<summary>点击查看详情</summary>
INV_P 是由 EL 生成的扩展规范链的 INVALID payload,其中 prevRandao 值不是给定 slot 的预期 randao 混合值INV_P</details>
[x] [Hive] 无效的 block_hash
<details>
<summary>点击查看详情</summary>
P 响应 INVALID_BLOCK_HASHBeaconBlock(P)</details>
[x] [Hive] SYNCING 具有无效链
<details>
<summary>点击查看详情</summary>
Genesis <- P1 <- P2 <- P3 <- P4BeaconBlock(P1) ... BeaconBlock(P4) 区块newPayload(P2) 上响应 SYNCINGnewPayload(P4) 上响应 status: INVALID, latestValidHash: P1.blockHashBeaconBlock(P1)forkchoiceUpdated(P1)finalized、safe 和 head 区块符合预期</details>
[x] [Hive] baseFee 编码检查
<details>
<summary>点击查看详情</summary>
P1,其中 baseFee 字段大于或等于 256BeaconBlock(P1) 已并入链中</details>
[x] [Hive] 超时 <details> <summary>点击查看详情</summary>
P 是扩展规范链的 VALID payloadBeaconBlock(P)newPayload 和 forkchoiceUpdated,在响应之前暂停 timeout - 1s 秒BeaconBlock(P) 是 CL 链的 headP 是 EL 链的 head</details>
[x] [Hive PR] 由于乐观同步而没有可行的 head <details> <summary>点击查看详情</summary>
SLOTS_PER_EPOCH = 32... <- P0 <- P1 <- P2 <- ... <- PnBeaconBlock(P0).slot % SLOTS_PER_EPOCH == 0BeaconBlock(P0).slot >= 128 距离 Genesis 足够远BeaconBlock(P0), ..., BeaconBlock(P10)status: VALIDBeaconBlock(P11), ..., BeaconBlock(P33):EL 模拟返回 status: VALIDBeaconBlock(P10), ..., BeaconBlock(P32):EL 模拟返回 status: SYNCINGBeaconBlock(P33)
newPayload(P33):{status: INVALID, latestValidHash: P10.blockHash}newPayload(P33):{status: SYNCING}forkChoiceUpdated(P33):{status: INVALID, latestValidHash: P10.blockHash}execution_optimistic 标志是否为 trueBeaconBlock(P10)BeaconBlock(P11, slot34), ..., BeaconBlock(Pn, slotN):EL 模拟返回 status: VALIDBeaconBlock(P11, slot34), ..., BeaconBlock(Pn, slotN):EL 模拟返回 status: VALIDslotN 应该足够高,以便 importer 可以从乐观状态恢复,N >= 96BeaconBlock(Pn, slotN) 是 head</details>
- 原文链接: github.com/txrx-research...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!