恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Bitcoin Core 29.3 维护版详解:P2P 惩罚策略调整、sighash 中间态缓存与钱包迁移修复全解析
首页
资讯中心
/
Bitcoin Core 29.3 维护版详解:P2P 惩罚策略调整、sighash 中间态缓存与钱包迁移修复全解析
Bitcoin Core 29.3 维护版详解:P2P 惩罚策略调整、sighash 中间态缓存与钱包迁移修复全解析
发布时间:2026/9/7 19:10:12
Bitcoin Core 29.3 维护版详解P2P 惩罚策略调整、sighash 中间态缓存与钱包迁移修复全解析【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoinBitcoin Core 29.3 是 29.x 系列的一个维护版本聚焦于各类 bug 修复与性能改进并同步更新了多语言翻译。本文以官方发布说明为骨架结合本仓库Bitcoin Core integration/staging tree源码逐一拆解本版 Notable Changes 中的每一项改动——包括「不再因共识无效交易惩罚对等节点」的 P2P 行为调整、针对 legacy/P2SH/segwitv0 脚本引入的逐输入 sighash midstate 缓存性能优化、无 witness 剥离检测、以及一批围绕 legacy 钱包迁移与createfromdump的工具链修复。读完本文你将能准确判断 29.3 对节点运行行为、验证性能与钱包运维的具体影响并据此规划自己的升级与回归测试。版本概览与发布信息Bitcoin Core 29.3 二进制可从 Bitcoin Core 官方下载站获取适用于生产环境及测试网、回归测试网regtest等多种网络。发布说明明确了两条与生态协作相关的渠道Bug 上报请使用 Bitcoin Core 项目的 issue 追踪器提交问题安全与更新通知建议订阅官方 announcements 邮件列表以便第一时间收到安全公告与版本更新通知。作为维护版本29.3 不包含新的共识规则或软分叉激活其价值体现在稳定性、性能与运维工具链的打磨上本仓库doc/release-notes/release-notes-29.3.md即为其官方发布说明原文。升级指南从 29.x 或更早版本平滑迁移官方推荐的升级步骤非常简单若你正在运行旧版本先将其完全关停等待进程彻底退出——在部分情况下优雅关闭可能耗时数分钟如需要 flush 内存池或等待相关线程收尾覆盖安装新版本二进制Windows运行 29.3 安装包macOS直接覆盖/Applications/Bitcoin-QtLinux覆盖bitcoind与bitcoin-qt以及bitcoin-cli、bitcoin-tx、bitcoin-util、bitcoin-wallet等配套工具。两个值得注意的升级语义跨 EOL 版本直升是允许的即便你的旧版本已经停止维护EOL仍可直接升级到 29.3。但如果数据目录需要迁移如旧版块索引或钱包数据库格式升级首次启动可能耗时较长旧钱包一般兼容发布说明明确「Old wallet versions of Bitcoin Core are generally supported」即旧格式钱包含 legacy/BDB 钱包在升级后通常仍可被识别与打开。这一点与 29.3 中围绕 legacy 钱包迁移的修复密切相关下文会展开。兼容性矩阵与系统要求发布说明给出的官方支持与测试平台如下操作系统要求LinuxKernel 3.17macOSmacOS 13WindowsWindows 10Bitcoin Core 在大多数其他 Unix-like 系统上理论上也可工作但官方在这些平台上测试频率较低官方不建议在不支持的系统上运行。据此选择 29.3 进行生产部署前应优先确保目标主机满足上述内核/系统版本要求并在同构系统上先行做一次升级演练。Notable changes 详解P2P 与网络层#33050不再因「共识无效交易」而惩罚对等节点本版最重要的 P2P 行为变化来自 PR #33050net, validation节点不再因为交易被判定为共识无效consensus-invalid而直接惩罚对等节点。理解该改动需要先看 Bitcoin Core 现有的「惩罚」机制。在 src/net_processing.cpp 中PeerManagerImpl::MaybePunishNodeForBlock依据区块验证结果类型决定是否对节点施加Misbehaving累计 misbehavior 分数可最终触发断连/封禁switch (state.GetResult()) { case BlockValidationResult::BLOCK_RESULT_UNSET: break; case BlockValidationResult::BLOCK_HEADER_LOW_WORK: break; // The node is providing invalid data: case BlockValidationResult::BLOCK_CONSENSUS: case BlockValidationResult::BLOCK_MUTATED: if (!via_compact_block) { if (peer) Misbehaving(*peer, message); return; } break; ...BLOCK_CONSENSUS定义于 src/consensus/validation.hinvalid by consensus rules。传统上节点在验证出「确定性错误」时倾向于惩罚对方因为这类数据不可能在其他合法状态下变成有效。但实践表明对共识无效交易的惩罚过于激进交易的有效性可能依赖节点尚未同步到的最新链状态如 BIP30、UTXO 状态差异共识无效可能是由于数据在传播/下载过程中的割裂状态造成而非对端恶意与 policy 层面的「拒绝但不断连」处理哲学一致Bitcoin Core 正在逐步收敛对等节点惩罚的触发面。29.3 采纳了 #33050共识无效的交易不再成为惩罚对等节点的理由节点仅做拒绝处理。从 src/policy/policy.h 的注释可以看到验证层刻意区分「共识无效」的判定边界这一改动的实际收益是降低误伤、提升网络对短暂分叉或状态滞后节点的容忍度同时避免攻击者利用判定差异诱导诚实节点惩罚无辜对等方。#33723移除 dashjr 社区 DNS 种子PR #33723chainparams从链参数中移除了 DNS 种子节点dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us。种子节点seed node用于新节点冷启动时发现网络中的其他对等节点移除该条目意味着 29.3 启动后不再向该域名发起种子解析请求。对于种子节点运营方这是一次及时的清退——域名停服或托管策略变化后继续保留可能导致新节点解析失败或连接被拒对于普通节点这一改动几乎无感因为 Bitcoin Core 的多 DNS 种子 硬编码地址簿机制仍可保证冷启动的健壮性。Notable changes 详解验证引擎与性能#32473为 legacy/P2SH/segwitv0 脚本引入逐输入 sighash midstate 缓存29.3 中最具含金量的性能优化来自 PR #32473validation/script为 legacy、P2SH、segwitv0即所有 ECDSA 系脚本的 sighash 计算引入per-txin逐交易输入的 SHA256 midstate 缓存。其原理落地在脚本解释器层。新的SigHashCache数据结构声明于 src/script/interpreter.h/** Data structure to cache SHA256 midstates for the ECDSA sighash calculations * (bare, P2SH, P2WPKH, P2WSH). */ class SigHashCache { /** For each sighash mode (ALL, SINGLE, NONE, ALL|ANYONE, SINGLE|ANYONE, NONE|ANYONE), * optionally store a scriptCode which the hash is for, plus a midstate for the SHA256 * computation just before adding the hash_type itself. */ std::optionalstd::pairCScript, HashWriter m_cache_entries[6]; ... };理解这个缓存的价值需要回顾 ECDSA sighashSignatureHash的计算过程实现在 src/script/interpreter.cpp先把交易的部分字段version、prevouts 哈希、sequence 哈希、outputs 哈希、被签名的输入 prevout/scriptCode/amount/nSequence、locktime 等序列化进一个HashWriter最后追加 4 字节的nHashType再取GetHash()。SHA256 是分组压缩算法序列化数据流的绝大多数字节在追加nHashType之前就已确定只有最后追加的 4 字节属于新数据。传统实现每次签名校验都从头做一遍完整哈希。而 midstate 缓存的思想是把「追加 sighash type 之前的哈希中间状态」缓存下来后续若再次校验同一输入、同一 scriptCode、同一 hash_type 组合的签名直接从缓存恢复HashWriter中间态只追加 4 字节即可得到最终 digest从而省去对整个交易数据流尤其是大额、多输入交易的重复 SHA256 压缩计算。缓存的关键设计细节src/script/interpreter.cpp用 6 个槽位对应 6 种 sighash 模式组合ALL / SINGLE / NONE× 是否带SIGHASH_ANYONECANPAY见CacheIndex的实现3 * anyonecanpay 2 * single 1 * none每个槽位除了保存中间态HashWriter还保存产生该状态的scriptCodeLoad()时若 scriptCode 不匹配则视为未命中避免不同 scriptCode 串用缓存注释特别指出缓存索引不区分 BASE 与 WITNESS_V0因为「同一输入不可能同时使用两种签名版本」缓存对象m_sighash_cache作为GenericTransactionSignatureChecker的mutable成员src/script/interpreter.h在CheckECDSASignature中被传入并复用src/script/interpreter.cpp。实际收益场景区块验证时同一输入可能对应多个需要检查的签名例如多签 P2SH/P2WSH 脚本中有多把公钥/多个签名者同一交易也可能在「先校验签名、后因状态差异重放校验」时被再次检查。有了 per-txin 的 midstate 缓存第二次起就跳过大部分 SHA256 压缩工作直接逼近「一次 ECDSA 验签」的最小代价。需要注意的是该缓存仅针对 legacy/P2SH/segwitv0 的 ECDSA 签名路径Taproot 的 Schnorr 签名走SignatureHashSchnorr同样位于 src/script/interpreter.cpp其 sighash 缓存语义由独立的PrecomputedTransactionData体系承载。#33105检测 witness 剥离无需重跑整轮 Script 检查PR #33105validation优化了witness 剥离witness stripping的检测路径。当对端以 compact block 或交易中继方式发送数据时若 witness 数据在传输中被裁剪/剥离接收方需要识别出「同一 txid 下缺少 witness」的状态以便正确地缓存拒绝结果、避免后续重复校验。在 29.3 之前检测此类情况往往需要重走脚本验证流程来确认「确实是缺 witness 而非真无效」#33105 使验证层能够仅凭非 witness 数据与 witness 缺失的对应关系即可判定无需为确认剥离而把整轮 Script 检查再跑一遍。这一判定的核心产物就是TX_WITNESS_STRIPPED这类状态标记。在 src/validation.cpp 中可以找到该状态的使用注释// Detect a failure due to a missing witness so that p2p code can handle rejection caching appropriately. state.Invalid(TxValidationResult::TX_WITNESS_STRIPPED, ...);配合 src/validation.cpp 对「相同非 witness 数据、不同 witness」的txn-same-nonwitness-data-in-mempool冲突检测验证层可以高效地区分「同 txid 但 witness 不同的重组攻击」与「普通无效交易」。这项改动的价值在于显著减少重复脚本验证的开销尤其在遭受 witness 剥离型 DoS 或运行在 witness 与无 witness 节点混播环境中时节点的验证与拒绝缓存行为更加经济且准确。Notable changes 详解钱包与钱包工具链#33268识别花费 0 值输出的交易并为钱包中的 anchor 输出补充测试PR #33268wallet让钱包能够正确识别花费 0 值输出的交易并围绕钱包内的anchor 输出anchor output增加测试覆盖。anchor 输出对应协议层的PayToAnchorP2A输出类型。在本仓库中该类型定义于 src/addresstype.hinline const std::vectorunsigned char ANCHOR_BYTES{0x4e, 0x73}; struct PayToAnchor : public WitnessUnknown { PayToAnchor() : WitnessUnknown(1, ANCHOR_BYTES) { Assume(CScript::IsPayToAnchor(1, ANCHOR_BYTES)); } ... };判断逻辑位于 src/script/script.cppCScript::IsPayToAnchor地址解码在 src/key_io.cpp 中完成RPC 侧亦在 src/wallet/rpc/addresses.cpp 为PayToAnchor提供地址序列化支持。anchor 输出在二层协议如闪电网络通道关闭场景中被用作可被第三方花费的 0 值输出用于 CPFP子为父付费手续费加速。此前钱包对「花费 0 值输出的交易」识别不完整容易在余额追踪、交易状态与费用核算上出现偏差29.3 补齐了这块逻辑并新增了对应的钱包级测试确保含 anchor 输出0 值输出的交易在钱包中被正确归类与跟踪。这对运行通道/接受 anchor 输出的钱包场景有直接的正向意义。legacy 钱包迁移系列修复#34156 / #34123 / #3422629.x 系列自早期版本起就通过migratewallet等工具推动从 legacyBDB钱包向 descriptorSQLite钱包的迁移。29.3 集中修复了一批迁移路径上的边角问题#34156修复未命名 legacy 钱包unnamed legacy wallet即没有显式名字、由默认路径加载的钱包迁移失败的问题。此前未命名钱包在迁移流程中可能因目录/文件名推导不一致而中断#34123避免从watch-only 的 legacy 钱包迁移出可花费spendable钱包。watch-only 钱包不含私钥迁移时应保持「仅监视」语义绝不能在迁移产物中意外生成带可花费密钥的钱包——这是安全语义上的关键修复#34226为「相对钱包Relative wallet迁移失败后的清理」补充测试用例确保迁移失败时不残留脏状态。这三项共同加强了迁移流程在命名边界、只读钱包语义与失败回滚三个维度的健壮性。从钱包命令实现看钱包工具的参数体系集中在 src/bitcoin-wallet.cpp迁移相关 RPC 则位于钱包模块内。wallettoolcreatefromdump修复#34215 / #34370比特币钱包工具bitcoin-wallet可执行文件提供了dump将钱包记录导出为文本与createfromdump从导出的记录重建钱包两条配套命令其命令行定义位于 src/bitcoin-wallet.cppargsman.AddArg(-dumpfilefile name, When used with dump, writes out the records to this file. When used with createfromdump, loads the records into a new wallet., ...); argsman.AddCommand(createfromdump, Create new wallet file from dumped records, {-dumpfile});实际用法示例从 dump 文件重建新钱包# 1. 导出旧钱包全部记录 bitcoin-wallet -walletlegacy_wallet.dat dump -dumpfilerecords.dump # 2. 依据导出记录重建为新钱包 bitcoin-wallet createfromdump -walletrebuilt_wallet.dat -dumpfilerecords.dump29.3 中的两项修复#34215修复未命名钱包执行createfromdump时 wallets 目录被误删的问题。此前若重建目标钱包未显式命名工具的清理逻辑可能误删整个wallets/目录属破坏性 bug#34370为迁移流程做进一步清理并修复createfromdump处理 BDBlegacy来源记录时的兼容问题确保从 legacy 钱包 dump 出的记录能够被正确重建为 descriptor 钱包而不只是在纯 SQLite 记录间搬移。Notable changes 详解挖矿与区块组装#33475修复addPackageTxs中的无符号整数溢出PR #33475miner是矿工侧的一个经典整数溢出修复区块组装过程中addPackageTxs将 mempool 中以祖先依赖为单位的交易包加入候选区块阶段对包体积/费用等累计量使用了无符号整数累加在极端取值下可能发生无符号回绕wrap-around导致区块模板出现错误的交易选择或体积越界。在本仓库中区块模板组装的主逻辑位于 src/node/miner.cpp配套的迷你矿工/费用排序逻辑见 src/node/mini_miner.h、src/node/mini_miner.cpp对应的基准测试与单元测试覆盖在 src/bench/block_assemble.cpp 与 src/test/miner_tests.cpp 中维护。此修复通过改用更宽的数值类型或在累加处增加溢出保护保证区块组装在打包大体积/高祖先链包时不产生错误的中间结果从而维持getblocktemplate与自建区块模板的稳定性。运行自定义矿池或频繁使用getblocktemplate构建模板的节点尤其受益。Notable changes 详解构建、文档、测试与 CIBuildguix 修复 osslsigncode 测试#34227PR #34227 修复了 Guix 可复现构建流程中osslsigncodeWindows 代码签名工具的测试问题。Guix 构建是 Bitcoin Core 保证二进制可复现性的核心路径相关文档见 doc/guix.md此项修复确保在 Guix 环境中对签名工具自身做校验时不会因环境差异而误报失败从而保障 Windows 签名二进制的可复现出包流程。Documentation#33623 记录 29.x 中 capnproto 与 libmultiprocess 依赖PR #33623 补齐了 29.x 分支关于Capn Proto 与 libmultiprocess构建依赖的文档说明。这两者服务于 Bitcoin Core 的多进程multiprocess架构实验Capn Proto 序列化框架的依赖定义见 depends/packages/native_capnp.mklibmultiprocess基于 Capn Proto 的进程间接口层依赖见 depends/packages/native_libmultiprocess.mk架构说明可参考 doc/design/multiprocess.md。依赖总览表在 doc/dependencies.md 中列明版本要求。对绝大多数仅构建标准单进程bitcoind的用户这些是可选项但若你尝试 29.x 的 multiprocess 构建则需要按文档安装对应版本的系统包或通过depends交叉编译。Test#33612 修改日志速率限制的版本门控PR #33612 调整了测试逻辑中与日志速率限制相关的版本门控version gate。Bitcoin Core 对重复日志有速率限制机制避免高频错误信息刷爆日志相关测试需要根据当前节点版本/行为选择是否断言受速率限制的日志。本版更新了门控条件使其与 29.3 的实际日志行为保持一致属于保障功能测试在后续版本中继续稳定通过的前瞻性修复。Misc/CI 维护#32513 / #33508 / #33581 / #34344发布说明还包含一组 CI持续集成维护项#32513移除 Windows DLL 构建作业中对第三方 JavaScript 的依赖收紧供应链#33508修复 fork 仓库上 buildx GHA 缓存认证失败的问题改善社区 PR 的 CI 体验#33581将$FILE_ENV正确纳入DEPENDS_HASH保证依赖哈希能反映实际构建环境变量避免缓存误命中#34344升级 GitHub Actions 版本跟进上游安全与功能更新。这些改动不改变节点二进制行为但对构建基础设施的可复现性与安全性有意义。仓库内的 CI 编排可参见 ci/lint.py、ci/test/test_run_all.sh 等文件。升级到 29.3 的验证清单综合以上改动建议按如下顺序完成 29.3 的上线验证版本与兼容确认操作系统满足 Linux Kernel 3.17 / macOS 13 / Windows 10并检查bitcoind --version输出为 29.3数据目录预检升级前对数据目录尤其是含 legacy/BDB 钱包的目录做完整备份并预留首次启动迁移的时间窗口钱包回归若使用 legacy 钱包重点验证打开、余额显示与migratewallet迁移路径若使用bitcoin-wallet dump/createfromdump流程验证-wallet命名显式化以避免 #34215 所述的目录误删问题网络与验证观察日志中对等节点惩罚事件是否如 #33050 预期减少结合 src/bench/block_assemble.cpp、src/test/miner_tests.cpp、src/bench/verify_script.cpp 与 src/test/sighash_tests.cpp 运行对应基准与测试确认 #32473/#33105 未引入验证回归构建侧若使用 Guix 或 multiprocess 构建参照 doc/dependencies.md 核对 capnproto/libmultiprocess 依赖并验证osslsigncode相关测试通过。致谢与进一步阅读29.3 汇集了 16 位直接贡献者的代码工作Anthony Towns、Antoine Poinsot、Ava Chow、fanquake、furszy、Pieter Wuille、willcl-ark 等以及 Transifex 上大量社区成员的翻译贡献。想深入理解本版改动的底层实现可按主题继续阅读sighash midstate 缓存的完整实现与测试src/script/interpreter.h、src/script/interpreter.cpp、src/test/sighash_tests.cpp对等节点惩罚与共识分类src/net_processing.cpp、src/consensus/validation.hanchor/P2A 输出与钱包识别src/addresstype.h、src/script/script.cpp、src/key_io.cpp钱包工具命令定义src/bitcoin-wallet.cpp区块组装相关src/node/miner.cpp、src/node/mini_miner.h、src/test/miner_tests.cpp。【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考