Polygon PoS 使用 Bor(go-ethereum 的分叉)作为区块生产层,区块生产按 span 和 sprint 组织。一个 span 包含固定数量的 sprint,在此期间由选定的验证者子集负责出块;在一个 span 内,生产者每个 sprint 轮换一次。活跃验证者集合仅在 span 边界发生变化,通常由 state-sync 或 checkpoint 事件触发。你可以通过 RPC 使用 Bor 特有方法(如 bor_getSnapshot、bor_getSigners、bor_getCurrentValidators 和 bor_getCurrentProposer)读取当前生产者、验证者集合以及 span/sprint 状态。本指南解释其机制,提供可运行代码来检查生产者状态,并涵盖常见 RPC 与同步问题的排查方法。
Polygon PoS Bor 如何组织区块生产
Polygon PoS 使用 Bor(go-ethereum 的分叉)作为其区块生产层。Bor 将权益证明验证者集合与 checkpoint 机制相结合,将最终性锚定到以太坊。活跃验证者集合通过在以太坊上质押选出,区块生产者从该集合中抽取。出块时间约为几秒,但确切值是一个有文档记录的参数,你可以在链上验证。
为了使区块生产可预测且高效,Bor 将生产者组织为 span 和 sprint。一个 span 是固定数量的连续 sprint,在此期间由选定的验证者子集负责出块。在一个 span 内,生产者轮换:一个 sprint 是由单个验证者连续出块的一段时间,之后由该 span 中的下一个验证者接管。这种结构意味着“谁出下一个块”是当前 span 状态的函数,而不是全局轮询。
验证者集合仅在 span 边界发生变化,通常由 state-sync 或 checkpoint 事件触发。这种设计降低了集合变更的频率,并使 span 内的生产者选择具有确定性。要深入了解这如何融入更广泛的 Polygon 网络,请参阅 Polygon 网络页面。
- Span:固定数量的 sprint,在此期间由选定的验证者子集出块。
- Sprint:由单个验证者连续出块的一段时间。
- 验证者集合变更发生在 span 边界,通常通过 state-sync 或 checkpoint 事件触发。
- 生产者选择由验证者集合和 span/seed 推导得出,因此可以从集合计算。
使用 Bor 特有 RPC 方法读取生产者状态
Bor 在 bor_ 命名空间下暴露了若干非标准 JSON-RPC 方法。这些方法不属于标准以太坊 JSON-RPC 规范,因此普通以太坊端点或非 Bor 链会返回方法未找到错误。读取生产者状态的关键方法如下:
bor_getSnapshot(blockNumber) 返回当前 span/sprint 快照,包括验证者集合、当前 span 和 sprint 编号以及生产者。bor_getSigners(blockNumber) 返回给定区块的签名者列表。bor_getCurrentValidators() 返回当前验证者集合。bor_getCurrentProposer() 返回将出下一个区块的验证者地址。
你也可以使用标准 eth_getBlockByNumber 获取区块元数据,包括 Bor 特有字段,如签名者(通常以 miner 形式提供,或通过 bor_getAuthor 获取)。要确认你的节点在正确的分叉上,请检查 eth_syncing 并将区块时间戳与可信来源进行比较。
- bor_getSnapshot:返回包含验证者集合和生产者的 span/sprint 快照。
- bor_getSigners:返回特定区块的签名者。
- bor_getCurrentValidators:返回当前验证者集合。
- bor_getCurrentProposer:返回下一个区块生产者。
- eth_getBlockByNumber:获取区块元数据的标准方法,包括 Bor 特有字段。
实际用途:区块归属、卡住的验证者与重组风险
了解当前生产者和验证者集合对于区块归属至关重要。如果你的应用需要将区块归功于特定验证者,可以使用 bor_getSigners 或区块的 miner 字段。这对于分析、奖励计算和监控验证者性能非常有用。
检测卡住的验证者是另一个常见用例。如果验证者在其 sprint 期间未能出块,你可能会看到空块或出块缺口。上游报告,例如标题为“Bor sync wedges on empty block after producer restart”的 GitHub issue,指出生产者重启可能导致空块并卡住同步。监控 bor_getCurrentProposer 和区块时间戳有助于及早发现此类异常。
最后,理解 span 边界有助于评估重组深度与最终性。由于验证者集合仅在 span 边界变化,跨越 span 边界的重组破坏性更大。有关最终性概念的更多信息,请参阅 OP-Stack 最终性与 safe/finalized 区块标签。
- 使用 bor_getSigners 或区块 miner 字段将区块归属到生产者。
- 通过监控生产者变化和出块缺口来检测卡住的验证者。
- 评估验证者集合变化的 span 边界附近的重组风险。
可运行代码:获取快照并交叉检查签名者
以下 Node.js 脚本连接到 Bor RPC 端点,获取给定区块的快照,打印当前验证者、sprint、span 和当前生产者,然后使用 bor_getSigners 对该区块进行交叉检查。请将 RPC URL 替换为你自己的端点。
此代码使用 ethers 库进行 JSON-RPC 调用。请确保已安装(npm install ethers)。该脚本是自包含的,可以直接使用 Node.js 运行。
const { JsonRpcProvider } = require('ethers');
const RPC_URL = 'https://your-bor-rpc-endpoint';
const BLOCK_NUMBER = 'latest'; // or a specific block number
async function main() {
const provider = new JsonRpcProvider(RPC_URL);
// Fetch snapshot
const snapshot = await provider.send('bor_getSnapshot', [BLOCK_NUMBER]);
console.log('Snapshot:');
console.log(' Span:', snapshot.span ? snapshot.span.id : 'N/A');
console.log(' Sprint:', snapshot.sprint);
console.log(' Current Validators:', snapshot.validators);
console.log(' Current Producer:', snapshot.producer);
// Fetch signers for the same block
const signers = await provider.send('bor_getSigners', [BLOCK_NUMBER]);
console.log('Signers for block', BLOCK_NUMBER, ':', signers);
// Fetch current proposer
const proposer = await provider.send('bor_getCurrentProposer', []);
console.log('Current Proposer:', proposer);
// Fetch current validators
const validators = await provider.send('bor_getCurrentValidators', []);
console.log('Current Validators (bor_getCurrentValidators):', validators);
}
main().catch(console.error);结果表:在你的端点上测量生产者状态
使用下表记录你自己 RPC 端点的结果。运行上面的代码并填写这些值。这有助于验证你的端点是否返回一致的 Bor 特有数据,以及生产者是否与区块的签名者匹配。
如果任何字段缺失或返回错误,请查看下面的故障排除部分。请注意,bor_getSnapshot 对于已修剪或非常旧的区块可能返回 null;历史快照需要归档节点。有关归档节点的更多信息,请参阅 Polygon 归档节点与历史 RPC。
- 区块编号:你查询的区块。
- Span ID:来自 snapshot.span.id。
- Sprint 编号:来自 snapshot.sprint。
- 当前验证者:来自 snapshot.validators 或 bor_getCurrentValidators 的列表。
- 当前生产者:来自 snapshot.producer 或 bor_getCurrentProposer。
- 签名者:来自同一区块的 bor_getSigners。
- 是否匹配?生产者是否出现在签名者列表中?
常见故障与排查清单
通过 RPC 读取 Bor 生产者状态时,你可能会遇到几个常见问题。以下是诊断清单:
方法未找到:如果 bor_ 方法返回“method not found”错误,你的端点很可能不是 Bor 节点,或者是普通以太坊端点。确保你连接到 Polygon PoS RPC 端点。有关提供商列表,请参阅 Polygon RPC 提供商与节点(RPC Assistant)。
旧区块快照为 null:bor_getSnapshot 对于已修剪的区块可能返回 null。历史查询请使用归档节点。请参阅 Polygon 归档节点与历史 RPC。
Sprint/span 边界边缘情况:在 sprint 或 span 的精确边界处,快照可能反映新生产者或旧生产者,具体取决于区块编号。始终查询你感兴趣的特定区块的快照,并与 bor_getSigners 交叉检查。
将快照误解为最终性:快照显示当前生产者和验证者集合,但不表示最终性。最终性通过以太坊上的 checkpoint 实现。不要将快照视为最终性信号。
节点落后于链头:如果你的节点未同步,快照可能已过时。检查 eth_syncing 并比较区块时间戳。请参阅 检测落后于链头的 RPC 节点。
- 验证端点支持 Bor 特有方法。
- 历史快照使用归档节点。
- 针对精确区块编号查询快照。
- 将生产者与签名者交叉检查。
- 监控节点同步状态。
通过 RPC 获取 Bor 生产者状态的局限性与权衡
虽然 Bor 的 RPC 方法为区块生产提供了有价值的洞察,但它们也有局限性。首先,这些方法是非标准的,可能并非所有 RPC 提供商都支持。即使在 Bor 节点中,bor_getSnapshot 对历史区块的可用性也取决于节点的修剪设置。其次,快照数据反映给定区块的状态,但不保证生产者能成功出下一个区块;网络状况或验证者停机可能导致偏差。
第三,如果你的节点未完全同步,仅依赖 bor_getCurrentProposer 进行实时监控可能会产生误导。始终验证节点健康状况和同步状态。有关监控最佳实践,请参阅 监控 RPC 端点与节点健康。
最后,验证者集合和 span 参数受治理和协议升级影响。始终在链上验证当前值,而不是假设固定数字。有关权威细节,请参阅 Polygon 官方文档中关于 Bor 架构和 Bor 共识包的内容。
- 非标准方法可能并非所有端点都可用。
- 历史快照需要归档节点。
- 快照不保证未来的区块生产。
- 节点同步状态影响数据新鲜度。
- 协议参数可能通过治理变更。
下一步:将生产者状态集成到你的应用中
现在你已经了解如何读取 Bor 生产者状态,可以将其集成到你的应用中。对于区块浏览器或分析仪表板,使用 bor_getSigners 将区块归属到验证者。对于监控工具,轮询 bor_getCurrentProposer 和 bor_getCurrentValidators 以检测集合变更和验证者停机。对于钱包或交易所,使用 span 边界来估计重组风险并调整确认要求。
要开始使用可靠的 RPC 端点,请浏览 OnFinality 的 Polygon 网络页面,并考虑适合你需求的 API 服务 方案。有关定价详情,请参阅 RPC 定价。更多指南,请访问 OnFinality Learn 中心。
请记住,针对多个端点测试你的集成,并使用上述结果表方法验证结果。这能确保你的应用优雅地处理边缘情况和提供商差异。
- 使用 bor_getSigners 进行区块归属。
- 轮询 bor_getCurrentProposer 进行实时监控。
- 根据 span 边界调整确认深度。
- 选择支持 Bor 的可靠 RPC 提供商。