From 8b44a51d358c3fcdd32df3f48a8d67644b4328b7 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Tue, 4 Jul 2023 18:51:21 +0900 Subject: [PATCH] feat: handle maj23 when only required --- Libplanet.Net.Tests/Consensus/ContextTest.cs | 17 +++++----- Libplanet.Net/Consensus/ConsensusContext.cs | 34 ++++++++++++++++++++ Libplanet.Net/Consensus/ConsensusReactor.cs | 27 ++++++---------- Libplanet.Net/Consensus/Context.Mutate.cs | 33 ++----------------- Libplanet.Net/Consensus/Context.cs | 28 ++++++++++++++++ 5 files changed, 81 insertions(+), 58 deletions(-) diff --git a/Libplanet.Net.Tests/Consensus/ContextTest.cs b/Libplanet.Net.Tests/Consensus/ContextTest.cs index f4cbec51e6c..4982f1479a1 100644 --- a/Libplanet.Net.Tests/Consensus/ContextTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextTest.cs @@ -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( diff --git a/Libplanet.Net/Consensus/ConsensusContext.cs b/Libplanet.Net/Consensus/ConsensusContext.cs index 2d0cbd42103..a1ee6fa674c 100644 --- a/Libplanet.Net/Consensus/ConsensusContext.cs +++ b/Libplanet.Net/Consensus/ConsensusContext.cs @@ -256,6 +256,40 @@ public bool HandleMessage(ConsensusMsg consensusMessage) } } + /// + /// Handles a received and return message to fetch. + /// + /// The received from any validator. + /// + /// + /// An to reply back. + /// + /// This method does not update state of the context. + 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; + } + /// /// Handles a received and return message to fetch. /// diff --git a/Libplanet.Net/Consensus/ConsensusReactor.cs b/Libplanet.Net/Consensus/ConsensusReactor.cs index 30ce7a23fac..6beab8853fc 100644 --- a/Libplanet.Net/Consensus/ConsensusReactor.cs +++ b/Libplanet.Net/Consensus/ConsensusReactor.cs @@ -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) { diff --git a/Libplanet.Net/Consensus/Context.Mutate.cs b/Libplanet.Net/Consensus/Context.Mutate.cs index 77ff97ce52f..ec8b0e5ee0f 100644 --- a/Libplanet.Net/Consensus/Context.Mutate.cs +++ b/Libplanet.Net/Consensus/Context.Mutate.cs @@ -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) { @@ -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 " + diff --git a/Libplanet.Net/Consensus/Context.cs b/Libplanet.Net/Consensus/Context.cs index 484b0d2d4fa..62905ad27c6 100644 --- a/Libplanet.Net/Consensus/Context.cs +++ b/Libplanet.Net/Consensus/Context.cs @@ -267,6 +267,34 @@ public VoteSetBits GetVoteSetBits(int round, BlockHash blockHash, VoteFlag flag) voteBits).Sign(_privateKey); } + /// + /// Add a to the context. + /// + /// A to add. + /// A if given is valid and + /// required. + 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 GetVoteSetBitsResponse(VoteSetBits voteSetBits) { IEnumerable votes = voteSetBits.Flag switch