Bitcoin Core 详解 exportasmap RPC:将构建时内嵌的 ASMap 数据导出到文件
本文基于 doc/release-notes-33920.md 中记录的 exportasmap 新 RPC 展开,讲清楚该命令的用途、参数与返回值、构建时启用条件,以及 Bitcoin Core 内嵌 ASMap 数据从编译期打包到运行期校验加载的完整链路。读完之后,你可以把节点编译时内嵌的 IP 前缀到 ASN(自治系统号)映射数据原样落盘,并通过返回的 SHA256 哈希验证其内容,用于离线备份、数据比对或进一步离线分析。
一、release note 原文与功能定位
doc/release-notes-33920.md 的完整内容只有三条:
A new
exportasmapRPC writes the ASMap data embedded at build time to a file.
这条记录非常精炼,核心信息有三个:
- 这是一个新增的 RPC,命令名为
exportasmap; - 它的操作对象是构建时(build time)内嵌进二进制的 ASMap 数据,而不是运行时从
-asmap文件路径加载的数据; - 行为是写出文件,即将二进制 ASMap 数据完整导出。
结合 doc/asmap-data.md 的背景说明,ASMap 是 IP 前缀到 ASN 的映射表(本质上是互联网路由表的某个快照),供 -asmap 选项在 netgroup 分桶时按 ASN 而不是 IP 前缀聚合对等节点,从而提升 peer 集合的多样性。当用户无法自行提供 ASMap 文件时,Bitcoin Core 会在构建时把一份默认映射(src/node/data/ip_asn.dat)内嵌进发行版,exportasmap 正是让用户把这份“看不见”的内嵌数据取出来的通道。
二、exportasmap 的参数、返回值与调用示例
RPC 的完整定义在 src/rpc/net.cpp 中,属于 network RPC 类别(注册于 src/rpc/net.cpp)。其声明的帮助文本如下:
- 命令描述:
Export the embedded ASMap data to a file. Any existing file at the path will be overwritten.(将内嵌 ASMap 数据导出到文件,目标路径上已有文件会被覆盖) - 参数:
path(字符串,必填)——输出文件路径;若是相对路径,会先拼接 datadir 前缀(代码中使用fsbridge::AbsPathJoin(args.GetDataDirNet(), ...)做绝对化,即网络相关的 datadir)。 - 官方示例(来自 HelpExampleCli / HelpExampleRpc):
# CLI 方式
bitcoin-cli exportasmap "asmap.dat"
# RPC 方式
curl --user myuser: --data-binary '{"jsonrpc":"1.0","id":"curltest","method":"exportasmap","params":["asmap.dat"]}' -H 'content-type: text/plain;' http://127.0.0.1:8333/
返回值为一个对象,包含三个字段:
| 字段 | 类型 | 含义 |
|---|---|---|
path |
字符串 | ASMap 数据实际写入的绝对路径 |
bytes_written |
数字 | 写入文件的字节数 |
file_hash |
十六进制字符串 | 所导出 ASMap 数据的 SHA256 哈希 |
这三个字段的实现在 src/rpc/net.cpp 中:path 由 export_path.utf8string() 给出,bytes_written 取 node::data::ip_asn.size(),file_hash 则是对同一份数据调用 HashWriter 后取 GetSHA256() 的结果。由于导出字节与哈希来自同一内存数据,file_hash 可以直接用 sha256sum 与落盘文件交叉验证,确保导出过程无损。
三、构建期前提:WITH_EMBEDDED_ASMAP 与 ENABLE_EMBEDDED_ASMAP
exportasmap 能否正常工作取决于构建配置,相关证据链如下:
- 构建选项:根 CMakeLists.txt 定义了
option(WITH_EMBEDDED_ASMAP "Embed default ASMap data." ON),即默认开启内嵌 ASMap。 - 数据嵌入方式:src/CMakeLists.txt 中,当
WITH_EMBEDDED_ASMAP开启时:- 为
bitcoin_node目标添加编译定义ENABLE_EMBEDDED_ASMAP=1; - 通过
target_raw_data_sources把 src/node/data/ip_asn.dat 编译为命名空间node::data下的ip_asn字节数组(由 cmake/module/TargetDataSources.cmake 机制生成头文件node/data/ip_asn.dat.h)。
- 为
- 运行时开关:RPC 实现体被
#ifndef ENABLE_EMBEDDED_ASMAP包裹(src/rpc/net.cpp):如果二进制里没有内嵌数据,调用该 RPC 会直接抛出RPC_MISC_ERROR(错误码 -1),报错信息为No embedded ASMap data available;如果内嵌数据为空或未通过CheckStandardAsmap完整性校验,则报Embedded ASMap data appears to be corrupted。
换句话说:只有默认构建(或显式保持 WITH_EMBEDDED_ASMAP=ON)得到的 bitcoind 才支持该 RPC,这一约束在下文的官方功能测试中也有对应断言。
四、导出实现细节与内嵌数据的完整性保障
导出逻辑本体(src/rpc/net.cpp)非常直白:
- 用
EnsureAnyArgsman(request.context)取得 ArgsManager,并以GetDataDirNet()为基准把相对路径转为绝对路径; fsbridge::fopen(export_path, "wb")以二进制写模式打开文件——注意"wb"意味着已存在的同名文件会被静默覆盖,这与帮助文本一致;- 将
node::data::ip_asn(即内嵌的完整原始字节序列)一次性写入,随后fclose;任一环节失败(打开失败、关闭失败)都会返回带具体路径的错误信息。
这里导出的 ip_asn 与节点启动时实际使用的数据是同一份。启动逻辑在 src/init.cpp:当用户配置了 -asmap 但未给出文件(或走内嵌分支)时,节点读取 node::data::ip_asn,先做 CheckStandardAsmap 校验,再用 NetGroupManager::WithEmbeddedAsmap(asmap) 构造分桶管理器,并以 AsmapVersion(即 SHA256,见 src/util/asmap.cpp)记录日志 “Using asmap version ... for IP bucketing”。因此 exportasmap 返回的 file_hash 与启动日志中打印的 asmap version 应当一致,这是核对“我导出的就是节点正在用的”最直接的依据。
数据格式与完整性校验
被导出的字节流不是普通文本,而是一套位打包(bit-packed)的“字节码”格式。src/util/asmap.cpp 的文件头注释说明了设计:整份映射被视为连续比特序列,小端位序存储,用变长整数和四类指令(RETURN、JUMP、MATCH、DEFAULT)表示一棵二叉 trie,运行时由 Interpret 函数逐位解释来查 ASN。
导出前的两道防线:
CheckStandardAsmap(src/util/asmap.cpp):对 128 位输入(IPv6)模拟所有执行路径,调用SanityCheckAsmap检查指令是否跨越文件边界、JUMP 是否越界或互相交叉、是否存在冗余的 DEFAULT/RETURN 序列等,不合法则记录Sanity check of asmap data failed警告并返回 false;- 空数据判断:
node::data::ip_asn.empty()时按“损坏”处理。
也就是说,exportasmap 只可能把一份“已经通过结构校验的内嵌数据”写到磁盘,导出文件与内嵌数据在字节层面严格一致。
五、功能测试中的验证方式
官方功能测试 test/functional/feature_asmap.py 对 exportasmap 有直接覆盖,可参考其断言方式:
- 在无内嵌数据构建的节点上调用该 RPC,断言抛出错误码
-1、信息No embedded ASMap data available; - 在常规构建上执行
result = self.node.exportasmap("asmap.dat"),验证返回结构。
该测试文件同时覆盖了 ASMap 的核心行为(-asmap 加载自定义文件、按 ASN 分桶等),如果要理解 exportasmap 在整个 ASMap 功能族中的位置,它是最好的入口。
六、典型使用场景小结
- 数据核对与审计:把内嵌 ASMap 导出后计算 SHA256,与 doc/asmap-data.md 所述 asmap-data 项目公开的文件哈希比对,确认当前二进制内嵌的是哪一份快照。ASMap 数据来源于 RPKI、IRR 与 Routeviews,由 Kartograf 工具确定性构建,因此“同一份原始数据 → 同一份编码文件”,哈希比对是可靠的核对手段。
- 离线分析与工具链接入:导出的
asmap.dat与通过-asmap=path加载的自定义文件格式完全一致,可供 contrib/asmap/asmap-tool.py 等工具链消费。 - 更新跟踪:结合 doc/release-process.md(其中要求每次发布前用新的 asmap 文件替换
src/node/data/ip_asn.dat),运维者可以在升级 bitcoind 后通过exportasmap的file_hash快速确认内嵌数据是否已随版本更新。
适用前提与限制:相对路径基于 datadir(网络相关 datadir)解析;目标文件会被覆盖;仅内嵌 ASMap 开启的构建可用该 RPC,且内嵌数据必须通过完整性校验,否则会返回 RPC_MISC_ERROR。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00