Zcash 2.0.2-rc1 发布要点解读:Sapling 钱包能力深化与交易过期 DoS 缓解
【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash
Zcash 2.0.2-rc1 是 Zcash 在 Sapling 网络升级落地后发布的一个重要候选版本,主线工作围绕两条展开:一是把 Sapling 深度整合进钱包与交易构建流程(如z_mergetoaddress支持 Sapling、z_getnewaddress默认返回 Sapling 地址、Sapling 默认 memo 规范);二是针对 ZEC-013 安全公告,从 P2P 传播与 RPC 入口两层缓解"交易即将过期"(expiring soon)带来的拒绝服务(DoS)攻击向量。阅读本篇文章后,你可以掌握该版本的升级注意事项、核心 RPC 行为变化,以及从源码层面理解交易过期机制与缓解策略的实现原理。
版本概览:2.0.2-rc1 的定位
本版本以候选发布(release candidate)形式提供,从 doc/release-notes/release-notes-2.0.2-rc1.md 的 Changelog 看,该版本汇集了来自 Zcash 核心团队及社区(Jack Grigg、Simon Liu、Larry Ruane、Eirik Ogilvie-Wigley、Suhas Daftuar 等)的大量改动,主要涉及:
- 钱包/交易层:
z_mergetoaddress支持 Sapling 池、z_getnewaddress默认地址类型切换、Sapling 默认 memo; - 安全层面:ZEC-013 交易过期 DoS 缓解;
- 网络层:修剪模式下的区块中继改进;
- 基础设施:librustzcash 迁移、Sapling 价值池记账、基准测试与测试框架加固。
由于是 RC 版本,其主要目标是收集回归测试与社区反馈,为正式版 2.0.2 铺路。
升级注意:Debian 升级时遇到的"吊销密钥"错误
该版本发布说明中专门记录了一个影响 Debian 系用户的升级问题:在通过 apt 更新到新版 zcashd 时,可能遇到如下签名校验错误:
The following signatures were invalid: REVKEYSIG AEFD26F966E279CD这表示本地 apt 信任链中仍持有已被吊销的旧签名密钥。发布说明给出的处理流程分三步:
- 删除被标记为吊销的密钥:
sudo apt-key del AEFD26F966E279CD- 重新获取更新后的密钥并导入:
wget -qO - https://apt.z.cash/zcash.asc | sudo apt-key add -- 更新软件包列表并继续升级:
sudo apt-get update需要说明的是,该操作是针对当时 Debian/Ubuntu 发行版 apt 生态的修复路径(对应上游 issue #3612);在现代较新的发行版中apt-key已逐步弃用,建议结合你所使用发行版的密钥管理方式(如/etc/apt/trusted.gpg.d/下的 gpg 文件)来更新 Zcash 软件源签名。无论采用哪种方式,核心要点是:先清除吊销密钥,再导入新密钥,最后刷新软件包列表,否则 apt 会持续拒绝签名校验而无法升级。
钱包功能深化:z_mergetoaddress 全面支持 Sapling
2.0.2-rc1 中最重要的钱包能力变化,是z_mergetoaddressRPC 从仅支持 Sprout 扩展到同时支持 Sapling 池,使用户可以把多个来源地址(含 Sapling 地址)的零钱合并到目标地址,用于整理碎片、控制 note 数量。
背后的重构工作
Changelog 显示,为支撑这一功能,Eirik Ogilvie-Wigley 做了一组配套重构:
- 将
GenerateNewZKey重命名为GenerateNewSproutZKey,明确其职责范围仅限 Sprout 池,并可返回SproutPaymentAddress; - 移除
GetUnspentFilteredNotes,把"按过滤条件取未花费 note"的能力并入GetFilteredNotes,避免两套逻辑重复维护; - 为 Sapling note 增加加锁(locking)支持,保证在读取/合并 note 时的线程安全;
- 补充了大量
z_mergetoaddress参数测试与断言,并扩展了 RPC 测试,使同一套测试同时覆盖 Sprout 与 Sapling 两条路径。
RPC 使用方式
在 src/wallet/rpcwallet.cpp 中,z_mergetoaddress的签名形如:
z_mergetoaddress ["fromaddress", ... ] "toaddress" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo ) ( privacyPolicy )一个典型的命令行用法是:
zcash-cli z_mergetoaddress '["ANY_SAPLING", "t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd"]' "ztestsapling..."其中来源地址支持ANY_SAPLING、ANY_SPROUT、ANY_TADDR这样的通配选择器,也可以显式列出具体地址。需要特别注意的是,从源码实现看,同一笔z_mergetoaddress不允许同时从 Sprout 与 Sapling 地址发送资金(代码中直接抛错 "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"),这是当时实现的明确限制,规划合并操作时需按池分开执行。
RPC 行为变更:z_getnewaddress 默认返回 Sapling 地址
另一个直接影响日常操作的变化是:z_getnewaddress的默认地址类型从 Sprout 切换为 Sapling。在 src/wallet/rpcwallet.cpp 中可以看到:
std::string defaultType = ADDR_TYPE_SAPLING;即不传参数调用时,默认生成 Sapling 支付地址;也可以显式传"sapling"或"sprout"。源码同时体现了两个约束:
- Canopy 激活后禁止再生成 Sprout 地址:若当前链高度已激活
UPGRADE_CANOPY,传入"sprout"会抛出RPC_INVALID_PARAMETER; - 初始区块下载(IBD)期间不支持创建 Sprout 地址。
在更现代的 Zcash 版本中,该 RPC 已进一步被z_getnewaccount与z_getaddressforaccount取代(源码中标注了 Deprecated 提示),统一账户/UA 模型成为钱包标准,但 2.0.2-rc1 中"默认 Sapling"这一变更仍是钱包默认行为迁移的关键一步。
安全修复:ZEC-013 交易过期 DoS 缓解
本版本最值得关注的安全工作是对ZEC-013的缓解:攻击者可能利用"即将过期(expiring soon)"的交易大量占用节点资源(如通过 P2P 消息反复广播、诱导节点长时间缓存),形成拒绝服务向量。2.0.2-rc1 从三个层面收紧:
- P2P 层不再传播即将过期的交易:节点在通过
inv/mempool 请求向对等节点转发交易前,会跳过那些即将过期的交易; - RPC 层拒绝即将过期的交易:
createrawtransaction与sendrawtransaction在交易即将过期时直接返回错误,从源头阻断恶意构造; - 测试同步更新:同步修正了被新阈值破坏的 QA 测试。
源码层的实现细节
交易是否"即将过期"由 src/main.cpp 中的两个函数判定:
bool IsExpiredTx(const CTransaction &tx, int nBlockHeight) { if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) { return false; } return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight; } bool IsExpiringSoonTx(const CTransaction &tx, int nNextBlockHeight) { return IsExpiredTx(tx, nNextBlockHeight + TX_EXPIRING_SOON_THRESHOLD); }其中阈值定义在 src/main.h:
static const unsigned int DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA = 20; static const unsigned int DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA = DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO; static constexpr uint32_t TX_EXPIRING_SOON_THRESHOLD = 3;也就是说:交易默认在创建后约 20 个区块(Blossom 之后按出块间隔比例放大)过期;当交易离过期高度不足 3 个区块时即被视为"expiring soon",不再参与中继与广播。另外 src/consensus/consensus.h 定义了TX_EXPIRY_HEIGHT_THRESHOLD = 500000000,用于区分"正常过期高度"与"永不过期"的特殊取值。
createrawtransaction对expiryheight参数的校验可以在 src/rpc/rawtransaction.cpp 看到,非法值(负数或 ≥ 阈值)会直接抛出RPC_INVALID_PARAMETER。相应的单元测试见 src/gtest/test_mempool.cpp 中的Mempool.ExpiringSoonTxRejection。
其他值得关注的变化
除上述主线外,2.0.2-rc1 还包含一批对稳定性和正确性有意义的改动:
- Sapling 默认 memo 规范:
z_sendmany在未显式提供 memo 时,默认写入0xf6后跟全零的 512 字节 memo(对应 src/zcash/memo.h 中static constexpr const Bytes noMemo{0xf6}的"no memo"定义,memo 总长为 512 字节)。这一约定让收方可区分"无 memo"与"有 memo",是后续 ZIP 302 memo 规范的基础; - TransactionBuilder 版本检查:构建器在添加 Sapling spends/outputs 之前先校验交易版本与版本组 ID,防止在 Overwinter 交易上错误拼接 Sapling 部件;
- Sapling 价值池记账:从磁盘加载区块索引时在内存中正确设置
nSaplingValue,并配套"Sapling 价值池记账"测试,为链上总供应量的可审计性提供保障; - 加载旧区块不再误封禁对等节点:修复了加载 Sapling/Blossom 之前的区块时可能错误 ban 对等节点的问题;
- 修剪模式下启用区块中继:允许在 pruning 节点上中继区块,同时避免对旧区块或缺失区块发送
inv; - 测试基础设施加固:
TestingSetup构造/析构时保存并恢复current_path,BasicTestingSetup增加SetupNetworking调用,保证测试之间不互相污染工作目录与网络环境; - 文档与文案修正:明确
sendmany/z_sendmany的金额参数不是浮点数(amount 以 zatoshis 整数表达),并修正了误称金额为 double 精度及 ZC/ZEC 混用的表述; - 性能基准:新增 Sapling spends 与 outputs 的基准测试(见 src/bench 与 src/zcbenchmarks.cpp),用于跟踪 Sapling 交易性能回归。
小结
Zcash 2.0.2-rc1 是一个"承前启后"的版本:它完成了 Sapling 在钱包工作流中的深度接入(合并、默认地址、默认 memo),同时针对 ZEC-013 从传播与交易入口两个层面落实了过期交易的 DoS 缓解。对于运维者,核心动作是处理 Debian 升级时的吊销密钥问题;对于开发者,IsExpiringSoonTx、TX_EXPIRING_SOON_THRESHOLD、z_getnewaddress默认类型等源码细节,都是理解 Zcash 交易过期模型与钱包地址策略演进的直接入口。后续的正式发布与更新记录可继续在 doc/release-notes 目录下追踪。
【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考