摘要
Solana 验证者在线率并非通过单一的专用在线率端点暴露。相反,您需要通过轮询标准 Solana JSON-RPC 方法(如 getVoteAccounts、getSlot、getEpochInfo 和 getBlockProduction)来获取数据,并随时间比较结果来推导。本文展示了请求模式、真正指示活跃度的指标,以及如何将它们转化为监控循环。
您还将了解如何选择一个能够持续承受轮询而不丢失请求的端点,何时共享公共端点就足够,以及何时专用 Solana 节点能提供验证者监控所依赖的一致访问。
Solana 并未发布单一的“验证者在线率”REST 端点。如果您搜索过这样的端点,实际答案是:在线率是一个派生指标——您通过针对 Solana RPC 端点轮询一小组标准 JSON-RPC 方法,并跟踪验证者的投票和 slot 活动随时间的变化来计算它。本页涵盖了确切的方法、请求格式以及您可以立即运行的监控循环。
您能从端点获取和不能获取的内容
没有 getValidatorUptime 方法。Solana 暴露的是原始链状态,让您可以推断活跃度:
getVoteAccounts返回当前和违规的投票账户,包括lastVote、rootSlot和epochCredits。getSlot和getBlockHeight告诉您集群进展到了哪里。getEpochInfo给出当前 epoch、slot 索引和 slot 范围。getBlockProduction报告每个身份的 leader slot 生产情况。getClusterNodes返回 gossip 可见的节点及其版本和特性。
在线率是您在这些之上构建的。一个停止投票、落后于集群 slot 或不再出现在投票账户中的验证者,在监控目的上实际上已经宕机,即使进程仍在运行。
决策指南:用于监控的共享端点还是专用节点
在编写轮询代码之前,先确定您的监控循环需要什么。验证者监控是一种稳定、低流量、始终在线的工作负载,这改变了哪种端点类型适合。
| 监控需求 | 共享/公共端点 | 专用 Solana 节点 |
|---|---|---|
| 偶尔手动检查 | 通常可以 | 过度 |
| 每隔几秒连续轮询 | 可能,但共享容量会变化 | 为您自己的循环提供可预测的访问 |
| 同时跟踪多个验证者 | 可能触及共享吞吐量限制 | 随您的节点扩展 |
| 对错过投票发出警报 | 需要稳定的请求成功 | 外部变量更少 |
| 历史投票/积分分析 | 取决于保留策略 | 您控制数据路径 |
如果您每天检查一个验证者几次,共享端点是合理的。如果您运行必须在验证者违规时触发的警报,专用节点可以消除由共享端点争用引起的一类误报。OnFinality 同时提供共享 RPC API 访问和专用 Solana 节点,因此您可以从共享开始,随着监控成熟再转向专用。
真正指示验证者活跃度的方法
getVoteAccounts
这是核心调用。它返回两个数组:current(正常投票)和 delinquent(未投票)。每个条目包括投票账户公钥、节点身份、activatedStake、lastVote、rootSlot 和 epochCredits。
curl -s https://solana.api.onfinality.io/public \
-X POST -H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getVoteAccounts",
"params": [{"votePubkey": "YOUR_VOTE_ACCOUNT"}]
}'
如果您的验证者出现在 delinquent 中,说明它已停止投票。如果它不在两个数组中,投票账户可能是新的,或者请求可能失败了,因此在发出警报前务必检查响应结构。
getSlot 和 getEpochInfo
将验证者的 lastVote 与当前 slot 进行比较。差距增大意味着验证者正在落后。getEpochInfo 给出 epoch 内的 slot 索引,以便您可以标准化差距。
curl -s https://solana.api.onfinality.io/public \
-X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getEpochInfo"}'
getBlockProduction
这返回 leader slot 生产情况。按身份过滤可以显示验证者预期生产多少 slot 以及实际生产了多少,这是与投票活动并行的有用次要信号。
用 JavaScript 构建轮询循环
一个最小监控器按间隔轮询 getVoteAccounts,记录 lastVote 和 epochCredits,并在值停止前进时标记验证者。下面的示例使用 OnFinality 公共 Solana 端点,并采用无 WebSocket 的轮询方法,因此可以在任何地方运行。
const RPC = "https://solana.api.onfinality.io/public";
const VOTE_ACCOUNT = "YOUR_VOTE_ACCOUNT";
async function rpc(method, params = []) {
const res = await fetch(RPC, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
});
const json = await res.json();
if (json.error) throw new Error(json.error.message);
return json.result;
}
let lastSeenVote = null;
let stalledPolls = 0;
async function poll() {
const { current, delinquent } = await rpc("getVoteAccounts", [
{ votePubkey: VOTE_ACCOUNT },
]);
const entry = current.find((v) => v.votePubkey === VOTE_ACCOUNT);
const isDelinquent = delinquent.some((v) => v.votePubkey === VOTE_ACCOUNT);
if (isDelinquent) {
console.warn("validator delinquent");
}
if (entry) {
if (lastSeenVote !== null && entry.lastVote === lastSeenVote) {
stalledPolls += 1;
} else {
stalledPolls = 0;
}
lastSeenVote = entry.lastVote;
console.log({ lastVote: entry.lastVote, epochCredits: entry.epochCredits });
}
}
setInterval(poll, 15000);
这里有两个细节很重要。首先,epochCredits 是一个 [epoch, credits, previousCredits] 数组;最后两个条目之间的差值比单独的 lastVote 更清晰。其次,以固定间隔轮询,该间隔应明显长于一个 slot(大约 400 毫秒),这样您就不会追逐噪声。15 到 30 秒是实用的默认值。
将原始响应转化为在线率数字
在线率是您定义的比率。常见方法:
- 每 N 秒轮询一次,记录验证者是否推进了投票或积分。
- 将成功推进计为“在线”样本,将停滞或违规状态计为“离线”样本。
- 在滚动窗口(例如 24 小时)内将在线样本除以总样本。
这为您提供了一个可辩护的数字,与您自己的监控节奏匹配,而不是您无法验证的外部数字。在百分比旁边记录节奏和窗口,因为同一个验证者可能根据采样频率显示不同的在线率。
端点可靠性是测量的一部分
如果您的 RPC 端点丢弃请求,您的监控器会记录错误的停机时间。这是验证者在线率数据不佳的最常见来源。防范措施:
- 区分传输失败和链状态。超时与验证者违规不同。
- 在计为离线样本之前重试失败的请求。
- 使用第二个端点作为警报决策的交叉检查。
- 如果您以后想要 slot 订阅而不是轮询,请优先选择支持 WebSocket 的端点。
OnFinality 的 Solana 端点同时支持 HTTP 和 WebSocket 传输,因此您现在可以用 JSON-RPC 轮询,以后添加订阅而无需更换提供商。有关连接详细信息,请参阅 Solana 网络页面。
链设置和连接参考
| 设置 | 值 |
|---|---|
| 网络 | Solana Mainnet |
| 原生货币 | SOL(9 位小数) |
| HTTP 端点 | https://solana.api.onfinality.io/public |
| WebSocket 端点 | wss://solana.api.onfinality.io/public-ws |
| 区块浏览器 | https://explorer.solana.com |
| 传输 | HTTP, WebSocket |
在将监控代码指向主网之前,请使用 Solana Devnet 端点进行测试,以免用测试数据污染生产指标。
常见故障模式及如何解读
| 症状 | 可能原因 | 下一步 |
|---|---|---|
验证者在 delinquent 中 | 停止投票 | 检查节点日志和投票账户余额 |
lastVote 未推进 | 停滞或落后 | 与 getSlot 差距比较 |
| 请求超时 | 端点争用 | 添加重试,考虑专用节点 |
| 空响应数组 | 投票公钥错误 | 验证投票账户地址 |
| 积分持平但未违规 | Epoch 边界时间 | 几个 slot 后重新检查 |
关键要点
- Solana 没有专用的验证者在线率端点;在线率派生自
getVoteAccounts、getSlot、getEpochInfo和getBlockProduction。 getVoteAccounts是主要的活跃度信号,epochCredits差值比单独的lastVote更可靠。- 以固定间隔轮询并定义自己的在线率窗口,使数字可复现。
- 端点可靠性直接影响测量的在线率;重试和第二个端点减少错误停机。
- 共享端点适合偶尔检查,而专用节点适合连续警报。
常见问题
是否有直接的 Solana 验证者在线率 API?
没有。Solana 通过 JSON-RPC 暴露链状态,在线率是您从投票和 slot 活动随时间计算出的指标。
检查验证者是否宕机的最佳方法是什么?
getVoteAccounts 最直接。验证者出现在 delinquent 数组中说明已停止投票,这是最清晰的宕机信号。
我应该多久轮询一次?
每 15 到 30 秒是实用的默认值。比 slot 更快的轮询会增加噪声而不会提高准确性。
我可以使用 WebSocket 代替轮询吗?
可以。Slot 和 root 订阅可以替代轮询,但您仍然从相同的底层信号推导在线率。OnFinality 的 Solana 端点支持 WebSocket 传输。
验证者监控需要专用节点吗?
仅当您运行连续警报或跟踪多个验证者时需要。对于偶尔检查,共享端点通常足够。在 RPC 定价页面和支持的 RPC 网络列表上比较选项。