aelf技术点解读 | AEDPoS合约实现逻辑

本文详细解析了aelf区块链中AEDPoS共识合约的实现逻辑,包括节点如何获取共识命令、区分主链与侧链的共识行为、共识命令的获取与验证过程,以及共识数据的生成与验证。重点讨论了区块生产周期、轮次管理和生产节点的选举机制,阐述了如何确保节点在正确的时间槽中生产区块,以及在网络异常情况下如何处理。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在aelf的共识合约标准中,其五个接口可以分为三组:

  • 对于任何一个节点,可在任意时刻,从合约中请求共识命令;

  • 得到有效出块时间的节点在调度器倒计时终结之后,从合约中获得共识数据,并基于此数据生产区块。

  • 节点在将某个区块添加至本地区块链时,将区块信息提交给共识合约,以进行一系列针对共识数据的验证。

请求共识命令 - GetConsensusCommand
这个方法的大致逻辑如下:

public override ConsensusCommand GetConsensusCommand(BytesValue input)
{
_processingBlockMinerPubkey = input.Value.ToHex();

if (Context.CurrentHeight < 2) return ConsensusCommandProvider.InvalidConsensusCommand;

// 如果查询不到当前轮次信息,返回一个无效的时间。
if (!TryToGetCurrentRoundInformation(out var currentRound))
    return ConsensusCommandProvider.InvalidConsensusCommand;
// 如果请求共识命令的公钥不在生产节点列表中,返回一个无效时间。
if (!currentRound.IsInMinerList(_processingBlockMinerPubkey))
    return ConsensusCommandProvider.InvalidConsensusCommand;
// 这条链开始运行的时间戳(大致)
var blockchainStartTimestamp = GetBlockchainStartTimestamp();

var behaviour = IsMainChain
    ? new MainChainConsensusBehaviourProvider(currentRound, _processingBlockMinerPubkey,
            GetMaximumBlocksCount(),
            Context.CurrentBlockTime, blockchainStartTimestamp, State.TimeEachTerm.Value)
        .GetConsensusBehaviour()
    : new SideChainConsensusBehaviourProvider(currentRound, _processingBlockMinerPubkey,
        GetMaximumBlocksCount(),
        Context.CurrentBlockTime).GetConsensusBehaviour();

Context.LogDebug(() =>
    $"{currentRound.ToString(_processingBlockMinerPubkey)}\nArranged behaviour: {behaviour.ToString()}");

return behaviour == aelfConsensusBehaviour.Nothing
    ? ConsensusCommandProvider.InvalidConsensusCommand
    : GetConsensusCommand(behaviour, currentRound, _processingBlockMinerPubkey, Context.CurrentBlockTime);

}
在该实现中,代码运行到获得区块链开始运行的时间戳后,获取共识命令分为两个步骤:
1.根据轮次(Round)信息和该条链是主链还是侧链,判断该公钥接下来应该生产一个什么类型的区块,这里描述为Consensus Behaviour;
2.如果能得到一个有效的Consensus Behaviour,再去进一步组装出共识命令(Consensus Command),作为结果返回。
获取Consensus Behaviour
aelf侧链和主链的区别在于,侧链不存在生产节点选举换届等事务(即Consensus Behaviour),在联合挖矿(Merged Mining)设计模式下,侧链共享主链的生产节点,因此与生产节点竞选等事务相关的合约只需要部署在主链上即可。
ConsensusBehaviourProviderBase为主链和侧链共享Consensus Behaviour的实现逻辑。

public override ConsensusCommand GetConsensusCommand(BytesValue input)
{
_processingBlockMinerPubkey = input.Value.ToHex();

if (Context.CurrentHeight < 2) return ConsensusCommandProvider.InvalidConsensusCommand;

// 如果查询不到当前轮次信息,返回一个无效的时间。
if (!TryToGetCurrentRoundInformation(out var currentRound))
    return ConsensusCommandProvider.InvalidConsensusCommand;
// 如果请求共识命令的公钥不在生产节点列表中,返回一个无效时间。
if (!currentRound.IsInMinerList(_processingBlockMinerPubkey))
    return ConsensusCommandProvider.InvalidConsensusCommand;
// 这条链开始运行的时间戳(大致)
var blockchainStartTimestamp = GetBlockchainStartTimestamp();

var behaviour = IsMainChain
    ? new MainChainConsensusBehaviourProvider(currentRound, _processingBlockMinerPubkey,
            GetMaximumBlocksCount(),
            Context.CurrentBlockTime, blockchainStartTimestamp, State.TimeEachTerm.Value)
        .GetConsensusBehaviour()
    : new SideChainConsensusBehaviourProvider(currentRound, _processingBlockMinerPubkey,
        GetMaximumBlocksCount(),
        Context.CurrentBlockTime).GetConsensusBehaviour();

Context.LogDebug(() =>
    $"{currentRound.ToString(_processingBlockMinerPubkey)}\nArranged behaviour: {behaviour.ToString()}");

return behaviour == aelfConsensusBehaviour.Nothing
    ? ConsensusCommandProvider.InvalidConsensusCommand
    : GetConsensusCommand(behaviour, currentRound, _processingBlockMinerPubkey, Context.CurrentBlockTime);

}
在该实现中,代码运行到获得区块链开始运行的时间戳后,获取共识命令分为两个步骤:
1.根据轮次(Round)信息和该条链是主链还是侧链,判断该公钥接下来应该生产一个什么类型的区块,这里描述为Consensus Behaviour;
2.如果能得到一个有效的Consensus Behaviour,再去进一步组装出共识命令(Consensus Command),作为结果返回。
获取Consensus Behaviour
aelf侧链和主链的区别在于,侧链不存在生产节点选举换届等事务(即Consensus Behaviour),在联合挖矿(Merged Mining)设计模式下,侧链共享主链的生产节点,因此与生产节点竞选等事务相关的合约只需要部署在主链上即可。
ConsensusBehaviourProviderBase为主链和侧链共享Consensus Behaviour的实现逻辑。
//
// First step of getting consensus command for any pubkey:
// to get expected consensus behaviour.
//
private abstract class ConsensusBehaviourProviderBase
{
protected readonly Round CurrentRound;
private readonly string _pubkey;
private readonly int _maximumBlocksCount;
private readonly Timestamp _currentBlockTime;
private readonly bool _isTimeSlotPassed;
private readonly MinerInRound _minerInRound;

protected ConsensusBehaviourProviderBase(Round currentRound, string pubkey, int maximumBlocksCount,
    Timestamp currentBlockTime)
{
    CurrentRound = currentRound;
    _pubkey = pubkey;
    _maximumBlocksCount = maximumBlocksCount;
    _currentBlockTime = currentBlockTime;
    _isTimeSlotPassed = CurrentRound.IsTimeSlotPassed(_pubkey, _currentBlockTime);
    _minerInRound = CurrentRound.RealTimeMinersInformation[_pubkey];
}

public aelfConsensusBehaviour GetConsensusBehaviour()
{
    // The most simple situation: provided pubkey isn't a miner.
    if (!CurrentRound.IsInMinerList(_pubkey))
    {
        return aelfConsensusBehaviour.Nothing;
    }
    // If out value is null, it means provided pubkey hasn't mine any block du
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值