美文网首页区块链研习社区块链大学
基于以太坊go-ethereum的DPOS实现(四)共识接口

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

作者: 豆包爹 | 来源:发表于2018-09-28 17:38 被阅读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实现(五)定时出块

    相关文章

      网友评论

        本文标题:基于以太坊go-ethereum的DPOS实现(四)共识接口

        本文链接:https://www.haomeiwen.com/subject/ymcpoftx.html