区块链研习社区块链大学

基于以太坊go-ethereum的DPOS实现(四)共识接口

2018-09-28  本文已影响36人  豆包爹

源码

GitHub地址 https://github.com/TTCECO/gttc

目录

基于以太坊go-ethereum的DPOS实现(一)源码及测试运行
基于以太坊go-ethereum的DPOS实现(二)简要说明
基于以太坊go-ethereum的DPOS实现(三)创世块
基于以太坊go-ethereum的DPOS实现(四)共识接口
基于以太坊go-ethereum的DPOS实现(五)定时出块

共识接口

在go-ethereum中添加一种共识机制,最方便的方式是实现consensus.go中Engine接口所定义的方法。

// Engine is an algorithm agnostic consensus engine.
type Engine interface {
    // Author retrieves the Ethereum address of the account that minted the given
    // block, which may be different from the header's coinbase if a consensus
    // engine is based on signatures.
    Author(header *types.Header) (common.Address, error)

    // VerifyHeader checks whether a header conforms to the consensus rules of a
    // given engine. Verifying the seal may be done optionally here, or explicitly
    // via the VerifySeal method.
    VerifyHeader(chain ChainReader, header *types.Header, seal bool) error

    // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
    // concurrently. The method returns a quit channel to abort the operations and
    // a results channel to retrieve the async verifications (the order is that of
    // the input slice).
    VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)

    // VerifyUncles verifies that the given block's uncles conform to the consensus
    // rules of a given engine.
    VerifyUncles(chain ChainReader, block *types.Block) error

    // VerifySeal checks whether the crypto seal on a header is valid according to
    // the consensus rules of the given engine.
    VerifySeal(chain ChainReader, header *types.Header) error

    // Prepare initializes the consensus fields of a block header according to the
    // rules of a particular engine. The changes are executed inline.
    Prepare(chain ChainReader, header *types.Header) error

    // Finalize runs any post-transaction state modifications (e.g. block rewards)
    // and assembles the final block.
    // Note: The block header and state database might be updated to reflect any
    // consensus rules that happen at finalization (e.g. block rewards).
    Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
        uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)

    // Seal generates a new block for the given input block with the local miner's
    // seal place on top.
    Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error)

    // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
    // that a new block should have.
    CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int

    // APIs returns the RPC APIs this consensus engine provides.
    APIs(chain ChainReader) []rpc.API
}

在本篇及接下来的几篇关于DPOS实现的文章中,所有的叙述都是围绕着这些方法的实现展开的,所以在这里先对这些方法做下说明。

Author

    // Author retrieves the Ethereum address of the account that minted the given
    // block, which may be different from the header's coinbase if a consensus
    // engine is based on signatures.
    Author(header *types.Header) (common.Address, error)

对于以太坊的POW共识来说Author返回的就是header.coinbase的地址,可以认为是矿工地址或受益人的地址,这个地址并不需要用签名来证明。但对于DPOS共识机制来说,必须证明出块地址必须是当前有权限出块的地址,所以在alien当中,Author的返回值是根据签名计算而来的,方式和clique中的完全相同。

VerifyHeader & VerifyHeaders

    // VerifyHeader checks whether a header conforms to the consensus rules of a
    // given engine. Verifying the seal may be done optionally here, or explicitly
    // via the VerifySeal method.
    VerifyHeader(chain ChainReader, header *types.Header, seal bool) error

    // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
    // concurrently. The method returns a quit channel to abort the operations and
    // a results channel to retrieve the async verifications (the order is that of
    // the input slice).
    VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)

这两个方法都是用来验证头部信息的,可以调用同一个方法实现,其中验证的内容会单独一篇叙述。

VerifyUncles

    // VerifyUncles verifies that the given block's uncles conform to the consensus
    // rules of a given engine.
    VerifyUncles(chain ChainReader, block *types.Block) error

叔块(Uncles)在DPOS共识当中没有意义,所以可以直接返回nil,也可以验证如果叔块存在则报错,需要注意的是挖矿奖金的计算处也不需要计算叔块。

VerifySeal

    // VerifySeal checks whether the crypto seal on a header is valid according to
    // the consensus rules of the given engine.
    VerifySeal(chain ChainReader, header *types.Header) error

注释中叙述的很清晰,但是在开发过程中,因为几个Verify方法会逐层调用,所以具体功能上的区分并不清晰。

Prepare

    // Prepare initializes the consensus fields of a block header according to the
    // rules of a particular engine. The changes are executed inline.
    Prepare(chain ChainReader, header *types.Header) error

在DPOS共识当中,如果启动后还未达到genesisTimestamp中所定义的首轮开始的出块时间,则等待。

Finalize

    // Finalize runs any post-transaction state modifications (e.g. block rewards)
    // and assembles the final block.
    // Note: The block header and state database might be updated to reflect any
    // consensus rules that happen at finalization (e.g. block rewards).
    Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
        uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)

Finalize是DPOS实现中非常重要的一个方法,除了计算header.extra中签名的部分以外,几乎所有的数据的计算和组装都在这个方法中完成。比如获取代表投票,提议,表决等的交易及根据快照所做的计算入出块顺序确认等。

Seal

    // Seal generates a new block for the given input block with the local miner's
    // seal place on top.
    Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error)

DPOS实现中,Seal方法根据已经unlock的账户信息,在header.extra中为block添加签名。

CalcDifficulty

    // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
    // that a new block should have.
    CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int

直接设置为1,DPOS不需要工作量证明。

APIs

    // APIs returns the RPC APIs this consensus engine provides.
    APIs(chain ChainReader) []rpc.API

对外提供的rpc接口定义。

下一节 基于以太坊go-ethereum的DPOS实现(五)定时出块

上一篇下一篇

猜你喜欢

热点阅读