> ## 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.

# IntentionBFT

> 共识：顺序与认证过的价格向量如何一并提交，以及网络是怎么布局的。

IntentionBFT 是 Intention 的共识协议——为金融基础设施做过扩展的 HotStuff 系 BFT 协议。在故障阈值以内，安全性无条件成立；活性在网络稳定之后成立。

这里的共识做了两件通用链的共识不做的事：它把**顺序**作为一等对象提交，并在同一个事件中提交一组**认证过的价格向量**。[内核](/zh/protocol/architecture/kernel)关于执行所能给出的一切保证，都依赖这两者在执行开始之前就已确定。

<h2 id="model">
  模型
</h2>

拜占庭对手最多控制总权益的三分之一，IntentionBFT 都能容忍。诚实权益因此始终超过三分之二：只要一组验证者的合计权益超过三分之二，就构成标准法定人数——本文档称之为 **$2f+1$ 权益加权法定人数**。网络是部分同步的：在稳定点之前，延迟是任意的；在稳定点之后，诚实验证者之间的延迟有界。

<div className="dg" data-dg="bft-round">
  <div className="dg-c" style={{aspectRatio:"720 / 318"}}>
    <svg className="dg-w" viewBox="0 0 720 318" aria-hidden="true">
      <path className="dg-rule dg-dash" d="M 90 40 L 90 266" />

      <path className="dg-rule dg-dash" d="M 360 40 L 360 266" />

      <path className="dg-rule dg-dash" d="M 630 40 L 630 266" />

      <path className="dg-wire dg--blue" d="M 94.00 64.00 L 349.60 64.00" />

      <path className="dg-head dg--blue" d="M 356.00 64.00 L 349.60 68.40 L 349.60 59.60 Z" />

      <path className="dg-wire dg--sky" d="M 364.00 92.00 L 414.00 92.00 L 414.00 114.00 L 374.40 114.00" />

      <path className="dg-head dg--sky" d="M 368.00 114.00 L 374.40 109.60 L 374.40 118.40 Z" />

      <path className="dg-wire dg--sky dg-dash" d="M 356.00 146.00 L 100.40 146.00" />

      <path className="dg-head dg--sky" d="M 94.00 146.00 L 100.40 141.60 L 100.40 150.40 Z" />

      <path className="dg-wire dg--blue" d="M 94.00 218.00 L 349.60 218.00" />

      <path className="dg-head dg--blue" d="M 356.00 218.00 L 349.60 222.40 L 349.60 213.60 Z" />

      <path className="dg-wire dg--green dg-dash" d="M 364.00 254.00 L 619.60 254.00" />

      <path className="dg-head dg--green" d="M 626.00 254.00 L 619.60 258.40 L 619.60 249.60 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"2.2222%",top:"0.0000%",width:"20.5556%",height:"9.4340%"}}><span className="dg-t">主节点</span></div>
    <div className="dg-b dg--sky" style={{left:"39.7222%",top:"0.0000%",width:"20.5556%",height:"9.4340%"}}><span className="dg-t">验证者</span></div>
    <div className="dg-b dg--green" style={{left:"77.2222%",top:"0.0000%",width:"20.5556%",height:"9.4340%"}}><span className="dg-t">链</span></div>
    <div className="dg-b dg-dashed dg-tight dg-solid" style={{left:"14.4444%",top:"52.2013%",width:"33.6111%",height:"8.1761%"}}><span className="dg-s">2f+1 按质押加权的聚合签名</span></div>
    <div className="dg-b dg--green" style={{left:"68.8889%",top:"86.7925%",width:"31.1111%",height:"11.9497%"}}><span className="dg-s">排序与价格自此不可更改</span></div>
    <div className="dg-lbl" style={{left:"31.2500%",top:"15.0943%",width:"34.4444%",whiteSpace:"normal"}}>提议区块 — 批次摘要与经认证的价格</div>
    <div className="dg-lbl" style={{left:"72.7778%",top:"32.3899%",width:"26.3889%",whiteSpace:"normal"}}>校验可得性、排序与价格</div>
    <div className="dg-lbl" style={{left:"31.2500%",top:"40.8805%"}}>投票</div>
    <div className="dg-lbl" style={{left:"31.2500%",top:"63.5220%"}}>认证本轮</div>
    <div className="dg-lbl" style={{left:"68.7500%",top:"74.8428%"}}>提交</div>
  </div>
</div>

每一轮都有一个指定的主节点。一轮之内，提案依次收集 $2f+1$ 的聚合签名，各阶段在相邻轮次之间流水线化，所以常规情况下，一个区块两次网络往返就达到最终性。在乐观响应性下，推进速度只受实际消息延迟约束；只有当网络处于对抗或分区状态时，pacemaker 的退避才会启动。

<h2 id="committing-an-ordering">
  提交一个顺序
</h2>

区块内的交易次序被提升成共识提交的对象，不再是执行过程的副产物。区块哈希覆盖已排序的载荷，所以共识之后再重排，提交它的那些签名就全部失效。

效果是：区块一旦最终确定，就有一个 $2f+1$ 权益加权法定人数对这个确切顺序签了名，而且同一轮里，没有哪个诚实验证者会为这批交易的另一种顺序签名。再加上按这个已提交顺序进行的串行执行，确定性重放就从一种实现惯例，变成了任何人都能核验的性质。

<Note>
  单个提案内部，主节点仍有自由裁量空间——纳入哪些可用批次、怎么排列——这是一处残留的攻击面，靠主节点声誉，以及“拿不出有效价格观测就根本出不了块”这个事实来缓解。更强的公平排序构造已在跟踪，作为未来升级的候选。
</Note>

<h2 id="batch-availability">
  批次可用性
</h2>

朴素的协议里，主节点提议的区块，载荷里装着本轮的全部交易，共识消息的大小就这样和吞吐量绑死了。IntentionBFT 把数据传播和排序拆开。

验证者在后台持续传播交易批次。每个批次会被逐一确认，直到发起方能够证明它达到了 $2f+1$ 权益加权的可用性，此后提案才可以引用它——按摘要引用，而不是按内容。吞吐量再高，共识消息都很小；已提交的区块也总是可重放，因为没有哪个区块能引用只握在拜占庭少数方手里的数据。

<h2 id="certifying-prices">
  认证价格
</h2>

验证者同时也是价格观测者，区块携带它据以执行的那组价格。

<div className="dg" data-dg="bft-prices">
  <div className="dg-c" style={{aspectRatio:"720 / 318"}}>
    <svg className="dg-w" viewBox="0 0 720 318" aria-hidden="true">
      <path className="dg-wire" d="M 163.00 78.00 L 176.60 78.00" />

      <path className="dg-head" d="M 183.00 78.00 L 176.60 82.40 L 176.60 73.60 Z" />

      <path className="dg-wire" d="M 350.00 78.00 L 363.60 78.00" />

      <path className="dg-head" d="M 370.00 78.00 L 363.60 82.40 L 363.60 73.60 Z" />

      <path className="dg-wire" d="M 537.00 78.00 L 550.60 78.00" />

      <path className="dg-head" d="M 557.00 78.00 L 550.60 82.40 L 550.60 73.60 Z" />
    </svg>

    <div className="dg-b dg--sky" style={{left:"0.0000%",top:"8.1761%",width:"22.0833%",height:"32.7044%"}}><span className="dg-t">预言机 sidecar</span><span className="dg-s">每个验证者一个</span></div>
    <div className="dg-b dg--blue" style={{left:"25.9722%",top:"8.1761%",width:"22.0833%",height:"32.7044%"}}><span className="dg-t">验证者校验并签名</span><span className="dg-s">包括按配置的阈值检查新鲜度</span></div>
    <div className="dg-b dg--blue" style={{left:"51.9444%",top:"8.1761%",width:"22.0833%",height:"32.7044%"}}><span className="dg-t">在验证者之间 gossip 扩散</span><span className="dg-s">作为一条共识网络消息</span></div>
    <div className="dg-b dg--green" style={{left:"77.9167%",top:"8.1761%",width:"22.0833%",height:"32.7044%"}}><span className="dg-t">认证价格</span><span className="dg-s">按纪元与轮次</span></div>
    <div className="dg-b dg--orange dg-left" style={{left:"0.0000%",top:"48.4277%",width:"100.0000%",height:"21.3836%"}}><span className="dg-t">价格可用性是出块的前提</span><span className="dg-s">拿得出当前轮次有效价格观测的验证者，才有资格提议区块——所以提交这些交易的签名，同时也提交了这些交易据以结算的价格。</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"75.4717%",width:"100.0000%",height:"19.4969%"}}><span className="dg-t">它并不主张什么</span><span className="dg-s">它把价格绑到了交易上，但并不能让价格变正确——共识认证的是一个法定人数的验证者在这一轮提交了这些观测值，仅此而已。</span></div>
  </div>
</div>

每个验证者都运行自己的[预言机 sidecar](/zh/protocol/architecture/oracle)，它采集各交易场所的数据，为每个品种产出一个指数价格。验证者取回这个价格，先做校验——包括按配置的阈值检查新鲜度——再签名，然后把已签名的提交作为一条共识网络消息 gossip 给其他验证者。认证价格按纪元和轮次组装，并随区块携带，因此提交这些交易的签名，同时也提交了这些交易据以结算的价格。

拿得出当前轮次有效价格观测的验证者，才有资格提议区块。所以价格可用性是出块的前提条件，不是执行时指望能找到的输入。

<Warning>
  这只是把价格绑到了交易上，并不能让价格变正确。共识认证的是“一个法定人数的验证者在这一轮提交了这些观测值”。底层交易场所准不准是另一个问题，由[预言机](/zh/protocol/architecture/oracle)页面上的聚合规则来处理，边界则由[风险披露](/zh/protocol/security/risks)界定。
</Warning>

<h2 id="leader-reputation">
  主节点声誉
</h2>

主节点按确定性的权益加权轮换逐轮选出，并叠加了一个基于滑动窗口的声誉启发式。验证者反复提案失败——要么是不可用，要么是有对抗行为——在后续选择中就会被降权，槽位转给近期响应良好的验证者。这样一来，不可用的验证者就不会占着分给它的槽位拖住进度。

由于价格观测构成提案资格的门槛，声誉机制还必须避免把主节点资格集中到行情连通性最好的那批验证者手里。一条场所多样性要求——每个品种的观测须取自多个相互独立的来源——堵住了这条路。

<h2 id="epochs-and-reconfiguration">
  纪元与重配置
</h2>

时间按纪元（epoch）组织。一个纪元之内，验证者集合和大多数参数保持不变。到了纪元边界，可以通过一次经治理授权的重配置改动：验证者集合变更、共识参数变更、风险参数更新，以及紧急动作。切换是原子的——每个诚实验证者都在同一个区块高度看到同一次切换。

<h2 id="network-topology">
  网络拓扑
</h2>

<div className="dg" data-dg="bft-topology">
  <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-soft" d="M 215.00 95.00 L 215.00 99.00" />

      <path className="dg-wire dg-soft" d="M 215.00 167.00 L 215.00 171.00" />

      <path className="dg-wire dg-soft" d="M 215.00 239.00 L 215.00 243.00" />
    </svg>

    <div className="dg-b dg--blue dg-left" style={{left:"0.0000%",top:"9.3168%",width:"59.7222%",height:"19.2547%"}}><span className="dg-t">验证者</span><span className="dg-s">共识 · 内存池 · 预言机 sidecar · 内核 · 存储</span></div>
    <div className="dg-b dg-plain dg-left" style={{left:"63.6111%",top:"9.3168%",width:"36.3889%",height:"19.2547%"}}><span className="dg-s">唯一投票的角色</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"0.0000%",top:"31.6770%",width:"59.7222%",height:"19.2547%"}}><span className="dg-t">验证者全节点</span><span className="dg-s">跟随并执行已提交区块；不投票</span></div>
    <div className="dg-b dg-plain dg-left" style={{left:"63.6111%",top:"31.6770%",width:"36.3889%",height:"19.2547%"}}><span className="dg-s">隔离——吸收公网读流量与对等连接，使验证者不直接暴露在开放互联网上</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"0.0000%",top:"54.0373%",width:"59.7222%",height:"19.2547%"}}><span className="dg-t">公共全节点</span><span className="dg-s">任何人都可以运行；跟随、执行、提供读取服务</span></div>
    <div className="dg-b dg-plain dg-left" style={{left:"63.6111%",top:"54.0373%",width:"36.3889%",height:"19.2547%"}}><span className="dg-s">开放的一层</span></div>
    <div className="dg-b dg--green dg-left" style={{left:"0.0000%",top:"76.3975%",width:"59.7222%",height:"19.2547%"}}><span className="dg-t">客户端</span><span className="dg-s">前端 · 交易智能体 · 做市商 · 索引器</span></div>
    <div className="dg-b dg-plain dg-left" style={{left:"63.6111%",top:"76.3975%",width:"36.3889%",height:"19.2547%"}}><span className="dg-s">它们连接的是全节点，不是验证者。需要最低延迟、最完整视图的客户端会自己跑一个。</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"0.0000%",width:"59.7222%"}}><div className="dg-n">四层，从共识向外</div></div>
    <div className="dg-free" style={{left:"63.6111%",top:"0.0000%",width:"36.3889%"}}><div className="dg-n">这一层为什么存在</div></div>
  </div>
</div>

**验证者**参与共识。每个验证者都跑完整的技术栈：共识、内存池、一个预言机 sidecar、内核执行和存储。它们是唯一投票的角色。

**验证者全节点**直接位于验证者之后。它们跟随并执行已提交的区块，但不投票。它们的作用是隔离——吸收公网的读流量和对等连接，使验证者不直接暴露在开放互联网上。

**公共全节点**是开放的一层。任何人都可以运行一个。它们跟随链、执行已提交的区块、提供读取服务，并为下游系统供数。

**客户端**——前端、交易智能体、做市商、索引器——连接的是全节点，而不是验证者。需要最低延迟、最完整视图的客户端，会自己跑一个全节点，而不是依赖别人的。

加入网络的节点默认不会从创世块开始重放；新节点如何追上进度，见[状态同步](/zh/protocol/architecture/state/sync)。

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

<CardGroup cols={2}>
  <Card title="内存池" href="/zh/protocol/architecture/mempool">
    什么能到达共识、以什么顺序到达，以及什么会被丢弃。
  </Card>

  <Card title="IntentionKernel" href="/zh/protocol/architecture/kernel">
    区块的顺序和价格提交之后，会发生什么。
  </Card>

  <Card title="预言机" href="/zh/protocol/architecture/oracle">
    验证者签名之前，指数价格是怎么产生的。
  </Card>

  <Card title="运行节点" href="/zh/developers/run-a-node">
    验证者集合为什么是封闭的，以及如何咨询加入事宜。
  </Card>
</CardGroup>
