+
POA

以太坊POA共识现在存在的问题

以太坊POA现在存在用户正常操作也可能导致分叉的问题

Posted by 咕🎨 on 2023-03-06
Words 405 and Reading Time 1 Minutes
Viewed Times

POA共识现在存在的问题

现在以太坊POA实现

设置矿工手续费账户:

1
2
3
4
5
6
7
8
9
10
11
12
// SetCoinbase sets the coinbase of the generated block.
// It can be called at most once.
func (b *BlockGen) SetCoinbase(addr common.Address) {
if b.gasPool != nil {
if len(b.txs) > 0 {
panic("coinbase must be set before adding transactions")
}
panic("coinbase can only be set once")
}
b.header.Coinbase = addr
b.gasPool = new(GasPool).AddGas(b.header.GasLimit)
}

自动对矿工地址设置手续费账户(clique.go):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Gather all the proposals that make sense voting on
addresses := make([]common.Address, 0, len(c.proposals))
for address, authorize := range c.proposals {
if snap.validVote(address, authorize) {
addresses = append(addresses, address)
}
}
// If there's pending proposals, cast a vote on them
if len(addresses) > 0 {
header.Coinbase = addresses[rand.Intn(len(addresses))]
if c.proposals[header.Coinbase] {
copy(header.Nonce[:], nonceAuthVote)
} else {
copy(header.Nonce[:], nonceDropVote)
}
}

这里proposals是候选人列表, 可以看出来, 当验证人没有设置Coinbase的时候, 默认取得是矿工得地址.
因为这里和前一步的setCoinbase没有做验证, 导致在后期其它节点加入进来的时候, 如果矿工设置了coinbase,那其它节点就会出现以下错误:

1
2
3
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
}

这里计算的stateROOT(世界状态不匹配)
下一篇文章我将详细讲解,当出现世界状态不匹配的时候, 应该怎么取调查具体语言,怎么去从程序方面解决这个问题.

这里我被这个问题困扰了一周, 如果你感觉这个对你有用的话, 不妨请我喝杯咖啡.


...

...

00:00
00:00