资讯详情

资讯详情

Bitcoin Core 27.2 发布说明解析:P2P 自连接竞态修复、PSBT 正确性与构建兼容性改进

Bitcoin Core 27.2 发布说明解析P2P 自连接竞态修复、PSBT 正确性与构建兼容性改进【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin27.2 是 Bitcoin Core 27.x 稳定分支的第二个补丁版本聚焦于 bug 修复与性能改进不含任何共识层变更或新增功能。本文基于仓库内 doc/release-notes/release-notes-27.2.md 展开逐条深入解读 9 个被合入的 PR涉及 P2P、Init、RPC、PSBT、Test、Doc、Build、CI 八个模块并对照当前仓库源码与提交历史说明每个修复的根因、实现方式与验证手段帮助运行 27.x 节点的运维人员与钱包开发者评估升级必要性。升级方式与兼容性要求如何从旧版本升级官方推荐的升级流程很简单先关闭正在运行的旧版本节点等待进程完全退出某些情况下可能需要数分钟然后执行以下操作之一Windows运行新版安装程序覆盖安装macOS覆盖/Applications/Bitcoin-QtLinux用新版bitcoind/bitcoin-qt二进制直接替换旧文件。文档明确说明直接从已到达生命周期结束EOL的版本升级是可行的但如果数据目录需要迁移可能耗时较长旧版本的钱包数据格式一般都能被继续支持不会因升级而丢失。支持的平台范围官方支持并经过充分测试的操作系统为Linux Kernel 3.17、macOS 11.0、Windows 7 及更新版本。文档同时指出Bitcoin Core 在大多数其他类 Unix 系统上也能工作但测试频率较低不推荐在不支持的平台上运行。P2P修复自连接检测中的竞态条件#30394问题根因VERSION 消息早于节点注册当节点意外连接到自身例如本地端口转发、NAT 回环或配置错误时网络层会通过比对 VERSION 握手中的临时 nonce 来识别并断开自连接。原实现中出站连接的建立流程见 CConnman::OpenNetworkConnection分为三步初始化节点状态通过PushNodeVersion队列发送 VERSION 消息把节点对象加入连接管理器的m_nodes向量。问题在于第 2 步发送的 VERSION 消息可能在节点对象加入m_nodes第 3 步之前就被本地接收并处理。此时自连接检测逻辑CConnman::CheckIncomingNonce见 src/net.cpp在m_nodes中找不到对应的出站对等节点导致自连接一直无法被发现形成自我连接的僵尸连接。修复方案交换注册与握手顺序提交0933cf53b4作者 Sebastian Falbesoner将PushNodeVersion调用从InitializeNode中移除改到SendMessages方法内执行。由于SendMessages只对已经加入m_nodes的CNode实例调用这就保证了节点注册永远先于 VERSION 消息的发送。修复后的自连接检测代码位于 src/net_processing.cpp// Disconnect if we connected to ourself if (pfrom.IsInboundConn() !m_connman.CheckIncomingNonce(nNonce)) { LogInfo(connected to self at %s, disconnecting\n, pfrom.addr.ToStringAddrPort()); pfrom.fDisconnect true; return; }同时在 src/net_processing.cpp 中出站连接的 VERSION 握手改为由m_outbound_version_message_sent标志控制确保每个出站对等节点只发送一次// Initiate version handshake for outbound connections if (!node.IsInboundConn() !peer.m_outbound_version_message_sent) { PushNodeVersion(node, peer); peer.m_outbound_version_message_sent true; }该修复涉及 src/net.h、src/net_processing.cpp 与 src/test/util/net.cpp 三个文件。测试侧通过 p2p 测试验证了连接到自己会被断开的行为这一改动对运行在端口转发或复杂网络环境下的节点尤为关键。Init调整加载区块线程与调度器的关闭顺序#30435问题重索引期间关闭可能无法完成提交05192ba84c作者 Martin Zumsande修复了重索引reindex场景下 shutdown 无法结束的问题。根因是加载区块线程m_thread_load会调用SyncWithValidationInterfaceQueue而旧代码先停止 scheduler 再 join 加载区块线程导致加载线程在 scheduler 已停止后仍尝试同步验证接口队列从而阻塞关闭流程。修复后的关闭顺序修改位于 src/init.cpp 的Shutdown函数中将两者顺序对调if (node.chainman node.chainman-m_thread_load.joinable()) node.chainman-m_thread_load.join(); // After everything has been shut down, but before things get flushed, stop the scheduler. // After this point, SyncWithValidationInterfaceQueue() should not be called anymore // as this would prevent the shutdown from completing. if (node.scheduler) node.scheduler-stop();即先 join 加载区块线程再停止 scheduler。注释明确警告scheduler 停止之后绝不能再调用SyncWithValidationInterfaceQueue()否则会阻碍 shutdown 完成。对经常执行-reindex或-reindex-chainstate的节点运维者来说这个修复消除了一个隐蔽的关不掉故障。RPC / 钱包修复 FillPSBT 误报 completetrue#30357问题签名后被修改的交易被误判为完成提交f22b9ca70c作者 willcl-ark修复了钱包FillPSBT在交易并非真正完成时错误返回completetrue的问题。该问题在 PayJoin 等场景中会出现部分输入已签名后交易又被修改但完成标志未随之重置。从当前源码 src/wallet/wallet.cpp 可以看到CWallet::FillPSBT遍历所有输入将每个输入的non_witness_utxo从钱包中补齐交给各个ScriptPubKeyMan签名最后统一计算完成标志RemoveUnnecessaryTransactions(psbtx); // Complete if every input is now signed complete true; for (size_t i 0; i psbtx.inputs.size(); i) { complete PSBTInputSignedAndVerified(psbtx, i, txdata); }修复前用的是PSBTInputSigned的简单判断修复后改用PSBTInputSignedAndVerified额外校验签名与交易的关联并且walletprocesspsbt在finalizeFalse时允许显式跳过自动 finalize不再因尝试把已 finalize 的十六进制串塞入而触发CHECK_NONFATAL中止。测试补充在 test/functional/rpc_psbt.py例如signed_psbt_incomplete wallet.walletprocesspsbt(psbtsigned_psbt_obj.to_base64(), finalizeFalse) assert_equal(signed_psbt_incomplete[complete], False)该修复对依赖walletprocesspsbt/finalizepsbt做多签或 PayJoin 流程的开发者有直接影响此前错误返回completetrue可能导致下游逻辑提前终结交易。PSBT在反序列化早期校验 non-witness UTXO 的 outpoint#29855提交fa90989503针对 fuzz 测试长期发现的一类问题——outpoint 在 non-witness UTXO 中不存在——在PSBT 反序列化阶段就做统一检查而不是分散在各自调用点。修改位于 src/psbt.h 的PartiallySignedTransaction::FromTx反序列化逻辑if (input.non_witness_utxo) { if (input.non_witness_utxo-GetHash() ! tx-vin[i].prevout.hash) { throw std::ios_base::failure(Non-witness UTXO does not match outpoint hash); } if (tx-vin[i].prevout.n input.non_witness_utxo-vout.size()) { throw std::ios_base::failure(Input specifies output index that does not exist); } }新增的第二重检查不仅校验交易哈希一致还校验输入引用的输出索引prevout.n确实存在于 non-witness UTXO 的 vout 列表内。非法 PSBT 现在会在反序列化时直接抛异常避免了后续签名、计算等环节中的越界访问与行为不一致。Test修复 msg_tx 构造器的共享可变默认值#30552提交500bba0561作者 Martin Zumsande修复了 test/functional/test_framework/messages.py 中msg_tx的构造器缺陷def __init__(self, txNone): if tx is None: self.tx CTransaction() else: self.tx tx在 Python 中可变对象作为默认参数会在所有实例间共享。原代码def __init__(self, txCTransaction())使得所有未传参的msg_tx实例共用同一个CTransaction对象一个实例被修改会影响其他实例这被推断为功能测试中多种间歇性故障intermittent bug的来源。改为None哨兵值后在每次调用时新建实例隔离了实例间状态。Doc修正 CTxMemPool::cs 的 Doxygen 格式#30504提交c838ce514f修复了 src/txmempool.h 中CTxMemPool::cs的注释格式。原注释在par Consistency guarantees后紧跟空行Doxygen 会渲染出有标题无正文的段落并导致 Clang 19 编译时触发-Wdocumentation告警error: empty paragraph passed to par command。该文档段落本身描述了 mempool 锁的重要一致性保证同时持有cs_main与mempool.cs可以看到与当前链尖一致且完全填充的 mempool仅持mempool.cs则看到与某条历史链状态一致的视图。这是纯文档修正不影响运行时行为。Buildminiupnpc 2.2.8 兼容与 GCC 15 编译修复UPnP适配 miniupnpc 2.2.8 的新返回值语义#30283提交391ce775f4作者 Cory Fields修复了与 miniupnpc 2.2.8 的构建兼容问题。该版本中UPNP_GetValidIGD的返回值语义变化返回值 2 现在表示找到了有效的已连接 IGD但其 IP 地址是保留不可路由地址。同时 2.2.8 修改了函数签名需要在 API 版本 17 时传入额外的urls与num参数。修复位于 src/mapport.cpp#if MINIUPNPC_API_VERSION 17 r UPNP_GetValidIGD(devlist, urls, data, lanaddr, sizeof(lanaddr)); #else r UPNP_GetValidIGD(devlist, urls, data, lanaddr, sizeof(lanaddr), nullptr, 0); #endif代码继续只认可返回值1的情况其余返回值包括新的 2一律忽略保持原有行为不变。注意在当前仓库较新的开发版本中miniupnpc 依赖已通过 #31130 被移除见提交1b6dec98da因此该兼容分支主要服务于 27.x 等仍保留 UPnP 依赖的稳定分支。GCC 15 兼容性修复#30633提交1a08364686作者 Matt Whitlock为 GCC 15 编译准备了修复在 src/chainparamsbase.h 与 src/node/interface_ui.h 中补充缺失的#include cstdint头文件。GCC 15 对隐式包含的依赖更严格此前依赖传递包含才能编译的代码在新编译器下会失败。这对使用较新发行版工具链自行编译节点的用户有实际意义。CIASan 任务迁移至 GitHub Actions#30193、#30299#30193提交0d524b1484将 ASan / LSan / USDT 任务从 Cirrus CI 迁移到 GitHub Actions 工作流 .github/workflows/ci.yml迁移动机是更易于维护、便于 fork 使用。相关环境脚本 ci/test/00_setup_env_native_asan.sh 与 ci/test/02_run_container.sh 也做了对应调整。#30299提交f34e44616d清理工作流中未使用的bcc变量.github/workflows/ci.yml 中删除一行。这两项属于开发流程维护对最终用户无功能影响。致谢与发布信息本次发布由以下 8 位开发者直接贡献Ava Chow、Cory Fields、Martin Zumsande、Matt Whitlock、Max Edwards、Sebastian Falbesoner、Vasil Dimov、willcl-ark翻译工作则由 Transifex 平台上的社区成员共同完成。总结27.2 的升级价值模块PR修复内容影响面P2P#30394自连接检测竞态先注册后握手所有节点尤其是端口转发/NAT 环境Init#30435重索引时 shutdown 卡死使用-reindex的节点RPC/钱包#30357FillPSBT误报 complete多签、PayJoin、PSBT 工具链PSBT#29855反序列化早期校验 outpoint 越界PSBT 解析健壮性Test#30552msg_tx共享默认值 bug功能测试稳定性Doc#30504Doxygen 注释格式构建告警Clang 19Build#30283 / #30633miniupnpc 2.2.8 / GCC 15 兼容新版依赖与编译器CI#30193 / #30299ASan 任务迁移、清理开发流程27.2 不引入任何新特性或共识变更因此升级风险极低但对于运行 27.x 节点、使用 PSBT 钱包工具链或在新版编译器/依赖环境下构建的用户建议尽快升级以获得上述健壮性与兼容性修复。升级前请确保节点完全关闭并在升级后检查bitcoind --version输出确认版本号。【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →