Skip to content

Commit

Permalink
feat: delayed consensus step transition
Browse files Browse the repository at this point in the history
  • Loading branch information
limebell committed Dec 6, 2024
1 parent 8577a80 commit cd60cf1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 18 deletions.
34 changes: 34 additions & 0 deletions src/Libplanet.Net/Consensus/Context.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,40 @@ private void AppendBlock(Block block)
_ = Task.Run(() => _blockChain.Append(block, GetBlockCommit()));
}

private async Task EnterPreCommitWait(int round, BlockHash hash)
{
if (!_preCommitWaitFlags.Add(round))
{
return;
}

if (_contextOption.EnterPreCommitDelay > 0)
{
await Task.Delay(
_contextOption.EnterPreCommitDelay,
_cancellationTokenSource.Token);
}

ProduceMutation(() => EnterPreCommit(round, hash));
}

private async Task EnterEndCommitWait(int round)
{
if (!_endCommitWaitFlags.Add(round))
{
return;
}

if (_contextOption.EnterEndCommitDelay > 0)
{
await Task.Delay(
_contextOption.EnterEndCommitDelay,
_cancellationTokenSource.Token);
}

ProduceMutation(() => EnterEndCommit(round));
}

/// <summary>
/// Schedules <see cref="ProcessTimeoutPropose"/> to be queued after
/// <see cref="TimeoutPropose"/> amount of time.
Expand Down
28 changes: 24 additions & 4 deletions src/Libplanet.Net/Consensus/Context.Mutate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ private void ProcessGenericUponRules()
ToString());
_lockedValue = p3.Block;
_lockedRound = Round;
EnterPreCommit(Round, p3.Block.Hash);
_ = EnterPreCommitWait(Round, p3.Block.Hash);

// Maybe need to broadcast periodically?
PublishMessage(
Expand All @@ -329,7 +329,7 @@ private void ProcessGenericUponRules()
"were collected. (context: {Context})",
Round,
ToString());
EnterPreCommit(Round, default);
_ = EnterPreCommitWait(Round, default);
}
else if (Proposal is { } proposal && !proposal.BlockHash.Equals(hash3))
{
Expand Down Expand Up @@ -387,12 +387,12 @@ private void ProcessHeightOrRoundUponRules(ConsensusMsg message)
PublishMessage(
new ConsensusMaj23Msg(
MakeMaj23(round, block4.Hash, VoteFlag.PreCommit)));
EnterEndCommit(Round);
_ = EnterEndCommitWait(Round);
return;
}

// NOTE: +1/3 prevote received, skip round
// FIXME: Tendermint uses +2/3, should fixed?
// FIXME: Tendermint uses +2/3, should be fixed?
if (round > Round &&
_heightVoteSet.PreVotes(round).HasOneThirdsAny())
{
Expand All @@ -409,20 +409,40 @@ private void ProcessHeightOrRoundUponRules(ConsensusMsg message)

private void EnterPreVote(int round, BlockHash hash)
{
if (Round != round || Step >= ConsensusStep.PreVote)
{
// Round and step mismatch
return;
}

Step = ConsensusStep.PreVote;
PublishMessage(
new ConsensusPreVoteMsg(MakeVote(round, hash, VoteFlag.PreVote)));
}

private void EnterPreCommit(int round, BlockHash hash)
{
if (Round != round || Step >= ConsensusStep.PreCommit)
{
// Round and step mismatch
return;
}

Step = ConsensusStep.PreCommit;
PublishMessage(
new ConsensusPreCommitMsg(MakeVote(round, hash, VoteFlag.PreCommit)));
}

private void EnterEndCommit(int round)
{
if (Round != round ||
Step == ConsensusStep.Default ||
Step == ConsensusStep.EndCommit)
{
// Round and step mismatch
return;
}

Step = ConsensusStep.EndCommit;
if (_decision is not { } block)
{
Expand Down
8 changes: 6 additions & 2 deletions src/Libplanet.Net/Consensus/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ public partial class Context : IDisposable
private readonly Channel<System.Action> _mutationRequests;
private readonly HeightVoteSet _heightVoteSet;
private readonly PrivateKey _privateKey;
private readonly HashSet<int> _preVoteTimeoutFlags;
private readonly HashSet<int> _hasTwoThirdsPreVoteFlags;
private readonly HashSet<int> _preVoteTimeoutFlags;
private readonly HashSet<int> _preCommitTimeoutFlags;
private readonly HashSet<int> _preCommitWaitFlags;
private readonly HashSet<int> _endCommitWaitFlags;
private readonly EvidenceExceptionCollector _evidenceCollector
= new EvidenceExceptionCollector();

Expand Down Expand Up @@ -184,9 +186,11 @@ private Context(
_messageRequests = Channel.CreateUnbounded<ConsensusMsg>();
_mutationRequests = Channel.CreateUnbounded<System.Action>();
_heightVoteSet = new HeightVoteSet(height, validators);
_preVoteTimeoutFlags = new HashSet<int>();
_hasTwoThirdsPreVoteFlags = new HashSet<int>();
_preVoteTimeoutFlags = new HashSet<int>();
_preCommitTimeoutFlags = new HashSet<int>();
_preCommitWaitFlags = new HashSet<int>();
_endCommitWaitFlags = new HashSet<int>();
_validatorSet = validators;
_cancellationTokenSource = new CancellationTokenSource();
_blockValidationCache =
Expand Down
24 changes: 12 additions & 12 deletions src/Libplanet.Net/Consensus/ContextOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(proposeTimeoutBase),
"ProposeSecondBase must be greater than 0.");
"ProposeTimeoutBase must be greater than 0.");
}

ProposeTimeoutBase = proposeTimeoutBase;
Expand All @@ -32,7 +32,7 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(preVoteTimeoutBase),
"PreVoteSecondBase must be greater than 0.");
"PreVoteTimeoutBase must be greater than 0.");
}

PreVoteTimeoutBase = preVoteTimeoutBase;
Expand All @@ -41,7 +41,7 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(preCommitTimeoutBase),
"PreCommitSecondBase must be greater than 0.");
"PreCommitTimeoutBase must be greater than 0.");
}

PreCommitTimeoutBase = preCommitTimeoutBase;
Expand All @@ -50,7 +50,7 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(proposeTimeoutDelta),
"ProposeMultiplier must be greater than 0.");
"ProposeTimeoutDelta must be greater than 0.");
}

ProposeTimeoutDelta = proposeTimeoutDelta;
Expand All @@ -59,7 +59,7 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(preVoteTimeoutDelta),
"PreVoteMultiplier must be greater than 0.");
"PreVoteTimeoutDelta must be greater than 0.");
}

PreVoteTimeoutDelta = preVoteTimeoutDelta;
Expand All @@ -68,34 +68,34 @@ public ContextOption(
{
throw new ArgumentOutOfRangeException(
nameof(preCommitTimeoutDelta),
"PreCommitMultiplier must be greater than 0.");
"PreCommitTimeoutDelta must be greater than 0.");
}

PreCommitTimeoutDelta = preCommitTimeoutDelta;

if (enterPreVoteDelay <= 0)
if (enterPreVoteDelay < 0)
{
throw new ArgumentOutOfRangeException(
nameof(enterPreVoteDelay),
"PreCommitMultiplier must be greater than 0.");
"EnterPreVoteDelay must be greater than or equal to 0.");
}

EnterPreVoteDelay = enterPreVoteDelay;

if (enterPreCommitDelay <= 0)
if (enterPreCommitDelay < 0)
{
throw new ArgumentOutOfRangeException(
nameof(enterPreCommitDelay),
"PreCommitMultiplier must be greater than 0.");
"EnterPreCommitDelay must be greater than or equal to 0.");
}

EnterPreCommitDelay = enterPreCommitDelay;

if (enterEndCommitDelay <= 0)
if (enterEndCommitDelay < 0)
{
throw new ArgumentOutOfRangeException(
nameof(enterEndCommitDelay),
"PreCommitMultiplier must be greater than 0.");
"EnterEndCommitDelay must be greater than or equal to 0.");
}

EnterEndCommitDelay = enterEndCommitDelay;
Expand Down

0 comments on commit cd60cf1

Please sign in to comment.