首页
/ Bitcoin Core 0.20.1 发布说明详解:Discouragement 节点机制、PSBT 双 utxo 兼容与 walletnotify 修复

Bitcoin Core 0.20.1 发布说明详解:Discouragement 节点机制、PSBT 双 utxo 兼容与 walletnotify 修复

2026-09-06 16:32:27作者:傅爽业Veleda

Bitcoin Core 0.20.1 是一次以缺陷修复与网络行为调整为核心的小版本发布。本篇基于仓库中收录的 0.20.1 发布说明 展开,完整覆盖升级步骤、兼容性边界与源码 tarball 构建已知问题,并深入剖析本版本三项标志性改动:将"自动封禁"替换为"discouragement(降级/劝退)"机制、恢复因新块冲突被移出内存池的交易的 -walletnotify 通知,以及 PSBT 对 segwit 输入同时携带 non_witness_utxowitness_utxo 的兼容性修复。读完本文,你可以安全地规划从旧版本到 0.20.1 的升级路径,理解日志中 "discouraged" 与 "banned" 的区别,并在自己的节点、矿机(GBT)与离线签名软件中正确使用相关 RPC 与 PSBT 字段。

一、如何升级到 0.20.1

发布说明给出了标准的升级流程,适用于三个主要平台:

  1. 先完全停止正在运行的旧版本节点,并等待其彻底退出(某些情况下需要几分钟,例如仍在落盘数据或关闭数据库);
  2. Windows 用户直接运行安装程序;macOS 用户覆盖 /Applications/Bitcoin-Qt;Linux 用户覆盖 bitcoind / bitcoin-qt 二进制。

升级路径上有两条重要说明:

  • 可以直接从已达到 EOL(停止支持)的更老版本升级,但如果数据目录需要迁移(例如数据库格式迁移),启动阶段可能明显变慢;
  • 旧格式的钱包文件仍然受支持,钱包数据不需要随节点升级而强制转换。

二、兼容性说明

Bitcoin Core 官方支持并做了充分测试的平台为:

  • 使用 Linux 内核的系统;
  • macOS 10.12 及以上;
  • Windows 7 及更新的版本。

其他类 Unix 系统通常也能运行,但测试频率较低,官方不建议在不受支持的平台上部署。0.20.0 起有两个明确的兼容性边界:

  • macOS 10.12 以下版本不再受支持(自 0.20.0 开始);
  • 激活 macOS "深色模式"(dark mode)时,Bitcoin Core 的界面外观暂不会随之改变。

三、已知问题:源码 tarball 构建回归

0.20.1 为了"让源码发布包更完整"而修改了生成 tarball 的流程,但引入了两个构建层面的回归。如果你是从官方下载的源码压缩包(而非 git clone)构建,必须注意:

  • 生成好的 configure 脚本缺失:需要自行安装 autotools(autoconfautomake 等),先运行 ./autogen.sh 生成 configure,再执行 ./configure——这与从 git 检出源码后的行为一致;
  • 不要直接运行裸 make:应当改用 BITCOIN_GENBUILD_NO_GIT=1 make,以避免构建系统在无 git 元数据的打包环境中出错。

对于通过安装器、macOS 磁盘映像或 Linux 包安装的用户,这两个回归不影响使用,只影响编译型用户。

四、P2P 行为变化:从"自动封禁"到"Discouragement(降级处理)"

这是 0.20.1 最重要的行为变化。此前,对发送无效块等恶意数据的对等节点(peer),日志和实现中都称其为 "misbehaving",且会触发自动封禁;从 0.20.1 起,这些节点被统一改称为 discouraged nodes(被降级的节点),因为它们的实际待遇从来(也依然不是)严格意义上的封禁:

  • 来自这些地址的入站连接仍然被允许
  • 但它们会成为优先被驱逐(eviction)的对象

对应实现为 #19219(sipa),它用"劝退过滤器"替换了原先的自动封禁逻辑。从当前仓库的源码结构看,这一机制的脉络仍然延续:PeerManagerImpl::Misbehaving() 在检测到违规(如无效的 compact block、mutated block、超大的 bloom filter 等)时记录日志并触发降级处理,见 src/net_processing.cpp,其中的惩罚判定还会经由 MaybePunishNodeForBlock 按块验证结果分级(例如 BLOCK_MUTATEDBLOCK_INVALID_HEADER 会直接降级对等节点,见 src/net_processing.cpp)。封禁状态的存储与列表则由 src/banman.cpp 负责,listbanned / setban RPC 的实现位于 src/rpc/net.cpp

0.20.1 对 discouraged 地址的处理还有四条具体规则,运维人员必须知晓:

行为 说明
超时机制 地址被降级不会在 24 小时(或 -bantime 设置的时间)后自动超时。降级状态何时失效取决于其他对等节点的流量,时间不确定
持久化 降级状态不会在节点重启后保留,重启即清除
可查询性 没有列出被降级地址的方法:listbanned RPC 不返回它们;同时该 RPC 也不再报告 ban_reason 字段,因为 "manually added" 成为唯一剩余选项
手动移除 setban remove 无法移除降级状态。确实需要清除时,只能通过停止并重启节点来移除全部降级记录

这四条规则意味着:如果你发现某个对等节点被持续降级且无法通过 RPC 解除,重启节点就是文档给出的唯一官方手段。

五、-walletnotify 恢复:与新区块冲突而被移出内存池的交易

0.20.1 修复了一个自 v0.19 起存在的回归(上游 issue #18325):当钱包交易因为与新区块冲突而内存池中移除时,现在会重新触发 -walletnotify 外部通知。在 v0.19 之前这类通知是正常发送的,v0.19 起被破坏,本版本通过 #18982(ryanofsky,最小修复)恢复了该行为。

这对依赖外部脚本监听钱包事件(如自动记账、支付网关)的部署很关键:以前这类"被区块挤出"的事务可能被静默忽略。从当前仓库源码结构看,这条处理链落在钱包的 transactionRemovedFromMempool 回调中:当移除原因为 MemPoolRemovalReason::CONFLICT 时,代码会显式"为这些交易触发外部 -walletnotify 通知",并解释了为何先将状态置为 UNCONFIRMED 而非 CONFLICTED(兼容性与历史同步实现的原因),见 src/wallet/wallet.cpp。通知命令本身来自启动参数解析,见 src/wallet/wallet.cpp

六、PSBT 变化:segwit 输入同时携带 non_witness_utxowitness_utxo

部分钱包软件开始要求对 segwit 输入提供完整的前序交易,而此前 Bitcoin Core 的 PSBT(Partially Signed Bitcoin Transaction,部分签名交易)只携带 witness_utxo。0.20.1 起(#19215,achow101):

  • PSBT 中 segwit 输入将同时包含 non_witness_utxowitness_utxo,以满足需要完整前序交易的软件;
  • 保留 witness_utxo 是为了兼容那些依赖"该字段存在与否"来判断输入是否为 segwit 的既有软件。

从当前仓库的 PSBT 实现可以看到这一设计的后续演进:解析时会校验 non_witness_utxo 的哈希与 prevout 一致(见 src/psbt.cppsrc/psbt.cpp),Finalize 阶段还有"能否丢弃 non_witness_utxo"的判定逻辑——仅当没有非 segwit 输入、不存在 segwit v0 输入且 sighash 类型不含 SIGHASH_ANYONECANPAY 时才允许丢弃(见 src/psbt.cpp)。理解这一点有助于排查跨软件互操作时 PSBT 字段"冗余"的问题。配套修复还包括 decodepsbt 中对输入值求和只按 UTXO 计一次的重复修复(#19517、#19524)。

七、挖矿 GBT 修复:rules 键恢复 !segwitcsv

本版本的 Mining 类修复只有 1 条但非常实用:#19019(luke-jr)恢复了 getblocktemplate 返回中 rules 键里的 !segwitcsv 标记,供矿机/矿池声明其支持的规则集。从当前仓库的 GBT 实现结构看,rules 参数约定与默认规则集的处理仍集中在 src/rpc/mining.cpp(例如 getblocktemplate 要求 {"rules": ["segwit"]}!segwit 规则在 src/rpc/mining.cpp 处被加入),升级前使用旧版客户端的矿池应当验证 0.20.1 的 getblocktemplate 输出与模板解析逻辑一致。

八、0.20.1 完整变更日志

以下为发布说明收录的完整 change log,按模块分类,便于按主题检索:

模块 PR 内容 作者
Mining #19019 Fix GBT: Restore "!segwit" and "csv" to "rules" key luke-jr
P2P 协议与网络 #19219 Replace automatic bans with discouragement filter sipa
钱包 #19300 Handle concurrent wallet loading promag
钱包 #18982 Minimal fix to restore conflicted transaction notifications ryanofsky
RPC 与其他 API #19524 Increment input value sum only once per UTXO in decodepsbt fanquake
RPC 与其他 API #19517 psbt: Increment input value sum only once per UTXO in decodepsbt achow101
RPC 与其他 API #19215 psbt: Include and allow both non_witness_utxo and witness_utxo for segwit inputs achow101
GUI #19097 Add missing QPainterPath include achow101
GUI #19059 update Qt base translations for macOS release fanquake
构建系统 #19152 improve build OS configure output skmcontrib
构建系统 #19536 qt, build: Fix QFileDialog for static builds hebasto
测试与 QA #19444 Remove cached directories and associated script blocks from appveyor config sipsorcery
测试与 QA #18640 appveyor: Remove clcache MarcoFalke
其他 #19194 util: Don't reference errno when pthread fails miztake
其他 #18700 Fix locking on WSL using flock instead of fcntl meshcollider

其中与日常运维直接相关的值得单独点出:

  • #18700(WSL 锁修复):在 Windows Subsystem for Linux 下改用 flock 代替 fcntl 做文件锁,修复了 WSL 环境中的锁问题——如果你在 WSL 里跑 bitcoind,这是升级的核心理由之一;
  • #19300(并发钱包加载):改进了多钱包并发加载的处理,对运行多钱包的节点是稳定性改进;
  • #19097 / #19059(GUI):补齐 macOS 构建所需的 QPainterPath 头文件包含,并更新 Qt 基础翻译。

九、版本定位与文档脉络

0.20.1 属于 0.20.x 维护系列中的 bugfix 小版本,不含共识规则或协议版本变化,升级风险主要集中在 P2P 降级语义的运维认知调整上。本仓库 doc/release-notes/ 目录下按时间线收录了从 0.3.x 一直到 31.x 的完整发布说明,例如前一个版本 release-notes-0.20.0.md 与后续 release-notes-0.21.0.md,可对照阅读理解 0.20.1 在整个版本演进中的位置。发布说明中引用的上游 issue/PR 编号(如 #18325、#19219)可直接用于检索对应社区的讨论与实现细节。

升级决策建议

  • 运行 WSL 节点、依赖 -walletnotify 事件流的部署、以及通过 GBT 对接矿机的节点,应优先升级到 0.20.1 获取对应修复;
  • 若依赖 PSBT 与第三方钱包/冷签软件互操作,升级后请重新校验双方对 non_witness_utxo / witness_utxo 字段的读写行为;
  • 从 tarball 源码编译的用户,务必按上文"已知问题"一节执行 ./autogen.shBITCOIN_GENBUILD_NO_GIT=1 make
  • 升级后如有节点被持续降级而无法通过 RPC 解除,重启节点即可清除全部降级状态,这是文档给出的唯一手段。
登录后查看全文
热门项目推荐
相关项目推荐