ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Aptos 共识管道(Pipeline):基于 Zaptos 优化的区块低延迟处理架构全解析

Aptos 共识管道(Pipeline):基于 Zaptos 优化的区块低延迟处理架构全解析 Aptos 共识管道Pipeline基于 Zaptos 优化的区块低延迟处理架构全解析【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-coreAptos Core 的共识管道Pipeline把区块排序、执行、认证、持久化四个阶段解耦成可并行推进的异步任务图让网络、CPU 与 IO 资源同时保持忙碌并借助 Zaptos 三项优化乐观执行、预提交、提前认证把执行、认证、落盘全部隐藏进共识延迟之内。本文基于consensus/src/pipeline/README.md展开结合 pipeline_builder.rs、buffer_manager.rs 等源码实现带你完整理解这条端到端延迟 ≈ 共识延迟的区块处理链路以及如何定位和验证其中的关键行为。一、为什么需要管道四个阶段的资源画像一笔交易在 Aptos 中要经历四个主要阶段各自的瓶颈资源完全不同引自 consensus/src/pipeline/README.mdConsensus共识—— 将交易排序进区块网络受限network-boundExecution执行—— 通过 Block-STM 并行执行区块内的交易CPU 受限CPU-boundCertification认证—— 验证节点对执行结果签名并聚合签名网络受限network-boundCommit提交—— 将已认证的区块持久化到存储IO 受限IO-bound。正因为四类阶段瓶颈各异把它们串行执行会让大量资源空转。管道化pipelining的核心思想就是让不同区块在不同阶段并行推进。1.1 基线管道Baseline Pipeline基线 Aptos 管道让相邻区块的阶段在时间轴上重叠任意时刻区块 i 正在排序、区块 i-1 正在执行、区块 i-2 正在认证、区块 i-3 正在提交Time ──────────────────────────────────────────────────────────────────────────────► Block N: [ Consensus ][ Execution ][ Certification ][ Commit ] Block N1: [ Consensus ][ Execution ][ Certification ][ Commit ] Block N2: [ Consensus ][ Execution ][ Cert.. ][ Commit ]这样 CPU、网络与 IO 可以同时保持忙碌获得高吞吐。但它仍是排完才执行的模型端到端延迟至少要叠加执行、认证、提交三段耗时。1.2 Zaptos 优化把后三个阶段影子化进共识延迟Zaptos 的三项优化让执行execution、认证certification、提交commit在共识完成排序之前就已经做完——也就是说当一个区块被排序ordered时它往往已经执行、认证并持久化完毕propose vote order vote ordered │ │ │ │ ▼ ▼ ▼ ▼ Consensus: [──────────────┼────────────┼───────────────] │ │ │ │ Execution: │ [] │ opt. execution (starts on vote) │ │ │ │ Commit: │ │ [] │ opt. commit (pre-commit) │ │ │ │ Certify: │ │ [] early certification │ │ │ │ │ │ │ all 3 done │ │ │ │ by ordered │三项优化分别是1. 乐观执行Optimistic Execution—— 验证节点一收到区块提案proposal立即开始执行而不是等共识排序完成。执行与剩余的投票轮次并行推进。2. 乐观提交Pre-Commit—— 执行完成后新状态立即写入存储不必等认证结束。该状态被标记为OptCommitted待认证完成后提升为Committed如果区块最终未被排序乐观提交的状态会被回滚。3. 提前认证Early Certification—— 如果执行已经完成验证节点在发送 order vote 的同时广播自己的认证投票commit vote从而把认证与共识的最后一轮重叠等效于省掉一轮延迟。最终效果区块链端到端延迟 ≈ 共识延迟执行、认证、提交都被隐藏在其内部。二、实现核心PipelineBuilder 的异步任务图README 明确指出PipelineBuilder为每个区块构建一张异步 future 的依赖图graph of async futures。每个阶段是一个独立 spawn 的任务先 await 自己的依赖再执行。依赖分两类块内依赖Intra-block—— 同区块的后续阶段等待前序阶段如 execute 等待 prepare跨块依赖Inter-block—— 每个阶段同时等待父区块的同名阶段如区块 N1 的 execute 等待区块 N 的 execute以此保证状态转换严格顺序进行同时允许不同阶段跨区块重叠。在 pipeline_builder.rs 中PipelineBuilder持有执行所需的全部组件BlockPreparer区块物化/准备、BlockExecutorTrait执行器、ValidatorSigner签名、TxnNotifier失败交易通知、ConsensusNotificationSender状态同步通知、TPayloadManager区块负载管理以及NetworkSender网络广播。build_internalpipeline_builder.rs#L510-L733展示了任务图的构建过程每个阶段通过spawn_shared_fut生成一个可共享、可 abort 的 future并显式把依赖的 future 传进去。源码注释里给出了当前管道完整依赖关系pipeline_builder.rs#L130-L142External inputs (via PipelineInputTx channels): qc, rand, order_vote, order_proof, commit_proof, secret_shared_key Critical path: qc - materialize - decrypt - prepare - has_rand_txns - rand_check - execute - ledger_update - pre_commit - commit_ledger Side/parallel paths: decrypt secret_shared_key - (internal: produces secret_sharing_derive_self) has_rand_txns rand - rand_check parent observer_publish decrypt order_proof - observer_publish prepare ledger_update - post_ledger_update ledger_update order_vote order_proof commit_proof - commit_vote ledger_update order_proof - pre_commit pre_commit commit_proof - commit_ledger pre_commit commit_ledger - notify_state_sync pre_commit order_proof commit_ledger notify_state_sync - post_commit所有阶段的输出 future 汇总在PipelineFutures结构体中pipelined_block.rs#L143-L159字段包括decryption_fut、prepare_fut、has_rand_txns_fut、rand_check_fut、execute_fut、ledger_update_fut、observer_publish_fut、post_ledger_update_fut、commit_vote_fut、pre_commit_fut、notify_state_sync_fut、commit_ledger_fut、post_commit_fut、secret_sharing_derive_self_fut。每个 future 的结果类型PrepareResult、RandResult、ExecuteResult、LedgerUpdateResult等也定义在同一文件pipelined_block.rs#L125-L141例如ExecuteResult Duration记录执行耗时供背压使用、LedgerUpdateResult (StateComputeResult, Duration, Optionu64)。此外每个阶段任务内部都有一个Trackerpipeline_builder.rs#L202-L271负责记录每个阶段等待时间与工作时长通过counters::PIPELINE_TRACING指标暴露出去——这是排查管道某阶段卡在哪里的直接抓手。三、逐阶段拆解每区块的 13 个管道阶段README 的Per-Block Pipeline Stages表是理解整条链路的索引完整继承如下等待对象与职责说明均来自 consensus/src/pipeline/README.md阶段等待对象Waits for做什么What it doesMaterialize区块的 QC 到达物化负载从 QuorumStore 拉取批次DecryptMaterialize、secret_shared_key_rx用门限解密密钥解密加密交易PrepareDecrypt准备区块进入执行、校验交易签名Rand Txns CheckPrepare、父区块 Execute扫描交易中的随机数注解Wait for RandRand Txns Check、rand_rx若区块需要随机数则等待随机值否则空操作ExecutePrepare、Wait for Rand、父区块 Execute运行 Block-STM 并行执行Ledger UpdateExecute、父区块 Ledger Update由执行输出生成StateComputeResultCommit VoteLedger Update、order vote/proof/commit proof 之一对执行结果签名并广播CommitVotePre-CommitLedger Update、父区块 Pre-Commit、order proof排序后、commit proof 前写入存储Commit LedgerPre-Commit、commit proof、父区块 Commit定稿已提交状态——数据从此对客户端可见Observer Publish父区块 Observer Publish、Decrypt、order_proof向共识观察者发布已排序区块仅验证节点Post Ledger UpdateLedger Update通知 mempool 失败交易不在关键路径上Notify State SyncPre-Commit、Commit Ledger通知状态同步器已提交交易Post CommitCommit Ledger、父区块 Post Commit更新计数器、通知 block store几个可以结合源码进一步确认的细节Prepare 阶段的签名校验使用一个专用 16 线程 rayon 线程池SIG_VERIFY_POOLpipeline_builder.rs#L71-L79通过into_par_iter()并行校验全部交易签名耗时计入PREPARE_BLOCK_SIG_VERIFICATION_TIME指标Materialize 阶段会重试materialize_block失败时 sleep 100ms 后重试pipeline_builder.rs#L737-L770因为 QuorumStore 中的批次可能尚未齐备根区块epoch 起点通过build_rootpipeline_builder.rs#L382-L453构建所有阶段直接以已就绪的 future 播种spawn_ready_fut其 commit vote 用本地签名者对既有 commit proof 直接签名作为整条跨块依赖链的起点。3.1 Zaptos 优化如何映射到具体阶段乐观执行Materialize 只依赖区块的 QC通过qc_rx接收而 QC 的到达时机正是验证节点投票时——早于区块被排序。因此 Prepare、Execute、Ledger Update 立即推进与共识剩余轮次重叠。提前认证Commit Vote 阶段等待 Ledger Update 完成且等待 order voteorder_vote_rx、order proof、commit proof 三者中的任意一个。当 order votes 启用且执行已完成时commit vote 在本节点发出 order vote 的同时就广播出去认证与最后一轮共识重叠。预提交生产环境下Pre-Commit 等待order proof而非 commit proof 才写入存储——这意味着写入发生在排序之后、完整 commit proof 之前避免了回滚乐观提交状态的开销。对于 epoch 结束区块或预提交被暂停如状态同步期间见PreCommitStatus时则额外等待 commit proof。PreCommitStatuspipeline_builder.rs#L81-L119持有round可预提交的最大轮次、paused、is_enabled三个字段正是 README 中提到的把sync_manager与管道连起来、在状态同步期间暂停预提交的那套机制对应提交413db84eeb引入的pre_commit_status。四、随机数路径为什么含随机数交易的区块无法享受 Zaptos 优化当链上随机数启用时随机数检查被拆成两个独立 future源码在 pipeline_builder.rs#L816-L927Rand Txns Checkhas_rand_txns_fut——在 Prepare 与父区块 Execute 完成后扫描区块内交易。实现上它遍历签名用户交易对EntryFunction类型交易通过CachedModuleView读取模块元数据调用get_randomness_annotation_for_entry_function判断是否带随机数注解pipeline_builder.rs#L838-L891。从源码结构看这里还处理了两种降级场景随机数功能整体禁用时直接返回falserand_check_enabled未开启如滚动部署期间时保守地返回true保证随机数聚合始终运行Wait for Randrand_check_fut——若区块需要随机数则等待rand_rx送达随机值该值依赖共识驱动的随机数聚合若不需要则是空操作。关键结论只要任一交易需要随机数执行就无法乐观化——它必须等待随机值从而阻塞 Execute 阶段使该区块的 Zaptos 延迟优化失效。这是使用randomness注解的交易付出的延迟代价。五、管道输入信号PipelineInputTx 通道每个区块通过PipelineInputTx通道接收外部信号。其完整定义在 pipelined_block.rs#L175-L193比 README 列出的信号多了一个观察者专用通道通道Tx对应接收端用途qc_txqc_rx本区块的 QC触发 materializerand_txrand_rx随机值区块需要随机数时order_vote_txorder_vote_rx本区块的 order vote 已发出order_proof_txorder_proof_fut包含本区块的一组已排序区块与 order proofWrappedLedgerInfoordered_blocks_for_observer_txordered_blocks_for_observer_fut待发布给观察者的已排序区块集合commit_proof_txcommit_proof_fut本区块的 commit proofLedgerInfoWithSignaturessecret_shared_key_txsecret_shared_key_rx门限解密密钥启用加密交易时从实现看pipeline_builder.rs#L328-L380这些通道全部是tokio::sync::oneshot一次性通道order_proof、commit_proof、观察者通道在构建时被包成共享 future取消时转为TaskError其余直接作为 oneshot receiver 被各阶段 await。PipelineFutures::wait_until_finishespipelined_block.rs#L161-L173则并行等待与执行器/状态同步相关的关键 future供清理路径使用。六、BufferManager有序区块缓冲区与提交投票聚合BufferManager是管道的中央编排器接收共识送来的有序区块、把它们喂给PipelineBuilder构建的 future 图、处理网络上到达的提交消息。其主循环结构在 mod.rs 顶部的架构图也有体现Ordered Blocks → Buffer Manager →Execution / Signing / Network / Persisting 各阶段并由 Ordering State Computer 通过 Sync Req 向它请求状态同步。6.1 BufferItem 的四种状态BufferItem是一个带状态迁移的枚举buffer_item.rs#L140-L145底层存储结构为buffer.rs中基于哈希的有序链式缓冲区状态含义Ordered从共识收到管道 future 已创建Executed执行完成开始收集 commit votesSigned本节点的 commit vote 已广播正在聚合签名Aggregated已收集 2f1 个 commit votes可持久化状态迁移由advance_to_executed_or_aggregated等方法驱动buffer_item.rs#L170 起执行完成后若本地已缓存足够多其他节点的未验证投票unverified_votes即先于执行到达的投票可直接越过中间态进入Aggregated。6.2 提交投票聚合与提前到达投票的缓存Commit votes 可能先于区块执行完成就到达例如其他验证节点执行得更快。BufferManager会把这些投票作为 pending votes 缓存待区块进入相应状态后再应用。一个完整的CommitDecision2f1 签名即 commit proof则可以把区块直接快进到 Aggregated 状态。6.3 可靠广播Reliable Broadcast参数Commit votes 走可靠广播通道README 给出的参数为指数退避起始 2ms上限 5 秒广播间隔1500ms —— 与源码常量COMMIT_VOTE_BROADCAST_INTERVAL_MS 1500buffer_manager.rs#L62一致过期投票重广播每 30 秒一次 —— 与 buffer_manager.rs#L863 处 Well try to re-initiate the broadcast after 30s 的注释一致追踪所有验证节点的 ACK全部响应后完成。可靠广播的具体重试逻辑实现于 commit_reliable_broadcast.rs。6.4 两级背压机制第一级BufferManager 的区块入口背压。当最新有序轮次与最高已提交轮次之差超过MAX_BACKLOG20 轮时BufferManager停止接收新的有序区块。源码中该阈值为常量const MAX_BACKLOG: Round 20;buffer_manager.rs#L925判断逻辑是self.back_pressure_enabled self.highest_committed_round MAX_BACKLOG self.latest_round并作为tokio::select!的守卫背压生效时block_rx.next()分支被禁用共识送来的区块排队等待直到提交追上。README 同时交代了这段机制的历史它最初是为防止状态同步拿到比预提交版本更旧的 ledger info 而引入的——若缓冲区无限增长pre-commit 会远远跑到 commit root 前面状态同步触发时会与已预提交状态冲突。该根因后来通过pre_commit_status把sync_manager与管道连接起来修复预提交可被暂停背压保留下来作为缓冲区大小的通用安全边界。第二级ProposalGenerator 的提案瘦身。ProposalGenerator用两个信号对提案施加更细粒度的背压管道积压延迟Pipeline pending latency度量最老未执行区块被排序以来的耗时超过配置阈值时降低max_sending_block_txns_after_filtering、max_sending_block_bytes并在提案前增加backpressure_proposal_delay_ms的延迟从而拖慢共识让管道排水执行耗时观察最近若干区块的执行时间观察窗口由num_blocks_to_look_at配置默认 30执行变慢时降低新区块的交易日数与 gas 上限产出更小、执行更快的区块。两个信号取所有背压来源的最小值即最严格的限制生效。相关配置项均可在 config/src/config/consensus_config.rs 中找到max_sending_block_txns_after_filteringL36、num_blocks_to_look_atL143Default为 30、各档背压配置里的max_sending_block_txns_after_filtering_override与backpressure_proposal_delay_msL295-L373 展示了从 1000/25ms 到 5/150ms 的多档递减配置。6.5 重置与状态同步重置通过ResetRequest触发有两个变体TargetRound(round)—— 由sync_to_target在节点落后需要状态同步时发出。把highest_committed_round与latest_round更新为目标值并排空该轮次之前的 pending commit proofsStop—— 由end_epoch在 epoch 边界发出。置位停止标志在清理完成后终止BufferManager主循环。两个变体随后执行相同的六步清理序列等待 pending 提交——pending_commit_blocks中已聚合并移交提交的区块等待完成它们没有剩余依赖强行中止会在 epoch 边界引发错误中止缓冲区块—— 缓冲区其余 item 的管道 future 经abort_pipeline()中止并等待结束对应的AbortHandle列表在build_internal中收集清空缓冲状态—— 用全新空缓冲替换并清空execution_root、signing_root、commit_proof_rb_handle排空入站区块队列——block_rx中未处理的区块被弹出并中止其管道 future等待在途任务—— 轮询ongoing_tasks计数器归零确保所有 spawn 任务结束发送 ack—— 向调用方状态同步或 epoch manager发送ResetAck调用方在此处阻塞。重置顺序是先 rand manager再 secret share manager最后 buffer manager每步等待 ack 后才进行下一步。对TargetRound状态同步所有 manager 重置完毕后execution proxy 执行到目标 ledger info 的实际状态同步对Stopepoch 结束所有 manager 停止后调用 execution proxy 的end_epoch。6.6 管道消息类型消息用途发送方 → 接收方CommitVote验证节点对执行结果的签名验证节点 → 全部验证节点CommitDecision2f1 个 commit vote 签名commit proof任一验证节点 → 全部验证节点七、关键文件导航README 的Key Files清单完整保留如下并给出仓库内路径方便逐文件深入文件职责pipeline_builder.rs构建逐区块的 future 图Zaptos 管道——从 materialize 到 post-commitbuffer_manager.rs中央编排器——有序缓冲区、commit vote 聚合、可靠广播buffer_item.rs带状态迁移Ordered → Executed → Signed → Aggregated的 BufferItem 枚举buffer.rs基于哈希的有序链式缓冲区数据结构commit_reliable_broadcast.rscommit votes 的带重试可靠广播execution_schedule_phase.rs向执行器发送区块、创建 futureexecution_wait_phase.rs等待执行 future 完成signing_phase.rs通过 safety rules 对 commit ledger info 签名persisting_phase.rs将已提交状态定稿到 ledger DBpipeline_phase.rsStatelessPipelinetrait 与任务计数execution_client.rsExecutionClient接口与BufferManagerHandledecoupled_execution_utils.rs各阶段之间的通道接线errors.rs管道错误类型目录中还有两个 README 未单列但直接相关的文件decryption_pipeline_builder.rs加密交易开启时接管管道构建与 execution_phase.rsmod.rs 汇总导出各模块tests/目录则放置管道集成测试。八、测试与验证README 给出的管道测试入口为cargo test -p aptos-consensus -- pipeline该命令会执行aptos-consensuscrate 中所有名称匹配pipeline的测试测试主体位于 consensus/src/pipeline/tests/ 目录。结合本文的理解框架验证管道改动时可以关注三条证据链阶段依赖是否符合第三节的等待表、Tracker打出的 wait/work 时间指标PIPELINE_TRACING是否符合预期以及BufferItem状态迁移是否仍满足 2f1 聚合语义。九、小结Aptos 共识管道的设计可以归纳为一句话用一张块内串行、跨块并行的 async future 依赖图把执行、认证、提交三个后处理阶段全部塞进共识排序的延迟窗口。理解它的关键抓手有三一是PipelineBuilder的两类依赖块内/跨块如何决定阶段重叠程度二是PipelineInputTx的七个 oneshot 信号如何把共识事件注入任务图三是BufferManager的四级状态机、可靠广播参数与两级背压如何保证乐观操作在乱序、落后、状态同步等异常场景下依然安全。掌握这三点再对照cargo test -p aptos-consensus -- pipeline的测试输出就能把这篇 README 的每个论断落到可验证的代码事实上。【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表