POA出块机制调整

修改POA共识机制的出块策略,以达到节省资源的目的..

问题描述

POA私有链中,没有交易时,经常会有空块(Empty Block)的产生,长时间的累积,对服务器空间的占用越来越来。
因此,想通过修改源码来达到,没有交易不会出块,以节省服务器的空间消耗。

POA共识机制

以太坊的 POA(Proof of Authority,权威证明) 是一种适用于联盟链或私有链的共识机制,其核心特点是依赖预先授权的可信节点(称为“验证者”)来生成区块。与
PoW(工作量证明)和 PoS(权益证明)不同,POA 的验证者身份需要经过严格的身份验证,且出块过程无需复杂的计算竞争,因此具有高吞吐量和低延迟的特性。多用于企业私有链、测试网络等。

POA 的核心机制

  1. 验证者(Signers)的授权

    • 验证者是网络中预先选定的可信节点(例如由联盟成员或企业指定)。
    • 验证者的公钥需要被写入区块链的创世块(Genesis Block),或通过投票机制动态加入/移除。
    • 身份绑定:每个验证者的身份通常与现实世界中的实体(如企业、机构)绑定,以提高作恶成本。
  2. 轮流出块(Round Robin)

    • 验证者按照预设顺序轮流生成区块。例如,若有 3 个验证者(A、B、C),出块顺序为 A → B → C → A → B → C…。
    • 时间间隔:每个区块的出块时间固定(如 5 秒),避免空块或延迟。
  3. 区块签名

    • 每个区块必须由当前轮次的验证者签名,其他节点验证签名合法性后接受该区块。
    • 若验证者未在规定时间内出块,网络会跳过当前验证者,由下一个验证者继续出块。
  4. 动态验证者管理

    • 现有验证者可以通过投票机制添加或移除其他验证者(例如,超过 50% 的验证者同意即可生效)。
    • 防止恶意行为:若某个验证者长期不参与出块或生成无效区块,会被投票踢出网络

出块流程

  1. 验证者节点根据轮次顺序等待出块。

  2. 当轮到某个验证者时,它收集交易并生成新区块。

  3. 验证者使用私钥对区块签名,广播到网络。

  4. 其他节点验证签名是否来自合法验证者,并接受有效区块。

修改思路

修改区块生成逻辑(miner/worker.go)

在创建新区块时,检查交易池是否为空。若无交易,则跳过生成区块。

1
2
3
4
5
6
// commit 函数中检查本地客户端的交易池是否有待处理的交易
pending := w.eth.TxPool().Pending(false)
if len(pending) == 0 {
log.Info("No transactions in the pool, not starting miner")
return nil // 如果没有交易,不启动挖矿
}

动态调整出块间隔(consensus/clique/clique.go)

根据交易池状态动态延长出块时间(例如,空池时等待 2 倍 period)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 原有逻辑
delay := time.Unix(int64(header.Time), 0).Sub(time.Now())
if header.Difficulty.Cmp(diffNoTurn) == 0 {
// It's not our turn explicitly to sign, delay it a bit
wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime
delay += time.Duration(rand.Int63n(int64(wiggle)))

log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
}

// 调整为
txCount := len(block.Transactions())
delay := time.Duration(c.config.Period) * time.Second
if txCount == 0 {
delay *= 2 // 无交易时等待更久
}


POA出块机制调整
https://zhyyao.me/2025/01/30/blockchain/poa_custom_block/
作者
zhyyao
发布于
2025年1月30日
许可协议