摘要
Bittensor 挖矿应用并不是一个可以下载的单一产品。它是一个技术栈:一个在子网上注册热键的矿工进程、一个跟踪子网状态的验证者或元图读取器,以及一个让所有这些组件读取链数据并提交外部交易的 RPC 连接。大多数“挖矿应用”的搜索实际上都是关于如何将这个技术栈连接起来并保持在线。
本文梳理了各个组件,展示了如何通过 HTTP 和 WebSocket 连接到 Bittensor Finney,并解释了何时共享公共端点就足够,以及何时专用节点或托管 RPC API 更适合生产矿工。
Bittensor 挖矿应用并不是一个带有启动按钮的可下载程序。它是一组与 Bittensor 链通信的小型进程栈,而大多数人低估的部分是底层的 RPC 层。如果你的矿工可以注册热键但无法可靠地读取元图,或者你的验证者在 epoch 中途丢失了 WebSocket 订阅,那么即使挖矿逻辑本身没问题,应用看起来也像是坏了。
本页解释了该技术栈实际包含什么、如何将其指向 Bittensor Finney,以及如何决定共享公共端点、托管 RPC API 还是专用节点才是你工作负载的正确基础。
从这里开始:你在构建哪种 Bittensor 应用?
在选择端点之前,先确定你的项目属于以下三种形态中的哪一种。它们有不同的 RPC 配置文件,混淆它们是最常见的可避免停机来源。
| 应用形态 | 在链上做什么 | RPC 配置文件 | 典型瓶颈 |
|---|---|---|---|
| 仅矿工 | 注册热键、提供 axon 响应、偶尔提交权重 | 低写入量,中等读取量 | 注册时机和 nonce 处理 |
| 验证者 | 每个 epoch 读取元图、设置权重、给矿工评分 | 高读取量,周期性写入 | 元图读取延迟和订阅稳定性 |
| 仪表板/监控 | 跟踪排放、子网统计、矿工健康状态 | 读取密集,大量小查询 | 查询吞吐量和缓存 |
如果你在构建矿工,通常可以从共享端点开始,之后再迁移。如果你运行的是验证者或其他人依赖的仪表板,请从一开始就规划专用连接,因为在设置权重期间丢失订阅事后调试代价很高。
“挖矿应用”背后的组件
大多数指南跳过这部分,直接跳到安装命令。先给各个部分命名会有所帮助:
- Subtensor 客户端 — 与 Bittensor 链通信的库。它需要一个 RPC 端点、一个钱包和一个网络名称。
- 钱包 — 冷键和热键。冷键持有质押;热键签署矿工或验证者操作。
- 子网逻辑 — 你的模型、评分函数或激励机制。这部分在链下运行。
- Axon 服务器 — 其他参与者调用以查询你的矿工的端点。
- 链读取器 — 拉取元图状态、区块号和子网参数的循环。
RPC 端点位于 subtensor 客户端和链读取器之下。其他所有内容都是本地的。这就是为什么 RPC 问题看起来像矿工问题:矿工进程是健康的,但链读取器是过时的。
链设置一览
Bittensor 主网是 Finney。在配置客户端、钱包或监控探针时使用这些值。
| 设置 | 值 |
|---|---|
| 网络名称 | Bittensor Finney Mainnet |
| 原生货币 | TAO(9 位小数) |
| 公共 HTTP 端点 | https://bittensor-finney.api.onfinality.io/public |
| 公共 WebSocket 端点 | wss://bittensor-finney.api.onfinality.io/public-ws |
| 支持的传输方式 | HTTP 和 WebSocket |
OnFinality 将 Bittensor Finney 作为托管 RPC API 提供,支持 HTTP 和 WebSocket 传输,因此同一端点系列可以服务于你矿工的一次性读取和验证者的订阅循环。请参阅 Bittensor Finney 网络页面 获取当前端点详情,如果需要规划套餐大小,请参阅 RPC 定价。
通过 HTTP 连接矿工或验证者
大多数 subtensor 客户端接受端点字符串。确认端点可达并返回链数据的快速方法是进行 JSON-RPC 调用。Bittensor 使用 Substrate 风格的方法,因此方法名称与 EVM 链不同。
curl -s https://bittensor-finney.api.onfinality.io/public \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "chain_getHeader",
"params": []
}'
健康的响应会返回一个包含区块号的头部对象。如果你得到超时或空结果,问题在于连接,而不是你的矿工逻辑。检查端点,然后检查你的客户端是否指向了正确的网络名称。
对于 JavaScript 客户端,模式相同:使用端点创建提供者,然后读取头部或元图。保持提供者实例长期存在,而不是每次调用都创建新实例,因为每次请求都重新连接会增加延迟并掩盖真正的故障。
import { ApiPromise, WsProvider } from '@polkadot/api';
const provider = new WsProvider('wss://bittensor-finney.api.onfinality.io/public-ws');
const api = await ApiPromise.create({ provider });
const header = await api.rpc.chain.getHeader();
console.log('current block', header.number.toNumber());
// read subnet state without polling the whole chain
const meta = await api.query.subtensorModule.subnetInfo(1);
console.log(meta.toHuman());
为什么 WebSocket 比你想象的更重要
在循环中轮询 chain_getHeader 对于仪表板是可行的。但对于需要对新区块或 epoch 变化做出反应的验证者来说,它并不合适。Substrate 客户端暴露了订阅功能,而 WebSocket 端点允许你订阅一次并在更新发生时接收更新。
const unsub = await api.rpc.chain.subscribeNewHeads((header) => {
console.log('new head', header.number.toNumber());
// trigger metagraph refresh or weight-setting logic here
});
需要警惕的故障模式是静默的订阅丢失。客户端保持连接,没有抛出错误,而你的矿工停止对新区块做出反应。添加心跳:跟踪你看到的最后一个区块号,如果它在几个区块内没有推进,则拆除提供者并重新连接。这一项检查可以防止大多数“我的矿工停止赚钱”的事件。
何时共享端点足够,何时不够
共享公共端点适用于开发、读取量适中的单个矿工以及探索性脚本。在以下情况下它不太适合:
- 你运行一个每个 epoch 设置权重的验证者,无法容忍订阅丢失。
- 你运营多个矿工,希望按进程隔离,以免一个嘈杂的循环影响其他矿工。
- 你需要为具有许多并发读取器的仪表板提供可预测的吞吐量。
- 你希望日志和指标与自己的流量关联,而不是共享池。
此时,选择在于托管 RPC API 和专用节点之间。托管 API 为你提供稳定的端点、WebSocket 支持,并由他人处理升级和链同步。专用节点 为你提供具有自己资源的私有实例,当你的读取模式很重或你想在运行时变更前后控制升级窗口时,这一点很重要。
| 情况 | 共享端点 | 托管 RPC API | 专用节点 |
|---|---|---|---|
| 本地开发 | 适合 | 可以 | 过度 |
| 单个矿工,低流量 | 适合 | 可以 | 过度 |
| 每个 epoch 设置权重的验证者 | 有风险 | 适合 | 适合 |
| 多矿工运营 | 有风险 | 适合 | 适合 |
| 高流量仪表板 | 不适合 | 适合 | 适合 |
| 自定义运行时或索引需求 | 不适合 | 有限 | 适合 |
注册、nonce 和其他写入端陷阱
读取是容易的部分。写入——注册热键、设置权重、转移质押——是挖矿应用以看起来像 RPC 故障但实际不是的方式出问题的地方。
- Nonce 冲突。 如果两个进程共享一个冷键并同时提交外部交易,其中一个会因 nonce 过时而失败。序列化写入或为每个进程使用单独的密钥。
- 注册成本变化。 子网注册成本是动态的。昨天成功的一笔交易今天可能因为成本变动而失败。在提交前读取当前成本。
- 有效性和最终性。 外部交易有有限的生命周期。如果你的端点滞后,交易可能在被打包前过期。确认你正在构建的区块是当前的。
- 设置权重窗口。 验证者必须在允许的窗口内设置权重。缓慢或过时的链读取器可能导致你错过它。
这些问题都不能仅靠更快的端点解决,但稳定的端点使它们更容易诊断,因为你可以信任你读取的区块数据是当前的。
一个最小监控探针
无论你选择哪个端点,都添加一个独立于矿工运行的探针。它应该回答一个问题:我读取的链数据是新鲜的吗?
#!/usr/bin/env bash
ENDPOINT="https://bittensor-finney.api.onfinality.io/public"
BLOCK=$(curl -s "$ENDPOINT" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"chain_getHeader","params":[]}' \
| grep -o '"number":"0x[0-9a-f]*"' | head -1)
echo "probe block: $BLOCK"
按计划运行它,记录区块号,如果它停止推进则发出警报。这比简单的正常运行时间检查更有用,因为端点可能在线但仍然落后。
矿工停止工作时的调试路径
按顺序处理这些步骤。大多数事件在前三步就能解决。
- 端点有响应吗? 运行上面的 curl 探针。如果超时,问题在于连接性或端点本身。
- 区块号在推进吗? 如果有响应但区块过时,你可能在一个滞后的节点上。切换端点并重新检查。
- 你的 WebSocket 订阅还活着吗? 如果你使用订阅,确认你仍在接收头部。如果没有,请重新连接。
- 你的钱包已加载并解锁了吗? 锁定的冷键会产生签名错误,在某些客户端中看起来像 RPC 错误。
- 注册成本仍然有效吗? 在重新提交前重新读取当前成本。
- 另一个进程在使用同一个密钥吗? 检查矿工和验证者进程之间的 nonce 冲突。
如果步骤一到三通过而矿工仍然不赚钱,问题在于你的子网逻辑,而不是你的 RPC 连接。
关键要点
- Bittensor 挖矿应用是一个技术栈:subtensor 客户端、钱包、子网逻辑、axon 服务器和链读取器。RPC 端点位于后两者之下。
- Bittensor 主网是 Finney,原生货币是 TAO。OnFinality 通过 HTTP 和 WebSocket 提供服务。
- 使用 HTTP 进行一次性读取,使用 WebSocket 进行订阅。添加心跳,以免静默的订阅丢失导致矿工停止。
- 共享端点适用于开发和单个矿工。验证者、多矿工设置和仪表板应使用托管 RPC API 或 专用节点。
- 挖矿应用中的大多数“RPC 故障”实际上是 nonce 冲突、过时的注册成本或过期的外部交易。在责怪端点之前先检查这些。
- 当你准备从共享端点迁移时,浏览 支持的 RPC 网络 和 RPC 定价。
常见问题
我需要一个特殊的应用来在 Bittensor 上挖矿吗? 不。没有单一的官方挖矿应用。你从 subtensor 客户端、钱包和你自己的子网逻辑组装一个技术栈,然后将其连接到 Bittensor RPC 端点。
我应该为 Bittensor Finney 使用哪个端点?
OnFinality 通过 HTTP 和 WebSocket 暴露 Bittensor Finney。使用 https://bittensor-finney.api.onfinality.io/public 进行读取,使用 wss://bittensor-finney.api.onfinality.io/public-ws 进行订阅。当前详情在 Bittensor Finney 网络页面。
我可以在共享公共端点上运行矿工吗? 可以,用于开发和低流量单矿工设置。如果你运行验证者或多个矿工,托管 RPC API 或专用节点可以减少其他人的流量影响你读取的机会。
为什么我的矿工在进程运行时停止赚钱? 通常是链读取器过时或 WebSocket 订阅丢失。添加一个心跳来检查区块号是否在推进,如果没有则重新连接。
Bittensor 上外部交易失败的原因是什么? 常见原因包括两个进程共享密钥时的 nonce 冲突、注册成本变化以及外部交易在被打包前过期。在提交前读取当前链状态。
我什么时候应该迁移到专用节点? 当你需要可预测的吞吐量、按进程隔离或控制运行时变更前后的升级窗口时。专用节点 通常是托管 RPC API 之后的下一步。