[Web3] 基础第5篇: 共识算法与 P2P 通信协议

一、内容提要

  • 共识算法
    • POW
    • POS
    • DPOS
    • PBFT
  • P2P
    • 协议的介绍
    • 协议的过程

文章目录

二、共识算法

怎么去理解共识算法

多方对某一个提案达成一致的过程叫做共识过程,共识过程需要一些算法机制,比方说 POW 和 POS 等

一个简单的例子,班级里面选择一个班长,如果是老师直接指定,那么是中心化的;如果是通过投票选举出来的,这种事去中心化的,投票的过程其实就是一个共识算法。

为什么区块链非要共识不可?因为账本要在互不信任的节点之间保持一致:谁有权记账、记哪一笔、以哪个版本为准,都必须有大家共同遵守的规则,否则就会出现"同一笔钱花两次"(双花)。评价一个共识算法通常看三件事:安全性 (诚实节点不会确认冲突的账本)、活性 (网络最终能继续出块)、终局性(确认后的区块能否被回滚)。PoW 用算力投票,终局是概率性的;BFT 类算法用消息投票,一旦提交就是确定性终局。下面这张表先建立全局印象,后面逐个展开:

主流共识算法速览

算法 类型 容错模型 终局性 代表链/项目
PoW 算力竞争 诚实算力占优(防 51% 攻击) 概率终局,最长链原则 比特币
PoS 质押投票 作恶罚没质押(Slashing) checkpoint 最终化 以太坊
DPoS 委托选举超级节点 选举 + PBFT 兜底 依实现而定 EOS、Solana
PBFT 三阶段消息投票 N = 3f + 1 确定性终局 Hyperledger Fabric 0.6
Tendermint 两轮投票 + 锁定 2/3 以上诚实 确定性终局 CometBFT / Cosmos 生态
HotStuff 线性通信 BFT 2/3 以上诚实 确定性终局 Libra/Diem 系

提示:Solana 是组合拳------POH 负责排序、DPoS 选出块人、PBFT 负责状态一致,不是单一算法。

共识算法相关的概念

确认位

图:确认位示意------后续区块不断叠加,交易被回滚的概率越来越低

长程攻击

图:长程攻击示意------攻击者试图从远古区块开始重写一条竞争链

区块分叉

图:区块分叉示意------同一高度出现竞争区块,网络需要规则选择主链

POW 共识算法

POW 共识算法主要是用在比特币及其衍生链里面,共识过程如下:

所有的 validator 一起来找一个 nonce 值,使得 Hash(nonce + blockData) < target

  • nonce:节点共识过程中需要寻找的值
  • target:是挖矿难度值,target 越小,挖矿难度越大

交易先发送到 mempool, 参与共识的节点先将交易打包成区块,开始去计算这个 nonce 值,若找到目标的 nonce 值,使得 Hash(nonce + blockData) < target, 就将区块生成出来,全网广播,其他节点接受到这个区块之后,进行区块验证,验证通过之后落块。

挖矿难度问题

  • 在比特币里面,每过 2016 个块,就会进行一次难度调整,按照每 10 分钟出一个块的话,每次调整大约需要两周的时间。
  • d i f f c u l t n e w = d i f f c u l t o l d ∗ ( A c t a u l T i m e / T a r g e t T i m e ) diffcult_{new} = diffcult_{old} * (ActaulTime / TargetTime) diffcultnew=diffcultold∗(ActaulTime/TargetTime)
  • 出块时间控制 10 分钟左右,保证区块不会发生分叉丢失

为什么难度要动态调整?因为全网算力随时在变:算力涨了不调难度,出块就会越来越快,分叉和通胀都会失控;算力跌了不调难度,网络可能半天出一个块。比特币用"每 2016 个块按实际耗时/目标耗时缩放难度"的反馈机制,把出块节奏钉在 10 分钟左右。还要理解 PoW 的概率终局:你的交易被打包后,后面每多叠一个块,回滚它需要重算的算力就越多,通常等 6 个确认就被认为足够安全------这不是数学上的绝对不可逆,而是经济上"不划算"。

Bitcoin 的总量是 2100 万枚,每隔 21 万个区块会发成一次减半

  • 50
  • 50 / 2
  • 50 / 4
  • 50 / 8
  • 50 / n

减半公式:50(1/2 + 1/4 + 1/8 + ... + 1/n) = 2100 万枚

比特币挖矿产生一个区块的时候会有两层奖励

  • 第一层:来自于比特币的挖矿奖励(区块里面的第一笔交易为挖矿奖励的交易)
  • 第二层:正常的交易手续费

下面用一段 Python 代码把「找 nonce」的过程最小化复现出来,帮助理解 Hash(nonce + blockData) < target 到底在算什么:

python 复制代码
import hashlib

def mine(block_data: str, target_prefix: str, max_nonce: int = 10_000_000) -> int:
    """暴力搜索 nonce,使 sha256(nonce + blockData) 以 target_prefix 个 0 开头。
    target_prefix 越大,难度越高(等价于 target 越小)。"""
    for nonce in range(max_nonce):
        raw = f"{nonce}{block_data}".encode()
        digest = hashlib.sha256(raw).hexdigest()
        if digest.startswith("0" * target_prefix):
            return nonce
    raise RuntimeError("在给定范围内没有找到满足条件的 nonce")

if __name__ == "__main__":
    data = "block#1000|txs:alice->bob:1BTC"
    for difficulty in (2, 3, 4):
        nonce = mine(data, difficulty)
        print(f"difficulty={difficulty}, nonce={nonce}")

运行后你会发现:难度每加 1,平均尝试次数大约翻 16 倍(十六进制每一位有 16 种取值),这正是比特币难度调整的数学基础。

比特币如何解决分叉问题

在比特币里面,当产生分叉的时候,以最长链为原则

POS 共识算法

使用质押投票的机制完成共识过程的一个共识算法,在共识过程中,若节点存在作恶,就会被惩罚,若节点正常完成共识,就会获得奖励。

  • 第一层意思:需要质押一定量的资金
  • 第二层意思:需要投票,完成共识过程
  • 第三层意思:正常投票(不做恶)就会获得奖励,投票者有投票奖励,出块人有出块的奖励
  • 第四层意思:异常投票(作恶)质押的资金就会被罚没有

前提条件是你要参与投票共识,必须要先质押,一般情况下很多质押协议要求最小质押量,要大于最小质押量,才有机会参与网络共识。

PoS 要解决的核心难题是"无利害关系"(nothing-at-stake)问题:PoW 里矿工押注算力,分叉两边只能选一边挖;PoS 里投票不耗电,理论上验证者可以在两条分叉上同时投票两头下注。解决办法就是罚没(Slashing):一旦检测到双重投票等作恶证据,直接扣掉质押金,让作恶有真金白银的成本。以太坊还通过 checkpoint 机制给区块"盖章":过一个检查点变 safe,过两个变 Finalized,Finalized 之后想回滚就要烧掉巨量质押金,经济上几乎不可能。

以太坊的 POS 共识算法

ETH2.0 和 Pectra 升级

从 POW 到 POS 升级是 ETH2.0 最核心的变化,共识算法从 POW 变成 POS

  • 在 Pectra 升级之前
    • 在 ETH2.0 升级的时候,限定如果要在以太坊上启动一个节点,需要质押 32 个 ETH,小于 32 个 ETH 不能启动这个节点;大于 32 ETH 多出部分不会纳入奖励的计算。
  • 在 Pectra 升级之后
    • 限定启动一个节点参与 ETH 网络共识最少需要 32 个 ETH,最大可以到 2048 个 ETH,目前正在运行 ETH 版本质押范围为 32-2048 个 ETH
以太坊的项目结构
  • 通过 engine_newPayLoad 生成 payload
  • 使用 engine_getPayLoad 通过 payload Id 获得生成数据
  • 执行 engine_forceUpdate 的方法将 payload 数据组织区块插入到链里面去
LSP

在真实情况中,很多人持有 ETH 都是小于 32 个,有的甚至只有几个 ETH,这些闲散的 ETH 就无法参与整个网络的共识获得奖励。

怎么办:有人做了一个系统,将这些散户 ETH 集中起来,当集中的 ETH 大于等于 32 个,就去启动节点参与网络的共识,参与网络共识会获得奖励,这些奖励一部分被中介拿走,比方说 5%-8%;剩下的再给到散户;我们一起来看看这个产品是怎么做的:

  • 第一步:用户质押 ETH,LSP mint 对应权益 token 给到用户
  • 第二步:当 LSP 里面的资金大等于 32 ETH 时,链下服务监听到该事件之后,驱动将 LSP 资金充值到信标链合约,当新质押再进来,先将该节点质押的数量补充到 2048; 最新的质押达到 32 ETH 再去启动新的节点。
  • 第三步:充值完成值,启动一个信标链节点参与网络的共识出块
  • 第四步:出块完成之后,节点会获得奖励,矿池节点进行奖励抽成(节点拿 5-8%),剩余的奖励给到 LSP 产品侧
  • 第五步:LSP 产品侧拿到奖励之后,抽成之后(LSP 拿 5-8%),将奖励分发给用户
  • 第六步:用户取回质押,需要将权益 token 退回去,合约 burn 权益 token 之后释放 ETH 给到用户
  • 第七步:LSP 退出,停掉节点,取回信标链合约资金

LSP(流动性质押协议)本质上做了两件事:一是聚沙成塔 ,把散户不足 32 ETH 的资金凑成整份去跑节点;二是发权益凭证,用户质押后拿到 LST(如 stETH 这类权益 token),凭证可以继续去 DeFi 里使用,质押不再是"死钱"。理解这条链路时抓住一个原则:节点运维和奖励分配分层抽成,用户承担的是协议合约风险与节点罚没风险的传导。

以太坊共识过程细化

第一步:用将交易发送到 geth/reth 的执行客户端里面的 txpool

第二步:信标链通过调用 engine_newPayload 的接口驱动 geth 客户端生成 payload

第三步:信标链通过调用 engine_getPayload 的接口获取 payload 的数据进行共识验证

第四步:信标链通过调用 engine_forceUpdate 方法将 payload 生成区块插入到链中

第五步:当区块确认位到 32 个区块时候,信标链指导 geth 将区块的状态变成 safe

第六步:当区块确认位到 64 个区块时候,信标链指导 geth 将区块的状态变成 Finalized

把上面六步落到代码层面,本质是执行客户端(geth/reth)对外暴露的 Engine API 调用序列,可以用下面的伪代码串起来:

python 复制代码
# 信标链(共识层)视角的伪代码:一个 slot 内的典型调用顺序
def on_slot_start(slot: int):
    # 1. 交易进入执行层 txpool(由用户 RPC 提交,非 Engine API)
    # 2. 让执行层基于父区块构造候选 payload
    payload_id = engine_new_payload(
        parent_hash=chain.head.hash,
        payload_attributes={
            "timestamp": slot * 12,
            "prevRandao": randao_reveal(slot),
            "suggestedFeeRecipient": proposer_fee_recipient(slot),
        },
    )

    # 3. 取回 payload 内容,用于在共识层做投票验证
    payload = engine_get_payload(payload_id)
    if not verify_state_root(payload):
        return vote_nil(slot)

    # 4. 投票通过后,把 payload 落成区块插入链中
    block_hash = engine_forkchoice_updated(
        head_block_hash=payload.block_hash,
        safe_block_hash=chain.safe.hash,
        finalized_block_hash=chain.finalized.hash,
    )

    # 5/6. 确认位推进时,同步更新 safe / finalized 指针
    if confirmations(block_hash) >= 32:
        chain.safe = block_hash
    if confirmations(block_hash) >= 64:
        chain.finalized = block_hash

注意 engine_forkchoice_updated 同时承担了「插入区块」和「推进 safe/finalized 指针」两个职责,这也是以太坊把共识与执行解耦(PoS 合并后)的关键设计。

理解区块的推导流程
  • Epoch: 以太坊共识出块的一个周期,在一个周期内,参与区块投票的人是一样的,一个 epoch 含有 32 个 slot
  • Slot: 用来装载区块的,每一个 slot 里面包含一个区块,每隔 12s 会出现一个 slot, 如果在一个 slot 期间没有任何交易,就不会出块,这个时候 slot 是空的
  • Block: 用来打包交易的,每一个区块都需要放到一个 slot 里面去,区块会有三个状态分别是:Unsafe, Safe 和 Finalized
  • CheckPoint: 每隔 32 个 slot 就有一个 checkpoint
  • 图中我们以 128 这个点开始去整个图
    • 64-96 个 slot 里面区块已经过一个 checkpoint, 过了 32 slot, 这里面区块状态都是 safe
    • 0-64 个 slot 里面的区块已经过了两个 checkpoint, 也就是说过了 64个slot,这里面区块状态都是 Finalized
以太坊共识过程中怎么去解决区块分叉问题的

DPOS

DPOS:委托质押协议,超级节点的机制,不是所有都可以参与出块,而是选举一群人具备出块的权限,代表链 EOS,21 个超级节点, Solana, 101 个超级;

DPOS 的工作流程

  • 质押 Token: 质押的 Token 越多,具备的权益越大
  • 投票选举:所以质押人投票选举出来一小群人来进行网络的出块
  • 出块流程:被选举出来人,开始打包,验证和区块出出来
  • PBFT 负责区块状态达成一致, 例如: 出块出现分叉,将由 PBFT 共识算法来解决
  • DPOS 选择出来节点挂,那么会新选择新的节点出来

Solana 共识 = POH + DPOS + PBFT

  • POH:交易的排序,按照一定规则进行交易排序
  • DPOS:质押选举出块人,超级节点负责出块
  • PBFT:负责区块状态达成一致

PBFT

最早追溯到拜占庭将军问题

PBFT 最早用在区块链里面,应该是 Hyperledger Fabric(IBM 出的联盟链,只有 Hyperledger Fabric 0.6 之前的版本使用了 PBFT, 1.0 之后用户的 kafka + zookeeper )

拜占庭容错算法 N = 3f + 1; n 代表的节点总数, f 代表允许出异常的节点; f = (N -1)/3;

例如我们有 10 个节点,公式会变成如下情况

10 = 3f + 1 ====> f = (10 - 1)/3 = 3; 在 PBFT, 需要有 2/3 以上的节点是正常,这个网络才能正常工作

Hyperledger Fabric 0.6

Hyperledger Fabric 0.6 算法分为三个阶段 pre-prepare, prepare 和 commit

  • pre-prepare(view change 过程耗时比较长)
    • 客户端将需要共识消息发送到 server, 当网络收到需要共识消息,会进行一次 view change, 选择出一个主节点完成整个共识过程
  • prepare
    • 主节点收到需要共识消息之后,会全网广播一个 prepare 的一个消息体,其他的副本节点收到消息之后,验证消息的真实性,然后对这个消息进行确认,给主节点回复确认消息。
  • commit
    • 主节点收到 2/3 以上的节点对消息的确认之后,再广播 commit 的消息,消息确认之后,主节点直接打包生成区块,返回给到客户端。

View change: 选择主节点的过程,如果网络主节点挂了,也会发一次 view change 重新选择主节点。

为什么容错公式是 N = 3f + 1?直觉上,f 个节点可能宕机不回复、另外 f 个节点可能作恶乱回复,剩下 f + 1 个诚实节点必须能推动流程,所以总节点数至少 3f + 1,收集到 2f + 1(约 2/3)票就能保证其中一定有诚实节点。PBFT 的代价是通信复杂度 O(n²):每个阶段大家都要互相广播消息,节点一多网络就被消息淹没,这也是它适合联盟链、不适合上万节点公链的原因。把三阶段画成流程就是:

图:PBFT 从客户端请求到提交出块的三阶段消息流

提示:pre-prepare/prepare 解决"大家看到同一条消息",commit 解决"大家都知道大家看到了",两轮确认缺一不可。

CometBFT

算法简介

CometBFT 采用Tentmint 共识,一种易于理解、基本异步的 BFT 共识算法。该算法遵循一个简单的状态机,如下所示:

上图展示了 Tendermint BFT 共识流程,描述了一个区块从提议(Propose)到最终提交(Commit)的完整过程。Tendermint 共识采用三阶段投票机制(Prevote、Precommit、Commit) 来确保区块最终性。以下是详细解析:

流程分解
  • 新高度(New Height)
    • 在前一个区块提交后,链进入新的高度(New Height)。
  • 提议阶段(Propose)
    • 提议者(Proposer) 选出一个区块并广播。
    • 可能情况:
      • 若区块有效且按时收到,则进入 Prevote Block。
      • 若区块无效或未及时收到,则进入 Prevote Nil。
  • Prevote 阶段
    • Prevote Block(若收到有效区块):
      • 等待至少 2/3 的 Prevote 票数(Wait for prevotes from +2/3)。
    • Prevote Nil(若未收到有效区块):
      • 进入 Precommit Nil,即该轮未能达成共识。
  • Precommit 阶段
    • Precommit Block(若 2/3 以上的节点 Prevote 了该区块):
      • 进入等待 Precommit(Wait for precommits from +2/3)。
    • Precommit Nil(若未达成 2/3 Prevote):
      • 进入新的轮次(New Round),重新开始提议流程。
  • Commit 阶段
    • 若 2/3 以上的节点 Precommit 了该区块:
      • 区块最终被 提交(Commit),状态更新,进入新高度(New Height)。
    • 否则,重新进入 New Round,重复上述流程。
核心逻辑总结
  • 三阶段投票机制(Prevote → Precommit → Commit)
    • 需要 2/3 以上的投票支持 才能进入下一阶段。
    • 若任何阶段未能达成 2/3 共识,则进入新一轮(New Round)。
  • 区块有效性判断
    • 若提议区块无效或未按时收到,节点会投 Prevote Nil,影响共识进展。
    • 在 Prevote 或 Precommit 阶段,若未达到 2/3,进入新轮次。
  • 最终性(Finality)
    • 当 2/3 以上的节点 Precommit 了某个区块,则该区块最终会被 Commit,不会被回滚。

Hyperledger fabric 和 cometBFT 的本质差异

  • Hyperledger Fabric 的 PBFT 有 pre-prepare 选择主节点的过程,但是 cometBFT 没有,这就很大程度上提高了算法的效率

Tendermint 相比经典 PBFT 的两个关键改进:一是轮流提议 ,出块权按质押权重轮换,省掉了昂贵的 view change 选主;二是锁定机制,节点一旦对某个区块投了 Precommit 就被"锁"在它上面,后续轮次不能随便改投别的区块,这保证了即使网络异步分区,也不会同时提交两个冲突区块。HotStuff 则进一步把通信复杂度从 O(n²) 降到 O(n),通过门限签名把一轮投票聚合成一个法定人数证书(QC),为更大规模的验证者集合铺路。

其他的 PBFT 变种算法(扩展)

  • HotStuff BFT: libra 项目用户的
  • Avalanche: 雪崩链自研 PBFT 算法

用一段 Python 模拟 PBFT 的三阶段投票,可以直观看到「为什么必须收到 2f+1 票」:

python 复制代码
from collections import Counter

N, F = 7, 2          # N = 3f + 1,f = 2
QUORUM = 2 * F + 1   # 需要收集的票数 = 5

def pbft_round(primary: int, faulty: set[int], msg: str) -> bool:
    replicas = list(range(N))

    # 阶段一:pre-prepare,主节点广播提案
    if primary in faulty:
        print("主节点作恶/宕机,触发 view change")
        return False
    print(f"[pre-prepare] primary={primary} 广播提案: {msg}")

    # 阶段二:prepare,副本节点校验后回复确认
    prepares = [r for r in replicas if r not in faulty and r != primary]
    print(f"[prepare] 收到确认票: {prepares}")
    if len(prepares) + 1 < QUORUM:   # +1 是主节点自己
        print("prepare 未达 2f+1,进入新一轮")
        return False

    # 阶段三:commit,主节点广播 commit 并落块
    commits = [r for r in replicas if r not in faulty]
    print(f"[commit] 收到提交票: {commits}")
    if len(commits) < QUORUM:
        print("commit 未达 2f+1,进入新一轮")
        return False

    print(f"区块提交成功: {msg}")
    return True

if __name__ == "__main__":
    print("=== 正常情况 ===")
    pbft_round(primary=0, faulty=set(), msg="block#100")
    print("\n=== 2 个节点作恶 ===")
    pbft_round(primary=0, faulty={3, 4}, msg="block#101")

把 faulty 集合扩大到 3 个节点(超过 f),你会看到 quorum 无法达成------这就是 N = 3f + 1 的边界。

三、P2P 协议

图解 P2P

点对点通信:节点与节点之间之间链接通信,没有通过任何的第三方服务进行连接,而是直接通信

P2P 通信协议详解P2P(Peer-to-Peer,对等网络)通信协议是一种去中心化的网络通信架构,允许网络中的节点(对等体)直接相互连接、交换数据和资源,而无需依赖中央服务器。这种协议相对于传统的客户端/服务器(C/S)模式,具有更高的可扩展性、容错性和资源利用效率。P2P 协议最早可追溯到 1969 年的 RFC1 文档,但真正流行于文件共享领域,如 BitTorrent 协议。

P2P 协议的基本原理

P2P 协议的核心思想是将网络中的每个节点视为平等的参与者(Peer),每个 Peer 既可以作为客户端请求资源,也可以作为服务器提供资源。这种设计避免了 C/S 模式中的单点故障和带宽瓶颈问题。

  • 去中心化结构:在 C/S 模式下,所有数据从中央服务器分发,服务器负载高且易失效。P2P 则通过分布式方式,让节点间直接通信,资源(如文件)被分割成小块(Pieces),节点间交换这些块,最终组装完整数据。
  • 资源共享机制:下载者同时也是上传者。参与节点越多,整体下载速度越快,因为资源分布在多个 Peer 上。
  • NAT 穿越与打洞技术:由于大多数节点位于 NAT(Network Address Translation,网络地址转换)设备后,P2P 需要解决"穿透"问题。常见技术包括 STUN(Simple Traversal of UDP through NATs)、TURN(Traversal Using Relays around NAT)和 ICE(Interactive Connectivity Establishment)。这些协议帮助节点发现公网 IP 和端口,并在防火墙/NAT 上"打洞"建立直接连接。
  • 例如,在两个 NAT 后的节点通信时,先通过公共服务器交换映射信息,然后尝试直接链接。

P2P 属于覆盖网络(Overlay Network)范畴,节点通过逻辑链接形成虚拟网络,底层通常基于 TCP/UDP 协议。

落到区块链上,P2P 承担两类流量:交易传播 和区块/状态同步。交易通常用 Gossip(流言)协议泛洪:节点收到新交易后随机转发给若干邻居,邻居再转发,几跳之内全网可见;区块传播则讲究"越快越好",因为慢一步就可能产生分叉。节点发现方面,比特币用硬编码种子节点 + DNS 种子 + 节点间地址交换,以太坊用基于 Kademlia 的 discv4/discv5 发现协议。把要点整理成表:

P2P 节点发现与消息传播要点

环节 关键技术 作用 区块链中的对应
节点发现 Tracker / DHT / PEX 找到可连接的 Peer 种子节点、DNS 种子、discv5
NAT 穿越 STUN / TURN / ICE 让内网节点建立直连 节点打洞、中继兜底
消息传播 Gossip 泛洪 交易/区块快速扩散全网 txpool 交易广播、新区块广播
数据校验 分片哈希校验 防止传输中被篡改 区块头哈希、Merkle 证明
拓扑组织 结构化 / 非结构化 平衡查找效率与鲁棒性 Kademlia DHT、随机邻居图

提示:P2P 网络天然开放,任何人都能跑节点接入,所以要靠签名和哈希校验来防恶意数据,靠节点评分/封禁来对抗 Sybil 与垃圾消息。

Gossip 泛洪是区块链 P2P 最核心的消息传播方式,下面用几十行 Python 模拟一个简化版网络,观察一条交易几跳能覆盖全网:

python 复制代码
import random
from collections import deque

class Node:
    def __init__(self, nid: int, peers: list[int]):
        self.nid = nid
        self.peers = peers
        self.seen: set[str] = set()

def build_network(size: int, degree: int = 4) -> dict[int, Node]:
    nodes = {}
    for i in range(size):
        peers = random.sample([j for j in range(size) if j != i], degree)
        nodes[i] = Node(i, peers)
    return nodes

def gossip(nodes: dict[int, Node], origin: int, tx_id: str, fanout: int = 3):
    """从 origin 节点泛洪一条交易,返回每个节点首次收到消息的跳数。"""
    hops = {origin: 0}
    queue = deque([origin])
    nodes[origin].seen.add(tx_id)

    while queue:
        cur = queue.popleft()
        targets = random.sample(nodes[cur].peers, min(fanout, len(nodes[cur].peers)))
        for nxt in targets:
            if tx_id in nodes[nxt].seen:
                continue
            nodes[nxt].seen.add(tx_id)
            hops[nxt] = hops[cur] + 1
            queue.append(nxt)
    return hops

if __name__ == "__main__":
    random.seed(42)
    net = build_network(size=200, degree=4)
    result = gossip(net, origin=0, tx_id="tx-abc")
    print(f"覆盖节点数: {len(result)}/200")
    print(f"最大跳数: {max(result.values())}")
    print(f"平均跳数: {sum(result.values()) / len(result):.2f}")

可以看到在随机图 + 小 fanout 的情况下,200 个节点通常 4~5 跳就能全覆盖,这就是 Gossip 高效又鲁棒的原因;代价是存在冗余消息,需要靠 seen 集合去重。

P2P 网络的组织结构

P2P 网络有多种拓扑结构根据应用场景选择:

这些结构确保节点高效定位和通信。

  • P2P 协议的工作流程以 BitTorrent(经典 P2P 文件共享协议)为例,说明典型工作过程:
  • 种子文件生成:文件被分成固定大小的分片(e.g., 2MB/片),生成 .torrent 文件,包含分片索引、哈希校验和 Tracker 服务器地址。
  • 连接 Tracker:客户端从 Tracker 获取其他 Peer 的 IP/端口列表。
  • Peer 发现与连接:使用 DHT 或 PEX(Peer Exchange)发现更多 Peer,建立 TCP/UDP 连接。
  • 数据交换:节点间查询已下载分片,交换缺失部分。同时上传已下载内容。
  • NAT 穿越:如果失败,使用 TURN 中继服务器转发数据。
  • 完成与共享:下载完成后,节点继续作为 Seed(种子)上传,帮助他人。

其他协议如 Wi-Fi Direct(Wi-Fi P2P)则专注于设备间直接连接,无需路由器,支持数据传输。

P2P 协议的应用场景

P2P 广泛应用于多个领域:

  • 文件共享:BitTorrent、eMule 等,高效分发大文件。
  • 流媒体:P2P 直播/点播(如 PPLive),节点间共享视频流,降低服务器压力。
  • 即时通信:Skype、QQ 使用 P2P 实现语音/视频通话,减少延迟。
  • 区块链:比特币等使用 P2P 网络同步区块数据。
  • 分布式计算:利用节点 CPU 进行科学计算(如 SETI@home)。
  • 云存储:如 IPFS(InterPlanetary File System),分布式存储文件。
  • 游戏平台:在线游戏支持 P2P 匹配和数据同步。

P2P 协议的优缺点

  • 优点:
    • 高效性与可扩展性:参与者越多,速度越快;无单点瓶颈。
    • 鲁棒性:节点故障不影响整体网络。
    • 隐私与安全性:减少中央服务器依赖,数据直接传输(但需加密)。
    • 成本低:利用用户带宽,降低基础设施开销。
  • 缺点:
    • 安全风险:易受恶意节点攻击(如 Sybil 攻击),传播病毒。
    • 网络质量依赖:带宽不均、节点 churn 导致不稳定。
    • 监控难题:去中心化使监管困难。
    • NAT 兼容性:需额外技术处理 Symmetric NAT 等复杂类型。

未来趋势与挑战

P2P 技术正向更安全的方向发展,如结合区块链增强信任。目前研究焦点包括节点延迟优化、Inter-Overlay 优化和 P2P 安全。

四、总结

  • POW
  • POS
  • PBFT
  • P2P

用一句话收尾:共识算法决定"账本以谁为准",P2P 决定"消息怎么传到大家手里",两者一个管决策、一个管通信,合起来才是一条能跑的链。选型时的经验法则是:公开无许可网络优先 PoW/PoS 这类抗女巫的机制,小规模许可网络可以用 PBFT/Tendermint 换取确定性终局和高吞吐。


本文是 Web3 基础知识系列的第 5 篇,

整套笔记从区块链的由来、密码学原理、组织结构、共识与公链实践逐讲展开。

五、参考资料 & 致谢

参考资料

  • Bitcoin 白皮书 :Satoshi Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System, 2008 --- PoW、最长链原则与概率终局的原始出处。
  • Ethereum 官方文档 :https://ethereum.org/zh/developers/docs/consensus-mechanisms/pos/ --- PoS、验证者、checkpoint 与 finality 的权威说明。
  • Ethereum Engine API 规范 :https://github.com/ethereum/execution-apis/tree/main/src/engine --- engine_newPayload / engine_getPayload / engine_forkchoiceUpdated 的接口定义。
  • EIP-7251(Pectra 升级) :https://eips.ethereum.org/EIPS/eip-7251 --- 验证者最大有效余额从 32 ETH 提升到 2048 ETH 的依据。
  • PBFT 原始论文 :Miguel Castro, Barbara Liskov, Practical Byzantine Fault Tolerance , OSDI 1999 --- 三阶段共识与 N = 3f + 1 的推导。
  • Tendermint / CometBFT 文档 :https://docs.cometbft.com/ --- Propose / Prevote / Precommit / Commit 状态机说明。
  • HotStuff 论文 :HotStuff: BFT Consensus with Linearity and Responsiveness, PODC 2019 --- 线性通信复杂度 BFT 的代表工作。
  • Hyperledger Fabric 文档 :https://hyperledger-fabric.readthedocs.io/ --- 0.6 版 PBFT 与 1.0 之后排序服务(Kafka/ZooKeeper、Raft)的演进。
  • BitTorrent 协议规范 :https://www.bittorrent.org/beps/bep_0003.html --- 分片、Tracker、PEX 与 DHT 的经典实现。
  • Kademlia 论文 :Petar Maymounkov, David Mazières, Kademlia: A Peer-to-Peer Information System Based on the XOR Metric, 2002 --- 以太坊 discv4/discv5 的理论基础。
  • RFC 1 :https://www.rfc-editor.org/rfc/rfc1 --- P2P 思想最早可追溯的文档。

致谢

  • 感谢 CSDN 平台提供的创作与发布环境,让这套 Web3 基础知识笔记得以系统整理成文。
  • 感谢以太坊基金会、比特币核心开发者以及 CometBFT、Hyperledger 等开源社区,本文大量概念与图示均受益于其公开文档与源码。
  • 感谢所有在评论区指出错漏、补充案例的读者,你们的反馈让文中关于 PoS 罚没、Engine API 调用顺序、PBFT 容错边界等细节得以不断修正。
  • 本文部分示意图来自公开技术资料,仅用于学习交流,版权归原作者所有;如有不当引用,请联系删除。

说明:本文为个人学习笔记,观点与理解难免有偏差,欢迎在评论区交流指正。若需转载,请注明出处。

相关推荐
Bczheng15 天前
四十六.创建一笔交易(9)--第三个区块 添加tx到钱包
区块链
2301_776045236 天前
理解Layer 1区块链协议
区块链
幻智星科技6 天前
零知识证明三大核心特性解析
区块链·零知识证明
木西7 天前
AI 驱动的去中心化资产管理:QuantixAI 核心金库与智能风控架构解析
web3·智能合约·solidity
2301_776045237 天前
山寨币与比特币之间的关系
大数据·人工智能·区块链
JF_Ma8 天前
1000个量化策略第29例:经典红利低波策略
区块链
AlanAshley8 天前
实时湖仓与区块链:数据架构的信任革命
架构·区块链
m0_547486668 天前
《Web开发技术基础》全套PPT课件2026
web3·web开发
代码方舟9 天前
零信任架构实战:基于天远企业法人四要素高级版构建自动化电子印章授权与签约准入网关
人工智能·架构·自动化·区块链