Solana 安全投票签名设计:从 PoH 验证到硬件安全飞地的投票签名架构解析

发布时间:2026/9/14 1:26:11
Solana 安全投票签名设计:从 PoH 验证到硬件安全飞地的投票签名架构解析 Solana 安全投票签名设计从 PoH 验证到硬件安全飞地的投票签名架构解析【免费下载链接】solanaWeb-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.项目地址: https://gitcode.com/GitHub_Trending/so/solana本文基于 Solana 代码仓库中的设计提案 vote-signing-to-implement.md完整解析 Solana 为提升投票签名安全性而设计的架构方案如何借助安全飞地Secure Enclave持有投票私钥、如何在签名前验证 PoHProof of History与分叉fork归属以及如何通过锁定期lockout策略防止投注违反惩罚slashing条件的投票。文章同时结合仓库中投票程序programs/vote、投票状态机sdk/program/src/vote/state/mod.rs等源码实现帮助读者理解设计提案与当前代码之间的对应关系并掌握投票签名安全性的核心考量。背景为什么投票签名需要更安全Solana 验证节点validator从当前 leader 接收条目entries并通过提交投票来确认这些条目有效。投票是节点选择分叉的核心动作当节点在同一个 slot 收到多个区块时它会跟踪所有可能的分叉直到能判断出最佳分叉然后通过向其提交投票来选定它。投票提交本质上是一个使用非对称密钥签名验证工作结果的交易。其他实体可以通过验证节点的公钥来验证该签名。问题在于如果验证节点的密钥被用于签署错误的数据例如在账本的多条分叉上投票节点的质押stake或资源就可能被削减slash。这是投票签名安全性的根本威胁相关阐述可参见仓库中的 vote-signing.md。当前 Solana 已经实现了一个投票签名服务vote-signing service它在每次投票时评估该投票是否违反削减条件。本文的设计提案则进一步描述额外的投票签名行为使整个过程更加安全——特别是结合硬件安全飞地如 Intel SGX的场景。角色划分Validator、Vote Signer 与 Stakeholder在深入架构之前先明确三个关键角色源自 vote-signing.md 的概念框架Validator验证节点接收区块、验证数据、选择并提交投票的节点。节点启动时创建新的投票账户并通过 gossip 向集群注册其他节点将其纳入 active set活跃集合。Vote Signer投票签名者实际持有投票私钥、执行签名动作的实体。在本文的设计中投票签名者可以是安全飞地。Stakeholder质押者控制质押资本的身份。质押者可以将其 stake 委托给投票签名者。一旦委托完成投票签名者的投票就代表了所有被委托质押的投票权重并为所有被委托的质押产生奖励。这种密钥持有者与资本控制者分离的模式是安全投票签名设计的出发点即使签名服务或飞地运行的硬件被攻破质押者的资本控制权依然可以保留在信任边界之外反之签名服务需要确保其签名的每一票都符合共识规则避免因签署违规投票而导致委托的 stake 被削减。安全投票签名架构的整体流程设计提案的核心思路是让投票签名服务可以有不同的实现变体具体取决于硬件平台能力。特别是它可以与安全飞地Secure Enclave如 SGX配合使用飞地生成非对称密钥向用户不可信代码暴露签名投票交易的 API同时将投票签名私钥保存在受保护的内存中。整个架构的消息流Message Flow分为四步1. 节点启动时初始化飞地飞地生成一对非对称密钥并将公钥返回给节点密钥对是临时ephemeral的节点每次启动都会生成新的密钥对未来也可能根据待定TBD的标准在运行时重新生成飞地将它的 attestation report证明报告返回给节点。这里的关键安全收益是投票私钥从不离开飞地的受保护内存不可信的主机软件永远无法直接读取或导出它。2. 节点对飞地执行证明attestation节点使用例如 Intel IAS APIs 对飞地执行远程证明节点确保安全飞地运行在 TPM可信平台模块之上节点确保飞地由受信任方签名即飞地镜像的真实性与完整性可被验证。证明环节解决了我凭什么相信这个飞地真的运行在可信硬件上的问题是安全链的第一环。3. 质押者授予临时密钥使用其质押的权限节点stakeholder授予临时密钥使用其 stake 的权限。设计文档明确指出该流程尚未确定to be determined。从当前实现看Solana 的质押委托与投票权重机制体现在投票程序中参见 programs/vote/src/vote_state/mod.rs委托关系建立后签名者的投票即代表被委托质押的权重。4. 不可信软件调用飞地签名节点的不可信、非飞地软件通过接口调用受信任的飞地软件来签名交易和其他数据。在投票签名场景下节点需要验证 PoHPoH 验证是签名过程不可分割的一部分飞地在签名投票之前会被呈现一些可验证的数据verifiable data以供检查在不可信空间生成这些可验证数据的具体流程尚未确定to be determined。提案在末尾的 Challenges 一节也再次强调这两点一是在不可信空间为飞地内的 PoH 验证生成可验证数据的机制二是为临时密钥授予 stake 所需的基础设施。PoH 验证与锁定期策略投票签名安全的核心约束来自 Solana 的锁定期lockout机制。设计提案用形式化规则描述了这一策略而当前源码则给出了精确的参数实现。设计提案中的规则当节点对条目X投票时存在一个锁定期N在锁定期内节点不能对不包含X的历史的分叉投票每当节点对X的衍生条目如Xy投票时X的锁定期按因子F增加即节点不能对不包含X的分叉投票的时长增加Xy自身的锁定期在节点再次投票之前仍是N锁定期增量有上限例如因子F最多应用 32 次签名飞地绝不能签署违反此策略的投票具体意味着飞地以N、F和因子上限Factor cap初始化飞地存储节点此前投票过的、数量为Factor cap的 entry ID签名请求包含新投票的 entry ID飞地验证新投票的 entry ID 是否在正确的分叉上遵循上述规则 1 和 2。源码中的对应实现设计文档中的N、F与上限在代码中有精确的落点。在 sdk/program/src/vote/state/mod.rs 中MAX_LOCKOUT_HISTORY: usize 31——最多保留的投票数量与 epoch_schedule::MINIMUM_SLOTS_PER_EPOCH 紧密耦合对应提案中因子 F 最多应用约 32 次的量级INITIAL_LOCKOUT: usize 2——对应初始锁定期N的基准值。同一文件中的Lockout结构体sdk/program/src/vote/state/mod.rs实现了核心逻辑lockout()方法返回INITIAL_LOCKOUT.pow(confirmation_count)即锁定期随确认次数confirmations按指数增长——这正是提案中锁定期按因子 F 增加的实现形态last_locked_out_slot()返回最后一次仍处于锁定的 slot验证节点不应在另一条分叉上投票小于或等于该 slot 的区块以避免其质押被削减——这与提案规则 1 直接对应confirmation_count每增加一次确认锁定期的幂次就提高一次从而让节点对同一分叉的持续投票产生越来越深的锁定承诺。投票状态机在处理投票时的校验逻辑同样印证了这些规则在 programs/vote/src/vote_state/mod.rs 中可以看到VoteError::LockoutConflict新投票状态与锁定期冲突、VoteError::RootOnDifferentFork根落在不同分叉、VoteError::SlotsMismatchslot 不匹配等错误类型这些正是投票程序在链上拒绝违规投票的闸门。也就是说即使签名服务飞地没有拦截链上投票程序也会以这些错误拒绝违反锁定/分叉规则的投票——设计提案的目标是把这道防线前移到签名环节。Ancestor Verification基于祖先投票的备选方案提案还给出了一种替代的、但确定性较弱的分叉验证方法——祖先验证Ancestor Verification验证节点维护集群中的活跃节点集合active set它观察活跃集合在最近一个投票周期内的投票它存储每个节点投票时的祖先ancestor / last_tick它将新的投票请求发送给投票签名服务请求中包含活跃集合节点先前的投票及其对应的祖先签名者检查先前的投票中是否包含该验证节点的投票并且该投票的祖先与大多数节点匹配检查成功则签署新投票检查不成功则断言触发某种警报。该方案的前提假设是验证节点最多只能被欺骗一次去投票错误的数据。如果攻击者劫持了验证节点并提交了伪造数据的投票请求该投票不会进入 PoH因为它会被集群拒绝下一次验证节点发送签名请求时签名服务会检测到验证节点上一次的投票缺失作为上述第 5 步的一部分从而发现问题。与 PoH 验证相比祖先验证不依赖飞地具备处理 PoH 的能力而是借助多数节点的祖先投票作为分叉正确性的代理信号因此在提案中被称为确定性较低的方案。Fork Determination飞地如何推断分叉归属由于飞地无法处理 PoH它对提交的验证节点投票所属分叉的历史没有直接知识。因此提案设计了如下机制每个飞地应使用当前的活跃集合active set公钥初始化验证节点应提交其当前投票同时提交它在其上一次投票所在 slot 中观察到的活跃集合的投票包括它自己通过这种方式飞地可以推断出验证节点上一次投票所伴随的投票从而推断出正在投票的分叉这对于验证节点的初始投票是不可能的因为初始投票没有前一个slot 可参考。为了弥补这一点应设置一个短暂的投票冻结期voting freeze直到提交第二个投票——该投票在初始投票的高度上包含活跃集合内的投票以及它自己的投票——之后才允许正常投票。Enclave 配置基于活跃集合与阈值的经济性护栏为了让质押客户端staking client可配置地避免在非活跃分叉上投票提案建议采用以下配置参数参数含义N_active客户端已知的活跃集合大小N_vote投票数量阈值N_depth深度阈值该机制以规则形式生效客户端只有在深度N_depth处观察到超过N_vote个投票时才会继续在提交的分叉上投票。从工程角度看这代表客户端确认它已在某个深度上观察到该提交分叉具有一定概率的经济最终性economic finality——在该深度上如果该分叉最终没有存活再投一票就会产生一段不期望时长的锁定期。换言之N_depth将锁定期代价与分叉存活概率做了量化权衡避免验证节点在可能死亡的分叉上过度投入锁定期。实现挑战与后续工作提案明确列出两大待解决的挑战在不可信空间为飞地内的 PoH 验证生成可验证数据这是 PoH 验证方案落地的核心难点——飞地无法直接处理 PoH 流必须由不可信主机生成可被飞地验证的数据摘要为临时密钥授予 stake 所需的基础设施临时每次启动重新生成的投票密钥需要被质押者授权才能代表委托的 stake 投票这一授权/委托基础设施尚未确定。结合源码现状可以看出该提案描述的是一个前移安全边界的演进方向当前链上投票程序programs/vote/src/vote_processor.rs、programs/vote/src/vote_state/mod.rs已经在交易执行层强制了LockoutConflict、RootOnDifferentFork、SlotsMismatch等违规投票校验而本提案试图把同样的策略检查下沉到硬件飞地的签名环节让私钥更安全、让违规投票在离开签名服务之前就被拦截。延伸阅读若希望进一步深入本主题可继续阅读仓库中的以下内容共识层投票签名说明验证节点、投票签名者与质押者的角色关系以及投票账户注册流程乐观确认与削减机制 与 削减机制设计理解违规投票为何会导致质押被削减投票程序状态机源码锁定期增长、投票校验与奖励分配的链上实现投票程序入口源码投票交易处理与VoteError的抛出位置投票状态与 Lockout 定义INITIAL_LOCKOUT、MAX_LOCKOUT_HISTORY等常量与Lockout结构体的精确定义votes 相关 CLI 操作验证节点投票账户的日常管理命令。【免费下载链接】solanaWeb-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.项目地址: https://gitcode.com/GitHub_Trending/so/solana创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考