Bitcoin Core 26.2 维护版全解析:升级流程、兼容性矩阵与修复项源码级解读
Bitcoin Core 26.2 是 26.x 系列维护版本之一,其发布说明完整存档于本仓库的 doc/release-notes/release-notes-26.2.md。本篇文章以此文档为主体骨架,围绕"如何升级到 26.2、官方支持哪些系统、本次修复了什么、这些修复在源码中如何落地"四条主线展开,并在每个修复项上结合当前仓库的 RPC、P2P 与构建源码给出可直接核对的路径与行号,帮助节点运维者、二次开发者和研究者既能完成一次稳妥的版本升级,也能透彻理解 26.2 背后各 PR 的实现细节。
需要先说明的一个前提:本文所在仓库是 Bitcoin Core 的 integration/staging 开发树,发布说明目录中同时归档了 0.3.x 至 31.x 的历史文档,因此下文引用的源码路径取自当前开发树,个别实现细节可能在 26.2 之后持续演进,但这不影响它作为 26.2 修复逻辑的证据。
26.2 发布说明与本仓库的对应关系
从仓库的 doc/release-notes 目录命名序列可以清晰看出 26.x 的维护节奏:release-notes-26.0.md、release-notes-26.1.md 与本文主角 release-notes-26.2.md 依次排列。这类 x.y.z 的第三段版本号递增(patch/minor 维护线)通常意味着:
- 不引入新的共识层规则与对等节点(peer)协议不兼容变更;
- 集中修复上一个小版本暴露的 bug、补齐健壮性校验,并优化构建与 CI 基础设施;
- 附带更新的多语言翻译。
26.2 的发布说明原文也印证了这一点——它开门见山列出"新特性、各类 bug 修复、性能改进以及更新的翻译",随后按 Script(脚本)、P2P 与网络、RPC、Build(构建)、Misc(其他) 五类分组陈列合并的 PR 编号。
如何升级:从旧版本平滑迁移到 26.2
发布说明给出的升级流程对 Linux / macOS / Windows 分别适用,核心原则是"先完整停止,再替换二进制,最后重启":
- 若你正在运行旧版本,先关闭节点进程,并等待其完全退出——在部分情况下优雅关闭可能需要几分钟(落盘、刷新 UTXO 缓存、断开对等连接等)。
- Windows 平台:直接运行新版安装包完成替换。
- macOS 平台:拷贝新版覆盖
/Applications/Bitcoin-Qt。 - Linux 平台:将新版的
bitcoind/bitcoin-qt可执行文件替换到原安装路径后重新启动。
文档还特别提示两类升级场景:
- 跨越已 EOL(停止维护)版本的直接升级是可行的,但若数据目录需要迁移,启动耗时可能更长;
- 旧钱包版本的数据一般仍然兼容,即钱包文件向后兼容性有保障。
对节点运维者而言,这是 26.x 内小版本升级的典型操作模式:不涉及链数据重建,替换二进制并观察日志即可。若需要从源码自行构建,仓库根目录的 INSTALL.md 提供了完整指引。
官方支持的操作系统与兼容性前提
发布说明的 "Compatibility" 一节界定了 26.2 的测试与支持边界,可整理为下表:
| 系统类别 | 支持状态 | 说明 |
|---|---|---|
| 基于 Linux 内核的操作系统 | ✅ 支持且经广泛测试 | 主流的发行版 |
| macOS 11.0 及以上 | ✅ 支持且经广泛测试 | 对更低版本不再维护 |
| Windows 7 及更新版本 | ✅ 支持且经广泛测试 | 覆盖经典 Win 桌面环境 |
| 其他类 Unix 系统 | ⚠️ 应当可用但测试较少 | 如各类 BSD,未列入常规 CI 主力 |
| 非上述系统 | ❌ 不建议使用 | 官方明确不推荐在未支持系统上运行 |
这段边界直接决定了升级决策:如果你的运行平台在 macOS 11.0 以下或 Windows 7 之前,26.2 官方并不保证可用性;其余主流服务器环境则可以放心跟随本发布说明的升级流程。
本次发布的关键变更:五类修复逐项解读
Script(脚本 / 签名)
本类只有一个条目:#29853:签名时不再假设正在解析的是"合乎常理"的 TapMiniscript。
Taproot 下的 Miniscript(TapMiniscript)允许以结构化策略表达花费条件。该 PR 修的是签名路径中的一个稳健性问题:当节点把某个 Miniscript 当作可解析对象处理时,不应预先假定它语法正常、字段有序。26.2 改为在遇到结构不符合预期的情况时安全降级处理,避免推导出错误签名或触发异常。对日常使用的影响主要体现为:涉及 Taproot Miniscript 策略的钱包/PSBT 签名流程在面对非常规但合法的脚本树时更不易出错。
P2P 与网络变化
本组包含两个条目,其中 CJDNS 相关的修复可以直接在当前源码中定位到实现。
#29691:Luke Dashjr 的种子节点更新为 dashjr-list-of-p2p-nodes.us
DNS 种子(seed)是比特币网络引导新节点发现对等节点的基础设施。该 PR 将核心开发者 Luke Dashjr 运营的种子主机名切换到了新域名,属于对等节点发现层面的常规运维性更新。仓库中 contrib/seeds 目录维护的 nodes_main.txt、nodes_test.txt 等文件以及 makeseeds.py 脚本,正是与种子节点管理相关的配套资产,可对照阅读。
#30085:在 GetAddedNodeInfo() 中识别通过 addnode 添加的 CJDNS 节点
这是本次网络层最具代表性的 bug 修复。CJDNS 使用 fc00::/8 网段,其地址在底层会被解析为 IPv6 形式。此前 GetAddedNodeInfo() 对手动添加(addnode)节点做数值解析时未做网段归位,导致一个 CJDNS 地址即使已连接,也可能因为"按 IPv6 比对"而匹配不上。
当前源码中,连接管理器在枚举手动添加节点时调用了 MaybeFlipIPv6toCJDNS 进行归一化,见 src/net.cpp 第 3021 行:
CService service{MaybeFlipIPv6toCJDNS(LookupNumeric(addr.m_added_node, GetDefaultPort(addr.m_added_node)))};
而 MaybeFlipIPv6toCJDNS 的实现位于 src/netbase.cpp:仅当地址确为 IPv6 且前缀落入 CJDNS 网段、同时 NET_CJDNS 处于可达网络集合中时,才把网络类别翻转为 CJDNS:
CService MaybeFlipIPv6toCJDNS(const CService& service)
{
CService ret{service};
if (ret.IsIPv6() && ret.HasCJDNSPrefix() && g_reachable_nets.Contains(NET_CJDNS)) {
ret.m_net = NET_CJDNS;
}
return ret;
}
修复后,getaddednodeinfo 等 RPC(其核心调用点位于 src/rpc/net.cpp 第 540 行的 connman.GetAddedNodeInfo(...))就能如实反映"我手动 addnode 的那个 CJDNS 节点当前是否已连接、是入站还是出站"。运维上配合 CJDNS 相关配置使用,详见仓库文档 doc/cjdns.md——其中建议的配置项如 -cjdnsreachable 与 -onlynet=cjdns,以及形如:
# bitcoin.conf 示例
# 只有网络环境允许向 fc00::/8 发起连接时才开启
cjdnsreachable=1
若想验证该修复,可在启用 CJDNS 的节点上执行 bitcoin-cli addnode <fc00::/8 地址> add,再通过 getaddednodeinfo 观察该地址是否被识别为 CJDNS 且正确标记连接状态。
RPC 行为修正与健壮性
RPC 类变更最多,共 4 项,先总览:
| PR | 主题 | 影响面 |
|---|---|---|
| #29869 | setmocktime 强制最大值 |
回归测试可靠性 |
| #28554 | getnetworkhashps 非法参数报错 |
调用方错误提示 |
| #30094 | blockToJSON 中移动 UniValue |
区块序列化性能微优化 |
| #29870 | 重写 SighashFromStr 错误文案 |
签名哈希参数错误可读性 |
setmocktime 时间上限(#29869)
setmocktime 仅用于回归测试(regtest)。当前源码中该 RPC 的定义位于 src/rpc/node.cpp,几处关键逻辑与 26.2 的修复直接呼应:
- 非 regtest(
!Params().IsMockableChain())调用会直接抛出 "setmocktime is for regression testing (-regtest mode) only"; - 加
cs_main锁,避免在链校验进行中篡改时间——因为 mocktime 会牵连 mempool 基于时间的驱逐、IsCurrentForFeeEstimation()与IsInitialBlockDownload()等判断; - 新增取值区间校验:
Mocktime must be in the range [0, %s],上限取uint32_t的最大值4294967295。
第 2 点正是 #29869 的核心。代码注释写得很直白:区块时间戳本身是 uint32_t,把模拟时间拨到该范围之外,对任何共识相关内容都没有意义,还会在时间算术中引发整数溢出/截断。对做回归测试的开发者,这意味着:
# 合法:回到系统时间
bitcoin-cli -regtest setmocktime 0
# 合法:当前值必须落在 [0, 4294967295]
bitcoin-cli -regtest setmocktime 1700000000
# 非法:负数或超过 4294967295 会抛出 RPC_INVALID_PARAMETER
getnetworkhashps 非法参数报错(#28554)
getnetworkhashps 用于估算全网算力,其 RPC 定义位于 src/rpc/mining.cpp。参数语义如下:
nblocks(默认 120):基于最近多少个区块估算;传-1表示"自上次难度调整以来的区块";height(默认 -1):若传入某高度,则估算该区块被发现时刻的网络算力水平。
该 PR 之前,部分非法参数会被静默接受或以混乱方式处理;修复后参数统一经过 self.Arg<int>("nblocks") / self.Arg<int>("height") 的类型化解析,传入非数值内容(例如字符串)时会抛出明确的参数类型错误,而不是继续执行内部指针回退。底层估算函数按区块累积工作量差除以时间窗得出算力,且对 minTime == maxTime 的分母为零情况返回 0,见 src/rpc/mining.cpp。日常用法:
bitcoin-cli getnetworkhashps # 最近 120 个区块
bitcoin-cli getnetworkhashps 120 -1 # 等价于上一条
bitcoin-cli getnetworkhashps -1 # 自上次难度调整以来
SighashFromStr 错误文案重写(#29870)
签名哈希(sighash)类型字符串到枚举值的解析集中在 src/core_io.cpp 的 SighashFromStr。它维护一张合法取值映射表,26.2 之前非法输入的错误信息含混;#29870 后统一为:
'<你输入的值>' is not a valid sighash parameter.
合法取值包括:DEFAULT、ALL、ALL|ANYONECANPAY、NONE、NONE|ANYONECANPAY、SINGLE、SINGLE|ANYONECANPAY。该工具函数被 RPC 层复用,例如 src/rpc/util.cpp 第 363 行附近在解析签名哈希参数时即调用它。对于通过 API 脚本拼参数的用户,这条改动把"猜错误原因"变成了"直接看到无效值是什么"。
blockToJSON 的 UniValue 移动语义优化(#30094)
这是纯内部性能优化:在把区块转换为 JSON 对象时改用移动语义传递 UniValue,减少深拷贝。对普通用户无感知,但高频调用 getblock 的索引类或监控类服务会获得微小的内存与耗时改善。
构建系统修复
- #29747:修复 depends 体系中 mingw-w64 下 Qt 的
DEBUG=1交叉编译问题,利好 Windows 调试版本构建; - #29985:修复近期 glibc 环境下 32 位平台 Qt 的编译问题,保障 32 位目标的构建链不被新工具链破坏;
- #30151:miniupnpc 源码改从备选站点拉取,规避原站点可用性问题,提升 UPnP 依赖获取的稳定性;
- #30283:适配 miniupnpc 2.2.8,修复 UPnP 与该版本库的编译兼容性。
这四项都集中在 depends 目录的包描述文件(如 depends/packages)所描述的依赖构建链上。若你的工作涉及交叉编译 Qt 钱包或启用 UPnP 映射,升级到 26.2 即可直接受益。
其他工程与基础设施
- #29776:修复 ThreadSanitizer 下暴露的数据竞争问题 #29767,属于并发正确性加固;
- #29856:CI 将 s390x 架构的测试环境从旧镜像升级到
ubuntu:24.04,保障大端架构(s390x)持续获得回归覆盖; - #29764:文档建议 Debian/Ubuntu 下构建 Qt5 版本时先安装对应的
-dev开发包,降低新手构建失败率; - #30149:续期 Windows 代码签名证书,保证 Windows 版本安装包的签名链持续有效。
如何在当前仓库中核对上述修复
阅读者若想在当前开发树上复现各修复的落点,推荐按如下路径检索:
- RPC 方法表(各 RPC 的注册与参数)集中在 src/rpc/client.cpp,其中可同时看到
setmocktime(第 59 行)与getnetworkhashps(第 69-70 行)的命令行参数占位定义; - 签名哈希解析的核心实现见 src/core_io.cpp 与 src/core_io.h;
- 连接管理器中 addnode 枚举与连接状态映射见 src/net.cpp 的
GetAddedNodeInfo,其对外 RPC 消费点在 src/rpc/net.cpp; - 网络地址的 CJDNS 归位工具函数见 src/netbase.cpp,接口声明在 src/netbase.h;
- CJDNS 相关运行配置与运维指南参见 doc/cjdns.md。
小结
Bitcoin Core 26.2 作为一个维护版本,其价值集中在"让存量节点在既有 26.x 功能面上更可靠":setmocktime 的时间上限与 getnetworkhashps 的参数校验直接消除了两类 RPC 层潜在的错误输入隐患;addnode 名单的 CJDNS 识别修复让混合网络(IPv4/IPv6/onion/I2P/CJDNS)节点的手动连接管理状态变得准确;构建侧围绕 Qt 交叉编译与 miniupnpc 的四项修复则保证了 Windows、32 位平台与 UPnP 功能在 26.2 上的可构建、可运行。根据原始发布说明的 Credits 一节,本次发布汇集了 Ava Chow、fanquake、glozow、Luke Dashjr、MarcoFalke、jonatack 等十余位直接贡献者以及广大翻译志愿者的工作。
对运维者而言,若当前运行版本已接近 EOL,或恰好踩中上述 RPC 错误提示与 CJDNS addnode 状态显示问题,升级到 26.2 是一条低风险且收益明确的路径。
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 StartedRust0623
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