Skip to content

Commit f185fce

Browse files
authored
Merge pull request #4008 from planetarium/feature/delayed-consensus
Feature/delayed consensus
2 parents bff17d3 + b17d8aa commit f185fce

19 files changed

+467
-226
lines changed

CHANGES.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,31 @@ Version 5.4.2
66

77
To be released.
88

9+
### Backward-incompatible API changes
10+
11+
- Removed `ContextTimeoutOption` class. Instead, added `ContextOption` class.
12+
The unit of the time-related options in `ContextOption` is millisecond,
13+
whereas `ContextTimeoutOption` was second. [[#4007]]
14+
- Removed `ConsensusReactorOption.ContextTimeoutOptions` property.
15+
Instead, added `ConsensusReactorOption.ContextOption` property. [[#4007]]
16+
- `ConsensusReactor` constructor requires `ContextOption` parameter
17+
instead of the `ContextTimeoutOption` parameter. [[#4007]]
18+
19+
### Behavioral changes
20+
21+
- `Gossip.RebuildTableAsync()` now bootstrap peers from the seed peers.
22+
[[#4007]]
23+
24+
25+
[#4007]: https://github.com/planetarium/libplanet/pull/4007
26+
927

1028
Version 5.4.1
1129
-------------
1230

1331
Released on November 22, 2024.
1432

15-
- Ported changes from [Libplanet 5.3.2] release. [[#3973]]
33+
- Ported changes from [Libplanet 5.3.2] release. [[#3973]]
1634

1735
[#3973]: https://github.com/planetarium/libplanet/pull/3973
1836
[Libplanet 5.3.2]: https://www.nuget.org/packages/Libplanet/5.3.2

src/Libplanet.Net/Consensus/ConsensusContext.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace Libplanet.Net.Consensus
3232
public partial class ConsensusContext : IDisposable
3333
{
3434
private readonly object _contextLock;
35-
private readonly ContextTimeoutOption _contextTimeoutOption;
35+
private readonly ContextOption _contextOption;
3636
private readonly IConsensusMessageCommunicator _consensusMessageCommunicator;
3737
private readonly BlockChain _blockChain;
3838
private readonly PrivateKey _privateKey;
@@ -58,22 +58,22 @@ private readonly EvidenceExceptionCollector _evidenceCollector
5858
/// <param name="newHeightDelay">A time delay in starting the consensus for the next height
5959
/// block. <seealso cref="OnTipChanged"/>
6060
/// </param>
61-
/// <param name="contextTimeoutOption">A <see cref="ContextTimeoutOption"/> for
62-
/// configuring a timeout for each <see cref="Step"/>.</param>
61+
/// <param name="contextOption">A <see cref="ContextOption"/> for
62+
/// configuring a timeout or delay for each <see cref="Step"/>.</param>
6363
public ConsensusContext(
6464
IConsensusMessageCommunicator consensusMessageCommunicator,
6565
BlockChain blockChain,
6666
PrivateKey privateKey,
6767
TimeSpan newHeightDelay,
68-
ContextTimeoutOption contextTimeoutOption)
68+
ContextOption contextOption)
6969
{
7070
_consensusMessageCommunicator = consensusMessageCommunicator;
7171
_blockChain = blockChain;
7272
_privateKey = privateKey;
7373
Running = false;
7474
_newHeightDelay = newHeightDelay;
7575

76-
_contextTimeoutOption = contextTimeoutOption;
76+
_contextOption = contextOption;
7777
_currentContext = CreateContext(
7878
_blockChain.Tip.Index + 1,
7979
_blockChain.GetBlockCommit(_blockChain.Tip.Index));
@@ -498,7 +498,7 @@ private Context CreateContext(long height, BlockCommit? lastCommit)
498498
lastCommit,
499499
_privateKey,
500500
validatorSet,
501-
contextTimeoutOptions: _contextTimeoutOption);
501+
contextOption: _contextOption);
502502
return context;
503503
}
504504

src/Libplanet.Net/Consensus/ConsensusReactor.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class ConsensusReactor : IReactor
4343
/// <param name="newHeightDelay">A time delay in starting the consensus for the next height
4444
/// block.
4545
/// </param>
46-
/// <param name="contextTimeoutOption">A <see cref="ContextTimeoutOption"/> for
46+
/// <param name="contextOption">A <see cref="ContextOption"/> for
4747
/// configuring a timeout for each <see cref="ConsensusStep"/>.</param>
4848
public ConsensusReactor(
4949
ITransport consensusTransport,
@@ -52,7 +52,7 @@ public ConsensusReactor(
5252
ImmutableList<BoundPeer> validatorPeers,
5353
ImmutableList<BoundPeer> seedPeers,
5454
TimeSpan newHeightDelay,
55-
ContextTimeoutOption contextTimeoutOption)
55+
ContextOption contextOption)
5656
{
5757
validatorPeers ??= ImmutableList<BoundPeer>.Empty;
5858
seedPeers ??= ImmutableList<BoundPeer>.Empty;
@@ -71,7 +71,7 @@ public ConsensusReactor(
7171
blockChain,
7272
privateKey,
7373
newHeightDelay,
74-
contextTimeoutOption);
74+
contextOption);
7575

7676
_logger = Log
7777
.ForContext("Tag", "Consensus")

src/Libplanet.Net/Consensus/ConsensusReactorOption.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace Libplanet.Net.Consensus
88
{
99
/// <summary>
10-
/// A option struct for initializing <see cref="ConsensusReactor"/>.
10+
/// An option struct for initializing <see cref="ConsensusReactor"/>.
1111
/// </summary>
1212
public struct ConsensusReactorOption
1313
{
@@ -42,8 +42,8 @@ public struct ConsensusReactorOption
4242
public TimeSpan TargetBlockInterval { get; set; }
4343

4444
/// <summary>
45-
/// A timeout second and multiplier value for used in <see cref="Context"/>.
45+
/// A timeout and delay value for used in <see cref="Context"/> in milliseconds.
4646
/// </summary>
47-
public ContextTimeoutOption ContextTimeoutOptions { get; set; }
47+
public ContextOption ContextOption { get; set; }
4848
}
4949
}

src/Libplanet.Net/Consensus/Context.Async.cs

+56
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,40 @@ private void AppendBlock(Block block)
189189
_ = Task.Run(() => _blockChain.Append(block, GetBlockCommit()));
190190
}
191191

192+
private async Task EnterPreCommitWait(int round, BlockHash hash)
193+
{
194+
if (!_preCommitWaitFlags.Add(round))
195+
{
196+
return;
197+
}
198+
199+
if (_contextOption.EnterPreCommitDelay > 0)
200+
{
201+
await Task.Delay(
202+
_contextOption.EnterPreCommitDelay,
203+
_cancellationTokenSource.Token);
204+
}
205+
206+
ProduceMutation(() => EnterPreCommit(round, hash));
207+
}
208+
209+
private async Task EnterEndCommitWait(int round)
210+
{
211+
if (!_endCommitWaitFlags.Add(round))
212+
{
213+
return;
214+
}
215+
216+
if (_contextOption.EnterEndCommitDelay > 0)
217+
{
218+
await Task.Delay(
219+
_contextOption.EnterEndCommitDelay,
220+
_cancellationTokenSource.Token);
221+
}
222+
223+
ProduceMutation(() => EnterEndCommit(round));
224+
}
225+
192226
/// <summary>
193227
/// Schedules <see cref="ProcessTimeoutPropose"/> to be queued after
194228
/// <see cref="TimeoutPropose"/> amount of time.
@@ -212,7 +246,18 @@ private async Task OnTimeoutPropose(int round)
212246
/// <param name="round">A round that the timeout task is scheduled for.</param>
213247
private async Task OnTimeoutPreVote(int round)
214248
{
249+
if (_preCommitTimeoutFlags.Contains(round) || !_preVoteTimeoutFlags.Add(round))
250+
{
251+
return;
252+
}
253+
215254
TimeSpan timeout = TimeoutPreVote(round);
255+
_logger.Debug(
256+
"PreVote step in round {Round} is scheduled to be timed out after {Timeout} " +
257+
"because 2/3+ PreVotes are collected for the round. (context: {Context})",
258+
round,
259+
timeout,
260+
ToString());
216261
await Task.Delay(timeout, _cancellationTokenSource.Token);
217262
_logger.Information(
218263
"TimeoutPreVote has occurred in {Timeout}. {Info}",
@@ -228,7 +273,18 @@ private async Task OnTimeoutPreVote(int round)
228273
/// <param name="round">The round that the timeout task is scheduled for.</param>
229274
private async Task OnTimeoutPreCommit(int round)
230275
{
276+
if (!_preCommitTimeoutFlags.Add(round))
277+
{
278+
return;
279+
}
280+
231281
TimeSpan timeout = TimeoutPreCommit(round);
282+
_logger.Debug(
283+
"PreCommit step in round {Round} is scheduled to be timed out in {Timeout} " +
284+
"because 2/3+ PreCommits are collected for the round. (context: {Context})",
285+
round,
286+
timeout,
287+
ToString());
232288
await Task.Delay(timeout, _cancellationTokenSource.Token);
233289
_logger.Information(
234290
"TimeoutPreCommit has occurred in {Timeout}. {Info}",

0 commit comments

Comments
 (0)