本文介绍了在以太坊执行层(EL)中实现 FOCIL (一种新的交易包含机制) 所需的更改,包括对三个引擎 API 的修改,以及FOCIL与区块构建抽象层(BALs)的兼容性。同时分享了在Geth中开发FOCIL的经验,强调EL可以独立于ePBS引入FOCIL。
本文介绍了 FOCIL 将给 EL 带来的改变。此外,它还研究了 FOCIL 与 BAL 的兼容性,因为 EL 客户端团队主要支持 BAL 作为 Glamsterdam 的 EL 主角。最后,作者分享了在 Geth 中开发 FOCIL 的经验。
FOCIL 添加或修改了三个引擎 API。以下章节将分别检查每个 API,描述更改和示例实现。
GetInclusionListCL 调用 GetInclusionList 引擎 API 来检索包含列表(IL)。一个诚实的验证者使用来自公共 mempool 的交易构建一个 IL。
输入是 parentHash,返回的 IL 应该基于此构建,输出是交易列表。虽然建议基于 head 构建 IL 以生成最新的 IL,但这不是严格要求的。在这方面,它稍后可能会更改为不接收任何参数。
此外,EL 可以在 IL 构建过程中执行或不执行交易。Geth 原型当前针对 parentHash 执行 IL 交易。但是,EL 可以选择在 IL 中包含交易而不执行它们。
NewPayload当证明者调用 NewPayload 引擎 API 时,他们现在传递一组唯一的 IL 交易来验证 IL 约束。使用执行后状态,EL 根据以下标准检查每个 payload 中不存在的 IL 交易:
如果任何缺失的 IL 交易满足所有这些条件,则 EL 响应 payload 未能满足 IL 约束。
def state_transition(
chain: BlockChain,
block: Block,
inclusion_list_transactions: Tuple[LegacyTransaction | Bytes, ...],
) -> None:
...
for i, tx in enumerate(map(decode_transaction, transactions)):
process_transaction(block_env, block_output, tx, Uint(i))
validate_inclusion_list_transactions(
block_env=block_env,
block_output=block_output,
transactions=transactions,
inclusion_list_transactions=inclusion_list_transactions,
)
process_withdrawals(block_env, block_output, withdrawals)
...
def validate_inclusion_list_transactions(
block_env: vm.BlockEnvironment,
block_output: vm.BlockOutput,
transactions: Tuple[LegacyTransaction | Bytes, ...],
inclusion_list_transactions: Tuple[LegacyTransaction | Bytes, ...],
) -> None:
for inclusion_list_transaction in inclusion_list_transactions:
# Skip if an inclusion list transaction is present in the block.
if inclusion_list_transaction in transactions:
continue
tx = decode_transaction(inclusion_list_transaction)
# Ignore blob transactions.
if isinstance(tx, BlobTransaction):
continue
try:
# Run the tests of intrinsic validity.
validate_transaction(tx)
check_transaction(block_env, block_output, tx)
except EthereumException:
# This inclusion list transaction could not be included.
continue
else:
# This inclusion list transaction could have been included.
# Mark the block as not satisfying inclusion list constraints.
block_output.is_inclusion_list_satisfied = False
break
这是原型代码,用于 测试本质有效性,
检查它是否可以被包含 和 调用它。
func ValidateInclusionListTransactions(evm *vm.EVM, block *types.Block, statedb *state.StateDB, inclusionListTxs []*types.Transaction) bool {
// Create a map of transaction hashes present in the block.
isIncludedTx := make(map[common.Hash]bool)
for _, tx := range block.Transactions() {
isIncludedTx[tx.Hash()] = true
}
// Get the block's gas limit and gas left.
gasLimit := block.GasLimit()
gasLeft := gasLimit - block.GasUsed()
// Make a singer to get transaction senders.
signer := types.MakeSigner(evm.ChainConfig(), block.Number(), block.Time())
// Iterate over each transaction in the inclusion list and check if it is either included in the block or cannot be placed at the end of the block.
for _, tx := range inclusionListTxs {
// Check if the transaction is included in the block.
if isIncludedTx[tx.Hash()] {
continue
}
// Check if there is not enough gas left to execute the transaction.
if tx.Gas() > gasLeft {
continue
}
// Get the transaction sender.
from, err := types.Sender(signer, tx)
if err != nil {
continue
}
// Check if the sender has not enough balance to cover the transaction cost.
balance := statedb.GetBalance(from).ToBig()
cost := tx.Cost()
if balance.Cmp(cost) < 0 {
continue
}
// Check if the sender has a nonce that doesn't match with the transaction nonce.
nonce := statedb.GetNonce(from)
if nonce != tx.Nonce() {
continue
}
// This transaction could have been appended at the end of the block. The block fails to satisfy the inclusion list constraints.
return false
}
return true
}
ForkchoiceUpdated当调用 ForkchoiceUpdated 引擎 API 时,构建者可以传递 IL 交易,以确保他们的 payload 符合 IL。它接收 payloadId 和 IL 交易,并新建或更新 payload,使其满足关于 IL 交易的 IL 约束。
以前,使用 UpdatePayloadWithInclusionList,但已替换为 ForkchoiceUpdated,因为 IL 现在是 payload 构建过程的一部分,因此 ForkchoiceUpdated 在语义上更合适。
FOCIL 和 BAL 可以独立实现。EL 可以在使用 BAL 并行执行交易后调用 IL 验证逻辑。例如,在 Geth 的 BAL 原型中,可以在 此处 调用 IL 验证逻辑。
此外,IL 验证逻辑可以并行执行,这符合 BAL 的优化。每个 IL 交易都采用相同的输入(区块环境和执行后状态)并产生相同的输出类型(布尔值)。
Geth 原型 PR 作者总共花费了大约三周的时间来实现和完善。预计 EL 将保持不可知状态,无论 FOCIL 是否与 ePBS 一起引入。
在测试复杂性方面,考虑 CL 和 EL 会更合适。我们目前正在与测试团队联系,即将发布的文章将解决这个问题。
下一步:如何在 CL 中实现 FOCIL](https://learnblockchain.cn/article/23630)
- 原文链接: hackmd.io/iqWhG99dTAKYTF...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!