Diem 状态同步器(State Synchronizer)技术规范详解:三种同步协议、网络消息格式与核心模块协作
Diem 状态同步器State Synchronizer技术规范详解三种同步协议、网络消息格式与核心模块协作【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diem导读本文以 Diem 开源仓库中的 State Synchronizer 规范文档 为主体系统讲解 Diem 节点如何通过状态同步组件将本地账本ledger同步到 Diem 支付网络的最新状态。文章将覆盖状态同步的整体流程、验证器同步Validator sync、全节点同步Full Node sync与 Waypoint 同步三种协议的技术要求、GetChunkRequest/GetChunkResponse等网络消息格式并结合 state-sync-v1 的实际 Rust 源码说明这些协议在实现层面的落地方式与关键配置参数。读完本文你将掌握 Diem 状态同步的协议设计、消息结构、验证规则与模块边界能够读懂并定位相关源码。一、组件定位与核心职责State Synchronizer状态同步器是 Diem 节点中的一个系统组件其职责是在 Diem 支付网络中的各个节点之间同步账本状态ledger state。借助状态同步节点可以发现并更新到更新的账本状态其一般流程如下节点向远端对等节点peer发送GetChunkRequest如果远端对等节点存在更新的账本状态它会返回对应的GetChunkResponse其中携带一批交易以及这些交易已由共识处理的对应证明proof请求方利用响应数据通过重新执行re-executing交易的方式推进本地账本状态。该组件解决的问题与常见分布式系统中的数据追赶场景一致节点掉线一段时间、网络分区恢复、新节点启动等情形都会导致节点账本落后于网络最新状态此时必须依靠状态同步完成追赶。从源码结构看该组件在当前仓库中的实现位于 state-sync/state-sync-v1含coordinator.rs、chunk_request.rs、chunk_response.rs、request_manager.rs、bootstrapper.rs等模块其库入口 lib.rs 中的注释点明了组件用途Used to perform catching up between nodes for committed states. Used for node restarts, network partitions, full node syncs用于在节点间对已提交状态进行追赶适用于节点重启、网络分区、全节点同步等场景。二、三类受支持的同步协议Diem 状态同步支持三种同步协议每种协议都要求组件同时具备**请求方requester与响应方responder**两种角色能力协议请求方Requester响应方Responder触发场景Validator sync验证器validator验证器验证器落后于共识状态时追赶Full Node sync全节点full node验证器或全节点全节点发现并同步到最新账本状态Waypoint sync验证器或全节点验证器或全节点节点初始化时按 waypoint 同步到指定状态验证器同步Validator sync参与者请求方为验证器响应方为验证器。一般情况下验证器通过参与共识协议获知最新账本状态但仍有可能落后——例如节点离线一段时间或发生网络分区。此时落后的验证器可以依赖状态同步追赶至最新状态。发送请求请求方发送GetChunkRequest其中target设置为TargetType::TargetLedgerInfo目标LedgerInfoWithSignatures由共识模块的sync_to请求提供即共识主动要求状态同步到某一目标账本信息。处理请求 / 发送响应响应方依据请求参数从存储模块获取一段TransactionListWithProof带证明的交易列表满足以下约束首笔交易的版本为known_version 1交易数量上限为limit这些交易属于同一个 epoch。随后响应方发送GetChunkResponse其中txn_list_with_proof设为上述交易列表response_li设为ResponseLedgerInfo::VerifiableLedgerInfo包含对应请求target中的账本信息或若这些交易属于更早的 epoch则设为该 epoch 结束时对应的带签名账本信息。接收 / 验证响应请求方执行以下验证txn_list_with_proof的起始版本 本地状态版本 1依据本地状态的可信 epoch验证ResponseLedgerInfo::VerifiableLedgerInfo中的账本信息通过执行模块的ChunkExecutor::execute_and_commit_chunk调用执行并存储这些交易。若已同步到目标状态则通知共识模块其sync_to请求已完成若尚未完成则基于新的本地状态再次按本协议发送下一个 chunk 请求如此循环直到达标。全节点同步Full Node sync参与者请求方为全节点响应方为验证器或全节点。全节点不参与共识因此只能依赖状态同步器来发现并同步到更新的账本状态。发送请求请求方发送GetChunkRequesttarget设置为TargetType::HighestAvailable。处理请求 / 发送响应响应方同样从存储模块获取满足三条约束起始版本known_version 1、上限limit笔、同属一个 epoch的TransactionListWithProof并发送GetChunkResponse其中response_li设置为ResponseLedgerInfo::ProgressiveLedgerInfo。全节点长轮询协议long-poll如果请求的目标状态在响应方处尚不可用响应方可将该请求缓存timeout_ms毫秒。若在此时间窗口内目标账本状态变为可用即响应方自身推进了账本状态则立即为该请求发送对应的 chunk 响应。接收响应请求方执行以下验证txn_list_with_proof的起始版本 本地状态版本 1依据本地状态的可信 epoch验证ResponseLedgerInfo::ProgressiveLedgerInfo中的所有账本信息通过ChunkExecutor::execute_and_commit_chunk执行并存储交易。随后基于新的本地状态继续发送下一个 chunk 请求直至追上最新状态。Waypoint 同步Waypoint sync参与者请求方与响应方均为验证器或全节点。Waypoint 同步发生在节点初始化阶段且必须在节点参与其他状态同步协议之前完成。当节点启动时可以指定一个 waypoint将本地状态同步到该 waypoint 对应的版本。发送请求请求方发送GetChunkRequesttarget设置为TargetType::Waypoint其中Waypoint携带的版本与节点初始化时提供的 waypoint 版本一致。处理请求 / 发送响应响应方依据请求参数从存储模块获取满足约束起始版本known_version 1、上限limit笔、同属一个 epoch的TransactionListWithProof并发送GetChunkResponse其中response_li设置为ResponseLedgerInfo::LedgerInfoForWaypoint。接收响应请求方执行以下验证依据节点初始化时提供的 waypoint验证waypoint_litxn_list_with_proof的起始版本 本地状态版本 1通过ChunkExecutor::execute_and_commit_chunk执行并存储交易。若处理完该响应后尚未同步到 waypoint 对应版本则基于更新后的账本状态按本协议继续发送下一个 chunk 请求。三、网络协议线上消息格式本节说明状态同步器在网络上传输的消息的技术细节。实际实现中所有消息被封装为StateSyncMessage枚举仅含GetChunkRequest与GetChunkResponse两个变体定义见 network.rs并通过 DiemNet 网络栈传输StateSyncEvents/StateSyncSender分别是网络到状态同步、状态同步到网络的封装接口。GetChunkRequest 请求结构struct GetChunkRequest { known_version: u64, current_epoch: u64, limit: u64, target: TargetType }字段说明known_version——请求方最新账本状态的版本号。current_epoch——请求方最新账本状态所处的 epoch。若请求方的状态已推进到 epochx的末尾则下一次请求的current_epoch应为x 1。limit——请求的交易数量chunk 大小。target——本次请求的同步目标见下节TargetType。仓库中的实际实现与规范一致见 chunk_request.rs并额外提供了new构造方法与Display实现便于日志输出请求的 known version、epoch、limit 与 target。TargetType 同步目标类型TargetType表示一次GetChunkRequest的同步目标其中携带的所有LedgerInfoWithSignatures都用于证明请求方想要同步到的账本状态enum TargetType { TargetLedgerInfo(LedgerInfoWithSignatures), HighestAvailable { target_li: OptionLedgerInfoWithSignatures, timeout_ms: u64, }, Waypoint(Version), }子类型说明TargetLedgerInfo——LedgerInfoWithSignatures表示请求方请求同步到的目标账本状态用于验证器同步场景。HighestAvailabletarget_li——若无已知的带签名账本信息可作为目标则设为None通常在全节点首次发送 chunk 请求时设为None否则携带一个目标账本信息。timeout_ms——请求方发送携带该目标类型的 chunk 请求后、在发送下一个 chunk 请求之前等待的时间间隔。Waypoint(Version)——对指定版本的同步请求该版本与节点初始化时提供的 waypoint 版本一致。从源码注释chunk_request.rs可以补充更深入的设计动机TargetLedgerInfo已标记为 DEPRECATED源码注释指出该类型仅为了向后兼容而保留状态同步已避免发送此类请求而改用HighestAvailable并计划在下一个破坏性版本中移除对应 issue 编号为 8013。因此读者阅读旧文档或旧版本代码时可能看到该类型但新实现已迁移。HighestAvailable的target_li语义它支持同步请求方落后于响应方太多的场景。如果响应方的最新账本信息版本持续前进即便同步请求方持续收到并同步交易这些交易也可能永远得不到账本信息LedgerInfo背书——因为账本信息只有在覆盖到其版本的全部交易收到之后才能提交而交易必须得到账本信息背书才能在存储查询时显示为已提交。为避免同步追赶期间交易永远得不到账本信息背书或同步请求方已同步版本与被提交账本信息版本的差距不断增大该目标类型可以同时做到(1) 询问最高可用账本信息(2) 指定一个目标账本信息用于构建请求的交易证明。通过 (1)同步请求方可以在同步到较早的目标账本信息之后存储该账本信息以便后续做目标同步。若target_li未指定响应方将基于其最高账本信息构建响应。TargetType还提供了epoch()与version()辅助方法chunk_request.rs前者提取目标账本信息所属 epochWaypoint返回None后者提取目标版本。GetChunkResponse 响应结构GetChunkResponse是对应GetChunkRequest的网络响应消息。响应中包含的交易 chunk 全部属于对应请求known_epoch即请求中的current_epoch指定的 epoch永远不会跨越 epoch 边界struct GetChunkResponse { response_li: ResponseLedgerInfo, txn_list_with_proof: TransactionListWithProof, }字段说明response_li——响应中的所有证明都相对于该账本信息构建账本信息验证的具体方式取决于其类型见下节ResponseLedgerInfo。txn_list_with_proof——与响应携带的账本信息对应的交易 chunk 及其证明。实际实现见 chunk_response.rs源码注释同样强调The returned chunk is bounded by the end of the known_epoch of the requester (i.e., a chunk never crosses epoch boundaries).返回的 chunk 以请求方 known_epoch 的末尾为界即 chunk 绝不跨越 epoch 边界。Display实现会输出响应账本信息类型以及交易覆盖的版本区间如versions [first - last]。ResponseLedgerInfo 响应账本信息enum ResponseLedgerInfo { VerifiableLedgerInfo(LedgerInfoWithSignatures), ProgressiveLedgerInfo { target_li: LedgerInfoWithSignatures, highest_li: OptionLedgerInfoWithSignatures, }, LedgerInfoForWaypoint { waypoint_li: LedgerInfoWithSignatures, end_of_epoch_li: OptionLedgerInfoWithSignatures, } }子类型说明VerifiableLedgerInfo——包含可用于验证响应中txn_list_with_proof的带签名账本信息。与TargetLedgerInfo类似源码注释也标记其为 DEPRECATED仅为向后兼容保留由ProgressiveLedgerInfo取代。ProgressiveLedgerInfotarget_li——用于验证响应中txn_list_with_proof的带签名账本信息highest_li——若响应方本地状态中存在不同于target_li的更高账本信息则设为此最高账本信息否则为None。LedgerInfoForWaypointwaypoint_li——对应请求TargetType::Waypoint指定版本处账本状态的带签名账本信息end_of_epoch_li——可选若txn_list_with_proof中的交易 chunk 终止于某个 epoch 边界则为该 epoch 结束对应的带签名账本信息否则为None。ResponseLedgerInfo提供version()方法chunk_response.rs返回证明所相对构建的账本信息版本三种类型分别取li.ledger_info().version()、target_li的版本、waypoint_li的版本。四、源码级实现协调器与长轮询机制规范描述的是应当如何而 state-sync-v1 给出了实际如何的实现。核心是StateSyncCoordinator见 coordinator.rs其start()函数运行一个无限事件循环根据外部与内部本地请求触发动作。源码注释明确描述了两种工作模式全节点模式FullNode向预定义的静态对等节点持续发送无限流式 chunk 请求若父节点在其已提交版本于超时窗口内变高则会返回 chunk 响应验证器模式Validator按需为特定目标账本信息生成 chunk 请求以同步到该目标。事件循环coordinator.rs通过futures::select!同时监听四类事件源共识通知consensus_listener处理ConsensusNotification::SyncToTarget即共识发起的sync_to请求对应验证器同步协议与ConsensusNotification::NotifyCommit共识提交通知状态同步需要把提交结果转发给 mempool 并维护自身状态客户端消息client_events处理GetSyncState查询同步状态与WaitForInitialization等待初始化完成即 waypoint 同步完成网络事件network_events处理NewPeer/LostPeer对等节点上线/下线动态启用或禁用请求管理器中的对等节点以及Event::Message收到远端发来的GetChunkRequest/GetChunkResponse交由process_chunk_message处理定时器interval以tick_interval_ms为周期调用check_progress()检查同步进度超时未进展则触发重试或广播。长轮询long-poll在实现层面体现为协调器维护的一张订阅表subscriptions: HashMapPeerNetworkId, PendingRequestInfocoordinator.rsPendingRequestInfo记录了每个挂起请求的过期时间、已知版本、请求 epoch、目标账本信息与 chunk 上限。当响应方收到一个HighestAvailable请求而目标状态尚未可用时会把该请求登记为订阅并在到期前一旦有新信息可用就主动通知对方——这与规范中缓存响应timeout_ms的描述完全对应。请求重试与多播策略由RequestManagerrequest_manager.rs负责协调器构造时依据节点角色计算重试超时coordinator.rs——全节点为tick_interval_ms long_poll_timeout_ms验证器为tick_interval_ms * 2——并传入多播超时multicast_timeout_ms若在限定时间内向一定数量的网络发送 chunk 请求仍无进展下一次同步请求将多播发送到更多网络。五、配置参数StateSyncConfig状态同步行为可通过节点配置中的state_sync节调整配置结构体StateSyncConfig定义于 state_sync_config.rs各项默认值如下参数默认值含义chunk_limit1000每次状态同步请求的 chunk 大小请求的交易笔数上限client_commit_timeout_ms5_000状态同步客户端处理一次提交通知的超时毫秒long_poll_timeout_ms10_000远端对等节点长轮询的默认超时毫秒max_chunk_limit1000合法 chunk 上限用于健全性检查拒绝异常请求max_timeout_ms120_000合法超时上限用于健全性检查mempool_commit_timeout_ms5_000协调器等待 mempool 提交确认ack的超时毫秒multicast_timeout_ms30_000状态同步默认多播超时若向一定数量网络发送请求仍无进展下一次请求将多播到更多网络sync_request_timeout_ms60_000处理同步请求时确保其有进展的超时即两次提交之间的最大间隔tick_interval_ms100检查状态同步进度的周期毫秒即协调器主循环的 tick 间隔这些参数直接驱动上一节的协调器行为tick_interval_ms控制interval定时器、long_poll_timeout_ms控制长轮询等待窗口、chunk_limit对应GetChunkRequest的limit字段、multicast_timeout_ms控制请求的多播策略。理解这些默认值有助于在部署验证器或全节点时合理调优同步行为。六、抽象模块接口状态同步器的协作边界状态同步器不是孤岛它需要与多个外部模块交互。规范将交互关系抽象为如下模块其中标注示例接口非严格必需的部分仅用于说明协作方式实现细节由各实现方自定。Network 网络状态同步器与网络模块交互向网络中的对等节点发送网络协议中定义的消息。规范给出的示例接口/// Sends message to recipient fn send_to(recipient: PeerId, message: StateSyncMessage)实际实现中网络侧通过StateSyncEvents网络事件流与StateSyncSender发送封装与状态同步层对接二者均为NetworkEvents/NetworkSender的薄封装见 network.rsStateSyncSender可克隆、可发送到独立异步任务。Consensus 共识状态同步器处理共识的StateComputer::sync_to调用通过执行验证器同步协议完成并在账本状态达到共识请求中账本信息指定的版本后通知共识。该交互的协调与实现属于实现细节仓库中的对应物是consensus_notificationscrate 提供的ConsensusSyncNotification与ConsensusNotificationListener见 coordinator.rs。Mempool 交易池状态同步器在处理 chunk 响应时会通知 mempool 哪些交易已成功执行并提交使 mempool 能清除这些交易。仓库中对应mempool_notifications::MempoolNotificationSender接口见 coordinator.rs协调器结构体持有mempool_notifier字段并配置了mempool_commit_timeout_ms超时。Execution 执行状态同步器使用执行模块的ChunkExecutor接口来执行并存储交易。该接口在 executor-types/src/lib.rs 中定义实际实现在 executor/src/lib.rs 的ExecutorV::execute_and_commit_chunk其流程为重置执行器缓存以与最新已同步状态保持一致验证输入交易列表verify_chunk依据已独立验证的目标账本信息验证证明执行交易并提交。源码签名executor/src/lib.rs为fn execute_and_commit_chunk( self, txn_list_with_proof: TransactionListWithProof, // 已独立验证的目标 LI证明相对于该版本构建 verified_target_li: LedgerInfoWithSignatures, // 可选的 epoch 结束账本信息不允许携带 epoch 变更 LI 的 chunk 直接结束 epoch epoch_change_li: OptionLedgerInfoWithSignatures, ) - ResultVecContractEventStorage 存储状态同步器与存储模块交互以TransactionListWithProof形式获取一段交易及其对应证明。规范给出的示例接口/// Returns a batch of transactions starting at known_version with /// max size limit with proofs built against target_version fn get_chunk( self, known_version: u64, limit: u64, target_version: u64, ) - ResultTransactionListWithProof七、总结Diem 状态同步器是连接共识、网络、执行与存储的关键枢纽它让落后的验证器能够追赶共识进度Validator sync、让全节点能够持续跟踪网络最新状态Full Node sync、让新启动的节点能够按 waypoint 完成初始化Waypoint sync。三套协议的骨架高度一致——请求方发送携带目标类型的GetChunkRequest响应方返回不跨 epoch 边界的交易 chunk 与证明请求方验证并重新执行交易——区别主要在于目标类型TargetLedgerInfo/HighestAvailable/Waypoint与响应账本信息类型VerifiableLedgerInfo/ProgressiveLedgerInfo/LedgerInfoForWaypoint的选择以及长轮询等配套机制。若需继续深入建议按以下路径阅读仓库源码协议消息定义chunk_request.rs、chunk_response.rs同步主流程coordinator.rs、request_manager.rs网络封装network.rs执行接口executor-types/src/lib.rs、executor/src/lib.rs配置项state_sync_config.rs。此外仓库中state-sync/state-sync-v1/tests目录下包含状态同步的测试用例可用于观察各协议在具体场景下的预期行为。【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考