本文档介绍了 go-ethereum 中负责挖矿和区块创建的系统,该系统通过从交易池中选择交易、执行它们并将最终区块准备好进行共识验证来构造新区块。该系统同时处理传统的挖矿场景和现代的权益证明(Proof-of-Stake)负载构建。
有关交易池管理和验证的信息,请参阅 交易处理。有关共识机制和区块验证的详细信息,请参阅共识包文档。
geth 中的挖矿系统围绕几个协同工作的关键组件构建,以创建有效的区块。
挖矿系统架构
来源:miner/miner.go67-78 miner/worker.go46-63 core/state_transition.go235-252
区块创建过程遵循一个结构化的序列,从初始化到交易执行再到最终区块组装。
区块创建序列
来源:miner/worker.go97-156 miner/miner.go136-139 core/state_processor.go207-214
Miner 结构体作为区块创建操作的主要协调者。
| 字段 | 类型 | 目的 |
|---|---|---|
config | *Config | 挖矿配置参数 |
chainConfig | *params.ChainConfig | 链特定的协议参数 |
engine | consensus.Engine | 区块最终确定的共识引擎 |
txpool | *txpool.TxPool | 待处理交易的来源 |
chain | *core.BlockChain | 区块链状态和历史 |
pending | *pending | 待处理区块生成的缓存 |
矿工暴露了几个关键方法:
BuildPayload() - 外部区块请求的主要入口点Pending() - 返回当前待处理区块SetExtra()、SetGasCeil()、SetGasTip() - 配置更新来源:miner/miner.go67-78 miner/miner.go136-174
environment 结构体代表构建单个区块的工作上下文。
此环境是为每个区块全新创建的,并维护区块构建过程中所需的所有状态。
区块生成过程分几个阶段实现:
prepareWork)此阶段设置初始区块环境。
fillTransactions)交易选择过程。
系统维护常规交易和 Blob 交易的独立池,具有不同的选择标准。
commitTransactions)对于每笔选定的交易:
ApplyTransaction 应用交易。最后阶段包括:
FinalizeAndAssemble 进行共识引擎最终确定。区块构建期间的交易执行使用了核心状态转换机制。
交易执行流程
该系统使用状态快照来确保失败的交易不会破坏区块状态。
来源:miner/worker.go265-317 core/state_processor.go207-214
挖矿系统通过 consensus.Engine 接口与共识层集成。
engine.Prepare() 允许共识引擎修改区块头字段。engine.FinalizeAndAssemble() 执行最终的共识特定处理。对于合并后(PoS)的操作,Engine API 提供了验证者请求使用特定参数构建区块的外部接口。
来源:miner/worker.go207-212 miner/worker.go143-146
影响区块创建的关键配置参数:
| 参数 | 目的 | 默认 |
|---|---|---|
GasCeil | 区块目标 Gas 上限。 | 36,000,000 |
GasPrice | 交易包含的最低 Gas 价格。 | 1 Gwei |
Recommit | 区块构建时间限制。 | 2 秒 |
ExtraData | 包含在区块头中的附加数据。 | 空 |
矿工还通过 SetPrioAddresses() 支持优先包含特定地址的交易。