Skip to content

Commit

Permalink
Merge pull request #4007 from planetarium/feature/delayed-consensus
Browse files Browse the repository at this point in the history
Delayed consensus step transition
  • Loading branch information
limebell authored Dec 12, 2024
2 parents cbd5352 + b17d8aa commit f80d526
Show file tree
Hide file tree
Showing 19 changed files with 472 additions and 225 deletions.
26 changes: 25 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
Libplanet changelog
===================

Version 5.4.2
-------------

To be released.

### Backward-incompatible API changes

- Removed `ContextTimeoutOption` class. Instead, added `ContextOption` class.
The unit of the time-related options in `ContextOption` is millisecond,
whereas `ContextTimeoutOption` was second. [[#4007]]
- Removed `ConsensusReactorOption.ContextTimeoutOptions` property.
Instead, added `ConsensusReactorOption.ContextOption` property. [[#4007]]
- `ConsensusReactor` constructor requires `ContextOption` parameter
instead of the `ContextTimeoutOption` parameter. [[#4007]]

### Behavioral changes

- `Gossip.RebuildTableAsync()` now bootstrap peers from the seed peers.
[[#4007]]


[#4007]: https://github.com/planetarium/libplanet/pull/4007


Version 5.4.1
-------------

Released on November 22, 2024.

- Ported changes from [Libplanet 5.3.2] release. [[#3973]]
- Ported changes from [Libplanet 5.3.2] release. [[#3973]]

[#3973]: https://github.com/planetarium/libplanet/pull/3973
[Libplanet 5.3.2]: https://www.nuget.org/packages/Libplanet/5.3.2
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFrameworks Condition="'$(_IsPacking)'=='true'">net6.0</TargetFrameworks>
<TargetFramework Condition="'$(_IsPacking)'!='true'">net6.0</TargetFramework>
<LangVersion>10</LangVersion>
<VersionPrefix>5.4.1</VersionPrefix>
<VersionPrefix>5.4.2</VersionPrefix>
<!-- Note: don't be confused by the word "prefix" here. It's merely a
version without suffix like "-dev.123". See the following examples:
Version: 1.2.3-dev.456
Expand Down
12 changes: 6 additions & 6 deletions src/Libplanet.Net/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace Libplanet.Net.Consensus
public partial class ConsensusContext : IDisposable
{
private readonly object _contextLock;
private readonly ContextTimeoutOption _contextTimeoutOption;
private readonly ContextOption _contextOption;
private readonly IConsensusMessageCommunicator _consensusMessageCommunicator;
private readonly BlockChain _blockChain;
private readonly PrivateKey _privateKey;
Expand All @@ -58,22 +58,22 @@ private readonly EvidenceExceptionCollector _evidenceCollector
/// <param name="newHeightDelay">A time delay in starting the consensus for the next height
/// block. <seealso cref="OnTipChanged"/>
/// </param>
/// <param name="contextTimeoutOption">A <see cref="ContextTimeoutOption"/> for
/// configuring a timeout for each <see cref="Step"/>.</param>
/// <param name="contextOption">A <see cref="ContextOption"/> for
/// configuring a timeout or delay for each <see cref="Step"/>.</param>
public ConsensusContext(
IConsensusMessageCommunicator consensusMessageCommunicator,
BlockChain blockChain,
PrivateKey privateKey,
TimeSpan newHeightDelay,
ContextTimeoutOption contextTimeoutOption)
ContextOption contextOption)
{
_consensusMessageCommunicator = consensusMessageCommunicator;
_blockChain = blockChain;
_privateKey = privateKey;
Running = false;
_newHeightDelay = newHeightDelay;

_contextTimeoutOption = contextTimeoutOption;
_contextOption = contextOption;
_currentContext = CreateContext(
_blockChain.Tip.Index + 1,
_blockChain.GetBlockCommit(_blockChain.Tip.Index));
Expand Down Expand Up @@ -498,7 +498,7 @@ private Context CreateContext(long height, BlockCommit? lastCommit)
lastCommit,
_privateKey,
validatorSet,
contextTimeoutOptions: _contextTimeoutOption);
contextOption: _contextOption);
return context;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Libplanet.Net/Consensus/ConsensusReactor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class ConsensusReactor : IReactor
/// <param name="newHeightDelay">A time delay in starting the consensus for the next height
/// block.
/// </param>
/// <param name="contextTimeoutOption">A <see cref="ContextTimeoutOption"/> for
/// <param name="contextOption">A <see cref="ContextOption"/> for
/// configuring a timeout for each <see cref="ConsensusStep"/>.</param>
public ConsensusReactor(
ITransport consensusTransport,
Expand All @@ -52,7 +52,7 @@ public ConsensusReactor(
ImmutableList<BoundPeer> validatorPeers,
ImmutableList<BoundPeer> seedPeers,
TimeSpan newHeightDelay,
ContextTimeoutOption contextTimeoutOption)
ContextOption contextOption)
{
validatorPeers ??= ImmutableList<BoundPeer>.Empty;
seedPeers ??= ImmutableList<BoundPeer>.Empty;
Expand All @@ -71,7 +71,7 @@ public ConsensusReactor(
blockChain,
privateKey,
newHeightDelay,
contextTimeoutOption);
contextOption);

_logger = Log
.ForContext("Tag", "Consensus")
Expand Down
6 changes: 3 additions & 3 deletions src/Libplanet.Net/Consensus/ConsensusReactorOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace Libplanet.Net.Consensus
{
/// <summary>
/// A option struct for initializing <see cref="ConsensusReactor"/>.
/// An option struct for initializing <see cref="ConsensusReactor"/>.
/// </summary>
public struct ConsensusReactorOption
{
Expand Down Expand Up @@ -42,8 +42,8 @@ public struct ConsensusReactorOption
public TimeSpan TargetBlockInterval { get; set; }

/// <summary>
/// A timeout second and multiplier value for used in <see cref="Context"/>.
/// A timeout and delay value for used in <see cref="Context"/> in milliseconds.
/// </summary>
public ContextTimeoutOption ContextTimeoutOptions { get; set; }
public ContextOption ContextOption { get; set; }
}
}
56 changes: 56 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 All @@ -212,7 +246,18 @@ private async Task OnTimeoutPropose(int round)
/// <param name="round">A round that the timeout task is scheduled for.</param>
private async Task OnTimeoutPreVote(int round)
{
if (_preCommitTimeoutFlags.Contains(round) || !_preVoteTimeoutFlags.Add(round))
{
return;
}

TimeSpan timeout = TimeoutPreVote(round);
_logger.Debug(
"PreVote step in round {Round} is scheduled to be timed out after {Timeout} " +
"because 2/3+ PreVotes are collected for the round. (context: {Context})",
round,
timeout,
ToString());
await Task.Delay(timeout, _cancellationTokenSource.Token);
_logger.Information(
"TimeoutPreVote has occurred in {Timeout}. {Info}",
Expand All @@ -228,7 +273,18 @@ private async Task OnTimeoutPreVote(int round)
/// <param name="round">The round that the timeout task is scheduled for.</param>
private async Task OnTimeoutPreCommit(int round)
{
if (!_preCommitTimeoutFlags.Add(round))
{
return;
}

TimeSpan timeout = TimeoutPreCommit(round);
_logger.Debug(
"PreCommit step in round {Round} is scheduled to be timed out in {Timeout} " +
"because 2/3+ PreCommits are collected for the round. (context: {Context})",
round,
timeout,
ToString());
await Task.Delay(timeout, _cancellationTokenSource.Token);
_logger.Information(
"TimeoutPreCommit has occurred in {Timeout}. {Info}",
Expand Down
Loading

0 comments on commit f80d526

Please sign in to comment.