关于 monerometrics
monerometrics 是面向 Monero 社区及链可靠性观察者的开源网络监测项目。其仪表板和只读 API 追踪链重组、孤块,以及挖矿、网络和 Haveno 市场指标。
主要功能
- 01链重组与孤块追踪
- 02网络算力和出块时间指标
- 03矿池分布与集中度
- 04实时内存池和手续费估算
- 05Haveno 订单簿与溢价指标
- 06仪表板、只读 API 和 Tor 访问
适用场景
- 01查看重组历史及被替换的交易
- 02监测矿池集中度
- 03检查当前网络和内存池状态
- 04按支付方式分析 Haveno 流动性
MCP 相关
项目在 `https://api.monerometrics.net/mcp` 提供 MCP 服务,通过 Streamable HTTP 向 MCP 客户端公开 Monero 指标。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://api.monerometrics.net/mcpclaude mcp add --transport http nowi333-monerometrics https://api.monerometrics.net/mcp{"mcpServers":{"nowi333-monerometrics":{"type":"http","url":"https://api.monerometrics.net/mcp"}}}在 Cursor 中打开{"servers":{"nowi333-monerometrics":{"type":"http","url":"https://api.monerometrics.net/mcp"}}}在 VS Code 中打开{"mcpServers":{"nowi333-monerometrics":{"type":"http","url":"https://api.monerometrics.net/mcp"}}}{"mcpServers":{"nowi333-monerometrics":{"serverUrl":"https://api.monerometrics.net/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
19此工具无需参数。
详细介绍
monerometrics
用于监测 Monero 网络健康状况、可感知链重组的观测平台:公共仪表板 + API。
monerometrics 由社区资助。 Kuno 众筹活动将为未来两年提供资金,用于托管、FCMP++ 就绪工作、免费的链重组提醒、开放数据导出以及第二个节点。
monerometrics 用于衡量并记录 Monero 网络的健康状况:网络算力、出块时间、内存池状态、矿池分布,最重要的是,链重组(reorg)和孤块,而大多数区块浏览器都无法妥善呈现这些信息。
本项目源于2025 年 8 月的 Qubic 事件。当时,一个以自有代币向矿工支付报酬的矿池,其算力接近网络总算力的一半,随后扣留区块并发布了一条更长的私有链。2025 年 9 月 14 日,这导致区块高度 3,499,659 处发生了 18 个区块的链重组,抹去了约 36 分钟的历史记录,远远超过了所有人都视为最终确认的 10 次确认:原以为已完成结算的交易突然又变回未确认状态。公众讨论缺少可靠、易于获取的数据来厘清此事。monerometrics 填补了这一空白,提供一个中立、可验证且能感知链重组的观测平台。
本项目开源并由自身资金支持,没有广告,也不追踪用户。仪表板和 API 永久免费开放:没有付费层级,今后也不会有。
从毕业设计到社区工具。 monerometrics V1 是作为法国 IT 基础设施职业项目开发并答辩的,并因此获得了文凭。随着这一阶段结束,V2 的目标是将项目交由 Monero 社区接手。
- 仪表板:monerometrics.net
- 公共 API:api.monerometrics.net(提供 OpenAPI 文档)
- MCP 服务:
https://api.monerometrics.net/mcp(Streamable HTTP;已收录于 MCP Registry) - Tor 隐藏服务:
6wbhchvavey26lbtscl6w6qg76balycixtsklcggrsslyk4xah6sbbad.onion(仪表板 + API,无 Cloudflare,不暴露 IP,参见通过 Tor 访问)
功能
Dashboard 是一个包含四个部分的 React SPA,提供英语、法语和西班牙语版本,支持浅色和深色主题,并且在手机上也易于阅读:
- 共识与重组:链分叉可视化工具,以树形图展示相互竞争的分支;按时间窗口统计重组情况,最长可涵盖全部已记录数据;并提供孤块历史记录。每个区块都会标明其矿池以及归属判定方式,并标记合并挖矿区块。
- 挖矿集中度:展示矿池分布、排名前两位矿池的合计份额,以及每项归属判定背后的证据。
- 网络状态:哈希率、区块时间方差、内存池、发行量,以及实时读取节点四个优先级别的交易费估算器。
- 点对点市场:展示 Haveno 相对于现货价格的溢价(买卖两侧)、实时订单簿深度、挂单流动性,以及按付款方式统计的溢价。
- 交易搜索:粘贴交易哈希,即可查看 Monero 实际公开的相关信息、挖出其所在区块的矿池,以及该高度是否曾因重组而出现争议。哈希通过 POST 请求正文传递,不会出现在 URL 中。
- 所有时间序列均可交互浏览:每张图表下方都有范围条,可拖动以浏览时间、缩放,并查看随可见时间窗口变化的统计数据,而非整个序列的统计数据。
公共 API:基于 FastAPI,提供按主题分组的只读 JSON 端点,并通过 OpenAPI 编写文档。
重组检测:Python 工作进程从已同步的节点读取每个区块、计算指标,并通过重新检查节点中近期区块的滚动窗口来检测重组,记录实际重组深度以及被替换的交易。
架构
访客通过 Cloudflare 访问 Dashboard 或 API。Cloudflare 负责终止 TLS 并应用边缘防护,然后将请求转发到经过加固的 边缘服务器(nginx + ModSecurity WAF)。边缘服务器提供静态 Dashboard,并将 API 请求反向代理到 k3s 节点,在那里运行应用核心:Monero 节点、索引器、PostgreSQL 和 API。
此外还有一条独立路径:运行在边缘服务器上的 Tor 隐藏服务,完全绕过 Cloudflare,并在同一个源站上同时提供 Dashboard 和 API,且使用相同的 WAF。
flowchart LR
User(["Visitor"]) -->|HTTPS| CF["Cloudflare<br/>DNS · WAF · proxy"]
CF -->|"HTTP/2 origin pull"| Edge
Tor(["Tor visitor"]) -.->|"Tor network"| Onion
subgraph HZ["Hetzner Cloud · private network 10.0.0.0/24"]
Onion["tor daemon<br/>hidden service v3"]
Edge["edge 10.0.0.20<br/>nginx + ModSecurity WAF<br/>static dashboard"]
Onion -.->|"127.0.0.1:8080"| Edge
subgraph K3S["k3s 10.0.0.30 · no public ingress"]
API["FastAPI"]
Worker["Python worker<br/>(indexer)"]
DB[("PostgreSQL 17")]
Node["monerod 0.18<br/>pruned"]
end
Edge -->|"api. proxy_pass"| API
API --> DB
Worker --> DB
Worker -->|JSON-RPC| Node
end
Node <-->|"P2P sync"| Monero(["Monero network"])
API -.->|"XMR price (cached)"| Price(["CoinGecko · Kraken<br/>Haveno (RetoSwap)"])
通过 Tor 访问
Dashboard 也以 Tor v3 隐藏服务的形式发布,提供不依赖 Cloudflare 且不会暴露访客 IP 地址的数据访问路径:
6wbhchvavey26lbtscl6w6qg76balycixtsklcggrsslyk4xah6sbbad.onion
- 单一源站,不泄露信息。 隐藏服务在
/提供 Dashboard,并将/api下的请求反向代理到 API。SPA 会在运行时检测.onion主机,并切换到相对路径,因此浏览器请求不会离开隐藏服务进入明网。同一构建版本可同时用于两者。 - 有意不使用 TLS。 Tor 已提供端到端加密和身份验证,而
.onion地址本身就是服务的公钥。 - 使用相同的 WAF。 隐藏服务虚拟主机采用与明网网站相同的 ModSecurity 规则,因此 Tor 不能绕过过滤。
- 无法通过互联网访问。
.onion虚拟主机仅监听127.0.0.1:8080,因此只有 Tor 守护进程能够访问它。Tor 只建立出站连接。 - 不记录日志。 所有请求都来自
127.0.0.1,因此在此虚拟主机上启用访问日志不会记录任何有用信息,故已禁用。 - 可供发现。 明网网站通过
Onion-Location标头公布该服务。 - 速率限制。 按 IP 限制对 Tor 没有意义,因此 nginx 会为隐藏服务流量添加标记,并将其隔离到单独的限流桶中,设置更高的上限。明网虚拟主机会移除此标记标头,因此无法从互联网伪造该标记。
通过 tor Ansible 角色部署(config/ansible/roles/tor/)。
基础设施
平台运行在 Hetzner Cloud(纽伦堡)的两个 Ubuntu 24.04 服务器上,两台服务器位于同一私有网络中,且各自配置了防火墙。它们都不向互联网开放 SSH:管理操作仅通过由两台服务器共同加入的 Tailscale(WireGuard)网状网络进行,Grafana 也只能通过 Tailscale 访问。备份目前已暂停:相关工具(Restic,已加密,参见 k8s/monerometrics/BACKUP-PRA.md)仍保留在仓库中,但目前没有按计划运行的备份任务。
flowchart TB
Admin(["Administrator"]) -->|"SSH over Tailscale"| Mesh
Internet(["Internet"]) -->|"80 / 443 via Cloudflare"| Edge
subgraph HZ["Hetzner Cloud (nbg1) · 10.0.0.0/24"]
Edge["edge 10.0.0.20<br/>firewall: 80/443 from Cloudflare only"]
K3s["k3s 10.0.0.30 + data volume<br/>firewall: no inbound (P2P 18080 only)"]
Edge -->|"private network"| K3s
end
Mesh["Tailscale mesh<br/>(admin SSH · kubectl · Grafana)"]
Mesh --- Edge
Mesh --- K3s
| 服务器 | 类型 | 公网暴露 | 角色 |
|---|---|---|---|
edge | CX23 | 通过互联网开放 80/443 端口 | nginx 反向代理 + ModSecurity WAF,提供仪表盘 |
k3s | CX33 + 250 GB 卷 | 仅开放 Monero P2P | k3s 集群:monerod、worker、PostgreSQL、API、OpenBao |
关键选择包括:每台服务器都配置防火墙,任何服务器都不公开 SSH,唯一公开的 Web 界面前设有 WAF,采用零信任管理网状网络,且 k3s 节点仅开放 Monero P2P 端口。专用 SSH 堡垒机已于 2026 年 10 月弃用:Tailscale 已提供零信任入口,因此增加一台服务器只会提高成本。Tailscale 自带的 SSH 已禁用;普通 OpenSSH 使用密钥通过网状网络运行,因此访问不会依赖浏览器重新验证。两段链路均使用 HTTP/2,且 WAF 处于启用状态。所有内容均以基础设施即代码管理:Hetzner 和 Cloudflare 资源通过 Terraform 管理,服务器配置和符合 CIS 标准的加固通过 Ansible 管理,镜像发布到 GHCR。通过 Prometheus + Grafana 进行监控,并针对索引、节点同步、磁盘和故障工作负载配置告警规则。备份工具(Restic)仍予以保留,但已暂停。
密钥。 集群使用 OpenBao(Vault 的免费分支)进行配置,清单中不包含任何明文凭据。OpenBao 启动时会自动解除密封(静态密封,密钥保存在仓库外创建的 Kubernetes Secret 中);工作负载也可以回退使用 Kubernetes Secret(postgres-credentials-fallback),因此密封的密钥库不会导致服务中断。
运行成本
Hetzner 标价,每月费用上限,含 20 % 增值税:
| 项目 | 每月 |
|---|---|
1 × CX23(edge) | ~6.60 € |
1 × CX33(k3s) | ~10.20 € |
| 2 × 主 IPv4 | ~1.20 € |
| 250 GB 卷 | ~17.20 € |
| 合计 | ~35 €,含增值税 |
Cloudflare、Let's Encrypt、Tailscale 和 GitHub Actions 均使用免费套餐。
占用空间变化的主要因素是区块链,而非索引。经过裁剪的 Monero 区块链占用 106 GB;完整索引数据库包含 377 万个区块和所有时间序列,占用 3.1 GB,每个区块约 540 字节,每年增长约 150 MB。
增长量依据已索引数据测算,而非估算。将所有规范区块记录的大小相加,完整区块链占用 186.8 GB,因此该裁剪节点保留了 Monero 区块链略多于一半的内容。过去 12 个完整月份内,区块链增长了 22.18 GB,折合磁盘上每年 12.35 GB,各年增长较为稳定(2022 年为 17.5 GB,2023 年为 18.3 GB,2024 年为 29.1 GB,2025 年为 22.2 GB)。卷的使用量达到 128 GB 的 94 %,因此于 2026 年 10 月扩容至 250 GB,由社区资助(Kuno 里程碑 1)。剩余空间远超此前承诺的两年需求,也能容纳 FCMP++ 带来的更大交易。同期移除 SSH 堡垒机节省的费用覆盖了大部分差额。
索引器的工作原理
工作进程(apps/worker/indexer.py)是项目的核心。每隔
POLL_INTERVAL 秒,它会查询 monerod 的状态;节点完成同步后,则会运行三个
步骤:
-
确认窗口重扫(重组检测)。 它会在一次调用中重新获取最后
CONFIRMATION_WINDOW个区块(默认 60)的区块头,并将每个哈希与已存储的规范哈希进行比较。任何不匹配都表示发生了重组:已存储的区块会被标记为孤块 (is_canonical = false),节点上的区块则成为规范区块;同时,系统会在reorgs_detected中写入一条记录,包含实际深度和受影响的交易数量。正是这一步 让重组检测成为可能:仅向前索引不会回看过去,因此会悄无声息地漏掉所有改写了已索引高度的重组。窗口也是检测上限。 深度超过
CONFIRMATION_WINDOW的重组会改写重扫范围之外的高度,因此会被完全漏掉,而不会以错误的深度报告。在 60 个区块时,余量很充足;有记录以来最深的 Monero 重组为 18 个区块,但这一限制是结构性的,本文发布的计数仅在该深度范围内完整。调高该值会让每次轮询都多进行一次更大的区块头调用。交易数量使用
num_txes,该值不包含 coinbase,因此统计的是用户实际广播的交易,而不是矿工自己的产出。 -
向前索引。 它会获取最后一个已索引高度之后的区块。在接近区块链顶端时,它会逐个拉取完整区块,以便准确归属;在落后较远时(全新部署),则会切换为快速区块头回填(每次调用约 1000 个区块),足以生成网络健康度时间序列,并且速度足够快,可在两小时内填满较长的时间窗口,而不是永远也填不满。
-
替代链(孤块)。 大多数竞争区块会在几秒内得到处理,远早于下一次轮询,因此上面的重扫永远看不到它们:它只能捕获我们已经索引过的区块。因此,工作进程还会读取节点自身的替代链 (
get_alternate_chains,该 RPC 端口仅工作进程可访问),并将每个竞争区块记录为孤块。在加入这一步之前,记录下来的孤块大约只有实际数量的四分之一。
flowchart TB
Start(["Every POLL_INTERVAL"]) --> Info["GET /get_info"]
Info --> Sync{"node synced?"}
Sync -->|no| Wait["log progress · sleep"]
Sync -->|yes| Rescan["Rescan last N blocks<br/>get_block_headers_range"]
Rescan --> Diff{"stored hash<br/>≠ node hash?"}
Diff -->|yes| Reorg["mark old → orphan<br/>insert new canonical<br/>record reorg (depth, tx)"]
Diff -->|no| Fwd
Reorg --> Fwd["Forward index<br/>new blocks (batch)"]
Fwd --> Alt["Read alternative chains<br/>record orphans"]
Alt --> Metrics["update Prometheus metrics"]
Metrics --> Start
可观测性。 工作进程会在 :9100/metrics 上暴露 Prometheus 指标(索引延迟、重组计数器、同步状态、矿池索引大小、通过视图密钥证明的区块、归属冲突),并写入一个由 Kubernetes 存活探针读取的心跳文件。只有成功完成一个步骤后才会写入心跳,因此,如果循环持续失败,工作进程会被重启,并触发 WorkerStalled 警报。
矿池归属判定
Monero 从设计上就注重隐私:coinbase 中不包含矿池名称,隐身地址也意味着你无法查询“款项支付给了谁”。归属必须经过验证,绝不能想当然。
monerometrics 绝不会根据矿池自行报告的算力推断其份额。它只统计有证据可将区块归属于某个矿池的区块,并在 blocks.pool_source 中逐区块记录所用的证据类型。
1. 查看密钥证明,密码学验证(viewkey_proof)。 有些矿池会公开其钱包主地址和秘密查看密钥(参见 blocks.p2pool.observer/proofs)。查看密钥只能显示流入的交易,不能用于花费。它足以证明某个 coinbase 输出归某方所有,无需信任任何人的 API:
R = transaction public key, parsed out of the coinbase tx_extra (tag 0x01)
derivation = 8 · a · R (a = the pool's secret view key)
P_expected = Hs(derivation ‖ varint(i)) · G + B (B = the pool's public spend key)
如果 P_expected 等于索引 i 处的输出密钥,则该输出支付给了矿池的钱包:这是一个数学事实,不依赖任何矿池 API,因此不受报告延迟影响。报告延迟会让刚产生的区块看起来尚未归属。该功能从零实现于
apps/worker/pool_proofs.py(ed25519 点运算、Keccak-256、Monero base58),每个区块约耗时 33 ms。
2. 矿池区块列表,交叉比对(pool_api)。 未公开查看密钥的矿池仍会公布其挖出的区块。这些列表每约 2 分钟汇总到索引
{block_hash → pool} 中,并通过区块哈希进行匹配,因此归属声明对应于真实区块。这种方法的弱点在于延迟,而非准确性:发布较慢的矿池会让其近期区块暂时显示为 unknown,直到数据补齐。每个周期都会重新归属,从而追溯修正这些区块。
3. Coinbase 启发式判断,结构特征(coinbase_heuristic)。 一次 coinbase 向多个输出付款是 P2Pool 的典型特征,因为它会在链上拆分奖励。这是最后的手段,并会标记为启发式判断。
防护措施
- 启动时会自行验证密钥。 每个查看密钥都必须能证明一个矿池自己的 API 声称挖出的区块。验证失败的密钥会被丢弃,因此过期或错误的密钥绝不会错误标记区块。
- 冲突会公开显示,而非隐藏,并计入
monerometrics_attribution_conflicts_total。 - 未经证明的声明会被标记。 如果公开查看密钥的矿池列出一个无法通过该密钥证明的区块,该区块会记录为
pool_api_unproven,而不会以相同置信度显示。 - 当证据并存时,证明优先于 API。
- 数据源健康状态公开可查:
/pools/sources,因此数据源无声失效时会清晰可见,而不会悄悄增加unknown区块。
汇总的数据源
| 矿池 | 端点 | 方法 / 深度 | 查看密钥证明 |
|---|---|---|---|
| supportxmr.com | www.supportxmr.com/api/pool/blocks | ?limit=(最多 10000) | ✅ |
| hashvault.pro | api.hashvault.pro/v3/monero/pool/blocks | ?limit=&page=0(最多 10000) | ✅ |
| moneroocean.stream | api.moneroocean.stream/pool/blocks | ?limit=100(矿池上限) | ✅ |
| xmrpool.eu | web.xmrpool.eu:8119/get_blocks | 通过 ?height= 分页 | ✅ |
| ownblock.xyz | 无区块 API | 仅查看密钥 | ✅ |
| p2pool(main / mini / nano) | *.p2pool.observer/api/pool/blocks | ?limit= | · |
| nanopool.org | api.nanopool.org/v1/xmr/pool/blocks/0/{n} | 路径参数计数(约 4600) | · |
| c3pool.com | api.c3pool.org/pool/blocks | ?limit=(最多 10000) | · |
| kryptex.com | pool.kryptex.com/xmr/api/v1/pool/blocks | 通过 next 分页 | · |
| herominers.com | monero.herominers.com/api/get_blocks | 通过 ?height= 分页 | · |
| monerohash.com | monerohash.com/api/get_blocks | 通过 ?height= 分页 | · |
P2Pool 运行着三条侧链(main/mini/nano);系统会轮询这三条侧链,并将其合并为单一的 p2pool 标签,因为从中心化角度看,它们属于同一个去中心化网络。
哪些情况无法归属,以及原因
大约五分之一的区块最终会被标记为 unknown(过去 7 天为 21.9 %,相比之下,45.8 % 已通过密码学验证,其余则由矿池 API 声称或推断),我们会如实报告这个数字,而不会对其进行平滑处理。原因是结构性的:
- Qubic 不发布区块列表,也不提供查看密钥,因此无法归属。
- 单独挖矿的矿工按设计不可见;这正是 Monero 的特点。
- 有些矿池没有可用的 API,也不发布查看密钥。
- 非常新的区块可能确实会有几分钟无法归属,除非矿池提供查看密钥,在这种情况下便能立即验证。
所有公开追踪器都会遇到相同的上限;类似网站报告的未知占比甚至更高。将这五分之一的比例降下来,是该项目尚待完成的主要工作。
合并挖矿
合并挖矿区块是指同一份工作量证明同时声明了一个 Monero 区块和一个辅助链区块。索引器会通过 coinbase tx_extra 中的 0x03 标签检测此类区块;某个时间段内的占比会通过 /chain/provenance 发布,并在分叉可视化工具的每个区块上标记为 M。
之所以追踪合并挖矿,是因为它会带来中心化风险:辅助链可以补贴矿工,并将算力吸引到支持该链的矿池;而算力集中正是重组得以发生的前提。
不过,Qubic 做的并不是合并挖矿。 Qubic 实行的是一种“有用的工作量证明”方案:它通过兑换挖出的 XMR,以自己的代币支付矿工;一度比普通挖矿获利高出约三倍,使其占比从 2025 年 5 月的不到 2 %,升至 8 月时自称的多数份额。这种补贴属于经济层面,通过矿池进行,而非通过 coinbase 进行合并挖矿。混为一谈是不对的。
过去 7 天中,约 60 % 的区块采用了合并挖矿。这一占比并非全网范围的变化,而是各矿池的策略所致:supportxmr、p2pool、c3pool 和 moneroocean 对它们找到的每个区块都进行合并挖矿,hashvault 对大多数区块进行合并挖矿,而 nanopool、herominers、xmrpool 和 kryptex 则完全不进行合并挖矿。因此,这条曲线反映的既是本周由哪个矿池找到区块,也是挖矿实践的变化。辅助链未具名:链上标签只携带一个 Merkle 根,因此要识别它就需要查询该链。我们报告数量和根,而不进行猜测。
数据模型
从 API 的角度来看,PostgreSQL 只读。两个表承载链记录
(k8s/monerometrics/20-configmap-postgres-init.yaml):
blocks,其主键是区块哈希,而不是高度。这是有意为之:这样同一高度可以有多个区块共存(规范链上的区块,以及重组后留下的孤块)。部分唯一索引(UNIQUE (height) WHERE is_canonical)可确保任意时刻每个高度恰好有一个规范区块。pool_source记录该区块的矿池是如何确定的,因此使用方可以区别对待加密证明和矿池自己的声明。reward_xmr是精确的NUMERIC,绝不是浮点数。reorgs_detected,每个检测到的事件占一行:fork_point_height、depth、old_chain_tip_hash、new_chain_tip_hash、affected_tx_count、detected_at。fork_point_height是被替换的第一个高度:该事件重写了从fork_point_height到fork_point_height + depth - 1的高度。
孤块与规范区块的划分为分叉可视化工具以及 /orphans/recent 和
/reorgs/stats 端点提供了支持。
其余都是时间序列,由工作进程在首次运行时创建:
| 表 | 写入方 | 内容 |
|---|---|---|
mempool_snapshots | 工作进程,每次轮询 | 随时间变化的待处理交易数量 |
fee_snapshots | 工作进程,每 5 分钟 | 节点的四个费用等级,单位为每字节 piconero |
price_snapshots | 工作进程,每 10 分钟 | 集中式现货价格和 Haveno 订单簿的买卖双方价格 |
haveno_offers | 工作进程,每 10 分钟 | Haveno 上的单笔未结报价及其付款方式 |
haveno_trades | 工作进程,每小时 | 截至 2024 年 5 月的已执行 Haveno 交易及其付款方式 |
haveno_liquidity | 工作进程,每小时 | 截至 2024 年 11 月的各市场每小时挂单流动性 |
spot_daily | 工作进程,每小时 | 每日集中式收盘价,用于给历史交易定价 |
pool_sources | 工作进程 | 各矿池 API 的可访问性和区块数量 |
api_usage | API | 外部请求计数器 |
它们全都是缓存,而非事实来源:链表可以从任意 monerod 重新推导,市场表可以从 haveno.markets 重新推导。这一特性使下文的高可用方案成本低廉。
有两个序列例外,无法重建:内存池快照和重组记录。交易被挖出后,链上没有任何信息能说明一小时前有多少笔交易处于待处理状态,而被丢弃的区块不会存在于任何区块浏览器中。两者都从本观测服务开始监控的那天起记录,因此会保留,而不会清理。
API 参考
API(apps/api/)为只读,使用 FastAPI 构建并返回 JSON,交互式 OpenAPI 架构见
api.monerometrics.net/docs。
高开销聚合会在服务端缓存,每个响应都带有自身的有效期
(Cache-Control + ETag),因此客户端已有某个版本时会收到空的 304。每个 IP
都有速率限制(每分钟 300 个请求;Tor 流量使用独立的共享额度)。CORS 对
GET 开放。无需密钥,无需账户,不追踪。
除非另有说明,window 接受 1h、24h、7d、30d、90d、1y、5y。
服务
| 端点 | 描述 |
|---|---|
GET /health | 存活状态 + 数据库连接检查。 |
GET /info | API 版本、最新索引高度、区块总数、孤块数和重组数。 |
GET /usage/external | 已处理的外部 API 请求数,不包括本仪表板和 MCP 服务。 |
网络
| 端点 | 描述 |
|---|---|
GET /network/info | 当前状态:同步状态、内存池大小、难度、预估算力(节点实时数据)。 |
GET /network/hashrate?window= | 历史网络算力(难度 / 120 s),按窗口分桶,约 300 个数据点。 |
GET /network/blocktime?window= | 连续规范区块之间的时间方差(目标为 120 s),每个区块一个数据点,最多 1500 个。 |
GET /network/mempool?window= | 内存池大小随时间的变化。分桶依据实际记录的历史数据,而非请求的窗口,因此较短的序列也能保持其数据密度。 |
GET /network/emission?window= | 平均区块奖励随时间的变化 · 门罗币尾部发行(约 0.6 XMR/区块)。 |
GET /network/fees | 节点的四档费用(慢速、普通、快速、最快),按约 1500 字节的参考交易计价,显示 XMR 和 USD。 |
GET /network/fees/history?window= | 普通档费用随时间的变化,单位为纳诺罗。window 接受 24h、7d、30d、90d、1y。 |
区块链与重组
| 端点 | 描述 |
|---|---|
POST /chain/search | 将哈希解析为交易或区块。返回 Monero 公开的交易信息(确认数、区块、费用、输入、输出、环大小)、挖出该区块的矿池,以及该高度是否曾出现竞争。特意使用 POST:哈希不会出现在 URL、日志行或引荐来源中。 |
GET /chain/window?from=&to= | 两个高度之间的原始区块窗口(最多 1000 个区块)。 |
GET /chain/provenance?window= | 我们自身归属判断的证据质量:经密码学证明、由矿池 API 声称、推断得出或未归属,以及矿池无法用自己的密钥证明的声明。window = 1h|6h|24h|48h|7d。 |
GET /chain/block/{hash} | 单个区块的完整详情,实时从节点读取,并附带矿池归属信息;对于已证明的区块,还会提供公开的证明输入,供任何人重新验证。 |
GET /chain/fork-window?limit= | 最新的 N 个区块,包括孤块,并带有分叉点标记。limit = 10..1000。 |
GET /reorgs?limit= | 最近检测到的重组。limit = 1..1000。 |
GET /reorgs/stats | 过去 24h / 7d / 30d / 90d / 所有已记录时段的重组统计(数量、平均和最大深度、受影响的交易),以及开始监测的日期。 |
GET /orphans/recent?window= | 孤块及其竞争的规范区块。window = 24h|48h|7d|30d|90d|180d|1y|all。 |
矿池
| 端点 | 描述 |
|---|---|
GET /pools/distribution?window= | 各矿池的区块占比,以及最大矿池占比和 Nakamoto 系数。未归属区块仍计入分母,但不计入任何矿池,因此该系数是上限。window = 1h|6h|24h|48h|7d。 |
GET /pools/sources | 索引器测得的各矿池归属 API 可访问性。 |
GET /pools/latency?window= | 各矿池公开声明自己挖出某区块所需的时间,包括中位数和第 90 百分位数。测量精度受我们自身的轮询间隔限制,响应中会说明该间隔。 |
市场
| 端点 | 描述 |
|---|---|
GET /price | 来自中心化参考源(CoinGecko,Kraken 为备用)的 XMR/USD 以及 Haveno 场外价格。返回高于现货价格的买卖双方最佳报价、按金额加权的对应价格,以及 round_trip_cost_pct。两种数据源都由服务器端代理,因此浏览器不会直接调用它们。 |
GET /price/spread?window= | Haveno 订单簿相对于现货价格的随时间变化数据,每 10 分钟采样一次,包含买卖双方。window 接受 24h、7d、30d、90d、1y。 |
GET /haveno/book | XMR_USD 的实时订单簿,按价格层级列出累计深度、报价数量、付款方式和 reversible 标记,每个价格均相对于现货价格。 |
GET /haveno/methods?window=¤cy= | 按付款方式分组的已执行交易,以及溢价的平均值、中位数和标准差。window = 30d|90d|180d|1y|all;currency = USD|EUR。 |
GET /haveno/liquidity?window=¤cy= | 开放报价中未成交的 XMR 数量,按小时统计,数据可追溯至 2024 年 11 月。 |
GET /haveno/trades?limit=¤cy= | 最近已执行的交易,包含付款方式、价格和溢价。 |
其他
| 端点 | 描述 |
|---|---|
GET /status | 一行式健康状况判定和链及挖矿集中度,依据最大矿池份额、两大矿池合计份额、24 小时重组深度和链尖端时龄计算。返回所有用于判定的阈值:协议中没有规定矿池份额达到多少就算高,因此我们公布了自己的阈值,而非暗中设定。 |
GET /news | 过去七天来自三个来源的 Monero 新闻:项目自身博客、Monero Observer 和 GitHub 发布内容,每条均标注来源。新闻由服务器端获取并缓存;会移除各来源自有域名之外的链接,避免遭入侵的 Feed 将访问者重定向到其他网站。 |
发现机制。 除了文档中记录的 API,该服务还会响应爬虫实际请求的 Agent 发现约定:llms.txt、agents.json、Agent 卡片、mcp.json、OpenRPC、ai-plugin.json、x402、owners.json,以及裸路径和 RFC 9728 格式下的 OAuth 受保护资源元数据。对于不存在的端点,服务会返回一个 JSON 正文,列出实际存在的接口,而非仅返回 404。服务有意不响应的是 /v1/models 及其变体:这些探测用于查找兼容 OpenAI 的推理 API,响应它们会宣称本项目并不具备的能力。
支付渠道的代价
对于一个无需 KYC 的交易所,真正值得关注的问题不是门罗币在那里多少钱,而是是什么让它变得更贵。按支付方式对所有已执行的交易进行分组,就能找到答案,而答案并不符合直觉:
| 支付方式 | 交易数 | 交易量(XMR) | 平均溢价 | 可撤销 |
|---|---|---|---|---|
| PayPal | 63 | 25 197 | +14.67% | 是 |
| Wise(TransferWise USD) | 86 | 15 756 | +13.60% | 是 |
| Cash App | 249 | 67 824 | +10.77% | 是 |
| Venmo | 30 | 9 569 | +8.92% | 是 |
| Zelle | 466 | 298 361 | +2.60% | 否 |
| 美国邮政汇票 | 8 | 4 615 | +1.46% | 否 |
| Revolut | 89 | 42 209 | +1.41% | 未分类 |
| 邮寄现金 | 219 | 455 897 | +1.37% | 否 |
美元市场,180 天数据,截至 2026 年 8 月 24 日,现货参考价为 Kraken 每日收盘价。
溢价取决于可撤销性,而非隐私性。 买家通过 PayPal 或 Cash App 付款后,可以在门罗币释放后发起拒付,而卖家无计可施,因此会将这一风险计入价格,溢价达 9% 至 15%。无法撤销的支付渠道溢价则在 1% 至 3% 左右。信封现金是列表中隐私性最高的方法之一,价格却属于最低之列,交易量也高于任何其他支付渠道。
reversible 标记是我们的分类,并非 Haveno 字段。Revolut 未作分类:Revolut 账户之间的转账原则上不可撤销,但银行会受理欺诈争议,而且其溢价与不可撤销的支付渠道接近。交易数很少的方法,其溢价不够稳定;现货参考价采用每日收盘价;2024 年 9 月之前的交易不在 Kraken 的数据范围内,因此完全不计入溢价。加密货币交易对不纳入统计:haveno.markets 对其报价采用反向表示。
如何解读溢价。 ask_premium_pct 将最低卖价与现货价进行比较;ask_avg_premium_pct 则比较所有卖出报价按金额加权后的平均值。这两个平均值之间的差值就是 round_trip_cost_pct,也就是买入后再卖出的成本。这个数字经受住了现实检验:约为 20%,而显眼的溢价数据接近 8%。此指标刻意使用按金额加权的平均值,而非买卖双方各自的最优报价,因此应将其视为上限:最优报价背后的交易量有时只有 1.49 XMR。只在第一个价位成交的小额交易成本更低;需要逐档吃单的交易则不会。
范围:仅法币市场。 Haveno 运行着 34 个市场,但约 95% 的总流动性来自加密货币交易对;其溢价始终接近于零,因为加密货币之间的兑换即时完成,也不需要交易对手方。法币点对点交易涉及真实交易对象、拒付风险和延迟,这些正是溢价存在的唯一原因。除非另有说明,所有数据均为 XMR_USD,因此有意呈现的数值远低于整个网站的总量。请注意,XMR_USD 指法定美元:稳定币交易对单独列出。
这些数据不代表什么。 /price/spread 背后的数据序列包含价格、金额和报价数量,但不包含支付方式,因为一级深度数据流未公开该信息。因此,最低卖价并非隐私购买门罗币的价格,而是最具竞争力的报价价格,无论使用哪种支付渠道。/haveno/book 是个例外:它读取二级数据流,因此每个价格档位都包含其支付方式。历史数据始于 2026 年 8 月 24 日,即开始记录之日,因为 haveno.markets 不提供历史序列,价差也就无法回填。
MCP 服务
同一组只读指标也会通过 Model Context Protocol 服务
(apps/mcp/)提供给 AI 助手,因此任何兼容 MCP 的客户端都可以直接查询 Monero 网络,无需
账户或 API 密钥。
- 端点(Streamable HTTP):
https://api.monerometrics.net/mcp - 注册表:以
io.github.nowi333/monerometrics发布于 MCP Registry。 - 工具:
network_info、network_hashrate、network_blocktime、network_mempool、network_emission、reorgs、reorg_stats、recent_orphans、pool_distribution、pool_sources、chain_provenance、search_block、get_block、chain_fork_window、price、haveno_book、haveno_premium、haveno_payment_methods,以及一个monerometrics://reference资源。
它是公共 REST API 的轻量封装,与 API 一同部署在 k3s 上,并路由至 /mcp。
仓库布局
apps/ Application code
dashboard/ React + Vite SPA (EN/FR/ES)
api/ FastAPI service
mcp/ Model Context Protocol server (thin wrapper over the API)
worker/ Python indexer (reorg detection) + shared pool module
infra/ Terraform, modules (network, server, dns) + environments
config/ Ansible, inventory, playbooks, roles (hardening, nginx, tor, k3s, ...)
k8s/ Kubernetes (k3s) manifests + backup/DR runbook (BACKUP-PRA.md)
scripts/ Helpers (env loader)
部署
整个平台都可以通过代码复现。你需要一个 Hetzner 项目、一个由 Cloudflare 管理的域名,以及环境中所需的令牌:
source scripts/load-env.sh # tokens from the keychain
cd infra/environments/poc
terraform init && terraform apply # servers, private network, firewalls, DNS
cd ../../../config/ansible
ansible-playbook site.yml # CIS L1 hardening, nginx+WAF, k3s, Tailscale, tor
kubectl apply -k k8s/monerometrics/ # application workloads
配置漂移。 服务器配置只能通过 Ansible 更改,绝不能手动更改。每次更改前后,试运行都必须显示所有主机均无需更改:
ansible-playbook site.yml --check --diff -e common_apt_upgrade=false
common_apt_upgrade=false 会跳过完整的软件包升级,因此仅修改配置的运行不会意外升级生产环境;安全补丁由 unattended-upgrades 提供。
服务器规格、数据中心和卷大小均为 Terraform 变量(参见
infra/environments/poc/terraform.tfvars.example)。
不会提交明文凭据。 集群内置 OpenBao:只需初始化一次数据库凭据(secret/postgres/credentials),所有使用方都可以从中读取。OpenBao 会在启动时自动解除密封;如果无法解除,工作负载则会读取 Kubernetes Secret。
本地开发(仪表板)
cd apps/dashboard
npm install
npm run dev # local dev server
npm run build # production build to dist/
仪表板会读取公共 API;将其指向 api.monerometrics.net(参见 src/api.js)。
迈向高可用
当前运行的是刻意保持精简的单节点 POC:一个 k3s 节点、一个未复制的 PostgreSQL 实例、一个边缘节点。它务实、成本低(含增值税约 35 €/月),足以验证 产品,但这三者都是单点故障。
这里有一项特性,使实现高可用的成本格外低:每项指标都可从 Monero 区块链确定性地推导得出。数据库是物化缓存,因此任何副本或整个区域都可以通过自己的本地 monerod 重新索引。因此,读取天然支持主动-主动;即使整个栈丢失,也只需从头重建,而不会丢失数据。例外是内存池和重组序列,它们属于观测数据,而非推导结果。
该计划分阶段消除单点故障,每一阶段都可以独立筹资,让基础设施随着项目社区的资金增长,而不是提前扩张:
- 单区域高可用应用。 在冗余边缘节点池前部署负载均衡器,采用 3 节点 k3s 控制平面(etcd 仲裁)、支持自动故障切换的复制 PostgreSQL(CloudNativePG)、采用 Raft 高可用模式的 OpenBao,以及冗余 Monero 节点。
- 多可用区。 将同样的架构分布到 Hetzner 的不同位置(
nbg1/fsn1/hel1),在第二个区域设置同步 PostgreSQL 副本以实现近零 RPO,并在第三个区域设置异步副本。这样,etcd 仲裁和边缘节点池便能承受整个区域的故障。 - 多区域主动-主动。 在不同区域或服务商部署两个完整栈,通过 Cloudflare Load Balancing 的健康检查和地理路由来分配流量。每个区域都从自己的 Monero 节点进行索引,因此读取流量可在本地处理,且每个区域都能独立重建。
flowchart TB
CF["Cloudflare · DNS / WAF / proxy"] --> LB["Load balancer"]
subgraph R1["Region"]
LB --> E1["edge-1<br/>nginx + WAF"]
LB --> E2["edge-2<br/>nginx + WAF"]
subgraph K3S["k3s HA · etcd quorum"]
S1(["server-1"]) --- S2(["server-2"]) --- S3(["server-3"])
end
E1 --> K3S
E2 --> K3S
subgraph PG["PostgreSQL HA"]
PGp[("primary")] --> PGr[("replicas")]
end
K3S -->|writes| PGp
K3S -.reads.-> PGr
K3S --> N1["monerod-1"]
K3S --> N2["monerod-2"]
end
N1 <--> MN(["Monero P2P network"])
N2 <--> MN
R1 -->|"encrypted 3-2-1"| OCI[("off-site backups")]
安全与机密信息
- 仓库中不存放机密信息。 凭据在运行时从 macOS Keychain / 环境变量(
scripts/load-env.sh)或 OpenBao 获取。Terraform 状态文件不存放在仓库中。 - 纵深防御:防火墙分段隔离、禁止公开 SSH、WAF、零信任管理网状网络、风险分析(EBIOS RM)以及书面的灾难恢复计划(备份目前已暂停)。
联系方式
如果你对方法有疑问、发现某个数字似乎不对、有矿池希望索引其视图密钥,或研究人员需要数据集,请联系:[email protected]。Bug 报告和功能请求最好通过 GitHub issues 提交,这样内容会保持公开且可搜索。
支持项目
monerometrics 使用适度的自筹资金基础设施运营(无广告、无跟踪、不出售数据),每月费用约为 35 €,含 VAT。XMR 捐款请发送至:
41mkUSrcAvdGw9E19a83rsh9zdSNC7m8PP34NvmRCCPLZVot61kJHc9i8KGge5JmxkDTuiz7a2nUtE7C4rcQJn4xKjfFyU2
也可以使用其他任何加密货币,通过 trocador.app AnonPay 结算至该地址,无需账户,也无需 KYC。
同一地址也发布在仪表板和 /.well-known/owners.json 中,因此你可以在发送前,通过三个独立来源交叉核对。
许可证
MIT,详见 LICENSE。
无广告。无跟踪。不出售数据。只有真实可信的 Monero 网络数据。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。