首页
/ Bitcoin Core 0.13.0 版本发布笔记:Compact Blocks、HD 钱包、SegWit 准备与 dbcache 扩容深度解读

Bitcoin Core 0.13.0 版本发布笔记:Compact Blocks、HD 钱包、SegWit 准备与 dbcache 扩容深度解读

2026-09-06 15:07:28作者:申梦珏Efrain

Bitcoin Core 0.13.0 是该项目历史上的一个里程碑版本:它引入了 BIP 152 Compact Blocks(紧凑区块)区块中继、BIP32 分层确定性(HD)钱包、Segregated Witness(分离见证)的 testnet 支持,以及基于“子付父”(CPFP)的矿机交易选择算法,同时把数据库缓存默认值从 100 MiB 提升到 300 MiB、移除了内部 CPU 挖矿器和 P2P alert 系统。读完本文,你将理解 0.13.0 每一项关键变更的动机、对应的命令行/RPC 参数用法,以及这些变更在当前代码库中的落地位置,便于你在维护节点、编写挖矿逻辑或排查版本升级问题时快速对照。

兼容性变化:不再支持 Windows XP

0.13.0 明确终止了对 Windows XP 的支持。原因有二:

  • 微软已于 2014 年 4 月 8 日终止对 XP 的安全更新,在该系统上运行钱包属于高风险行为;
  • 0.12.x 时代有用户报告 Bitcoin Core 在 XP 上随机崩溃,且原因不明,很可能与 Qt 等上游库停止在 XP 上做测试有关。

官方态度是:不主动阻止你在 XP 上安装或运行,但属于“自担风险”,且不再受理 XP 相关问题报告。从源码结构看,当前仓库的构建系统(CMakeLists.txtcmake/)已全面转向现代工具链(CMake + C++11 起、后续演进为 C++20),与当年 autotools 时代的 XP 支持早已不兼容,这一点可以作为版本演进的历史佐证。

数据库缓存内存扩容(dbcache 100 → 300 MiB)

变更内容

由于 UTXO 集持续增长,100 MiB 的默认数据库缓存性能已明显下降,0.13.0 将默认值改为 300 MiB。在低内存机器上可改回:

  • bitcoin.conf 中添加 dbcache=100
  • 或在 GUI 的 Options → Size of database cache 中修改。

官方特别提醒:数据库缓存的性能影响主要集中在节点初始同步和宕机后追赶区块两个阶段。

源码中的实现

当年由 PR #8273 完成(对应 changelog 中 396f9d6 "Bump -dbcache default to 300MiB")。在当前仓库中,相关逻辑演进到了 src/node/caches.cpp

  • src/node/caches.cpp 中的 GetDefaultDBCache()CalculateDbCacheBytes() 负责解析 -dbcache 参数并做上下限钳制(MIN_DBCACHE_BYTESMAX_DBCACHE_BYTES);
  • 当前版本已进一步智能化:在 64 位系统且检测到总内存 ≥ 4 GiB 时,默认缓存提升到 HIGH_DEFAULT_DBCACHE(1 GiB),这延续了 0.13.0 “按内存状况调整缓存”的治理思路;
  • 参数定义在 src/init.cpp-dbcache=<n>,单位为 MiB,并提示它与 mempool 共享未使用内存(见 -maxmempool);
  • 若设置过大会触发警告(见 src/node/caches.cppLogOversizedDbCache)。

另外 changelog 中 GUI 侧的 PR #8407(45eba4b "Add dbcache migration path")为已有用户提供了从 100 MiB 迁移到新默认值的平滑路径,避免升级后节点因缓存变化产生意外行为。

bitcoin-cli:-stdin 参数保护敏感信息

变更内容

bitcoin-cli 新增 -stdin 参数,从标准输入逐行读取额外参数直到 EOF/Ctrl-D:

$ src/bitcoin-cli -stdin walletpassphrase
mysecretcode
120
..... 按 Ctrl-D 结束输入
$

官方推荐使用此方式传递钱包密码等敏感信息,因为命令行参数通常可以被系统上任何用户通过进程表读取,而标准输入不会出现在进程列表中。

当前代码中的实现

该功能源自 PR #7550(8b958ab "Input-from-stdin mode for bitcoin-cli"),由 Wladimir J. van der Laan 实现。在当前仓库 src/bitcoin-cli.cpp 中可以看到完整的参数族:

  • -stdin:逐行读取额外 RPC 参数;
  • -stdinrpcpass:从标准输入读取一行作为 RPC 密码;
  • -stdinwalletpassphrase:从标准输入读取钱包密码,并与 -stdinrpcpass 组合时有明确的行消费顺序(密码行在前、钱包口令行在后)。

参数读取逻辑在 src/bitcoin-cli.cpp 附近实现。这套 stdin 参数族后来成为运维脚本(如 contrib/shell/git-utils.bash 风格的自动化)中传递凭据的标准做法。

构建与运行环境变化

C++11

代码库开始使用 C++11,构建要求 GCC ≥ 4.7 或 Clang ≥ 3.3。针对没有 C++11 运行库的目标做交叉编译时,官方给出的 configure 姿势是:

./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++

对应 changelog 中的 PR #7165(06162f1 "build: Enable C++11 in build, require C++11 compiler")及 #7302、#7322 等修复。从当前仓库的 cmake/CheckCXXFeatures.cmake 等构建脚本看,C++ 标准检测机制一脉相承,只是标准本身已随版本大幅前移。

Python 3 功能测试

运行 qa/rpc-tests(即今天 test/functional/ 目录下的功能测试)从本版本起要求 Python 3.4 或更高。changelog 中 #7814(77b637f "Switch to py3")与 #7751(84370d5 "test_framework: python3.4 authproxy compat")是核心提交。当前仓库的测试入口 test/functional/test_runner.py 等文件全部以 Python 3 编写,与这一决定一致。

Linux ARM 构建

应社区需求,0.13.0 开始在发布包中提供 Linux ARM 二进制(对应 PR #8188 9201ce8 "Add armhf/aarch64 gitian builds"):

  • bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz:面向 32 位 ARMv7-A;
  • bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz:面向 64 位 ARMv8-A。

官方强调 ARM 构建仍属实验性质,并给出架构兼容性判断示例:树莓派 2 Model B / 3 Model B(32 位执行态)可以运行 ARMv7-A 目标二进制;而树莓派 1 全系为 ARMv6,两个二进制都无法运行。另外 Android 不在此语境下的 ARM Linux,官方不保证可直接运行。

Compact Blocks(BIP 152)

协议机制

区块中继改用紧凑区块协议(PR #8068,TheBlueMatt 实现),核心思想是:发送方只发送区块头 + 少量预填交易 + 其余交易 ID 的短哈希,接收方用自己 mempool 里的交易“补齐”区块,只需向发送方 getblocktxn 请求缺失的那一小部分。

主要收益是降低中继时刻的带宽尖峰,很多情况下同时降低传播延迟。它在兼容节点之间自动启用,无需额外配置。

对挖矿策略的副作用(值得矿工注意)

文档特别指出一个非显而易见的后果:如果你的 mempool 与矿工的交易选择策略相似,区块补全速度会更快;反之,矿工放入了大量被你节点视为“不鼓励”的交易时,区块中继会变慢。整体上,包含大量网络内普遍不鼓励交易的区块可能在“stale 竞赛”中落败,因此矿工应让自己的节点参考主流中继策略

从当前源码结构看,这一机制依然健在:src/blockencodings.cppPartiallyDownloadedBlock::InitData 负责把 cmpctblock(区块头 + 短 ID + 预填交易)与本地 mempool 合并重建区块,src/bench/blockencodings.cpp 则提供了对应基准测试。协议版本方面,src/node/protocol_version.h 保留了版本阶梯:SENDHEADERS_VERSION = 70012FEEFILTER_VERSION = 70013SHORT_IDS_BLOCKS_VERSION = 70014(Compact Blocks)、WTXID_RELAY_VERSION = 70016 等,清晰记录了 P2P 协议各特性引入的版本号。

分层确定性密钥生成(HD 钱包,BIP 32)

这是 0.13.0 对钱包用户影响最深远的变更(PR #8035,jonasschnelli 实现):

  • 新钱包按 BIP32 生成 HD 密钥,密钥路径为 m/0'/0'/k';已有钱包保持传统随机密钥不变;
  • HD 钱包的备份任何时候都可以恢复出全部可能的私钥,包括备份时尚未生成的那些——这是传统钱包备份做不到的;
  • 重要警告:加密钱包会生成新的 HD seed,必须重新备份!
  • dumpwallet 产生的 dump 文件将包含确定性 seed,预期未来版本可直接导入 seed 恢复全部资金(0.13.0 时尚未实现);
  • 可用 -usehd=0 关闭新创建钱包的 HD 功能,但注意:该开关只对新钱包生效,一旦创建了 HD 钱包就无法再关闭
  • 本版本不区分内部(找零)地址与外部地址;
  • HD 钱包与 0.13 之前的版本不兼容,changelog 中 #8367(3b38a6a "Ensure <0.13 clients can't open HD wallets")专门保证了旧客户端打开 HD 钱包文件时不会静默丢数据。

相关 changelog 条目还包括:#8206 将 HD xpriv 加入 dumpwallet、#8323 在 validateaddress 中报告 hdmasterkeyid/hdkeypath 元数据、#8389(c3c82c4 "Create a new HD seed after encrypting the wallet")落实了“加密即换 seed”的行为、#8324 在 salvagewallet 时保留 HD seed、#8309 新增了 wallet-hd 功能测试。

Segregated Witness 的代码准备

0.13.0 完成了 BIP 141/143/144/145 描述的全部代码准备(changelog 中 #8149 d612837 "Testnet-only segregated witness"),但有两个关键限制:

  1. BIP 141 当时尚未指定主网激活参数,因此本版本不支持在主网上使用 segwit,仅 testnet 可用;
  2. 即使未来 BIP 141 在网络中激活,0.13.0 节点的行为仍与其他 pre-segwit 版本一致——无法在主网上发出激活信号、挖 segwit 块、完整验证/中继 segwit 块或在钱包中使用 segwit 交易。要使用主网 segwit 必须升级到实现激活参数的后续版本。

这条注意事项对 0.13.0 时代长期运行的节点运维者尤其重要:版本本身没有过期报错,功能上却停留在激活前状态。

挖矿交易选择:Child Pays For Parent(CPFP)

算法变更

挖矿的交易选择算法被替换为按“含未确认祖先交易的综合费率”(package feerate)选择(PR #7600 66db2d6,Suhas Daftuar)。含义是:一笔低费率交易,只要有一笔高费率交易花费了它的输出,整包的综合费率就可能达标而被选中——这就是 CPFP 机制,它让支付方可以“付费催促进祖交易”确认。

命令行参数变化

参数 0.13.0 状态 说明
-blockminsize 已移除 不再提供最小区块大小限制
-blockmaxsize 保留 限制生成区块的序列化字节数;为满足该约束需额外计算,仅指定它可能造成性能下降
-blockmaxweight 新增 按 BIP 141 的“区块权重”限制生成区块

官方建议矿工在命令行指定 -blockmaxweight 而不指定 -blockmaxsize,以获得最佳性能。主网上两者换算关系为:-blockmaxweight ≈ 4 × 期望的 -blockmaxsize(因为非见证数据按 4 倍权重计)。文档同时说明:本版本中 BIP 141 未在主网激活,两种度量的实际差异尚不体现,但在未来版本和 segwit 激活后将产生差别。

当前仓库中可对照 src/init.cpp-blockmaxweight 参数定义(Set maximum BIP141 block weight (default: %d))与 src/policy/policy.h 的默认值 DEFAULT_BLOCK_MAX_WEIGHT = MAX_BLOCK_WEIGHT(400 万),以及 src/node/mining_args.cpp 的读取逻辑。

重索引(Reindex)机制拆分

早期版本的重索引是“边读盘上区块文件边验证”,0.13.0 起两者被拆分:

  • 第一阶段:“Reindexing blocks on disk”——先让所有区块进入区块索引(GUI 中显示该提示);
  • 第二阶段:“Processing blocks on disk”——索引完整后再开始验证(较慢)。

拆分的原因,是让正常同步可用的某些优化(例如 Compact Blocks 相关的预取逻辑)在重索引期间同样可用。

新增命令行选项 -reindex-chainstate(PR #7917 239d419 "Optimize reindex" 的一部分):只重建链状态(UTXO 集)而不重建区块索引。适用场景是“盘上区块可信、但 chainstate 损坏”,也适合做基准测试。当前仓库 src/init.cpp 中该参数依然存在,只是帮助文本已更新(提示 prune 模式与其互斥等),说明设计沿用至今。

移除内部挖矿器

CPU 挖矿早已无效,本版本移除了内部挖矿器(PR #7507 11c7699 "Remove internal miner",Leviathn),测试框架改用更简单的实现。对外的直接后果:

  • 移除 RPC setgenerategetgenerate 与命令行选项 -gen-genproclimit
  • generate 调用保留,可在测试中继续出块(#7663 使其在非 regtest 也可工作);
  • 新增 generatetoaddress RPC(#7671 e2ebd25,achow101):向指定地址挖块,钱包禁用状态下也可用,这是后来功能测试框架(见 test/functional/ 中大量 generatetoaddress 用例)的标准出块手段。

当前仓库中 src/bitcoin-cli.cpp 仍保留 generatetoaddress 的本地 RPC 处理实现,印证其沿用至今。

bytespersigop 过滤的新实现

旧的 bytes-per-sigop 过滤逻辑有一个事故级 bug:它实际上破坏了裸多签交易的处理(本应由 permitbaremultisig 选项控制)。原因是共识协议出于向后兼容始终把这些旧式交易按 20 个 sigop 计数。如果简单地“精确计数”来修 bug,会重新引入一个历史漏洞。

新实现(PR #8364 3f65ba2,sipa)的思路是:不再拒绝这类交易,而是仅在费率计算时把它们视为“占满 20 sigop 的同等大小交易”(即视为更大的交易,从而拉低其费率竞争力)。changelog 中 #8362 86edc20 "Scale legacy sigop count in CreateNewBlock" 配合完成挖矿侧的同等处理。这个“把问题交易变大而不是拒绝它”的处理方式,是政策层设计的一个经典案例。

P2P 协议层变更

0.13.0 的 P2P 层是一次系统性更新,协议版本号提升到 70013

  1. feefilter 消息(BIP 133):收到对端的 feefilter 后,节点不再向对端发送费率低于过滤值交易的 inv(PR #7542 c946a15)。当前代码中消息名常量在 src/protocol.hFEEFILTER{"feefilter"}),版本常量 FEEFILTER_VERSION = 70013 保留在 src/node/protocol_version.h
  2. P2P alert 系统移除(PR #7692 29b2be6):alert 消息不再支持,网络公告职能移交其他渠道。
  3. 交易中继机制重设计(PR #7840 3b9a0bf、#8082 01d8359):旧机制对 1/4 交易即时中继、其余批处理发送,导致依赖链交易被乱序、系统性伤害中继质量。新机制始终批量发送 inv,并按依赖顺序排序,孤儿交易显著减少;为补偿取消即时中继,出站对端的批量发送频率翻倍。
  4. BIP35 mempool 命令:自 #7840 起也进入批处理;且当通过 -peerbloomfilters=0 禁用 NODE_BLOOM 时,不再处理非白名单对端的 mempool 请求(#8078)。
  5. 孤儿交易上限提高(PR #8179 94ab58b):内存中保留的孤儿交易上限从 5000 字节提到 99999 字节,并增加三种回收条件——被区块包含、与区块冲突、20 分钟超时。
  6. getaddr 限流(PR #7856):每条连接生命周期内至多响应一次 getaddr。
  7. 近期有效区块/交易提供者保护(PR #8084):最近向我们第一个提供有效新区块或交易的对端,其连接受保护、不会被主动断开(AttemptToEvictConnection 逻辑的一部分)。

RPC 层变更

新增 RPC

  • getmempoolentry / getmempoolancestors / getmempooldescendants:查询 mempool 单条目的详细统计,以及交易在 mempool 内的祖先/后代集合(PR #7292 7ce9ac5);
  • generatetoaddressimportprunedfundsremoveprunedfundssignmessagewithprivkey
  • Segwit 相关createwitnessaddressaddwitnessaddress

行为变化

  • gettxoutsetinfohash_serialized(UTXO 集哈希)发生变化:修复了 32 位/64 位平台在大于 4 GB 数据上哈希的分歧,且此前哈希数据漏掉了 txid(PR #7756、#7848)。如果你的工具依赖该哈希做链状态对比,跨版本比较会不一致;
  • RPC 全面支持 UTF-8(PR #7892 9c3d0fa):钱包标签等非 ASCII 字符此前在 JSON 处理中一直是损坏的,GUI 调试控制台同样受益;
  • 脚本反汇编更名OP_NOP2 显示为 OP_CHECKLOCKTIMEVERIFY(BIP 65)、OP_NOP3 显示为 OP_CHECKSEQUENCEVERIFY(BIP 112)。受影响输出:getrawtransaction(verbose)、decoderawtransactiondecodescript、REST /rest/tx//rest/block/(JSON)、bitcoin-tx -json
  • getrawmempool 输出的排序方式改变;
  • fundrawtransaction 新增选项:includeWatchingchangeAddresschangePositionfeeRate(费率单位 BTC/kB,#7967、#8153);
  • 移除 setgenerategetgenerate

ZMQ 变更:通知序列号

每条 ZMQ 通知现在携带一个递增序列号(PR #7762 a1eb344),位于多部分消息的最后一部分,因此向后兼容;每种消息类型有独立计数器。监听端可以据此检测通知丢失。仓库中 src/zmq/doc/zmq.md 可继续查阅当前实现细节,配套示例见 contrib/zmq/zmq_sub.py

0.13.0 变更日志要点(按主题节选)

以下为原始发布笔记 changelog 的完整分类(此处列出与行为直接相关的关键条目,完整列表见原文档):

RPC 与 API:#7550(stdin 输入模式)、#7726(importaddress 帮助文本)、#7774(getblock/getblockheader 增加 versionHex)、#7863(getblockchaininfobip9_softforks 改为对象)、#7518(fundrawtransaction 多选项)、#7756(UTXO 集游标并用于 gettxoutsetinfo)、#7292(ancestor/descendant 信息暴露到 RPC)、#7892(UTF-8)、#7957(sequence number 支持)等 30 余项。

区块与交易处理:#8273(dbcache 默认 300 MiB)、#8149(testnet-only segwit)、#7997(mapNextTx 换成更省的 setSpends)、#8020(非密码学哈希改用 SipHash-2-4)、#8364(高 sigop 交易“变大”而非拒绝)、#8381(witness v0 输出视为非标准)等。

P2P:#8068(Compact Blocks)、#7692(移除 alert)、#7542(feefilter)、#7840/#8082(inv/mempool 批处理与依赖排序)、#8084(近期提供者保护)、#8179(孤儿交易 99999 字节)、#8408(防 Compact Blocks 指纹/磁盘 DoS)、#8312(mempool 可篡改交易 DoS 修复)等 40 余项。

构建系统:#7165(强制 C++11)、#7911(leveldb 纳入构建系统)、#8188(armhf/aarch64 gitian 构建)、#8167(发布带调试符号的 tarball/zip)、#8210(Qt 升至 5.6.1)等。

GUI:#8073(密码对话框确认后清空输入)、#7707(废弃交易 UI 支持)、#8042(启动/校验期间禁止打开调试窗口)、#8407(dbcache 迁移路径)等 40 余项。

钱包:#8035(BIP32/HD 密钥生成核心实现)、#8389(加密后生成新 HD seed)、#8206(dumpwallet 含 HD xpriv)、#8367(阻止旧客户端打开 HD 钱包)、#7891(生成密钥总是要求 OS 随机源)、#7689(OpenSSL AES 换为 ctaes 实现)等。

挖矿:#7507(移除内部挖矿器)、#7671(generatetoaddress)、#7935(Versionbits GBT 支持)、#7600(含祖先费率交易选择)、#8489(segwit 激活前 GBT 使用 pre-BIP141 sigops)。

测试与 QA:#7814(测试框架切换 Python 3)、#8309(wallet-hd 功能测试)、#7849(varints 位图测试)、#8222(单元测试启用 mempool 一致性检查)等 80 余项。

对升级者的检查清单

综合本文,从 0.12.x 升级到 0.13.0 时应确认:

  1. Windows XP 用户:准备迁移到新系统,否则自担风险;
  2. 内存:确认机器能容纳 300 MiB 默认 dbcache,低内存机器在 bitcoin.conf 写回 dbcache=100
  3. 矿工:把 -blockmaxsize 迁移为 -blockmaxweight(主网按 4 倍换算),删除 -gen/-genproclimit/setgenerate 相关配置,改用 generatetoaddress
  4. 钱包用户:新建钱包即为 HD 钱包——理解“备份可恢复全部未来私钥”“加密后必须重新备份”“不能与旧版本混用”三点;
  5. 脚本与监控gettxoutsetinfo.hash_serialized 值变化、脚本反汇编中 OP_NOP2/3 命名变化、getrawmempool 排序变化,都需要同步修改下游解析逻辑;
  6. ZMQ 消费者:多部分消息末尾多了一个序列号字段,按设计向后兼容,但解析器应确认按“最后一部分”取值而非固定下标;
  7. 构建:确认编译器支持 C++11(GCC ≥ 4.7 / Clang ≥ 3.3),跑功能测试需 Python ≥ 3.4。

0.13.0 的发布笔记完整地保留在当前仓库的 doc/release-notes/release-notes-0.13.0.md 中,包含全部 200 余条 changelog 与完整贡献者名单;文中提到的实现细节均可在 src/blockencodings.cppsrc/node/protocol_version.hsrc/node/caches.cppsrc/bitcoin-cli.cppsrc/init.cpp 等文件中继续追踪验证。

登录后查看全文
热门项目推荐
相关项目推荐