教程区块链区块链技术ch066.7 网络升级与协议版本协商

本页目录

一条区块链网络由成千上万个独立节点组成,它们运行的软件版本各不相同。如何让这些异构节点相互识别能力、协商共同支持的协议版本,并在不分裂网络的前提下完成升级,是长期可演化性的核心议题。


6.7.1 版本握手:version/verack 与 Hello

当两个节点建立 TCP 连接后,第一件事是协议握手——不是传输区块,而是交换"我是谁、我能做什么"。

比特币的 version/verack 握手

发起方(Outbound)先发送 version 消息,接收方回复 verack,随后发起方也回复 verack。两次交叉的 version/verack 构成握手完成:

sequenceDiagram
    participant A as 节点A(发起方)
    participant B as 节点B(接收方)
    A->>B: TCP 连接建立
    A->>B: version (v=70015, services=13, height=876543)
    B->>A: verack
    Note over A,B: A 开始监听 B 的消息
    B->>A: version (v=70015, services=13, height=876510)
    A->>B: verack
    Note over A,B: 双向握手完成
    A->>B: getaddr / addr 交换对等地址

version 消息核心字段

字段类型说明
versionint32协议版本号(当前主流 70016)
servicesuint64服务位掩码
timestampint64Unix 时间戳(用于时间同步)
addr_recvnet_addr对方网络地址
addr_fromnet_addr自身网络地址
nonceuint6464 位随机数(防止自连接循环)
start_heightint32本地区块高度
relaybool是否接收交易广播

以太坊的 Hello + Status 握手

以太坊采用更现代的两消息设计:

  1. Hello:协议版本、客户端标识、监听端口、Capabilities 列表(如 eth/68, snap/1);
  2. Status:创世哈希、最新区块头哈希、区块总难度(TD)。

随后通过 Ping/Pong 心跳维持连接活性。


6.7.2 服务位与能力协商

比特币的 services 字段是一个位掩码(bitmask),每个比特位代表一项能力:

位值名称说明
1NODE_NETWORK可提供完整区块链数据
2NODE_BLOOM支持 Bloom Filter 查询
4NODE_WITNESS支持 SegWit 隔离见证
64NODE_COMPACT_FILTERS支持 Golomb 编码过滤器
1024NODE_NETWORK_LIMITED仅提供近期区块数据(pruned 节点)

能力协商通过按位与完成:

shared=servicesA & servicesB\text{shared} = \text{services}_A \ \& \ \text{services}_B
ts
// version-handshake-sim.ts
// 纯内置:模拟版本/服务位握手与服务发现

const NODE_NONE = 0;
const NODE_NETWORK = 1 << 0;
const NODE_BLOOM = 1 << 1;
const NODE_WITNESS = 1 << 2;
const NODE_COMPACT_FILTERS = 1 << 6;

function hasService(services: number, flag: number): boolean {
  return (services & flag) === flag;
}

function intersectServices(a: number, b: number): string[] {
  const shared = a & b;
  const names: Record<number, string> = {
    [NODE_NETWORK]: 'NETWORK',
    [NODE_BLOOM]: 'BLOOM',
    [NODE_WITNESS]: 'WITNESS',
    [NODE_COMPACT_FILTERS]: 'COMPACT_FILTERS',
  };
  return Object.entries(names)
    .filter(([flag]) => hasService(shared, Number(flag)))
    .map(([, name]) => name);
}

// 两节点握手
const nodeA = NODE_NETWORK | NODE_WITNESS; // 可完整提供 + 支持 SegWit
const nodeB = NODE_NETWORK | NODE_BLOOM | NODE_WITNESS | NODE_COMPACT_FILTERS;
console.log('共享能力:', intersectServices(nodeA, nodeB));
// 输出: [ 'NETWORK', 'WITNESS' ]
// B 的 BLOOM 和 COMPACT_FILTERS 不被 A 支持

6.7.3 BIP-9 VersionBits:软分叉信号协商

软分叉激活需要全网节点达成"是否支持"的共识。BIP-9 引入 VersionBits——使用区块头 nVersion 字段的未使用比特位作为能力信令信道

状态说明
Defined提案被分配一个 VersionBit 位置,等待信号起始
Started信号窗口开始,矿工在该位设为 1 表示支持
Locked In在窗口期内达到 95% 信号率,该升级被锁定激活
Active达到锁定高度 + 延迟后,规则正式生效
Failed信号窗口结束,未达 95%,提案竞争失败
graph LR
    A[Defined] -->|信号窗口| B[Started]
    B -->|≥95% 信号率| C[Locked In]
    B -->|窗口结束<br>&lt;95%| F[Failed]
    C -->|延迟激活| D[Active]
    style C fill:#ccffcc
    style F fill:#ffcccc

6.7.4 向后兼容与协议演化的哲学

核心原则:软分叉必须保持向后兼容。旧节点可以继续运行,只是无法验证新规则的额外数据。

比特币的协议演化策略是极度保守:一次升级从 BIP 提案到激活可能需要数年时间。以太坊的演化速度更快,通过硬分叉(如 The Merge、Dencun)引入激进改进。

两种哲学的对比:

特性比特币(保守)以太坊(积极)
升级周期数年/次数月/次
兼容性软分叉为主,向后兼容硬分叉为主,所有节点必须升级
争议处理社区辩论 + 算力信号核心开发者驱动 + 社区公投
代表升级SegWit (4年)The Merge, Dencun

关键认知:协议版本协商与升级机制回答的是"如何让去中心化系统持续进化而不崩溃"。版本握手是一个微共识过程——在发起任何数据交换前,两个节点必须先就"我们能共享什么"达成一致。BIP-9 的 VersionBits 将这种微共识扩展为全网升级的协调工具


← 6.6 轻客户端与全节点 | 前往 → ch06-summary

评论

0

评论加载中…

发表评论

0/2000