Bitcoin Core 0.20.0 发布说明详解:BIP61 移除、UTXO 快照与 asmap 等关键变更
Bitcoin Core 0.20.0 是 2019 年发布的稳定版本,其发布说明(doc/release-notes/release-notes-0.20.0.md)记录了一批对节点运营者、钱包开发者和构建者都有实际影响的变更:彻底移除 BIP61 reject 消息、引入 dumptxoutset UTXO 快照导出、新增 rpcwhitelist RPC 权限白名单与实验性的 -asmap ASN 分桶选项、钱包默认改用 bech32 地址,以及构建系统告别 OpenSSL 等。本文以该发布说明为主线逐项展开,并结合当前仓库源码标注这些特性在代码中的落点与验证方式,帮助读者既了解 0.20.0 的历史变更全貌,又掌握在当前代码树中定位对应实现与测试的方法。
升级方式与兼容性
如何升级到 0.20.0
发布说明给出的升级步骤非常直接:
- 若正在运行旧版本,先将其关闭,并等待它完全退出(某些情况下可能需要几分钟,因为涉及数据库与网络套接字的收尾);
- Windows 上运行安装程序;macOS 上替换
/Applications/Bitcoin-Qt;Linux 上覆盖bitcoind/bitcoin-qt可执行文件; - 从已到达生命周期终点(EOL)的旧版本直接升级是可行的,但如果数据目录需要迁移,可能需要额外时间;旧版本格式的数据钱包一般仍可被新版加载。
操作系统支持矩阵
0.20.0 对平台支持的边界做了明确收缩与声明:
- 受支持平台:Linux 内核系统、macOS 10.12 及以上、Windows 7 及以上,这些平台经过广泛测试;
- macOS 10.12 成为最低要求:从 0.20.0 起,更早的 macOS 不再受支持。源码层面可以佐证这一点:变更日志中的 PR #17550(Set minimum supported macOS to 10.12)与 PR #18364(移除针对 macOS < 10.12 的
getentropy()回退实现)都落在平台支持类别中; - 暗色模式:该版本在 macOS 开启 Dark Mode 时不会改变界面外观,属于已知限制;
- 其他类 Unix 系统通常可以运行,但测试频率较低,官方不建议在不受支持的系统上部署。
已知问题:源码压缩包(tarball)的构建回归
0.20.0 为让源码发布包更完整而改变了 tarball 生成流程,但带来了两个已知回归,构建用户需要特别注意:
- 缺少
configure脚本:发布包中没有预生成的configure,需要先安装 autotools 并运行./autogen.sh,才能执行./configure——这与直接从 git 检出的行为一致; - 需要指定环境变量构建:不能直接
make,应运行:
BITCOIN_GENBUILD_NO_GIT=1 make
对应的底层变更是 PR #18331(Use git archive as source tarball):源码压缩包不再包含任何 autotools 产物,因此构建者本机必须安装 autotools 及其他必需依赖。
P2P 与网络层:BIP61 reject 消息的彻底移除
这是 0.20.0 中最具代表性的协议层变更。-enablebip61 命令行选项(用于开启 BIP61 建议的 reject 网络消息)被完全删除(PR #17004)。该功能自 0.18.0 起已默认关闭,本次是移除最后的开关。
移除的核心理由在发布说明中写得很清楚:网络上的节点(包括它们发送的 reject 消息本身)通常不可信,因此 reject 消息只应在连接可信节点的场景下使用。在当前的仓库源码中,搜索 enablebip61 已无任何结果,印证该选项在当前代码树中已彻底不存在。
移除后的替代方案
发布说明针对原先依赖 BIP61 的几类使用场景,给出了明确的替代路径:
调试 P2P 协议实现:改用近期版本 Bitcoin Core 的日志输出。Bitcoin Core 将调试消息(-debug=<category>)输出到控制台流(-printtoconsole)或调试日志文件(-debuglogfile=<debug.log>)。
校验区块有效性:使用专用 RPC:
submitblock:提交区块并触发本地校验;getblocktemplate且'mode'设为'proposal':用于校验可能带有无效 POW 的区块。
校验交易有效性:
sendrawtransaction:广播并观察接受结果;testmempoolaccept:仅做内存池接受性测试而不广播。
钱包侧的语义修正:
- 钱包不应因为“没有收到 reject 消息”就认为交易已传播到全网,而应监听其他节点对该交易的广播(announce);
- 钱包也不应以“没有 reject”推断手续费足够。正确做法是使用费率估算(fee estimation)设置手续费,并在交易超时未确认时用 replace-by-fee(RBF)提高手续费。
附带影响:RPC 与日志中的 reject code
BIP61 支持移除还带来两个次级变化:
testmempoolaccept与sendrawtransaction在交易未被内存池接受时,不再返回 P2P reject 数字错误码,但仍返回文字形式的拒绝原因(verbal reject reason);- 日志中此前在交易被内存池拒绝时报告 reject code 的信息,现在只报告拒绝原因,不再报告 code。
从源码结构看,与这一改动相关的清理包括变更日志中的 “#17004 Remove REJECT code from CValidationState”(从验证状态机中移除 REJECT 码)以及 “#17399 Templatize ValidationState instead of subclassing”。
新增 RPC:dumptxoutset 与 generatetodescriptor
0.20.0 引入两个新 RPC,分别服务于全节点运维与回归测试两大场景。
dumptxoutset:UTXO 集合快照导出
dumptxoutset 将当前 UTXO 集合序列化为快照文件输出。发布说明指出配套脚本位于 contrib/devtools 目录(用于在指定区块高度生成快照)。在当前仓库中,该功能已经演进为一条完整的 UTXO 快照工具链:
- RPC 实现位于 src/rpc/blockchain.cpp 中的
dumptxoutset()方法,帮助文本给出了典型用法,例如-rpcclienttimeout=0 dumptxoutset utxo.dat latest,并支持rollback=<height>参数回滚快照;实现中还包含修剪(prune)保护逻辑,在导出期间注册高度上的修剪锁,防止快照过程中数据被修剪掉; - 快照转 SQL 的辅助脚本现位于 contrib/utxo-tools/utxo_to_sqlite.py;
- 功能测试包括 test/functional/rpc_dumptxoutset.py 与 test/functional/tool_bitcoin_chainstate.py;
- 该快照机制是后来 assumeutxo 功能的基础,相关设计可进一步参阅 doc/assumeutxo.md。
generatetodescriptor:regtest 定向挖矿
generatetodescriptor(PR #16943)允许 regtest 模式的测试者生成挖出任意输出脚本描述符的区块,例如把区块奖励支付给指定的 P2WPKH 描述符地址,简化了测试中对特定类型 UTXO 的构造。其功能测试可在测试目录中按 RPC 名称检索到(变更日志类别 “Tests and QA” 中列有 “#16943 Add generatetodescriptor RPC”)。
RPC 更新与描述符能力增强
sortedmulti 描述符
接受描述符的 RPC 从 0.20.0 起支持新的 sortedmulti(...) 描述符类型(PR #17056):它支持多签脚本,且在最终脚本中将公钥按字典序排序,使多方各自提供的公钥顺序不同也能得到同一脚本,是多方协作生成同一多签地址的关键能力。
当前仓库中,sortedmulti(含 P2TR 环境下的变体 sortedmulti_a)的解析与执行实现集中在 src/script/descriptor.cpp:解析入口通过 Func("sortedmulti", expr) 识别语法,MultisigDescriptor 以 sorted 标志区分普通 multi 与排序版本,并限制 multi/sortedmulti 只能出现在顶层、sh() 或 wsh() 中。相关单元测试位于 src/test/descriptor_tests.cpp。
PSBT 相关 RPC 的默认行为变化
walletprocesspsbt与walletcreatefundedpsbt现在默认在公钥附带 BIP32 派生路径(在已知派生信息时),可用bip32derivs参数设为false关闭(PR #17264)。这让外部签名工具(硬件钱包、HWI 等)能直接从 PSBT 中读取派生路径来匹配密钥;bumpfee对禁用私钥(watch-only/外部签名)钱包使用时,会返回 PSBT 而非直接签名交易(PR #16373),与 GUI 侧剪贴板行为呼应(见下文 GUI 章节);bumpfee的参数totalFee曾在 0.19 被弃用,本版本正式移除(PR #18312)。
其他 RPC 变更
getpeerinfo新增mapped_as字段,显示用于多样化对等点选择的映射自治系统号,对应下文-asmap选项(PR #16702)。当前仓库中该字段贯穿多个文件:RPC 输出在 src/rpc/net.cpp,网络核心在 src/net.cpp、src/netgroup.cpp 与 src/addrman.cpp,CLI 展示在 src/bitcoin-cli.cpp,GUI 展示在 src/qt/rpcconsole.cpp;createmultisig与addmultisigaddress现在会返回新创建地址的输出脚本描述符(PR #18032),便于以描述符形式继续管理多签地址;verifychain的默认参数改为静态值,不再受命令行选项或配置文件(-checklevel、-checkblocks)影响,需要非默认行为时可显式传参(PR #18541);getblockchaininfo的verificationprogress字段不再报告大于 1 的值,修复了偶尔“验证进度超过 100%”的问题(PR #17328)。
新配置参数:rpcwhitelist 与 asmap
rpcwhitelist / rpcwhitelistdefault:按用户划分 RPC 权限
新增的 rpcwhitelist 与 rpcwhitelistdefault 配置参数允许为特定 RPC 用户授予仅能调用部分 RPC 的权限(PR #12763,基于更早的 #12248)。
当前仓库中,这两个参数的定义位于 src/init.cpp,帮助文本说明了语义:
-rpcwhitelist=<whitelist>:格式为<USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>,为某个用户设置 RPC 调用白名单;同一用户设置多个白名单时,取交集;-rpcwhitelistdefault:控制默认行为。除显式设为 0 外,只要设置了任意-rpcwhitelist,RPC 服务器就视所有用户都受“未显式指定即为空白名单”的约束;若设为 1 且未设置任何-rpcwhitelist,则所有用户的白名单默认为空。
白名单的实际执行发生在 HTTP RPC 层:src/httprpc.cpp 在启动时读取 -rpcwhitelistdefault 与全部 -rpcwhitelist 条目并建立用户名到白名单的映射,供请求分发时做权限过滤。对应的功能测试为 rpc_whitelist 测试(变更日志中列有 “#17806 Change filemode of rpc_whitelist.py”)。
-asmap:基于 ASN 的连接多样化(实验性)
新增 -asmap 配置选项:通过把 IP 地址映射到自治系统号(ASN)并限制连往单个 ASN 的连接数,来多样化节点的网络连接。发布说明明确指出这是实验性选项,未来版本可能移除或发生破坏性变更,因此默认仍沿用传统的 /16 前缀 IP 映射。
实现脉络(见变更日志 P2P 类别):
- PR #16702 将 asmap 引入 addrman 的 IP 分桶(#15437 之外的核心 PR,即 “Supply and use asmap to improve IP bucketing in addrman”);
- PR #17812 补充了配置、网络层细化与功能测试;
- PR #18023 修复若干 asmap 相关问题。
从源码结构看,asmap 加载与分桶逻辑落在 src/addrman.cpp、src/netgroup.cpp 一带,与 getpeerinfo 的 mapped_as 字段(见上文 RPC 章节)共同构成该特性。
配置项更新、移除与行为变化
更新设置
- 启动配置写入调试日志:所有在 Bitcoin Core 启动时配置的自定义设置现在都会写入
debug.log,便于排障(PR #16115,变更日志 Miscellaneous 类别 “On bitcoind startup, write config args to debug.log”); - bootstrap.dat 不再默认导入:启动时通过
bootstrap.dat导入区块的行为被移除,现在必须用-loadblock=<file>显式指定文件(PR #17044)。当前仓库中loadblock的处理逻辑分布在 src/init.cpp、src/validation.cpp 与 src/node/blockstorage.cpp; -debug=db更名为-debug=walletdb:为了与coindb区分,钱包数据库日志类别改名,-debug=db被弃用并在下一个大版本移除(PR #17410);-walletnotify支持%w替换:参数中的%w会被替换为触发通知的钱包名称(Windows 平台不支持,PR #13339)。
移除设置
-whitelistforcerelay 被移除(PR #17985):调查发现该参数自 0.13 起就已失效,实际上近四年都未被真正支持,移除属于清理。
测试与配置注意事项
- 在 testnet/regtest 网络下,配置文件中未限定网络的
walletdir=path现在是错误,必须写成chain.walletdir=path或放入对应的[chain]段(PR #17447,“Make -walletdir network only”); -fallbackfee默认值统一为 0:此前主链默认 0(禁用)、测试链默认 0.0002,现在全链统一为 0。testnet/regtest 用户若希望维持旧行为,需要在配置中显式添加fallbackfee=0.0002(PR #16524);- 带网络前缀的命令行选项变为错误:形如
-main.port=8333、-test.server=1这类带主网/测试网/回归网前缀的选项,此前被允许但静默忽略,现在启动时直接报 “Invalid parameter” 错误(PR #17482)。
构建系统:移除 OpenSSL、BIP70 与 glibc 2.17
- OpenSSL 被移除(PR #17265):Bitcoin Core 不再依赖 OpenSSL,密码学实现完全由内置组件承担。这一变更还带动了一批清理,如 “#17151 Remove OpenSSL PRNG seeding (Windows, Qt only)”、MSVC 构建说明中移除 Qt OpenSSL 链接等;
- BIP70 支持完全移除:
--enable-bip70选项虽保留,但在 configure 阶段会直接报错(PR #17165); - 发布二进制要求 glibc 2.17+:以保持与 RHEL 7、CentOS 7、Debian 8、Ubuntu 14.04 LTS 的兼容(PR #17538);
- 源码压缩包不含 autotools 产物:如前文“已知问题”所述,需先
./autogen.sh(PR #18331); - Android NDK 构建支持(PR #16110):为基于 Android 原生开发工具链的构建提供了支持,后续 PR #17365 更新了 README 中可工作的 Android 目标与 API 级别说明。
构建与 CI 侧的其他值得注意的变更包括:S390X 与 POWER 目标支持(PR #17678)、--enable-determinism configure 选项(PR #18135)、cov_fuzz 目标(PR #18107)、leveldb 更新到 1.22+(PR #17398)、libevent 提升到 2.1.11(PR #17008)。当前仓库中构建系统已转向 CMake(参见根目录 CMakeLists.txt 与 cmake/ 目录),0.20.0 时代的 autotools 细节仅作为历史背景参考。
GUI 变更
- macOS 移除“登录时启动”选项(PR #17567);
- Peers 窗口新增 “Mapped AS” 字段:显示对等点对应的映射 ASN,与
-asmap功能联动(PR #18402); - 修复 0.18 遗留的多钱包 + Coin Control 冲突:0.18 发布说明中报告的“同时使用多个钱包与 GUI coin control 时出错”的问题在本版本修复(PR #18894);
- watch-only 钱包的 PSBT 剪贴板工作流(PR #16944、#17492):对于 watch-only 钱包,在 Send 界面创建新交易或在 Transactions 界面对现有交易做提额(bump fee)时,会自动把部分签名交易(PSBT)复制到系统剪贴板,可直接粘贴到外部签名程序(如硬件钱包交互工具)完成签名。在 GUI 支持 PSBT 的最终签名与广播之前,可先用调试控制台的
finalizepsbt与sendrawtransactionRPC 完成收尾。这条链路与上文bumpfee在禁用私钥钱包时返回 PSBT 的行为、以及 PSBT RPC 默认附带 BIP32 派生路径的改动共同构成 0.20.0 的“离线签名”能力拼图。
钱包行为变化
- 默认地址类型改为 bech32:通过 RPC 创建地址时默认使用 bech32 地址,找零输出默认使用原生 segwit(PR #16884)。这直接降低了后续交易的手续费,也推动了大量 RPC 示例文档同步改为 bech32(变更日志 Documentation 类别多条);
- 输出可信度(output trust)计算修复:
IsTrusted现在递归扫描父交易,影响确认/未确认余额状态与选币(PR #16766); - 钱包交易 RPC 暴露所在区块高度:
gettransaction、listtransactions、listsinceblock的响应新增交易所在区块的高度(如存在,PR #17437); getaddressinfo字段弃用:label字段被弃用(本版本可用-deprecatedrpc=label恢复旧行为);labels字段从 JSON 对象数组改为标签名 JSON 数组(可用-deprecatedrpc=labelspurpose恢复旧行为)。兼容性参数预计在 0.21 移除(PR #17585、#17578)。
工具与命令行层面
bitcoin-cli -getinfo字段调整:新增headers字段(最佳头链上已下载的区块头数量,与blocks并列)与verificationprogress字段(估计本地节点已同步的链比例);同时移除了protocolversion、walletversion、keypoololdest字段(PR #17302、#17650);-stdinwalletpassphrase新参数:调用walletpassphrase与walletpassphrasechange时可从标准输入读取钱包密码且不回显,降低屏幕窥视风险;既有的-stdinrpcpass也同步更新为不回显密码(PR #13716)。
变更日志速览(按类别)
0.20.0 的完整变更日志覆盖了 300 余个 PR,按类别归纳如下(完整列表见原文档 doc/release-notes/release-notes-0.20.0.md):
| 类别 | 代表性变更 |
|---|---|
| Mining | #18742 修复 validationinterface 中的 stack-use-after-return |
| 区块与交易处理 | #16902 OP_IF/NOTIF/ELSE/ENDIF 的 O(1) 实现;#16974 无效时沿 pindexBestHeader 回退到 ChainActive().Tip();#18500 更新 assumed valid hash |
| P2P 与网络 | #15437 移除 BIP61 reject 消息;#16702 asmap 改进 addrman IP 分桶;#17951 用近期区块交易的 rolling bloom filter 做 AlreadyHave() 判断;#17754 禁止解析含嵌入式 NUL 的字符串并加测试 |
| 钱包 | #16884 默认地址类型改为 bech32;#17261 将 ScriptPubKeyMan 变为真正的接口并支持多实例;#16766 IsTrusted 递归扫描父交易 |
| RPC 与其他 API | #12763 RPC 白名单;#16899 dumptxoutset;#18346 为所有 RPC 调用声明 RPCResult 并在编译期强制检查 |
| GUI | #18894 多钱包 + 手动 coin control 修复;#18402 Peers 窗口显示 mapped AS |
| 构建系统 | #17265 移除 OpenSSL;#17538 发布二进制 glibc 最低 2.17;#17678 S390X/POWER 支持;#18331 git archive 作为源码包 |
| 平台支持 | #16110 Android NDK;#17550 macOS 最低 10.12;#17916 Windows 启用堆损坏即终止 |
| 测试与 QA | 大量 fuzzing harness 增加(#17009 系列)、ASan stack-use-after-return 检查、s390x 大端平台 CI(#17591)、非标准交易系列单测/功能测试 |
| 杂项 | #16115 启动时把配置写入 debug.log;#15600 lockedpool 尽量用 madvise 避免敏感数据进 core dump |
小结与适用前提
0.20.0 的发布说明是一份典型的“面向运维与开发的变更契约”:BIP61 移除改变了 P2P 调试与钱包确认判定的语义,rpcwhitelist 与 asmap 分别扩展了 RPC 权限管理与网络拓扑控制能力,dumptxoutset 为 UTXO 快照生态奠基,bech32 默认化则统一了钱包地址策略。阅读此类发布说明时的适用前提:其中的默认值(如 -fallbackfee=0)与弃用时间表(如 -debug=db、-deprecatedrpc=label)均以 0.20.0 为基准,后续版本(当前仓库已演进至 30+ 版本)可能再次调整;验证具体行为时,优先以当前仓库的源码与功能测试(src/、test/functional/)为准,而非仅依赖历史发布说明。
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