> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 状态同步

> 一个从未见过这条链的节点如何到达当前版本，以及如何保持在当前版本上。

节点加入网络，得回答两个问题：怎么走到这条链现在所在的位置，走到之后又怎么待在那儿。状态同步把两个问题都回答了，而且中间的取舍摆在明面上，不藏着。

<h2 id="two-modes-of-catching-up">
  追赶的两种模式
</h2>

引导（bootstrapping）——从零走到当前版本——有两条根本不同的路子。

**重放历史**。从创世往前推，要么把每笔交易重新执行一遍，要么套用执行当年产出的输出。这样得到的节点持有完整历史：每个版本、每份证明、每笔交易。代价是慢，而且这条链每多跑一天就更慢。

**下载当前状态**。跳过历史，直接取最新版本上的状态键和值，对照已提交的根验一遍。节点花零头的时间就追上了当下，但对这条链怎么走到这一步一无所知。

<div className="dg" data-dg="state-sync">
  <div className="dg-c" style={{aspectRatio:"720 / 322"}}>
    <svg className="dg-w" viewBox="0 0 720 322" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 134.00 126.00 L 159.60 126.00" />

      <path className="dg-head dg--blue" d="M 166.00 126.00 L 159.60 130.40 L 159.60 121.60 Z" />

      <path className="dg-wire dg--sky" d="M 324.00 126.00 L 356.54 75.38" />

      <path className="dg-head dg--sky" d="M 360.00 70.00 L 360.24 77.76 L 352.84 73.00 Z" />

      <path className="dg-wire dg--yellow" d="M 324.00 126.00 L 356.54 176.62" />

      <path className="dg-head dg--yellow" d="M 360.00 182.00 L 352.84 179.00 L 360.24 174.24 Z" />

      <path className="dg-wire dg--green" d="M 568.00 70.00 L 578.66 119.74" />

      <path className="dg-head dg--green" d="M 580.00 126.00 L 574.36 120.66 L 582.96 118.82 Z" />

      <path className="dg-wire dg--green" d="M 568.00 182.00 L 578.66 132.26" />

      <path className="dg-head dg--green" d="M 580.00 126.00 L 582.96 133.18 L 574.36 131.34 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"30.4348%",width:"18.0556%",height:"17.3913%"}}><span className="dg-t">新节点</span></div>
    <div className="dg-b dg--yellow dg-round" style={{left:"23.6111%",top:"29.1925%",width:"20.8333%",height:"19.8758%"}}><span className="dg-t">引导模式</span></div>
    <div className="dg-b dg--sky" style={{left:"50.5556%",top:"6.2112%",width:"27.7778%",height:"31.0559%"}}><span className="dg-t">重放历史</span><span className="dg-s">从创世开始重新执行，或套用已存的输出</span><span className="dg-n">慢，而且这条链每多跑一天就更慢</span></div>
    <div className="dg-b dg--yellow" style={{left:"50.5556%",top:"40.9938%",width:"27.7778%",height:"31.0559%"}}><span className="dg-t">下载当前状态</span><span className="dg-s">最新版本上的键与值，对照已提交的根验证</span><span className="dg-n">花零头的时间就追上当下</span></div>
    <div className="dg-b dg--green" style={{left:"81.1111%",top:"25.4658%",width:"18.8889%",height:"27.3292%"}}><span className="dg-t">当前版本</span><span className="dg-s">此后持续同步</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"0.0000%",top:"78.2609%",width:"100.0000%",height:"18.0124%"}}><span className="dg-t">两条路并不等价</span><span className="dg-s">下载当前状态的节点提供不了历史查询，也答不出某个仓位是怎么走到今天这一步的。给索引器或审计供数据的节点，恰恰需要它跳过的那段历史。</span></div>
  </div>
</div>

重放这条路里还有一层选择——重新执行交易、套用已存的输出，或者让节点每一步自己挑快的那种。重新执行校验更强，因为它是把结果重新算出来，而不是信一份记下来的结果；套用输出则更快。混合模式之所以存在，是因为哪一种更对，要看节点落后多少。

<Note>
  这是运维决定，不是可以不假思索就接受的默认值。下载当前状态的节点提供不了历史查询，也答不出某个仓位是怎么走到今天这一步的——它手上没有历史可读。给[索引器](/zh/protocol/architecture/indexer)或审计流程供数据的节点，恰恰需要它跳过的那段历史。
</Note>

<h2 id="staying-current">
  保持在当前版本
</h2>

到了当前版本，节点靠消费陆续到达的已提交区块跟上进度——同样可以选执行交易或套用输出，验证强度和速度之间还是那套取舍。

和引导不同：这里的差距小而恒定，不像引导那样又大、又要慢慢追平。节点落后到一定程度就退回引导路径，不再逐块去补一个不知道多大的缺口。

<h2 id="how-data-moves">
  数据如何流动
</h2>

同步不是一个节点向另一个节点要一段区块。它被拆成若干层，这样没有哪个对等节点会变成依赖，也没有哪个单点故障能让进度停下来。

| 层         | 职责                            |
| --------- | ----------------------------- |
| **存储服务**  | 向其他节点提供数据：交易、输出、状态值，以及随附的证明   |
| **数据客户端** | 选择对等节点、跟踪谁有哪些数据、发送请求，并处理失败的请求 |
| **流式服务**  | 把“把我从这里带到那里”变成一条有序、经过验证的数据块流  |
| **驱动器**   | 决定节点接下来需要什么，并应用到达的内容          |

有一个推论值得记住：正在同步的节点并不信任对等节点。每个数据块到达时都带着一份证明，对的是网络已提交的根；哪个对等节点给的数据对不上，就被拒掉，而不是被相信。挑对等节点是性能决定，不是信任决定。

<h2 id="verification">
  验证
</h2>

状态同步里，没有任何东西是凭发送方是谁就被接受的。

状态值对照已提交的状态根来验，交易和输出对照累加器来验。节点引导完成时，它的状态根和验证者法定人数签下的那个一致——快速路径之所以安全，靠的就是这一点：下载当前状态跳过的是历史，不是验证。

<h2 id="where-to-go-next">
  后续阅读
</h2>

<CardGroup cols={2}>
  <Card title="存储与证明" href="/zh/protocol/architecture/state/storage">
    使同步可验证的那些结构。
  </Card>

  <Card title="运行节点" href="/zh/developers/run-a-node">
    节点角色，以及运营节点该找谁问。
  </Card>

  <Card title="网络拓扑" href="/zh/protocol/architecture/intention-bft">
    正在同步的对等节点在和哪一层节点通信。
  </Card>

  <Card title="索引器" href="/zh/protocol/architecture/indexer">
    历史能回答而当前状态无法回答的问题。
  </Card>
</CardGroup>
