Skip to content

Commit

Permalink
feat: handle maj23 when only required
Browse files Browse the repository at this point in the history
  • Loading branch information
limebell committed Jul 4, 2023
1 parent 8396585 commit 8b44a51
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 58 deletions.
17 changes: 8 additions & 9 deletions Libplanet.Net.Tests/Consensus/ContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -531,15 +531,14 @@ public async void CanReplaceProposal()

// Validator 1 (key1) collected +2/3 pre-vote messages,
// sends maj23 message to context.
var maj23 = new ConsensusMaj23Msg(
new Maj23Metadata(
1,
0,
blockB.Hash,
DateTimeOffset.UtcNow,
key1.PublicKey,
VoteFlag.PreVote).Sign(key1));
context.ProduceMessage(maj23);
var maj23 = new Maj23Metadata(
1,
0,
blockB.Hash,
DateTimeOffset.UtcNow,
key1.PublicKey,
VoteFlag.PreVote).Sign(key1);
context.AddMaj23(maj23);

var preVoteB0 = new ConsensusPreVoteMsg(
new VoteMetadata(
Expand Down
34 changes: 34 additions & 0 deletions Libplanet.Net/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,40 @@ public bool HandleMessage(ConsensusMsg consensusMessage)
}
}

/// <summary>
/// Handles a received <see cref="Maj23"/> and return message to fetch.
/// </summary>
/// <param name="maj23">The <see cref="Maj23"/> received from any validator.
/// </param>
/// <returns>
/// An <see cref="IEnumerable{ConsensusMsg}"/> to reply back.
/// </returns>
/// <remarks>This method does not update state of the context.</remarks>
public VoteSetBits? HandleMaj23(Maj23 maj23)
{
long height = maj23.Height;
if (height < Height)
{
_logger.Debug(
"Ignore a received VoteSetBits as its height " +
"#{Height} is lower than the current context's height #{ContextHeight}",
height,
Height);
}
else
{
lock (_contextLock)
{
if (_contexts.ContainsKey(height))
{
return _contexts[height].AddMaj23(maj23);
}
}
}

return null;
}

/// <summary>
/// Handles a received <see cref="VoteSetBits"/> and return message to fetch.
/// </summary>
Expand Down
27 changes: 9 additions & 18 deletions Libplanet.Net/Consensus/ConsensusReactor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,17 @@ private void ProcessMessage(MessageContent content)
case ConsensusMaj23Msg maj23Msg:
try
{
if (_consensusContext.HandleMessage(maj23Msg))
VoteSetBits? voteSetBits = _consensusContext.HandleMaj23(maj23Msg.Maj23);
if (voteSetBits is null)
{
VoteSetBits voteSetBits = _consensusContext.Contexts[maj23Msg.Height]
.GetVoteSetBits(
maj23Msg.Round,
maj23Msg.Maj23.BlockHash,
maj23Msg.Maj23.Flag);
if (voteSetBits.VoteBits.All(b => b))
{
// No any votes to received, so no need to send reply.
break;
}

var sender = _gossip.Peers.First(
peer => peer.PublicKey.Equals(maj23Msg.ValidatorPublicKey));

_gossip.PublishMessage(
new ConsensusVoteSetBitsMsg(voteSetBits),
new[] { sender });
break;
}

var sender = _gossip.Peers.First(
peer => peer.PublicKey.Equals(maj23Msg.ValidatorPublicKey));
_gossip.PublishMessage(
new ConsensusVoteSetBitsMsg(voteSetBits),
new[] { sender });
}
catch (InvalidOperationException)
{
Expand Down
33 changes: 2 additions & 31 deletions Libplanet.Net/Consensus/Context.Mutate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,28 +126,10 @@ private bool AddMessage(ConsensusMsg message)
voteMsg.ValidatorPublicKey.ToAddress(),
voteMsg.BlockHash,
ToString());
}
else
{
switch (message)
{
case ConsensusMaj23Msg maj23:
_heightVoteSet.SetPeerMaj23(maj23.Maj23);
break;
}

_logger.Debug(
"{FName}: Message: {Message} => Height: {Height}, Round: {Round}, " +
"Validator Address: {VAddress}. (context: {Context})",
nameof(AddMessage),
message,
message.Height,
message.Round,
message.ValidatorPublicKey.ToAddress(),
ToString());
return true;
}

return true;
return false;
}
catch (InvalidProposalException ipe)
{
Expand All @@ -171,17 +153,6 @@ private bool AddMessage(ConsensusMsg message)
ExceptionOccurred?.Invoke(this, icme);
return false;
}
catch (InvalidMaj23Exception ime)
{
var icme = new InvalidConsensusMessageException(
ime.Message,
message);
var msg = $"Failed to add invalid message {message} to the " +
$"{nameof(HeightVoteSet)}";
_logger.Error(icme, msg);
ExceptionOccurred?.Invoke(this, icme);
return false;
}
catch (InvalidConsensusMessageException icme)
{
var msg = $"Failed to add invalid message {message} to the " +
Expand Down
28 changes: 28 additions & 0 deletions Libplanet.Net/Consensus/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,34 @@ public VoteSetBits GetVoteSetBits(int round, BlockHash blockHash, VoteFlag flag)
voteBits).Sign(_privateKey);
}

/// <summary>
/// Add a <see cref="ConsensusMsg"/> to the context.
/// </summary>
/// <param name="maj23">A <see cref="ConsensusMsg"/> to add.</param>
/// <returns>A <see cref="VoteSetBits"/> if given <paramref name="maj23"/> is valid and
/// required.</returns>
public VoteSetBits? AddMaj23(Maj23 maj23)
{
try
{
if (_heightVoteSet.SetPeerMaj23(maj23))
{
var voteSetBits = GetVoteSetBits(maj23.Round, maj23.BlockHash, maj23.Flag);
return voteSetBits.VoteBits.All(b => b) ? null : voteSetBits;
}

return null;
}
catch (InvalidMaj23Exception ime)
{
var msg = $"Failed to add invalid maj23 {ime} to the " +
$"{nameof(HeightVoteSet)}";
_logger.Error(ime, msg);
ExceptionOccurred?.Invoke(this, ime);
return null;
}
}

public IEnumerable<ConsensusMsg> GetVoteSetBitsResponse(VoteSetBits voteSetBits)
{
IEnumerable<Vote> votes = voteSetBits.Flag switch
Expand Down

0 comments on commit 8b44a51

Please sign in to comment.