正如文章AElf共识合约标准中所述,GetConsensusCommand接口用于获取某个公钥下一次生产区块的时间等信息。
在AEDPoS的实现中,其输入仅为一个公钥(public key),该接口实现方法的调用时间另外作为参考(其实也是一个重要的输入)。AElf区块链中,当系统内部调用只读交易时,合约执行的上下文是自行构造出来的,调用时间也就是通过C#自带函数库的DateTime.UtcNow生成了一个时间,然后把这个时间转化为protobuf提供的时间戳数据类型Timestamp,传入合约执行的上下文中。
事实上,无论要执行的交易是否为只读交易,合约代码中都可以通过Context.CurrentBlockTime来获取当前合约执行上下文传进来的时间戳。
本文主要解释AEDPoS共识如何实现GetConsensusCommand。在此之前,对不了解AElf共识的聚聚简单介绍一下AEDPoS的流程。
AEDPoS Process
DPoS的基本概念我们不再赘述,假设现在AElf主链通过投票选举出17个节点,我们(暂时地)称之为AElf Core Data Center,简称CDC。(对应eos中的BP即Block Producer这个概念。)
这些CDC是通过全民投票在某个区块高度(或者说时间点)的结果,直接取前17名得到。每次重新统计前17名候选人并重新任命CDC,称为换届(Term)。
在每一届中,所有的CDC按轮(Round)次生产区块。每一轮有17+1个时间槽,每位CDC随机地占据前17个时间槽之一,最后一个时间槽由本轮额外区块生产者负责生产区块。额外区块生产者会根据本轮每个CDC公布的随机数初始化下一轮的信息。18个时间槽后,下一轮开始。如此循环。
Round的数据结构如下:
// The information of a round. message Round { sint64 round_number = 1; mapreal_time_miners_information = 2; sint64 main_chain_miners_round_number = 3; sint64 blockchain_age = 4; string extra_block_producer_of_previou