Skip to content

Commit

Permalink
test: add unit test for delayed consensus
Browse files Browse the repository at this point in the history
  • Loading branch information
limebell committed Dec 7, 2024
1 parent 3831106 commit 611edf4
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions test/Libplanet.Net.Tests/Consensus/ContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using Serilog;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace Libplanet.Net.Tests.Consensus
{
Expand Down Expand Up @@ -715,6 +716,91 @@ public async Task CanCreateContextWithLastingEvaluation()
Assert.Equal(2, consensusContext.Height);
}

[Theory(Timeout = Timeout)]
[InlineData(0)]
[InlineData(100)]
[InlineData(500)]
public async Task CanCollectPreVoteAfterMajority(int delay)
{
var stepChangedToPreVote = new AsyncAutoResetEvent();
var stepChangedToPreCommit = new AsyncAutoResetEvent();
Block? proposedBlock = null;
int numPreVotes = 0;
var (_, context) = TestUtils.CreateDummyContext(
contextOption: new ContextOption(
enterPreCommitDelay: delay));
context.StateChanged += (_, eventArgs) =>
{
if (eventArgs.Step == ConsensusStep.PreVote)
{
stepChangedToPreVote.Set();
}
else if (eventArgs.Step == ConsensusStep.PreCommit)
{
stepChangedToPreCommit.Set();
}
};
context.MessageToPublish += (_, message) =>
{
if (message is ConsensusProposalMsg proposalMsg)
{
proposedBlock = BlockMarshaler.UnmarshalBlock(
(Dictionary)new Codec().Decode(proposalMsg!.Proposal.MarshaledBlock));
}
};
context.VoteSetModified += (_, tuple) =>
{
if (tuple.Flag == VoteFlag.PreVote)
{
numPreVotes = tuple.Votes.Count();
}
};
context.Start();
await stepChangedToPreVote.WaitAsync();
Assert.Equal(ConsensusStep.PreVote, context.Step);
if (proposedBlock is not { } block)
{
throw new XunitException("No proposal is made");
}

for (int i = 0; i < 3; i++)
{
context.ProduceMessage(
new ConsensusPreVoteMsg(
new VoteMetadata(
block.Index,
0,
block.Hash,
DateTimeOffset.UtcNow,
TestUtils.PrivateKeys[i].PublicKey,
TestUtils.ValidatorSet[i].Power,
VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[i])));
}

// Send delayed PreVote message after sending preCommit message
var cts = new CancellationTokenSource();
const int preVoteDelay = 300;
_ = Task.Run(
async () =>
{
await Task.Delay(preVoteDelay, cts.Token);
context.ProduceMessage(
new ConsensusPreVoteMsg(
new VoteMetadata(
block.Index,
0,
block.Hash,
DateTimeOffset.UtcNow,
TestUtils.PrivateKeys[3].PublicKey,
TestUtils.ValidatorSet[3].Power,
VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[3])));
}, cts.Token);

await stepChangedToPreCommit.WaitAsync();
cts.Cancel();
Assert.Equal(delay < preVoteDelay ? 3 : 4, numPreVotes);
}

public struct ContextJson
{
#pragma warning disable SA1300
Expand Down

0 comments on commit 611edf4

Please sign in to comment.