From efc476d39011dc5b1a4eb751542ca114a59da3cd Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 3 Nov 2022 19:40:19 +0600 Subject: [PATCH 001/133] Add repository for message envelope --- src/Lachain.Storage/EntryPrefix.cs | 1 + .../IMessageEnvelopeRepository.cs | 10 +++++++ .../Repositories/MessageEnvelopeRepository.cs | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs create mode 100644 src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs diff --git a/src/Lachain.Storage/EntryPrefix.cs b/src/Lachain.Storage/EntryPrefix.cs index f9b286c84..9c88a85ab 100644 --- a/src/Lachain.Storage/EntryPrefix.cs +++ b/src/Lachain.Storage/EntryPrefix.cs @@ -55,6 +55,7 @@ public enum EntryPrefix : short /* consensus */ ConsensusState = 0x0b01, KeyGenState = 0x0b02, + MessageEnvelope = 0xb03, /* validator attendance */ ValidatorAttendanceState = 0x0c01, diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs new file mode 100644 index 000000000..cd4a9621d --- /dev/null +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Lachain.Storage.Repositories +{ + public interface IMessageEnvelopeRepository + { + void SaveMessages(byte[] keygenState); + byte[] LoadMessages(); + } +} \ No newline at end of file diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs new file mode 100644 index 000000000..a3443ced4 --- /dev/null +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using Lachain.Proto; + +namespace Lachain.Storage.Repositories +{ + public class RootProtocolMessageRepository : IMessageEnvelopeRepository + { + private readonly IRocksDbContext _rocksDbContext; + + public RootProtocolMessageRepository(IRocksDbContext rocksDbContext) + { + _rocksDbContext = rocksDbContext ?? throw new ArgumentNullException(nameof(rocksDbContext)); + } + + public void SaveMessages(byte[] messages) + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(); + _rocksDbContext.Save(key, messages); + } + + public byte[] LoadMessages() + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(); + return _rocksDbContext.Get(key); + } + } +} \ No newline at end of file From 66ba32b6d25832cb949df5e9c50bdea1630d4d5b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 3 Nov 2022 19:57:41 +0600 Subject: [PATCH 002/133] Add classes for saving message envelopes to repo --- .../Messages/MeasageEnvelopeList.cs | 43 +++++++++++++++ .../MessageEnvelopeRepositoryManager.cs | 53 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs create mode 100644 src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs diff --git a/src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs new file mode 100644 index 000000000..56e513b1f --- /dev/null +++ b/src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace Lachain.Consensus.Messages +{ + public class MessageEnvelopeList + { + public long era { get; } + public ICollection messageList { get; } + + + public MessageEnvelopeList(long era) + { + this.era = era; + this.messageList = new List(); + } + + public void addMessage(MessageEnvelope messageEnvelope) + { + messageList.Add(messageEnvelope); + } + + public byte[] ToBytes() + { + throw new NotImplementedException(); + // var a = new List + // { + // era.ToBytes().ToArray() + // }; + // foreach (var message in _messageList) + // { + // a.Add(message.ToBytes()); + // } + // + // return RLP.EncodeList(a.Select(RLP.EncodeElement).ToArray()); + } + + public static MessageEnvelopeList FromBytes(byte[] bytes) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs new file mode 100644 index 000000000..518ebbaa9 --- /dev/null +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Lachain.Storage.Repositories; + +namespace Lachain.Consensus.Messages +{ + public class RootProtocolMessageRepositoryManager + { + private IMessageEnvelopeRepository _repository; + private MessageEnvelopeList _messageEnvelopeList; + + public RootProtocolMessageRepositoryManager(IMessageEnvelopeRepository repository) + { + _repository = repository; + var bytes = repository.LoadMessages(); + _messageEnvelopeList = MessageEnvelopeList.FromBytes(bytes); + } + + public long GetEra() + { + return _messageEnvelopeList.era; + } + + public void StartEra(long era) + { + if (_messageEnvelopeList.era == era) + { + throw new ArgumentException($"Start Era called with same era number {era}"); + } + else + { + _messageEnvelopeList = new MessageEnvelopeList(era); + SaveToDb(_messageEnvelopeList); + } + } + + public void AddMessage(MessageEnvelope message) + { + _messageEnvelopeList.addMessage(message); + SaveToDb(_messageEnvelopeList); + } + + public ICollection GetMessages() + { + return _messageEnvelopeList.messageList; + } + + private void SaveToDb(MessageEnvelopeList messageEnvelopeList) + { + _repository.SaveMessages(messageEnvelopeList.ToBytes()); + } + } +} \ No newline at end of file From 0194b98f7f5b147a2acf8ea5de5dd58f010b9e54 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 3 Nov 2022 20:04:05 +0600 Subject: [PATCH 003/133] Add messageEnvelope Repo to constructor and constructor calls --- .../{MeasageEnvelopeList.cs => MessageEnvelopeList.cs} | 0 src/Lachain.Core/Consensus/ConsensusManager.cs | 9 +++++++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 10 +++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) rename src/Lachain.Consensus/Messages/{MeasageEnvelopeList.cs => MessageEnvelopeList.cs} (100%) diff --git a/src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs similarity index 100% rename from src/Lachain.Consensus/Messages/MeasageEnvelopeList.cs rename to src/Lachain.Consensus/Messages/MessageEnvelopeList.cs diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index 0ee52cf68..e251b5f79 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -31,6 +31,7 @@ public class ConsensusManager : IConsensusManager private readonly IConsensusMessageDeliverer _consensusMessageDeliverer; private readonly IValidatorManager _validatorManager; private readonly IValidatorAttendanceRepository _validatorAttendanceRepository; + private readonly IMessageEnvelopeRepository _messageEnvelopeRepository; private readonly INetworkManager _networkManager; private readonly IBlockProducer _blockProducer; private readonly IBlockManager _blockManager; @@ -58,6 +59,7 @@ public ConsensusManager( IBlockSynchronizer blockSynchronizer, IPrivateWallet privateWallet, IValidatorAttendanceRepository validatorAttendanceRepository, + IMessageEnvelopeRepository messageEnvelopeRepository, IConfigManager configManager, INetworkManager networkManager, IKeyGenManager keyGenManager @@ -69,6 +71,7 @@ IKeyGenManager keyGenManager _blockManager = blockManager; _privateWallet = privateWallet; _validatorAttendanceRepository = validatorAttendanceRepository; + _messageEnvelopeRepository = messageEnvelopeRepository; _networkManager = networkManager; _keyGenManager = keyGenManager; _terminated = false; @@ -181,7 +184,8 @@ private void FinishEra() CurrentEra += 1; _eras[CurrentEra] = new EraBroadcaster( - CurrentEra, _consensusMessageDeliverer, _privateWallet, _validatorAttendanceRepository + CurrentEra, _consensusMessageDeliverer, _privateWallet, + _validatorAttendanceRepository, _messageEnvelopeRepository ); Logger.LogTrace($"Current Era is advanced. Current Era: {CurrentEra}"); } @@ -196,7 +200,8 @@ private void Run(ulong startingEra) { Logger.LogTrace("Create EraBroadcaster"); _eras[CurrentEra] = new EraBroadcaster( - CurrentEra, _consensusMessageDeliverer, _privateWallet, _validatorAttendanceRepository + CurrentEra, _consensusMessageDeliverer, _privateWallet, + _validatorAttendanceRepository, _messageEnvelopeRepository ); } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index bd2193443..578672630 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -36,6 +36,7 @@ public class EraBroadcaster : IConsensusBroadcaster private readonly IMessageFactory _messageFactory; private readonly IPrivateWallet _wallet; private readonly IValidatorAttendanceRepository _validatorAttendanceRepository; + private readonly IMessageEnvelopeRepository _messageEnvelopeRepository; private bool _terminated; private int _myIdx; private IPublicConsensusKeySet? _validators; @@ -59,7 +60,8 @@ public class EraBroadcaster : IConsensusBroadcaster public EraBroadcaster( long era, IConsensusMessageDeliverer consensusMessageDeliverer, - IPrivateWallet wallet, IValidatorAttendanceRepository validatorAttendanceRepository + IPrivateWallet wallet, IValidatorAttendanceRepository validatorAttendanceRepository, + IMessageEnvelopeRepository messageEnvelopeRepository ) { _consensusMessageDeliverer = consensusMessageDeliverer; @@ -69,6 +71,7 @@ public EraBroadcaster( _era = era; _myIdx = -1; _validatorAttendanceRepository = validatorAttendanceRepository; + _messageEnvelopeRepository = messageEnvelopeRepository; } public void SetValidatorKeySet(IPublicConsensusKeySet keySet) @@ -108,6 +111,11 @@ public void Broadcast(ConsensusMessage message) } } + public void RestoreState() + { + + } + public void SendToValidator(ConsensusMessage message, int index) { message.Validator = new Validator {Era = _era}; From a955e305b26a9c05650ec755111772037eaf10af Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 3 Nov 2022 20:20:28 +0600 Subject: [PATCH 004/133] Implement Restore Messages for ConsensusMessages --- .../Messages/MessageEnvelopeRepositoryManager.cs | 4 ++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 518ebbaa9..2fab851d6 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -4,12 +4,12 @@ namespace Lachain.Consensus.Messages { - public class RootProtocolMessageRepositoryManager + public class MessageEnvelopeRepositoryManager { private IMessageEnvelopeRepository _repository; private MessageEnvelopeList _messageEnvelopeList; - public RootProtocolMessageRepositoryManager(IMessageEnvelopeRepository repository) + public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { _repository = repository; var bytes = repository.LoadMessages(); diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 578672630..46920352b 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -36,7 +36,7 @@ public class EraBroadcaster : IConsensusBroadcaster private readonly IMessageFactory _messageFactory; private readonly IPrivateWallet _wallet; private readonly IValidatorAttendanceRepository _validatorAttendanceRepository; - private readonly IMessageEnvelopeRepository _messageEnvelopeRepository; + private readonly MessageEnvelopeRepositoryManager _messageEnvelopeRepositoryManager; private bool _terminated; private int _myIdx; private IPublicConsensusKeySet? _validators; @@ -71,7 +71,7 @@ IMessageEnvelopeRepository messageEnvelopeRepository _era = era; _myIdx = -1; _validatorAttendanceRepository = validatorAttendanceRepository; - _messageEnvelopeRepository = messageEnvelopeRepository; + _messageEnvelopeRepositoryManager = new MessageEnvelopeRepositoryManager(messageEnvelopeRepository); } public void SetValidatorKeySet(IPublicConsensusKeySet keySet) @@ -113,7 +113,17 @@ public void Broadcast(ConsensusMessage message) public void RestoreState() { - + foreach (var messageEnvelope in _messageEnvelopeRepositoryManager.GetMessages()) + { + if (messageEnvelope.External) + { + Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); + } + else + { + throw new NotImplementedException(); + } + } } public void SendToValidator(ConsensusMessage message, int index) From 8cb75a4b0e00ea1b7fb902b0fd7c387929f7192b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 15:58:23 +0600 Subject: [PATCH 005/133] Implement Restoring Protocol Request and Protocol Response --- .../Messages/MessageEnvelope.cs | 6 +- src/Lachain.Core/Consensus/EraBroadcaster.cs | 63 ++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index 32be15df2..17ca30ede 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -4,6 +4,8 @@ namespace Lachain.Consensus.Messages { public class MessageEnvelope { + public const string PROTOCOL_REQUEST = "ProtocolRequest"; + public const string PROTOCOL_RESPONSE = "ProtocolResponse"; public ConsensusMessage? ExternalMessage { get; } public int ValidatorIndex { get; } @@ -29,8 +31,8 @@ public string TypeString() { if (External) return ExternalMessage!.PayloadCase.ToString(); return InternalMessage!.GetType().GetGenericTypeDefinition().Name.Contains("Request") - ? "ProtocolRequest" - : "ProtocolResponse"; + ? PROTOCOL_REQUEST + : PROTOCOL_RESPONSE; } } } \ No newline at end of file diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 46920352b..a1b15dd20 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -15,6 +15,8 @@ using Lachain.Core.Blockchain.SystemContracts; using Lachain.Core.Blockchain.Validators; using Lachain.Core.Vault; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; using Lachain.Networking; using Lachain.Proto; using Lachain.Storage.Repositories; @@ -119,9 +121,68 @@ public void RestoreState() { Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); } + else if (messageEnvelope.TypeString() == MessageEnvelope.PROTOCOL_REQUEST) + { + switch (messageEnvelope.InternalMessage) + { + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + default: + throw new InvalidOperationException("Unexpected template parameters for ProtocolRequest"); + } + } + else if (messageEnvelope.TypeString() == MessageEnvelope.PROTOCOL_RESPONSE) + { + switch (messageEnvelope.InternalMessage) + { + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + default: + throw new InvalidOperationException("Unexpected template parameters for ProtocolResponse"); + } + + } else { - throw new NotImplementedException(); + throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); } } } From a5d2c8e7e1d82a39c50024a1ec80bdbf4fbc6fed Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 16:08:23 +0600 Subject: [PATCH 006/133] Register MessageEnvelope Repository --- src/Lachain.Core/DI/Modules/StorageModule.cs | 1 + src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Core/DI/Modules/StorageModule.cs b/src/Lachain.Core/DI/Modules/StorageModule.cs index ae3fe73a7..aa12a88ab 100644 --- a/src/Lachain.Core/DI/Modules/StorageModule.cs +++ b/src/Lachain.Core/DI/Modules/StorageModule.cs @@ -30,6 +30,7 @@ public void Register(IContainerBuilder containerBuilder, IConfigManager configMa containerBuilder.RegisterSingleton(); containerBuilder.RegisterSingleton(); containerBuilder.RegisterSingleton(); + containerBuilder.RegisterSingleton(); containerBuilder.RegisterSingleton(); /* database query */ diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index a3443ced4..5b3b05042 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -4,11 +4,11 @@ namespace Lachain.Storage.Repositories { - public class RootProtocolMessageRepository : IMessageEnvelopeRepository + public class MessageEnvelopeRepository : IMessageEnvelopeRepository { private readonly IRocksDbContext _rocksDbContext; - public RootProtocolMessageRepository(IRocksDbContext rocksDbContext) + public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) { _rocksDbContext = rocksDbContext ?? throw new ArgumentNullException(nameof(rocksDbContext)); } From ca30a45ecaf8d8159d8cdb138625dae1ee6c041b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 16:08:52 +0600 Subject: [PATCH 007/133] Call RestoreState() in Consensus Manager --- src/Lachain.Core/Consensus/ConsensusManager.cs | 1 + src/Lachain.Core/Consensus/EraBroadcaster.cs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index e251b5f79..eb799c4bb 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -232,6 +232,7 @@ private void Run(ulong startingEra) { broadcaster = _eras[CurrentEra]; broadcaster.SetValidatorKeySet(validators); + broadcaster.RestoreState(); } bool weAreValidator; diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index a1b15dd20..83e6f8f3e 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -178,7 +178,6 @@ public void RestoreState() default: throw new InvalidOperationException("Unexpected template parameters for ProtocolResponse"); } - } else { From 562efc5258c90c017e269b2e3f6f96f0abac62a9 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 18:24:05 +0600 Subject: [PATCH 008/133] Add ByteSerializable Interface --- .../Serialization/IByteSerializable.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/Lachain.Utility/Serialization/IByteSerializable.cs diff --git a/src/Lachain.Utility/Serialization/IByteSerializable.cs b/src/Lachain.Utility/Serialization/IByteSerializable.cs new file mode 100644 index 000000000..2a1d32ccf --- /dev/null +++ b/src/Lachain.Utility/Serialization/IByteSerializable.cs @@ -0,0 +1,11 @@ +using System; + +namespace Lachain.Utility.Serialization +{ + public interface IByteSerializable + { + // When implementing this interface make sure to implement also following methods: + // public static MyClass FromBytes(byte[] bytes); + public byte[] ToBytes(); + } +} \ No newline at end of file From 514da2cda81076831b174960c60dbb64824305ec Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 18:24:25 +0600 Subject: [PATCH 009/133] Serialize MessageEnvelopeList --- .../Messages/MessageEnvelope.cs | 13 +++++- .../Messages/MessageEnvelopeList.cs | 41 +++++++++++++------ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index 17ca30ede..50126f399 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -1,8 +1,9 @@ using Lachain.Proto; +using Lachain.Utility.Serialization; namespace Lachain.Consensus.Messages { - public class MessageEnvelope + public class MessageEnvelope : IByteSerializable { public const string PROTOCOL_REQUEST = "ProtocolRequest"; public const string PROTOCOL_RESPONSE = "ProtocolResponse"; @@ -34,5 +35,15 @@ public string TypeString() ? PROTOCOL_REQUEST : PROTOCOL_RESPONSE; } + + public byte[] ToBytes() + { + throw new System.NotImplementedException(); + } + + public static MessageEnvelope FromBytes(byte[] bytes) + { + throw new System.NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index 56e513b1f..fc64e91d8 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.Linq; +using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Consensus.Messages { - public class MessageEnvelopeList + public class MessageEnvelopeList : IByteSerializable { public long era { get; } public ICollection messageList { get; } @@ -22,22 +25,34 @@ public void addMessage(MessageEnvelope messageEnvelope) public byte[] ToBytes() { - throw new NotImplementedException(); - // var a = new List - // { - // era.ToBytes().ToArray() - // }; - // foreach (var message in _messageList) - // { - // a.Add(message.ToBytes()); - // } - // - // return RLP.EncodeList(a.Select(RLP.EncodeElement).ToArray()); + var list = new List(); + + list.Add(era.ToBytes().ToArray()); + list.Add(messageList.Count.ToBytes().ToArray()); + + foreach (var message in messageList) + { + list.Add(message.ToBytes()); + } + + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } public static MessageEnvelopeList FromBytes(byte[] bytes) { - throw new NotImplementedException(); + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + var count = decoded[1].RLPData.AsReadOnlySpan().ToInt32(); + + var messageEnvelopeList = new MessageEnvelopeList(era); + + for (int i = 0; i < count; i++) + { + var envelopeBytes = decoded[2 + i].RLPData; + messageEnvelopeList.addMessage(MessageEnvelope.FromBytes(envelopeBytes)); + } + + return messageEnvelopeList; } } } \ No newline at end of file From 0325673f1d714391d55ec353a5c1059315e5a48c Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 20:46:43 +0600 Subject: [PATCH 010/133] Add isProtocolRequest and isProtocolResponse properties --- src/Lachain.Consensus/Messages/MessageEnvelope.cs | 2 ++ src/Lachain.Core/Consensus/EraBroadcaster.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index 50126f399..ab68c37c3 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -27,6 +27,8 @@ public MessageEnvelope(IInternalMessage msg, int validatorIndex) } public bool External => !(ExternalMessage is null); + public bool isProtocolRequest => !(InternalMessage is null) && TypeString() == PROTOCOL_REQUEST; + public bool isProtocolResponse => !(InternalMessage is null) && TypeString() == PROTOCOL_RESPONSE; public string TypeString() { diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 83e6f8f3e..9651ab4e6 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -121,7 +121,7 @@ public void RestoreState() { Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); } - else if (messageEnvelope.TypeString() == MessageEnvelope.PROTOCOL_REQUEST) + else if (messageEnvelope.isProtocolRequest) { switch (messageEnvelope.InternalMessage) { @@ -150,7 +150,7 @@ public void RestoreState() throw new InvalidOperationException("Unexpected template parameters for ProtocolRequest"); } } - else if (messageEnvelope.TypeString() == MessageEnvelope.PROTOCOL_RESPONSE) + else if (messageEnvelope.isProtocolResponse) { switch (messageEnvelope.InternalMessage) { From 4c25266d1392f3bd1cf8356cfdb9e8636c2998c5 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 21:38:04 +0600 Subject: [PATCH 011/133] Add protocol Type enum and helper methods --- src/Lachain.Consensus/ProtocolType.cs | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/Lachain.Consensus/ProtocolType.cs diff --git a/src/Lachain.Consensus/ProtocolType.cs b/src/Lachain.Consensus/ProtocolType.cs new file mode 100644 index 000000000..254b62be0 --- /dev/null +++ b/src/Lachain.Consensus/ProtocolType.cs @@ -0,0 +1,47 @@ +using System; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; + +namespace Lachain.Consensus +{ + public enum ProtocolType: int + { + BinaryAgreement = 1, + BinaryBroadcast = 2, + CommonCoin = 3, + CommonSubset = 4, + HoneyBadger = 5, + ReliableBroadcast = 6, + RootProtocol = 7, + } + + public static class ProtocolTypeMethods + { + public static ProtocolType getProtocolType(IProtocolIdentifier id) + { + switch (id) + { + case BinaryAgreementId _: + return ProtocolType.BinaryAgreement; + case BinaryBroadcastId _: + return ProtocolType.BinaryBroadcast; + case CoinId _: + return ProtocolType.CommonCoin; + case CommonSubsetId _: + return ProtocolType.CommonSubset; + case HoneyBadgerId _: + return ProtocolType.HoneyBadger; + case ReliableBroadcastId _: + return ProtocolType.ReliableBroadcast; + case RootProtocolId _: + return ProtocolType.RootProtocol; + default: + throw new ArgumentException("Unknown protocol type"); + } + } + } +} \ No newline at end of file From 088dada3b366f7626c155be604b69f270c7da429 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 4 Nov 2022 22:20:57 +0600 Subject: [PATCH 012/133] Serialize MessageEnvelope --- .../Messages/IInternalMessage.cs | 4 +- .../Messages/MessageEnvelope.cs | 106 +++++++++++++++++- .../Messages/ProtocolRequest.cs | 11 ++ .../Messages/ProtocolResult.cs | 11 ++ 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/IInternalMessage.cs b/src/Lachain.Consensus/Messages/IInternalMessage.cs index 2c4999440..f5b5d767d 100644 --- a/src/Lachain.Consensus/Messages/IInternalMessage.cs +++ b/src/Lachain.Consensus/Messages/IInternalMessage.cs @@ -1,6 +1,8 @@ +using Lachain.Utility.Serialization; + namespace Lachain.Consensus.Messages { - public interface IInternalMessage + public interface IInternalMessage: IByteSerializable { IProtocolIdentifier From { get; } IProtocolIdentifier? To { get; } diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index ab68c37c3..d8f52852a 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -1,5 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Google.Protobuf; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; using Lachain.Proto; using Lachain.Utility.Serialization; +using Lachain.Utility.Utils; +using Nethereum.RLP; namespace Lachain.Consensus.Messages { @@ -40,12 +54,100 @@ public string TypeString() public byte[] ToBytes() { - throw new System.NotImplementedException(); + var list = new List(); + list.Add(ValidatorIndex.ToBytes().ToArray()); + list.Add((External ? 1 : 0).ToBytes().ToArray()); + + if (External) + { + list.Add(ExternalMessage.ToByteArray()); + } + else { + list.Add( (isProtocolRequest ? 1 : 0).ToBytes().ToArray()); + var protocolType = (int) ProtocolTypeMethods.getProtocolType(InternalMessage.To); + list.Add(protocolType.ToBytes().ToArray()); + list.Add(InternalMessage.ToBytes()); + } + + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } public static MessageEnvelope FromBytes(byte[] bytes) { - throw new System.NotImplementedException(); + var decoded = (RLPCollection)RLP.Decode(bytes.ToArray()); + var validatorIndex = decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + var external = decoded[1].RLPData.AsReadOnlySpan().ToInt32(); + + if (external == 1) + { + var message = ConsensusMessage.Parser.ParseFrom(decoded[2].RLPData); + return new MessageEnvelope(message, validatorIndex); + } + else + { + var isProtocolRequest = decoded[2].RLPData.AsReadOnlySpan().ToInt32(); + var protocolType = (ProtocolType)decoded[3].RLPData.AsReadOnlySpan().ToInt32(); + IInternalMessage message; + + if (isProtocolRequest == 1) + { + message = GetProtocolRequestFromBytes(protocolType, decoded[4].RLPData); + } + else if (isProtocolRequest == 0) + { + message = GetProtocolResponseFromBytes(protocolType, decoded[4].RLPData); + } + else + { + throw new InvalidOperationException("Unknown MessageEnvelope Type"); + } + return new MessageEnvelope(message, validatorIndex); + } + } + + private static IInternalMessage GetProtocolRequestFromBytes(ProtocolType protocolType, byte[] bytes) + {switch (protocolType) + { + case ProtocolType.BinaryAgreement: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.BinaryBroadcast: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.CommonCoin: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.CommonSubset: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.HoneyBadger: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.ReliableBroadcast: + return ProtocolRequest.FromBytes(bytes); + case ProtocolType.RootProtocol: + return ProtocolRequest.FromBytes(bytes); + default: + throw new InvalidOperationException($"Unknown Protocol Type {protocolType}"); + } } + private static IInternalMessage GetProtocolResponseFromBytes(ProtocolType protocolType, byte[] bytes) + { + switch (protocolType) + { + case ProtocolType.BinaryAgreement: + return ProtocolResult.FromBytes(bytes); + case ProtocolType.BinaryBroadcast: + return ProtocolResult.FromBytes(bytes); + case ProtocolType.CommonCoin: + return ProtocolResult.FromBytes(bytes); + case ProtocolType.CommonSubset: + return ProtocolResult>.FromBytes(bytes); + case ProtocolType.HoneyBadger: + return ProtocolResult.FromBytes(bytes); + case ProtocolType.ReliableBroadcast: + return ProtocolResult.FromBytes(bytes); + case ProtocolType.RootProtocol: + return ProtocolResult.FromBytes(bytes); + default: + throw new InvalidOperationException($"Unknown Protocol Type {protocolType}"); + } + } + } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 6ae63b3fd..50c0ab771 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -1,3 +1,5 @@ +using System; + namespace Lachain.Consensus.Messages { public class ProtocolRequest : IInternalMessage where TIdType : IProtocolIdentifier @@ -14,5 +16,14 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) public IProtocolIdentifier From { get; } public IProtocolIdentifier To { get; } + public byte[] ToBytes() + { + throw new NotImplementedException(); + } + + public static ProtocolRequest FromBytes(byte[] bytes) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index f7b94eadb..c9aa4578d 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -1,3 +1,5 @@ +using System; + namespace Lachain.Consensus.Messages { public class ProtocolResult : IInternalMessage where TIdType : IProtocolIdentifier @@ -13,5 +15,14 @@ public ProtocolResult(TIdType id, TResultType value) public TResultType Result { get; } public IProtocolIdentifier From => Id; public IProtocolIdentifier? To => null; + public byte[] ToBytes() + { + throw new NotImplementedException(); + } + + public static ProtocolResult FromBytes(byte[] bytes) + { + throw new NotImplementedException() + } } } \ No newline at end of file From e43bedb3e84ab53c40952cd6296b5a6ff5adbca9 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 06:12:22 +0600 Subject: [PATCH 013/133] Create new era if db era is not same or no data found --- .../MessageEnvelopeRepositoryManager.cs | 30 ++-- .../Messages/ProtocolResult.cs | 2 +- src/Lachain.Core/Consensus/EraBroadcaster.cs | 133 ++++++++++-------- 3 files changed, 95 insertions(+), 70 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 2fab851d6..664d47db6 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using Lachain.Storage.Repositories; namespace Lachain.Consensus.Messages @@ -8,34 +9,47 @@ public class MessageEnvelopeRepositoryManager { private IMessageEnvelopeRepository _repository; private MessageEnvelopeList _messageEnvelopeList; - + public bool isPresent { get; private set; } public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { _repository = repository; var bytes = repository.LoadMessages(); - _messageEnvelopeList = MessageEnvelopeList.FromBytes(bytes); + isPresent = !(bytes is null); + + if (isPresent) + { + _messageEnvelopeList = MessageEnvelopeList.FromBytes(bytes); + } + } public long GetEra() { + if (!isPresent) + { + throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); + } return _messageEnvelopeList.era; } public void StartEra(long era) { - if (_messageEnvelopeList.era == era) + if (isPresent && _messageEnvelopeList.era == era) { throw new ArgumentException($"Start Era called with same era number {era}"); } - else - { - _messageEnvelopeList = new MessageEnvelopeList(era); - SaveToDb(_messageEnvelopeList); - } + + _messageEnvelopeList = new MessageEnvelopeList(era); + SaveToDb(_messageEnvelopeList); + isPresent = true; } public void AddMessage(MessageEnvelope message) { + if (!isPresent) + { + throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); + } _messageEnvelopeList.addMessage(message); SaveToDb(_messageEnvelopeList); } diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index c9aa4578d..fbe766809 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -22,7 +22,7 @@ public byte[] ToBytes() public static ProtocolResult FromBytes(byte[] bytes) { - throw new NotImplementedException() + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 9651ab4e6..a23984de0 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -115,73 +115,84 @@ public void Broadcast(ConsensusMessage message) public void RestoreState() { - foreach (var messageEnvelope in _messageEnvelopeRepositoryManager.GetMessages()) + if (!_messageEnvelopeRepositoryManager.isPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { - if (messageEnvelope.External) - { - Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); - } - else if (messageEnvelope.isProtocolRequest) + Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); + _messageEnvelopeRepositoryManager.StartEra(_era); + } + else + { + Logger.LogInformation($"Restoring {_messageEnvelopeRepositoryManager.GetMessages().Count} Messages from era {_era}"); + foreach (var messageEnvelope in _messageEnvelopeRepositoryManager.GetMessages()) { - switch (messageEnvelope.InternalMessage) + if (messageEnvelope.External) { - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - case ProtocolRequest request: - InternalRequest(request); - break; - default: - throw new InvalidOperationException("Unexpected template parameters for ProtocolRequest"); + Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); } - } - else if (messageEnvelope.isProtocolResponse) - { - switch (messageEnvelope.InternalMessage) + else if (messageEnvelope.isProtocolRequest) + { + switch (messageEnvelope.InternalMessage) + { + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + case ProtocolRequest request: + InternalRequest(request); + break; + default: + throw new InvalidOperationException( + "Unexpected template parameters for ProtocolRequest"); + } + } + else if (messageEnvelope.isProtocolResponse) { - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult> result: - InternalResponse(result); - break; - case ProtocolResult> result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - default: - throw new InvalidOperationException("Unexpected template parameters for ProtocolResponse"); + switch (messageEnvelope.InternalMessage) + { + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + default: + throw new InvalidOperationException( + "Unexpected template parameters for ProtocolResponse"); + } + } + else + { + throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); } - } - else - { - throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); } } } From bb0508688775de32e72ba134e2db176397183903 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:00:10 +0600 Subject: [PATCH 014/133] Add toBytes for protocolrequest --- .../BinaryAgreement/BinaryAgreementId.cs | 21 ++++++++++++++ src/Lachain.Consensus/IProtocolIdentifier.cs | 3 +- .../Messages/MessageEnvelope.cs | 2 +- .../Messages/ProtocolRequest.cs | 29 +++++++++++++++++-- src/Lachain.Consensus/ProtocolType.cs | 2 +- 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs index 610c5c708..1c9d0e333 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs @@ -1,4 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.Messages; +using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Consensus.BinaryAgreement { @@ -40,5 +45,21 @@ public override string ToString() { return $"BA (E={Era}, A={AssociatedValidatorId})"; } + + public byte[] ToBytes() + { + var list = new List(); + list.Add(Era.ToBytes().ToArray()); + list.Add(AssociatedValidatorId.ToBytes().ToArray()); + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static BinaryAgreementId FromBytes(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + var id = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + return new BinaryAgreementId(era, id); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/IProtocolIdentifier.cs b/src/Lachain.Consensus/IProtocolIdentifier.cs index 7d7fae79f..0826ad724 100644 --- a/src/Lachain.Consensus/IProtocolIdentifier.cs +++ b/src/Lachain.Consensus/IProtocolIdentifier.cs @@ -1,8 +1,9 @@ using System; +using Lachain.Utility.Serialization; namespace Lachain.Consensus { - public interface IProtocolIdentifier : IEquatable + public interface IProtocolIdentifier : IEquatable, IByteSerializable { long Era { get; } } diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index d8f52852a..feeb4df94 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -64,7 +64,7 @@ public byte[] ToBytes() } else { list.Add( (isProtocolRequest ? 1 : 0).ToBytes().ToArray()); - var protocolType = (int) ProtocolTypeMethods.getProtocolType(InternalMessage.To); + var protocolType = (int) ProtocolTypeMethods.GetProtocolType(InternalMessage.To); list.Add(protocolType.ToBytes().ToArray()); list.Add(InternalMessage.ToBytes()); } diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 50c0ab771..0aeabf1e3 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -1,8 +1,14 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Utility.Serialization; +using MCL.BLS12_381.Net; +using Nethereum.RLP; namespace Lachain.Consensus.Messages { - public class ProtocolRequest : IInternalMessage where TIdType : IProtocolIdentifier + public class ProtocolRequest : IInternalMessage + where TIdType : IProtocolIdentifier { public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) { @@ -18,7 +24,26 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) public IProtocolIdentifier To { get; } public byte[] ToBytes() { - throw new NotImplementedException(); + var list = new List(); + list.Add(((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray()); + list.Add(From.ToBytes().ToArray()); + list.Add(To.ToBytes().ToArray()); + + switch (Input) + { + case null: + break; + case bool b: + list.Add((b ? 1: 0).ToBytes().ToArray()); + break; + case IByteSerializable b: + list.Add(b.ToBytes().ToArray()); + break; + default: + throw new InvalidOperationException("Unrecognized TInputType"); + } + + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } public static ProtocolRequest FromBytes(byte[] bytes) diff --git a/src/Lachain.Consensus/ProtocolType.cs b/src/Lachain.Consensus/ProtocolType.cs index 254b62be0..c7b15adb1 100644 --- a/src/Lachain.Consensus/ProtocolType.cs +++ b/src/Lachain.Consensus/ProtocolType.cs @@ -21,7 +21,7 @@ public enum ProtocolType: int public static class ProtocolTypeMethods { - public static ProtocolType getProtocolType(IProtocolIdentifier id) + public static ProtocolType GetProtocolType(IProtocolIdentifier id) { switch (id) { From 5e72dec82bc0b5db61f54778fe0c586d964e8774 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:09:34 +0600 Subject: [PATCH 015/133] rename Tobytes->ToByteArray() --- .../Messages/MessageEnvelope.cs | 41 ++++++++++--------- .../Messages/MessageEnvelopeList.cs | 8 ++-- .../MessageEnvelopeRepositoryManager.cs | 4 +- .../Messages/ProtocolRequest.cs | 10 ++--- .../Messages/ProtocolResult.cs | 4 +- .../Serialization/IByteSerializable.cs | 2 +- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index feeb4df94..a97e2ccc6 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -52,7 +52,7 @@ public string TypeString() : PROTOCOL_RESPONSE; } - public byte[] ToBytes() + public byte[] ToByteArray() { var list = new List(); list.Add(ValidatorIndex.ToBytes().ToArray()); @@ -66,13 +66,13 @@ public byte[] ToBytes() list.Add( (isProtocolRequest ? 1 : 0).ToBytes().ToArray()); var protocolType = (int) ProtocolTypeMethods.GetProtocolType(InternalMessage.To); list.Add(protocolType.ToBytes().ToArray()); - list.Add(InternalMessage.ToBytes()); + list.Add(InternalMessage.ToByteArray()); } return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } - public static MessageEnvelope FromBytes(byte[] bytes) + public static MessageEnvelope FromByteArray(byte[] bytes) { var decoded = (RLPCollection)RLP.Decode(bytes.ToArray()); var validatorIndex = decoded[0].RLPData.AsReadOnlySpan().ToInt32(); @@ -105,45 +105,46 @@ public static MessageEnvelope FromBytes(byte[] bytes) } } - private static IInternalMessage GetProtocolRequestFromBytes(ProtocolType protocolType, byte[] bytes) - {switch (protocolType) + private static IInternalMessage GetProtocolRequestFromByteArray(ProtocolType protocolType, byte[] bytes) + { + switch (protocolType) { case ProtocolType.BinaryAgreement: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.BinaryBroadcast: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.CommonCoin: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.CommonSubset: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.HoneyBadger: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.ReliableBroadcast: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); case ProtocolType.RootProtocol: - return ProtocolRequest.FromBytes(bytes); + return ProtocolRequest.FromByteArray(bytes); default: throw new InvalidOperationException($"Unknown Protocol Type {protocolType}"); } } - private static IInternalMessage GetProtocolResponseFromBytes(ProtocolType protocolType, byte[] bytes) + private static IInternalMessage GetProtocolResponseFromByteArray(ProtocolType protocolType, byte[] bytes) { switch (protocolType) { case ProtocolType.BinaryAgreement: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); case ProtocolType.BinaryBroadcast: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); case ProtocolType.CommonCoin: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); case ProtocolType.CommonSubset: - return ProtocolResult>.FromBytes(bytes); + return ProtocolResult>.FromByteArray(bytes); case ProtocolType.HoneyBadger: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); case ProtocolType.ReliableBroadcast: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); case ProtocolType.RootProtocol: - return ProtocolResult.FromBytes(bytes); + return ProtocolResult.FromByteArray(bytes); default: throw new InvalidOperationException($"Unknown Protocol Type {protocolType}"); } diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index fc64e91d8..e7994c369 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -23,7 +23,7 @@ public void addMessage(MessageEnvelope messageEnvelope) messageList.Add(messageEnvelope); } - public byte[] ToBytes() + public byte[] ToByteArray() { var list = new List(); @@ -32,13 +32,13 @@ public byte[] ToBytes() foreach (var message in messageList) { - list.Add(message.ToBytes()); + list.Add(message.ToByteArray()); } return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } - public static MessageEnvelopeList FromBytes(byte[] bytes) + public static MessageEnvelopeList FromByteArray(byte[] bytes) { var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); @@ -49,7 +49,7 @@ public static MessageEnvelopeList FromBytes(byte[] bytes) for (int i = 0; i < count; i++) { var envelopeBytes = decoded[2 + i].RLPData; - messageEnvelopeList.addMessage(MessageEnvelope.FromBytes(envelopeBytes)); + messageEnvelopeList.addMessage(MessageEnvelope.FromByteArray(envelopeBytes)); } return messageEnvelopeList; diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 664d47db6..400d83cdd 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -18,7 +18,7 @@ public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) if (isPresent) { - _messageEnvelopeList = MessageEnvelopeList.FromBytes(bytes); + _messageEnvelopeList = MessageEnvelopeList.FromByteArray(bytes); } } @@ -61,7 +61,7 @@ public ICollection GetMessages() private void SaveToDb(MessageEnvelopeList messageEnvelopeList) { - _repository.SaveMessages(messageEnvelopeList.ToBytes()); + _repository.SaveMessages(messageEnvelopeList.ToByteArray()); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 0aeabf1e3..1c7781ee8 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -22,12 +22,12 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) public IProtocolIdentifier From { get; } public IProtocolIdentifier To { get; } - public byte[] ToBytes() + public byte[] ToByteArray() { var list = new List(); list.Add(((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray()); - list.Add(From.ToBytes().ToArray()); - list.Add(To.ToBytes().ToArray()); + list.Add(From.ToByteArray().ToArray()); + list.Add(To.ToByteArray().ToArray()); switch (Input) { @@ -37,7 +37,7 @@ public byte[] ToBytes() list.Add((b ? 1: 0).ToBytes().ToArray()); break; case IByteSerializable b: - list.Add(b.ToBytes().ToArray()); + list.Add(b.ToByteArray().ToArray()); break; default: throw new InvalidOperationException("Unrecognized TInputType"); @@ -46,7 +46,7 @@ public byte[] ToBytes() return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } - public static ProtocolRequest FromBytes(byte[] bytes) + public static ProtocolRequest FromByteArray(byte[] bytes) { throw new NotImplementedException(); } diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index fbe766809..a280ef268 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -15,12 +15,12 @@ public ProtocolResult(TIdType id, TResultType value) public TResultType Result { get; } public IProtocolIdentifier From => Id; public IProtocolIdentifier? To => null; - public byte[] ToBytes() + public byte[] ToByteArray() { throw new NotImplementedException(); } - public static ProtocolResult FromBytes(byte[] bytes) + public static ProtocolResult FromByteArray(byte[] bytes) { throw new NotImplementedException(); } diff --git a/src/Lachain.Utility/Serialization/IByteSerializable.cs b/src/Lachain.Utility/Serialization/IByteSerializable.cs index 2a1d32ccf..640e1223f 100644 --- a/src/Lachain.Utility/Serialization/IByteSerializable.cs +++ b/src/Lachain.Utility/Serialization/IByteSerializable.cs @@ -6,6 +6,6 @@ public interface IByteSerializable { // When implementing this interface make sure to implement also following methods: // public static MyClass FromBytes(byte[] bytes); - public byte[] ToBytes(); + public byte[] ToByteArray(); } } \ No newline at end of file From 3fcfb655e12c86971dfc78441b607c32dbd757ed Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:10:35 +0600 Subject: [PATCH 016/133] Add toBytes and fromBytes for BinaryBroadcastId and BinaryAgreementId --- .../BinaryAgreement/BinaryAgreementId.cs | 4 +-- .../BinaryAgreement/BinaryBroadcastId.cs | 26 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs index 1c9d0e333..a0c1d5a25 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs @@ -46,7 +46,7 @@ public override string ToString() return $"BA (E={Era}, A={AssociatedValidatorId})"; } - public byte[] ToBytes() + public byte[] ToByteArray() { var list = new List(); list.Add(Era.ToBytes().ToArray()); @@ -54,7 +54,7 @@ public byte[] ToBytes() return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } - public static BinaryAgreementId FromBytes(byte[] bytes) + public static BinaryAgreementId FromByteArray(byte[] bytes) { var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs index d2461571b..1ce3e1aba 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs @@ -1,4 +1,9 @@ -namespace Lachain.Consensus.BinaryAgreement +using System.Collections.Generic; +using System.Linq; +using Lachain.Utility.Serialization; +using Nethereum.RLP; + +namespace Lachain.Consensus.BinaryAgreement { public class BinaryBroadcastId : IProtocolIdentifier { @@ -46,5 +51,24 @@ public override string ToString() { return $"BB (Er={Era}, A={Agreement}, Ep={Epoch})"; } + public byte[] ToByteArray() + { + var list = new List + { + Era.ToBytes().ToArray(), + Agreement.ToBytes().ToArray(), + Epoch.ToBytes().ToArray() + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static BinaryBroadcastId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + var agreement = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + var epoch = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + return new BinaryBroadcastId(era, agreement, epoch); + } } } \ No newline at end of file From 58da6508787be5e680ea2e49b93c42be3a8d5695 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:56:19 +0600 Subject: [PATCH 017/133] implement toBytes and FromBytes for all protocolIds --- src/Lachain.Consensus/CommonCoin/CoinId.cs | 21 ++++++++++++++++ .../CommonSubset/CommonSubsetId.cs | 21 +++++++++++++++- .../HoneyBadger/HoneyBadgerId.cs | 24 ++++++++++++++++++- .../ReliableBroadcast/ReliableBroadcastId.cs | 23 ++++++++++++++++++ .../RootProtocol/RootProtocolId.cs | 20 ++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/CommonCoin/CoinId.cs b/src/Lachain.Consensus/CommonCoin/CoinId.cs index 6c3a86496..77ade9921 100644 --- a/src/Lachain.Consensus/CommonCoin/CoinId.cs +++ b/src/Lachain.Consensus/CommonCoin/CoinId.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using Lachain.Consensus.BinaryAgreement; using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Consensus.CommonCoin { @@ -50,5 +52,24 @@ public override int GetHashCode() { return HashCode.Combine(Era, Agreement, Epoch); } + public byte[] ToByteArray() + { + var list = new List + { + Era.ToBytes().ToArray(), + Agreement.ToBytes().ToArray(), + Epoch.ToBytes().ToArray() + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static CoinId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + var agreement = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + var epoch = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + return new CoinId(era, agreement, epoch); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/CommonSubset/CommonSubsetId.cs b/src/Lachain.Consensus/CommonSubset/CommonSubsetId.cs index 4d0ea2608..3116120ad 100644 --- a/src/Lachain.Consensus/CommonSubset/CommonSubsetId.cs +++ b/src/Lachain.Consensus/CommonSubset/CommonSubsetId.cs @@ -1,4 +1,8 @@ -using Lachain.Consensus.HoneyBadger; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.HoneyBadger; +using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Consensus.CommonSubset { @@ -43,5 +47,20 @@ public override int GetHashCode() { return Era.GetHashCode(); } + public byte[] ToByteArray() + { + var list = new List + { + Era.ToBytes().ToArray(), + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static CommonSubsetId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + return new CommonSubsetId((int)era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs b/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs index 58e4289ae..07d56bf8d 100644 --- a/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs +++ b/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs @@ -1,4 +1,10 @@ -namespace Lachain.Consensus.HoneyBadger +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.CommonSubset; +using Lachain.Utility.Serialization; +using Nethereum.RLP; + +namespace Lachain.Consensus.HoneyBadger { public class HoneyBadgerId : IProtocolIdentifier @@ -37,5 +43,21 @@ public override string ToString() { return $"HB (Er={Era})"; } + + public byte[] ToByteArray() + { + var list = new List + { + Era.ToBytes().ToArray(), + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static HoneyBadgerId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + return new HoneyBadgerId(era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs index 86402181f..506e6205f 100644 --- a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs +++ b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs @@ -1,4 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.CommonSubset; +using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Consensus.ReliableBroadcast { @@ -41,5 +46,23 @@ public override string ToString() { return $"RBC (E={Era}, A={SenderId})"; } + + public byte[] ToByteArray() + { + var list = new List + { + SenderId.ToBytes().ToArray(), + Era.ToBytes().ToArray(), + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static ReliableBroadcastId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var senderId = decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + var era = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + return new ReliableBroadcastId(senderId, era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RootProtocol/RootProtocolId.cs b/src/Lachain.Consensus/RootProtocol/RootProtocolId.cs index 31d29dd0e..09c3ffda0 100644 --- a/src/Lachain.Consensus/RootProtocol/RootProtocolId.cs +++ b/src/Lachain.Consensus/RootProtocol/RootProtocolId.cs @@ -1,3 +1,8 @@ +using System.Collections.Generic; +using System.Linq; +using Lachain.Utility.Serialization; +using Nethereum.RLP; + namespace Lachain.Consensus.RootProtocol { public class RootProtocolId : IProtocolIdentifier @@ -36,5 +41,20 @@ public override int GetHashCode() { return Era.GetHashCode(); } + public byte[] ToByteArray() + { + var list = new List + { + Era.ToBytes().ToArray(), + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + + public static RootProtocolId FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); + return new RootProtocolId((int)era); + } } } \ No newline at end of file From db5109184c74809d4d2e6ab06b5813088145f132 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:57:54 +0600 Subject: [PATCH 018/133] Setup tests for repo manager --- .../Lachain.ConsensusTest.csproj | 6 +++ .../Resources/config.json | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 test/Lachain.ConsensusTest/Resources/config.json diff --git a/test/Lachain.ConsensusTest/Lachain.ConsensusTest.csproj b/test/Lachain.ConsensusTest/Lachain.ConsensusTest.csproj index 63ee9f278..7570bebcc 100644 --- a/test/Lachain.ConsensusTest/Lachain.ConsensusTest.csproj +++ b/test/Lachain.ConsensusTest/Lachain.ConsensusTest.csproj @@ -15,4 +15,10 @@ + + + Always + config.json + + \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/Resources/config.json b/test/Lachain.ConsensusTest/Resources/config.json new file mode 100644 index 000000000..199474fbf --- /dev/null +++ b/test/Lachain.ConsensusTest/Resources/config.json @@ -0,0 +1,46 @@ +{ + "network": { + "magic": 56754, + "host": "tcp://172.16.238.1", + "port": 5050, + "peers": [ + ], + "forceIPv6": false, + "maxPeers": 100, + "bootstrapAddresses": [] + }, + "genesis" : { + "balances": { + "0xe855e8f8e5f66a84c62800e9fc8fa06d77c35baf": "100.0", + "0x6c809b2845b1334bd860988d24adccc9fab2a28d": "123.321", + "0x6bc32575acb8754886dc283c2c8ac54b1bd93195": "1000000.0" + }, + "validators": [ + { + "ECDSAPublicKey": "02e5974f3e1e9599ff5af036b5d6057d80855e7182afb4c2fa1fe38bc6efb9072b", + "thresholdSignaturePublicKey": "0xa89024362500526196412db2f8b2c113386af2a7c334738202d052b294d2e48999fc7d69c43b2ae2d75280446ddc5309", + "resolvableName": "localhost:5050" + } + ], + "TPKEPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockReward": "5.000000000000000000", + "basicGasPrice": "0.000000100000000000" + }, + "rpc": { + "hosts": [ + "+" + ], + "port": 7070 + }, + "vault": { + "path": "wallet.json", + "password": "12345" + }, + "blockchain": { + "targetBlockTime": 5000 + }, + "storage": { + "provider": "RocksDB", + "path": "ChainTest" + } +} \ No newline at end of file From e093d3658f2ec0ba79e96f44a0b9d6596d8bb5e2 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 09:58:32 +0600 Subject: [PATCH 019/133] Add basic serialization tests --- .../SerializationTest.cs | 31 +++++++++++++++++++ test/Lachain.ConsensusTest/TestUtils.cs | 25 +++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/Lachain.ConsensusTest/SerializationTest.cs diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs new file mode 100644 index 000000000..7bca69ef0 --- /dev/null +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -0,0 +1,31 @@ +using Google.Protobuf; +using Lachain.Consensus.Messages; +using Lachain.ConsensusTest; +using Lachain.Proto; +using NUnit.Framework; + +namespace Lachain.CoreTest +{ + public class SerializationTest + { + [SetUp] + public void SetUp() + { + } + + [Test] + public void Test_Serialization() + { + var binaryBroadcastMessage = TestUtils.GenerateBinaryBroadcastConsensusMessage(); + Assert.AreEqual(binaryBroadcastMessage, ConsensusMessage.Parser.ParseFrom(binaryBroadcastMessage.ToByteArray())); + + var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, 2); + Assert.AreEqual(binaryBroadcastEnvelope, MessageEnvelope.FromByteArray(binaryBroadcastEnvelope.ToByteArray())); + + + var messageList = new MessageEnvelopeList(1029); + messageList.addMessage(binaryBroadcastEnvelope); + TestUtils.AssertEqual(messageList, MessageEnvelopeList.FromByteArray(messageList.ToByteArray())); + } + } +} \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 26bb318c7..33d3f20be 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -1,4 +1,8 @@ using Lachain.Consensus; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.Messages; +using Lachain.Proto; +using NUnit.Framework; namespace Lachain.ConsensusTest { @@ -8,5 +12,26 @@ public static IPrivateConsensusKeySet EmptyWallet(int n, int f) { return new PrivateConsensusKeySet(null!, null!, null!); } + + public static ConsensusMessage GenerateBinaryBroadcastConsensusMessage() + { + var _broadcastId = new BinaryBroadcastId(2142, 42342, 13124312); + var message = new ConsensusMessage + { + Bval = new BValMessage + { + Agreement = _broadcastId.Agreement, + Epoch = _broadcastId.Epoch, + Value = true + } + }; + return message; + } + + public static void AssertEqual(MessageEnvelopeList a, MessageEnvelopeList b) + { + Assert.AreEqual(a.era, b.era); + CollectionAssert.AreEqual(a.messageList, b.messageList); + } } } \ No newline at end of file From d471327cfae7a8e73ff040121cf8ec4a106059ab Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 10:01:28 +0600 Subject: [PATCH 020/133] Add repo manager tests --- .../MessageEnvelopeRepositoryManagerTest.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs new file mode 100644 index 000000000..e12d3a428 --- /dev/null +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -0,0 +1,66 @@ +using System.IO; +using System.Reflection; +using Lachain.Core.CLI; +using Lachain.Core.Config; +using Lachain.Core.DI; +using Lachain.Core.DI.Modules; +using Lachain.Core.DI.SimpleInjector; +using Lachain.Storage; +using NUnit.Framework; +using Lachain.Consensus.Messages; +using Lachain.Storage.Repositories; + + +namespace Lachain.ConsensusTest +{ + public class MessageEnvelopeRepositoryManagerTest + { + private IContainer _container; + private IRocksDbContext _dbContext; + + [SetUp] + public void Setup() + { + var containerBuilder = new SimpleInjectorContainerBuilder(new ConfigManager( + Path.Join(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json"), + new RunOptions() + )); + + containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + _container = containerBuilder.Build(); + _dbContext = _container.Resolve(); + } + + [TearDown] + public void TearDown() + { + _container.Dispose(); + Lachain.UtilityTest.TestUtils.DeleteTestChainData(); + + } + + [Test] + public void Test_MessageEnvelopeRepositoryManager() + { + var repo = new MessageEnvelopeRepository(_dbContext); + var manager = new MessageEnvelopeRepositoryManager(repo); + Assert.AreEqual(manager.isPresent, false); + + manager.StartEra(23); + Assert.AreEqual(manager.GetEra(), 23); + Assert.AreEqual(manager.GetMessages().Count, 0); + + manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77)); + manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23)); + + var era = manager.GetEra(); + var list = manager.GetMessages(); + + manager = new MessageEnvelopeRepositoryManager(repo); + Assert.AreEqual(manager.GetEra(), era); + CollectionAssert.AreEqual(manager.GetMessages(), list); + + } + } +} \ No newline at end of file From d46e670d699c6b245f8a867d208cd62ebfb6b049 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 10:33:58 +0600 Subject: [PATCH 021/133] Add ProtocolId tests and fix errors --- .../BinaryAgreement/BinaryBroadcastId.cs | 2 +- src/Lachain.Consensus/CommonCoin/CoinId.cs | 2 +- .../Messages/MessageEnvelope.cs | 4 +- .../ReliableBroadcast/ReliableBroadcastId.cs | 2 +- test/Lachain.ConsensusTest/ProtocolInvoker.cs | 5 ++ .../SerializationTest.cs | 70 +++++++++++++++++-- 6 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs index 1ce3e1aba..e115e9897 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcastId.cs @@ -67,7 +67,7 @@ public static BinaryBroadcastId FromByteArray(byte[] bytes) var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); var agreement = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); - var epoch = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + var epoch = decoded[2].RLPData.AsReadOnlySpan().ToInt64(); return new BinaryBroadcastId(era, agreement, epoch); } } diff --git a/src/Lachain.Consensus/CommonCoin/CoinId.cs b/src/Lachain.Consensus/CommonCoin/CoinId.cs index 77ade9921..b03a4d849 100644 --- a/src/Lachain.Consensus/CommonCoin/CoinId.cs +++ b/src/Lachain.Consensus/CommonCoin/CoinId.cs @@ -68,7 +68,7 @@ public static CoinId FromByteArray(byte[] bytes) var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); var era = decoded[0].RLPData.AsReadOnlySpan().ToInt64(); var agreement = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); - var epoch = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); + var epoch = decoded[2].RLPData.AsReadOnlySpan().ToInt64(); return new CoinId(era, agreement, epoch); } } diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index a97e2ccc6..64c9d3b7e 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -91,11 +91,11 @@ public static MessageEnvelope FromByteArray(byte[] bytes) if (isProtocolRequest == 1) { - message = GetProtocolRequestFromBytes(protocolType, decoded[4].RLPData); + message = GetProtocolRequestFromByteArray(protocolType, decoded[4].RLPData); } else if (isProtocolRequest == 0) { - message = GetProtocolResponseFromBytes(protocolType, decoded[4].RLPData); + message = GetProtocolResponseFromByteArray(protocolType, decoded[4].RLPData); } else { diff --git a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs index 506e6205f..f337a899e 100644 --- a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs +++ b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs @@ -62,7 +62,7 @@ public static ReliableBroadcastId FromByteArray(byte[] bytes) var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); var senderId = decoded[0].RLPData.AsReadOnlySpan().ToInt32(); var era = decoded[1].RLPData.AsReadOnlySpan().ToInt64(); - return new ReliableBroadcastId(senderId, era); + return new ReliableBroadcastId(senderId, (int) era); } } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/ProtocolInvoker.cs b/test/Lachain.ConsensusTest/ProtocolInvoker.cs index efebbcbb5..9bf4dec79 100644 --- a/test/Lachain.ConsensusTest/ProtocolInvoker.cs +++ b/test/Lachain.ConsensusTest/ProtocolInvoker.cs @@ -35,6 +35,11 @@ public override string ToString() return $"Invoker {Id}"; } + public byte[] ToByteArray() + { + throw new NotImplementedException(); + } + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 7bca69ef0..501340210 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,5 +1,11 @@ using Google.Protobuf; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; using Lachain.Consensus.Messages; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; using Lachain.ConsensusTest; using Lachain.Proto; using NUnit.Framework; @@ -8,24 +14,74 @@ namespace Lachain.CoreTest { public class SerializationTest { + private MessageEnvelopeList _messageList; [SetUp] public void SetUp() { + _messageList = new MessageEnvelopeList(1029); } [Test] public void Test_Serialization() { - var binaryBroadcastMessage = TestUtils.GenerateBinaryBroadcastConsensusMessage(); - Assert.AreEqual(binaryBroadcastMessage, ConsensusMessage.Parser.ParseFrom(binaryBroadcastMessage.ToByteArray())); + TestBinaryAgreementSerialization(); + TestBinaryBroadcastSerialization(); + TestCommonCoinSerialization(); + TestHoneyBadgerSerialization(); + TestHoneyBadgerSerialization(); + TestReliableBroadcastSerialization(); + TestRootProtocolSerialization(); - var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, 2); - Assert.AreEqual(binaryBroadcastEnvelope, MessageEnvelope.FromByteArray(binaryBroadcastEnvelope.ToByteArray())); + TestUtils.AssertEqual(_messageList, MessageEnvelopeList.FromByteArray(_messageList.ToByteArray())); + } + private void TestBinaryAgreementSerialization() + { + var binaryAgreementId = new BinaryAgreementId(4944, 32232352); + Assert.AreEqual(binaryAgreementId, BinaryAgreementId.FromByteArray(binaryAgreementId.ToByteArray())); + + + // var binaryBroadcastMessage = TestUtils.GenerateBinaryBroadcastConsensusMessage(); + // Assert.AreEqual(binaryBroadcastMessage, ConsensusMessage.Parser.ParseFrom(binaryBroadcastMessage.ToByteArray())); + // + // var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, 2); + // Assert.AreEqual(binaryBroadcastEnvelope, MessageEnvelope.FromByteArray(binaryBroadcastEnvelope.ToByteArray())); + // + // _messageList.addMessage(binaryBroadcastEnvelope); - var messageList = new MessageEnvelopeList(1029); - messageList.addMessage(binaryBroadcastEnvelope); - TestUtils.AssertEqual(messageList, MessageEnvelopeList.FromByteArray(messageList.ToByteArray())); + } + + + private void TestBinaryBroadcastSerialization() + { + var binaryBroadcastId = new BinaryBroadcastId(4944, 8998452, 1234567); + Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); + } + + private void TestCommonCoinSerialization() + { + var coinId = new CoinId(8744, 322322, 44123); + Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); + } + private void TestCommonSubsetSerialization() + { + var commonSubsetId = new CommonSubsetId(32352); + Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); + } + private void TestHoneyBadgerSerialization() + { + var honeyBadgerId = new HoneyBadgerId(2210); + Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); + } + private void TestReliableBroadcastSerialization() + { + var reliableBroadcastId = new ReliableBroadcastId(9987, 122531); + Assert.AreEqual(reliableBroadcastId, ReliableBroadcastId.FromByteArray(reliableBroadcastId.ToByteArray())); + } + private void TestRootProtocolSerialization() + { + var rootProtocolId = new RootProtocolId(4587); + Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); } } } \ No newline at end of file From 0c7f61b0117426c81802bdbf23b4258662433af2 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 11:14:36 +0600 Subject: [PATCH 022/133] Serialize RawShare and EncryptedShare --- src/Lachain.Crypto/IRawShare.cs | 3 ++- src/Lachain.Crypto/RawShare.cs | 20 ++++++++++++++++++++ src/Lachain.Crypto/TPKE/EncryptedShare.cs | 12 +++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Crypto/IRawShare.cs b/src/Lachain.Crypto/IRawShare.cs index 028dbdf33..d17ccb61b 100644 --- a/src/Lachain.Crypto/IRawShare.cs +++ b/src/Lachain.Crypto/IRawShare.cs @@ -1,8 +1,9 @@ using System; +using Lachain.Utility.Serialization; namespace Lachain.Crypto { - public interface IRawShare : IEquatable + public interface IRawShare : IEquatable, IByteSerializable { byte[] ToBytes(); int Id { get; } diff --git a/src/Lachain.Crypto/RawShare.cs b/src/Lachain.Crypto/RawShare.cs index d4d070f6a..0635c3dd6 100644 --- a/src/Lachain.Crypto/RawShare.cs +++ b/src/Lachain.Crypto/RawShare.cs @@ -1,4 +1,7 @@ +using System.Collections.Generic; using System.Linq; +using Lachain.Utility.Serialization; +using Nethereum.RLP; namespace Lachain.Crypto { @@ -30,6 +33,23 @@ public override int GetHashCode() } } + public byte[] ToByteArray() + { + var list = new List + { + Id.ToBytes().ToArray(), + Data + }; + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); + } + public static RawShare FromByteArray(byte[] bytes) + { + var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + var id = decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + var bb = decoded[1].RLPData; + return new RawShare(bb, id); + } + public int Id { get; } public byte[] Data { get; } diff --git a/src/Lachain.Crypto/TPKE/EncryptedShare.cs b/src/Lachain.Crypto/TPKE/EncryptedShare.cs index 2265149b8..98aa98082 100644 --- a/src/Lachain.Crypto/TPKE/EncryptedShare.cs +++ b/src/Lachain.Crypto/TPKE/EncryptedShare.cs @@ -6,7 +6,7 @@ namespace Lachain.Crypto.TPKE { - public class EncryptedShare : IEquatable + public class EncryptedShare : IEquatable, IByteSerializable { public G1 U { get; } @@ -52,5 +52,15 @@ public override int GetHashCode() { return HashCode.Combine(U, V, W, Id); } + + public byte[] ToByteArray() + { + return ToBytes().ToArray(); + } + + public static EncryptedShare FromByteArray(byte[] bytes) + { + return FromBytes(bytes); + } } } \ No newline at end of file From d66bcbc607c21e9727fd8cf63df66056e7770313 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 11:15:00 +0600 Subject: [PATCH 023/133] Add test for rawshare and encrypted share serialzation --- .../SerializationTest.cs | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 501340210..f88a52fee 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,3 +1,4 @@ +using System; using Google.Protobuf; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; @@ -7,44 +8,53 @@ using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; using Lachain.ConsensusTest; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; using Lachain.Proto; +using MCL.BLS12_381.Net; using NUnit.Framework; -namespace Lachain.CoreTest +namespace Lachain.ConsensusTest { public class SerializationTest { private MessageEnvelopeList _messageList; + private Random random; [SetUp] public void SetUp() { - _messageList = new MessageEnvelopeList(1029); + var seed = 123456; + random = new Random(seed); + _messageList = new MessageEnvelopeList(random.Next()); + } [Test] public void Test_Serialization() { - TestBinaryAgreementSerialization(); - TestBinaryBroadcastSerialization(); - TestCommonCoinSerialization(); - TestHoneyBadgerSerialization(); - TestHoneyBadgerSerialization(); - TestReliableBroadcastSerialization(); - TestRootProtocolSerialization(); - - TestUtils.AssertEqual(_messageList, MessageEnvelopeList.FromByteArray(_messageList.ToByteArray())); + for (int i = 0; i < 100; i++) + { + TestSerializationAndAdd_BinaryAgreement(); + TestSerializationAndAdd_BinaryBroadcast(); + TestSerializationAndAdd_CommonCoin(); + TestSerializationAndAdd_CommonSubset(); + TestSerializationAndAdd_HoneyBadger(); + TestSerializationAndAdd_ReliableBroadcast(); + TestSerializationAndAdd_RootProtocol(); + TestUtils.AssertEqual(_messageList, MessageEnvelopeList.FromByteArray(_messageList.ToByteArray())); + } } - private void TestBinaryAgreementSerialization() + private void TestSerializationAndAdd_BinaryAgreement() { - var binaryAgreementId = new BinaryAgreementId(4944, 32232352); + var binaryAgreementId = new BinaryAgreementId(random.Next(), random.Next()); Assert.AreEqual(binaryAgreementId, BinaryAgreementId.FromByteArray(binaryAgreementId.ToByteArray())); // var binaryBroadcastMessage = TestUtils.GenerateBinaryBroadcastConsensusMessage(); // Assert.AreEqual(binaryBroadcastMessage, ConsensusMessage.Parser.ParseFrom(binaryBroadcastMessage.ToByteArray())); // - // var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, 2); + // var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, random.Next()); // Assert.AreEqual(binaryBroadcastEnvelope, MessageEnvelope.FromByteArray(binaryBroadcastEnvelope.ToByteArray())); // // _messageList.addMessage(binaryBroadcastEnvelope); @@ -52,36 +62,57 @@ private void TestBinaryAgreementSerialization() } - private void TestBinaryBroadcastSerialization() + private void TestSerializationAndAdd_BinaryBroadcast() { - var binaryBroadcastId = new BinaryBroadcastId(4944, 8998452, 1234567); + var binaryBroadcastId = new BinaryBroadcastId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); } - private void TestCommonCoinSerialization() + private void TestSerializationAndAdd_CommonCoin() { - var coinId = new CoinId(8744, 322322, 44123); + var coinId = new CoinId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); } - private void TestCommonSubsetSerialization() + private void TestSerializationAndAdd_CommonSubset() { - var commonSubsetId = new CommonSubsetId(32352); + var commonSubsetId = new CommonSubsetId(random.Next()); Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); + + var share = TestSerializationAndGet_EncryptedShare(); } - private void TestHoneyBadgerSerialization() + private void TestSerializationAndAdd_HoneyBadger() { - var honeyBadgerId = new HoneyBadgerId(2210); + var honeyBadgerId = new HoneyBadgerId(random.Next()); Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); + + var share = TestSerializationAndGet_IRawShare(); } - private void TestReliableBroadcastSerialization() + private void TestSerializationAndAdd_ReliableBroadcast() { - var reliableBroadcastId = new ReliableBroadcastId(9987, 122531); + var reliableBroadcastId = new ReliableBroadcastId(random.Next(), random.Next()); Assert.AreEqual(reliableBroadcastId, ReliableBroadcastId.FromByteArray(reliableBroadcastId.ToByteArray())); } - private void TestRootProtocolSerialization() + private void TestSerializationAndAdd_RootProtocol() { - var rootProtocolId = new RootProtocolId(4587); + var rootProtocolId = new RootProtocolId(random.Next()); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); } + + private EncryptedShare TestSerializationAndGet_EncryptedShare() + { + var rnd = new byte[32]; + random.NextBytes(rnd); + var share = new EncryptedShare(G1.Generator, rnd, G2.Generator, random.Next()); + Assert.AreEqual(share, EncryptedShare.FromByteArray(share.ToByteArray())); + return share; + } + private IRawShare TestSerializationAndGet_IRawShare() + { + var rnd = new byte[32]; + random.NextBytes(rnd); + var share = new RawShare(rnd, random.Next()); + Assert.AreEqual(share, RawShare.FromByteArray(share.ToByteArray())); + return share; + } } } \ No newline at end of file From 8a5e9936130f35c6ce965ccc9f36eec2fd62ac77 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 11:25:09 +0600 Subject: [PATCH 024/133] Add coinResult and boolset share serialzation --- src/Lachain.Consensus/CommonCoin/CoinResult.cs | 13 ++++++++++++- src/Lachain.Utility/Utils/BoolSet.cs | 14 +++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/CommonCoin/CoinResult.cs b/src/Lachain.Consensus/CommonCoin/CoinResult.cs index e7e7ba7b5..f57454f90 100644 --- a/src/Lachain.Consensus/CommonCoin/CoinResult.cs +++ b/src/Lachain.Consensus/CommonCoin/CoinResult.cs @@ -1,10 +1,11 @@ using System; using System.Linq; +using Lachain.Utility.Serialization; using Lachain.Utility.Utils; namespace Lachain.Consensus.CommonCoin { - public class CoinResult : IEquatable + public class CoinResult : IEquatable, IByteSerializable { public CoinResult(byte[] bytes) { @@ -36,5 +37,15 @@ public override int GetHashCode() { return RawBytes.Aggregate(0, (i, b) => i * 31 + b); } + + public byte[] ToByteArray() + { + return RawBytes; + } + + public static CoinResult FromByteArray(byte[] bytes) + { + return new CoinResult(bytes); + } } } \ No newline at end of file diff --git a/src/Lachain.Utility/Utils/BoolSet.cs b/src/Lachain.Utility/Utils/BoolSet.cs index c7af212e0..0e1519fbe 100644 --- a/src/Lachain.Utility/Utils/BoolSet.cs +++ b/src/Lachain.Utility/Utils/BoolSet.cs @@ -2,12 +2,13 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; +using Lachain.Utility.Serialization; namespace Lachain.Utility.Utils { // Simple struct that represents subset of {false, true} // Note, this is declared as struct to copy by value always - public struct BoolSet : IEquatable, IComparable + public struct BoolSet : IEquatable, IComparable, IByteSerializable { private readonly byte _mask; @@ -88,5 +89,16 @@ public override string ToString() { return $"BoolSet({String.Join(", ", Values())})"; } + + public byte[] ToByteArray() + { + byte[] bytes = { _mask }; + return bytes; + } + + public static BoolSet FromByteArray(byte[] bytes) + { + return new BoolSet(bytes[0]); + } } } \ No newline at end of file From a89f2f3f6c618bba257ba1acec149bba03835c1c Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 5 Nov 2022 11:34:59 +0600 Subject: [PATCH 025/133] Add tests for coinResult and boolset share serialzation --- .../SerializationTest.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index f88a52fee..b89b3182c 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -11,6 +11,7 @@ using Lachain.Crypto; using Lachain.Crypto.TPKE; using Lachain.Proto; +using Lachain.Utility.Utils; using MCL.BLS12_381.Net; using NUnit.Framework; @@ -66,12 +67,16 @@ private void TestSerializationAndAdd_BinaryBroadcast() { var binaryBroadcastId = new BinaryBroadcastId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); + + var bs = TestSerializationAndGet_BoolSet(); } private void TestSerializationAndAdd_CommonCoin() { var coinId = new CoinId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); + + var cr = TestSerializationAndGet_Coinresult(); } private void TestSerializationAndAdd_CommonSubset() { @@ -114,5 +119,24 @@ private IRawShare TestSerializationAndGet_IRawShare() Assert.AreEqual(share, RawShare.FromByteArray(share.ToByteArray())); return share; } + + private CoinResult TestSerializationAndGet_Coinresult() + { + var rnd = new byte[32]; + random.NextBytes(rnd); + var coinResult = new CoinResult(rnd); + Assert.AreEqual(coinResult, CoinResult.FromByteArray(coinResult.ToByteArray())); + return coinResult; + } + + private BoolSet TestSerializationAndGet_BoolSet() + { + bool[] bools = { random.Next(0, 1) == 1, random.Next(0, 1) == 0 }; + var bs = new BoolSet(bools); + Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); + return bs; + } + + } } \ No newline at end of file From a3d377f9f483aba88b08f6c8fe6982c37470d93c Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 7 Nov 2022 19:42:21 +0600 Subject: [PATCH 026/133] Write correct serializer for Protocol Request --- src/Lachain.Consensus/Messages/ProtocolRequest.cs | 14 ++++++++++++++ src/Lachain.Core/Consensus/EraBroadcaster.cs | 13 +++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 1c7781ee8..101381e55 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Lachain.Consensus.BinaryAgreement; using Lachain.Utility.Serialization; using MCL.BLS12_381.Net; using Nethereum.RLP; @@ -39,6 +40,13 @@ public byte[] ToByteArray() case IByteSerializable b: list.Add(b.ToByteArray().ToArray()); break; + case ISet set: + list.Add(set.Count.ToBytes().ToArray()); + foreach (var element in set) + { + list.Add(element.ToByteArray().ToArray()); + } + break; default: throw new InvalidOperationException("Unrecognized TInputType"); } @@ -48,6 +56,12 @@ public byte[] ToByteArray() public static ProtocolRequest FromByteArray(byte[] bytes) { + // switch (Type.GetTypeCode(typeof(TIdType))) + // { + // var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); + // var protocolType = (ProtocolType) decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + // + // } throw new NotImplementedException(); } } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index a23984de0..615b81668 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -279,7 +279,9 @@ public void Dispatch(ConsensusMessage message, int from) throw new InvalidOperationException($"Unknown message type {message}"); } - HandleExternalMessage(protocolId, new MessageEnvelope(message, from)); + var messageEnvelope = new MessageEnvelope(message, from); + _messageEnvelopeRepositoryManager.AddMessage(messageEnvelope); + HandleExternalMessage(protocolId, messageEnvelope); } private void HandleExternalMessage(IProtocolIdentifier protocolId, MessageEnvelope message) @@ -340,9 +342,11 @@ public void InternalRequest(ProtocolRequest re Logger.LogTrace($"Protocol {request.From} requested result from protocol {request.To}"); EnsureProtocol(request.To); - + + + var messageEnvelope = new MessageEnvelope(request, GetMyId()); if (_registry.TryGetValue(request.To, out var protocol)) - protocol?.ReceiveMessage(new MessageEnvelope(request, GetMyId())); + protocol?.ReceiveMessage(messageEnvelope); if (!(protocol is null)) { @@ -385,8 +389,9 @@ public void InternalResponse(ProtocolResult // message is also delivered to self // Logger.LogTrace($"Result from protocol {result.From} delivered to itself"); + var messageEnvelope = new MessageEnvelope(result, GetMyId()); if (_registry.TryGetValue(result.From, out var protocol)) - protocol?.ReceiveMessage(new MessageEnvelope(result, GetMyId())); + protocol?.ReceiveMessage(messageEnvelope); } public int GetMyId() From af3e6bf1bab3008bf4843bfac58ccc529e0e8284 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 9 Nov 2022 14:32:54 +0600 Subject: [PATCH 027/133] Serialize and deserialize protocol reuqest and response --- .../MessageEnvelopeRepositoryManager.cs | 4 + .../Messages/ProtocolRequest.cs | 125 ++++++++++++++---- .../Messages/ProtocolResult.cs | 75 ++++++++++- 3 files changed, 178 insertions(+), 26 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 400d83cdd..5cde30567 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using Lachain.Logger; using Lachain.Storage.Repositories; namespace Lachain.Consensus.Messages @@ -9,6 +10,8 @@ public class MessageEnvelopeRepositoryManager { private IMessageEnvelopeRepository _repository; private MessageEnvelopeList _messageEnvelopeList; + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + public bool isPresent { get; private set; } public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { @@ -61,6 +64,7 @@ public ICollection GetMessages() private void SaveToDb(MessageEnvelopeList messageEnvelopeList) { + Logger.LogTrace("Saving list to db: " + messageEnvelopeList.ToByteArray()); _repository.SaveMessages(messageEnvelopeList.ToByteArray()); } } diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 101381e55..3090d234e 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -2,8 +2,14 @@ using System.Collections.Generic; using System.Linq; using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; using Lachain.Utility.Serialization; -using MCL.BLS12_381.Net; using Nethereum.RLP; namespace Lachain.Consensus.Messages @@ -25,30 +31,63 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) public IProtocolIdentifier To { get; } public byte[] ToByteArray() { - var list = new List(); - list.Add(((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray()); - list.Add(From.ToByteArray().ToArray()); - list.Add(To.ToByteArray().ToArray()); + var list = new List + { + ((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray(), + From.ToByteArray().ToArray(), + ((int)ProtocolTypeMethods.GetProtocolType(To)).ToBytes().ToArray(), + To.ToByteArray().ToArray() + }; - switch (Input) + switch (To) { - case null: + case BinaryAgreementId _: + if (!(Input is bool binaryAgreementInput)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(( binaryAgreementInput ? 1: 0).ToBytes().ToArray()); + break; + case BinaryBroadcastId _: + if (!(Input is bool binaryBroadcastInput)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(( binaryBroadcastInput ? 1: 0).ToBytes().ToArray()); + break; + case CoinId _: + if (!(Input is null)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + break; + case CommonSubsetId _: + if (!(Input is EncryptedShare commonSubsetInput)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + list.Add(commonSubsetInput.ToByteArray()); break; - case bool b: - list.Add((b ? 1: 0).ToBytes().ToArray()); + case HoneyBadgerId _: + if (!(Input is IRawShare honeyBadgerInput)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + list.Add(honeyBadgerInput.ToByteArray()); break; - case IByteSerializable b: - list.Add(b.ToByteArray().ToArray()); + + case ReliableBroadcastId _: + if (Input is null) + break; + if (!(Input is EncryptedShare reliableBroadcastInput)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); + list.Add(reliableBroadcastInput.ToByteArray()); break; - case ISet set: - list.Add(set.Count.ToBytes().ToArray()); - foreach (var element in set) - { - list.Add(element.ToByteArray().ToArray()); - } + case RootProtocolId _: + if (!(Input is IBlockProducer)) + throw new ArgumentException( + $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); break; default: - throw new InvalidOperationException("Unrecognized TInputType"); + throw new InvalidOperationException($"Unrecognized TIdType {To.GetType()}"); } return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); @@ -56,13 +95,49 @@ public byte[] ToByteArray() public static ProtocolRequest FromByteArray(byte[] bytes) { - // switch (Type.GetTypeCode(typeof(TIdType))) - // { - // var decoded = (RLPCollection) RLP.Decode(bytes.ToArray()); - // var protocolType = (ProtocolType) decoded[0].RLPData.AsReadOnlySpan().ToInt32(); - // - // } - throw new NotImplementedException(); + var decoded = (RLPCollection)RLP.Decode(bytes.ToArray()); + var fromType = (ProtocolType)decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + var from = GetProtocolIdentifier(fromType, decoded[1].RLPData); + + var toType = (ProtocolType)decoded[2].RLPData.AsReadOnlySpan().ToInt32(); + var to = GetProtocolIdentifier(toType, decoded[3].RLPData); + + var input = GetInputData(toType, decoded[4]?.RLPData); + + return new ProtocolRequest(from, (TIdType)Convert.ChangeType(to, typeof(TIdType)), + (TInputType)Convert.ChangeType(to, typeof(TInputType))); + } + + private static object? GetInputData(ProtocolType toType, byte[]? bytes) + { + return toType switch + { + ProtocolType.BinaryAgreement => bytes.AsReadOnlySpan().ToInt32() == 1, + ProtocolType.BinaryBroadcast => bytes.AsReadOnlySpan().ToInt32() == 1, + ProtocolType.CommonCoin => null, + ProtocolType.CommonSubset => EncryptedShare.FromBytes(bytes), + ProtocolType.HoneyBadger => RawShare.FromByteArray(bytes), + ProtocolType.ReliableBroadcast => bytes is null ? null : EncryptedShare.FromBytes(bytes), + ProtocolType.RootProtocol => null, + _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {toType.ToString()}") + }; + } + + private static IProtocolIdentifier GetProtocolIdentifier(ProtocolType type, byte[] bytes) + { + return type switch + { + ProtocolType.BinaryAgreement => BinaryAgreementId.FromByteArray(bytes), + ProtocolType.BinaryBroadcast => BinaryBroadcastId.FromByteArray(bytes), + ProtocolType.CommonCoin => CoinId.FromByteArray(bytes), + ProtocolType.CommonSubset => CommonSubsetId.FromByteArray(bytes), + ProtocolType.HoneyBadger => HoneyBadgerId.FromByteArray(bytes), + ProtocolType.ReliableBroadcast => ReliableBroadcastId.FromByteArray(bytes), + ProtocolType.RootProtocol => RootProtocolId.FromByteArray(bytes), + _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {type.ToString()}") + }; } + + } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index a280ef268..623ee5a41 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -1,4 +1,18 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; +using Lachain.Utility.Serialization; +using Lachain.Utility.Utils; +using Nethereum.RLP; +using Org.BouncyCastle.Utilities.Collections; namespace Lachain.Consensus.Messages { @@ -17,7 +31,66 @@ public ProtocolResult(TIdType id, TResultType value) public IProtocolIdentifier? To => null; public byte[] ToByteArray() { - throw new NotImplementedException(); + var list = new List(); + list.Add(((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray()); + list.Add(From.ToByteArray().ToArray()); + list.Add(To.ToByteArray().ToArray()); + + switch (To) + { + case BinaryAgreementId _: + if (!(Result is bool binaryAgreementResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(( binaryAgreementResult ? 1: 0).ToBytes().ToArray()); + break; + case BinaryBroadcastId _: + if (!(Result is BoolSet binaryBroadcastResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(binaryBroadcastResult.ToByteArray()); + break; + case CoinId _: + if (!(Result is CoinResult coinResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + list.Add(coinResult.ToByteArray()); + break; + case CommonSubsetId _: + if (!(Result is ISet commonSubsetResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(commonSubsetResult.Count.ToBytes().ToArray()); + list.AddRange(commonSubsetResult.ToList().OrderBy(c => c.GetHashCode()).Select(share => share.ToByteArray())); + break; + case HoneyBadgerId _: + if (!(Result is ISet honeyBadgerResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + + list.Add(honeyBadgerResult.Count.ToBytes().ToArray()); + list.AddRange(honeyBadgerResult.ToList().OrderBy(c => c.GetHashCode()).Select(share => share.ToByteArray())); + break; + + case ReliableBroadcastId _: + if (!(Result is EncryptedShare reliableBroadcastResult)) + throw new ArgumentException( + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + list.Add(reliableBroadcastResult.ToByteArray()); + break; + case RootProtocolId _: + if (!(Result is null)) + throw new ArgumentException( + $"Unexpected Result type (not null) for ProtocolId {To.GetType()}"); + break; + default: + throw new InvalidOperationException($"Unrecognized TIdType {To.GetType()}"); + } + + return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } public static ProtocolResult FromByteArray(byte[] bytes) From 4008a9ed61212998477d6677a1d19a4da288a24b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 9 Nov 2022 20:13:36 +0600 Subject: [PATCH 028/133] Add desrializer for protocol result --- .../Messages/ProtocolRequest.cs | 20 +++- .../Messages/ProtocolResult.cs | 97 ++++++++++++++++--- 2 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 3090d234e..8fd672d1a 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -105,7 +105,7 @@ public static ProtocolRequest FromByteArray(byte[] bytes) var input = GetInputData(toType, decoded[4]?.RLPData); return new ProtocolRequest(from, (TIdType)Convert.ChangeType(to, typeof(TIdType)), - (TInputType)Convert.ChangeType(to, typeof(TInputType))); + (TInputType) Convert.ChangeType(input, typeof(TInputType))); } private static object? GetInputData(ProtocolType toType, byte[]? bytes) @@ -137,7 +137,23 @@ private static IProtocolIdentifier GetProtocolIdentifier(ProtocolType type, byte _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {type.ToString()}") }; } - + protected bool Equals(ProtocolRequest other) + { + return EqualityComparer.Default.Equals(Input, other.Input) && From.Equals(other.From) && To.Equals(other.To); + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((ProtocolRequest)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(Input, From, To); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index 623ee5a41..e307041bf 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -12,7 +12,6 @@ using Lachain.Utility.Serialization; using Lachain.Utility.Utils; using Nethereum.RLP; -using Org.BouncyCastle.Utilities.Collections; namespace Lachain.Consensus.Messages { @@ -31,37 +30,38 @@ public ProtocolResult(TIdType id, TResultType value) public IProtocolIdentifier? To => null; public byte[] ToByteArray() { - var list = new List(); - list.Add(((int)ProtocolTypeMethods.GetProtocolType(From)).ToBytes().ToArray()); - list.Add(From.ToByteArray().ToArray()); - list.Add(To.ToByteArray().ToArray()); - - switch (To) + var list = new List + { + ((int)ProtocolTypeMethods.GetProtocolType(Id)).ToBytes().ToArray(), + Id.ToByteArray().ToArray() + }; + + switch (Id) { case BinaryAgreementId _: if (!(Result is bool binaryAgreementResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(( binaryAgreementResult ? 1: 0).ToBytes().ToArray()); break; case BinaryBroadcastId _: if (!(Result is BoolSet binaryBroadcastResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(binaryBroadcastResult.ToByteArray()); break; case CoinId _: if (!(Result is CoinResult coinResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(coinResult.ToByteArray()); break; case CommonSubsetId _: if (!(Result is ISet commonSubsetResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(commonSubsetResult.Count.ToBytes().ToArray()); list.AddRange(commonSubsetResult.ToList().OrderBy(c => c.GetHashCode()).Select(share => share.ToByteArray())); @@ -69,7 +69,7 @@ public byte[] ToByteArray() case HoneyBadgerId _: if (!(Result is ISet honeyBadgerResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(honeyBadgerResult.Count.ToBytes().ToArray()); list.AddRange(honeyBadgerResult.ToList().OrderBy(c => c.GetHashCode()).Select(share => share.ToByteArray())); @@ -78,16 +78,16 @@ public byte[] ToByteArray() case ReliableBroadcastId _: if (!(Result is EncryptedShare reliableBroadcastResult)) throw new ArgumentException( - $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {To.GetType()}"); + $"Unexpected Result type ({Result?.GetType()}) for ProtocolId {Id.GetType()}"); list.Add(reliableBroadcastResult.ToByteArray()); break; case RootProtocolId _: if (!(Result is null)) throw new ArgumentException( - $"Unexpected Result type (not null) for ProtocolId {To.GetType()}"); + $"Unexpected Result type (not null) for ProtocolId {Id.GetType()}"); break; default: - throw new InvalidOperationException($"Unrecognized TIdType {To.GetType()}"); + throw new InvalidOperationException($"Unrecognized TIdType {Id.GetType()}"); } return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); @@ -95,7 +95,72 @@ public byte[] ToByteArray() public static ProtocolResult FromByteArray(byte[] bytes) { - throw new NotImplementedException(); + var decoded = (RLPCollection)RLP.Decode(bytes.ToArray()); + + var toType = (ProtocolType)decoded[2].RLPData.AsReadOnlySpan().ToInt32(); + var from = GetProtocolIdentifier(toType, decoded[3].RLPData); + + var result = GetResultData(toType, decoded); + + return new ProtocolResult((TIdType)Convert.ChangeType(from, typeof(TIdType)), + (TResultType)Convert.ChangeType(result, typeof(TResultType))); + } + + private static object? GetResultData(ProtocolType toType, RLPCollection decoded) + { + var bytes = decoded[4].RLPData; + return toType switch + { + ProtocolType.BinaryAgreement => bytes.AsReadOnlySpan().ToInt32() == 1, + ProtocolType.BinaryBroadcast => BoolSet.FromByteArray(bytes), + ProtocolType.CommonCoin => CoinResult.FromByteArray(bytes), + ProtocolType.CommonSubset => GetSetOfEncryptedShareFromBytes(decoded), + ProtocolType.HoneyBadger => GetSetOfIRawShareFromBytes(decoded), + ProtocolType.ReliableBroadcast => EncryptedShare.FromBytes(bytes), + ProtocolType.RootProtocol => null, + _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {toType.ToString()}") + }; + } + + private static object? GetSetOfIRawShareFromBytes(RLPCollection decoded) + { + var count = decoded[5].RLPData.AsReadOnlySpan().ToInt32(); + ISet set = new HashSet(); + for (var i = 0; i < count; i++) + { + var share = RawShare.FromByteArray(decoded[6+i].RLPData); + set.Add(share); + } + + return set; + } + + private static ISet GetSetOfEncryptedShareFromBytes(RLPCollection decoded) + { + var count = decoded[5].RLPData.AsReadOnlySpan().ToInt32(); + ISet set = new HashSet(); + for (var i = 0; i < count; i++) + { + var share = EncryptedShare.FromByteArray(decoded[6+i].RLPData); + set.Add(share); + } + + return set; + } + + private static IProtocolIdentifier GetProtocolIdentifier(ProtocolType type, byte[] bytes) + { + return type switch + { + ProtocolType.BinaryAgreement => BinaryAgreementId.FromByteArray(bytes), + ProtocolType.BinaryBroadcast => BinaryBroadcastId.FromByteArray(bytes), + ProtocolType.CommonCoin => CoinId.FromByteArray(bytes), + ProtocolType.CommonSubset => CommonSubsetId.FromByteArray(bytes), + ProtocolType.HoneyBadger => HoneyBadgerId.FromByteArray(bytes), + ProtocolType.ReliableBroadcast => ReliableBroadcastId.FromByteArray(bytes), + ProtocolType.RootProtocol => RootProtocolId.FromByteArray(bytes), + _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {type.ToString()}") + }; } } } \ No newline at end of file From 68dfc4e623c4a258a61f53c1e1d3f5ff8f891b4b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 9 Nov 2022 20:14:14 +0600 Subject: [PATCH 029/133] Add Equals and hashcode methods to message related objects (and some refactoing) --- .../Messages/MessageEnvelope.cs | 31 +++++++++++---- .../Messages/MessageEnvelopeList.cs | 39 ++++++++++++++----- .../MessageEnvelopeRepositoryManager.cs | 8 ++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 4 +- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index 64c9d3b7e..879a167b9 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -19,8 +19,8 @@ namespace Lachain.Consensus.Messages { public class MessageEnvelope : IByteSerializable { - public const string PROTOCOL_REQUEST = "ProtocolRequest"; - public const string PROTOCOL_RESPONSE = "ProtocolResponse"; + public const string ProtocolRequest = "ProtocolRequest"; + public const string ProtocolResponse = "ProtocolResponse"; public ConsensusMessage? ExternalMessage { get; } public int ValidatorIndex { get; } @@ -41,15 +41,15 @@ public MessageEnvelope(IInternalMessage msg, int validatorIndex) } public bool External => !(ExternalMessage is null); - public bool isProtocolRequest => !(InternalMessage is null) && TypeString() == PROTOCOL_REQUEST; - public bool isProtocolResponse => !(InternalMessage is null) && TypeString() == PROTOCOL_RESPONSE; + public bool IsProtocolRequest => !(InternalMessage is null) && TypeString() == ProtocolRequest; + public bool IsProtocolResponse => !(InternalMessage is null) && TypeString() == ProtocolResponse; public string TypeString() { if (External) return ExternalMessage!.PayloadCase.ToString(); return InternalMessage!.GetType().GetGenericTypeDefinition().Name.Contains("Request") - ? PROTOCOL_REQUEST - : PROTOCOL_RESPONSE; + ? ProtocolRequest + : ProtocolResponse; } public byte[] ToByteArray() @@ -63,7 +63,7 @@ public byte[] ToByteArray() list.Add(ExternalMessage.ToByteArray()); } else { - list.Add( (isProtocolRequest ? 1 : 0).ToBytes().ToArray()); + list.Add( (IsProtocolRequest ? 1 : 0).ToBytes().ToArray()); var protocolType = (int) ProtocolTypeMethods.GetProtocolType(InternalMessage.To); list.Add(protocolType.ToBytes().ToArray()); list.Add(InternalMessage.ToByteArray()); @@ -150,5 +150,22 @@ private static IInternalMessage GetProtocolResponseFromByteArray(ProtocolType pr } } + protected bool Equals(MessageEnvelope other) + { + return Equals(ExternalMessage, other.ExternalMessage) && ValidatorIndex == other.ValidatorIndex && Equals(InternalMessage, other.InternalMessage); + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((MessageEnvelope)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(ExternalMessage, ValidatorIndex, InternalMessage); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index e7994c369..4d7ab686f 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -8,29 +8,29 @@ namespace Lachain.Consensus.Messages { public class MessageEnvelopeList : IByteSerializable { - public long era { get; } - public ICollection messageList { get; } + public long Era { get; } + public ICollection MessageList { get; } public MessageEnvelopeList(long era) { - this.era = era; - this.messageList = new List(); + this.Era = era; + this.MessageList = new List(); } - public void addMessage(MessageEnvelope messageEnvelope) + public void AddMessage(MessageEnvelope messageEnvelope) { - messageList.Add(messageEnvelope); + MessageList.Add(messageEnvelope); } public byte[] ToByteArray() { var list = new List(); - list.Add(era.ToBytes().ToArray()); - list.Add(messageList.Count.ToBytes().ToArray()); + list.Add(Era.ToBytes().ToArray()); + list.Add(MessageList.Count.ToBytes().ToArray()); - foreach (var message in messageList) + foreach (var message in MessageList) { list.Add(message.ToByteArray()); } @@ -49,10 +49,29 @@ public static MessageEnvelopeList FromByteArray(byte[] bytes) for (int i = 0; i < count; i++) { var envelopeBytes = decoded[2 + i].RLPData; - messageEnvelopeList.addMessage(MessageEnvelope.FromByteArray(envelopeBytes)); + messageEnvelopeList.AddMessage(MessageEnvelope.FromByteArray(envelopeBytes)); } return messageEnvelopeList; } + + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((MessageEnvelopeList)obj); + } + + public bool Equals(MessageEnvelopeList other) + { + return Era == other.Era && MessageList.Equals(other.MessageList); + } + + public override int GetHashCode() + { + return HashCode.Combine(Era, MessageList); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 5cde30567..97a208914 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -32,12 +32,12 @@ public long GetEra() { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } - return _messageEnvelopeList.era; + return _messageEnvelopeList.Era; } public void StartEra(long era) { - if (isPresent && _messageEnvelopeList.era == era) + if (isPresent && _messageEnvelopeList.Era == era) { throw new ArgumentException($"Start Era called with same era number {era}"); } @@ -53,13 +53,13 @@ public void AddMessage(MessageEnvelope message) { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } - _messageEnvelopeList.addMessage(message); + _messageEnvelopeList.AddMessage(message); SaveToDb(_messageEnvelopeList); } public ICollection GetMessages() { - return _messageEnvelopeList.messageList; + return _messageEnvelopeList.MessageList; } private void SaveToDb(MessageEnvelopeList messageEnvelopeList) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 615b81668..aa13105bd 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -129,7 +129,7 @@ public void RestoreState() { Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); } - else if (messageEnvelope.isProtocolRequest) + else if (messageEnvelope.IsProtocolRequest) { switch (messageEnvelope.InternalMessage) { @@ -159,7 +159,7 @@ public void RestoreState() "Unexpected template parameters for ProtocolRequest"); } } - else if (messageEnvelope.isProtocolResponse) + else if (messageEnvelope.IsProtocolResponse) { switch (messageEnvelope.InternalMessage) { From 86285e03eb409840455100be074abf2de209320f Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 9 Nov 2022 20:16:35 +0600 Subject: [PATCH 030/133] Add test for binaryagreement --- .../SerializationTest.cs | 86 +++++++++++-------- test/Lachain.ConsensusTest/TestUtils.cs | 49 ++++++++++- 2 files changed, 95 insertions(+), 40 deletions(-) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index b89b3182c..c5a2bd8a6 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,5 +1,4 @@ using System; -using Google.Protobuf; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; using Lachain.Consensus.CommonSubset; @@ -7,10 +6,8 @@ using Lachain.Consensus.Messages; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; -using Lachain.ConsensusTest; using Lachain.Crypto; using Lachain.Crypto.TPKE; -using Lachain.Proto; using Lachain.Utility.Utils; using MCL.BLS12_381.Net; using NUnit.Framework; @@ -35,75 +32,92 @@ public void Test_Serialization() { for (int i = 0; i < 100; i++) { - TestSerializationAndAdd_BinaryAgreement(); - TestSerializationAndAdd_BinaryBroadcast(); - TestSerializationAndAdd_CommonCoin(); - TestSerializationAndAdd_CommonSubset(); - TestSerializationAndAdd_HoneyBadger(); - TestSerializationAndAdd_ReliableBroadcast(); - TestSerializationAndAdd_RootProtocol(); - TestUtils.AssertEqual(_messageList, MessageEnvelopeList.FromByteArray(_messageList.ToByteArray())); + TestSerializationAndAddToListBinaryAgreement(_messageList); + TestSerializationAndAddToListBinaryBroadcast(_messageList); + TestSerializationAndAddToListCommonCoin(_messageList); + TestSerializationAndAddToListCommonSubset(_messageList); + TestSerializationAndAddToListHoneyBadger(_messageList); + TestSerializationAndAddToListReliableBroadcast(_messageList); + TestSerializationAndAddToListRootProtocol(_messageList); } } - private void TestSerializationAndAdd_BinaryAgreement() + private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList messageList) { - var binaryAgreementId = new BinaryAgreementId(random.Next(), random.Next()); + var binaryAgreementId = TestUtils.GenerateBinaryAgreementId(random); Assert.AreEqual(binaryAgreementId, BinaryAgreementId.FromByteArray(binaryAgreementId.ToByteArray())); + + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), binaryAgreementId, true); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); - // var binaryBroadcastMessage = TestUtils.GenerateBinaryBroadcastConsensusMessage(); - // Assert.AreEqual(binaryBroadcastMessage, ConsensusMessage.Parser.ParseFrom(binaryBroadcastMessage.ToByteArray())); - // - // var binaryBroadcastEnvelope = new MessageEnvelope(binaryBroadcastMessage, random.Next()); - // Assert.AreEqual(binaryBroadcastEnvelope, MessageEnvelope.FromByteArray(binaryBroadcastEnvelope.ToByteArray())); - // - // _messageList.addMessage(binaryBroadcastEnvelope); - + var result = new ProtocolResult (binaryAgreementId, true); + Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } - private void TestSerializationAndAdd_BinaryBroadcast() + private MessageEnvelope TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList _messageList) { var binaryBroadcastId = new BinaryBroadcastId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); + + var bs = TestUtils.GenerateBoolSet(random); + Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); + + + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), binaryBroadcastId, true); + + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); - var bs = TestSerializationAndGet_BoolSet(); + var message = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(message, MessageEnvelope.FromByteArray(message.ToByteArray())); + + return message; + } - private void TestSerializationAndAdd_CommonCoin() + private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList _messageList) { var coinId = new CoinId(random.Next(), random.Next(), random.Next()); Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); - var cr = TestSerializationAndGet_Coinresult(); + // var cr = TestUtils.Gene(MessageEnvelopeList _messageList); } - private void TestSerializationAndAdd_CommonSubset() + private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList _messageList) { var commonSubsetId = new CommonSubsetId(random.Next()); Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); - var share = TestSerializationAndGet_EncryptedShare(); + var share = TestSerializationAndGetEncryptedShare(); } - private void TestSerializationAndAdd_HoneyBadger() + private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList _messageList) { var honeyBadgerId = new HoneyBadgerId(random.Next()); Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); - var share = TestSerializationAndGet_IRawShare(); + var share = TestSerializationAndGetIRawShare(); } - private void TestSerializationAndAdd_ReliableBroadcast() + private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList _messageList) { var reliableBroadcastId = new ReliableBroadcastId(random.Next(), random.Next()); Assert.AreEqual(reliableBroadcastId, ReliableBroadcastId.FromByteArray(reliableBroadcastId.ToByteArray())); } - private void TestSerializationAndAdd_RootProtocol() + private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList _messageList) { var rootProtocolId = new RootProtocolId(random.Next()); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); } - private EncryptedShare TestSerializationAndGet_EncryptedShare() + private EncryptedShare TestSerializationAndGetEncryptedShare() { var rnd = new byte[32]; random.NextBytes(rnd); @@ -111,7 +125,7 @@ private EncryptedShare TestSerializationAndGet_EncryptedShare() Assert.AreEqual(share, EncryptedShare.FromByteArray(share.ToByteArray())); return share; } - private IRawShare TestSerializationAndGet_IRawShare() + private IRawShare TestSerializationAndGetIRawShare() { var rnd = new byte[32]; random.NextBytes(rnd); @@ -120,7 +134,7 @@ private IRawShare TestSerializationAndGet_IRawShare() return share; } - private CoinResult TestSerializationAndGet_Coinresult() + private CoinResult TestSerializationAndGetCoinResult() { var rnd = new byte[32]; random.NextBytes(rnd); @@ -129,9 +143,9 @@ private CoinResult TestSerializationAndGet_Coinresult() return coinResult; } - private BoolSet TestSerializationAndGet_BoolSet() + private BoolSet TestSerializationAndGetBoolSet() { - bool[] bools = { random.Next(0, 1) == 1, random.Next(0, 1) == 0 }; + bool[] bools = { random.Next(0, 1) == 1, random.Next(0, 1) == 1 }; var bs = new BoolSet(bools); Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); return bs; diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 33d3f20be..19e1badc4 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -1,7 +1,14 @@ +using System; +using System.Runtime.Serialization; using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; -using Lachain.Consensus.Messages; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; using Lachain.Proto; +using Lachain.Utility.Utils; using NUnit.Framework; namespace Lachain.ConsensusTest @@ -13,6 +20,7 @@ public static IPrivateConsensusKeySet EmptyWallet(int n, int f) return new PrivateConsensusKeySet(null!, null!, null!); } + public static ConsensusMessage GenerateBinaryBroadcastConsensusMessage() { var _broadcastId = new BinaryBroadcastId(2142, 42342, 13124312); @@ -28,10 +36,43 @@ public static ConsensusMessage GenerateBinaryBroadcastConsensusMessage() return message; } - public static void AssertEqual(MessageEnvelopeList a, MessageEnvelopeList b) + public static BinaryAgreementId GenerateBinaryAgreementId(Random random) + { + return new BinaryAgreementId(random.Next(), random.Next()); + } + public static BinaryBroadcastId GenerateBinaryBroadcastId(Random random) + { + return new BinaryBroadcastId(random.Next(), random.Next(), random.Next()); + } + public static CoinId GenerateCoinId(Random random) + { + return new CoinId(random.Next(), random.Next(), random.Next()); + } + public static CommonSubsetId GenerateCommonSubsetId(Random random) + { + return new CommonSubsetId(random.Next()); + } + public static HoneyBadgerId GenerateHoneyBadgerId(Random random) + { + return new HoneyBadgerId(random.Next()); + } + public static ReliableBroadcastId GenerateReliableBroadcastId(Random random) + { + return new ReliableBroadcastId(random.Next(), random.Next()); + } + public static RootProtocolId GenerateRootProtocolId(Random random) + { + return new RootProtocolId(random.Next()); + } + + public static BoolSet GenerateBoolSet(Random random) { - Assert.AreEqual(a.era, b.era); - CollectionAssert.AreEqual(a.messageList, b.messageList); + var bs = new BoolSet(); + if (random.Next(0, 1) == 1) + bs.Add(true); + if (random.Next(0, 1) == 1) + bs.Add(false); + return bs; } } } \ No newline at end of file From b7563821d81f7c88217fc6c4656fd7d2ed33695b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 9 Nov 2022 21:15:14 +0600 Subject: [PATCH 031/133] Write tests for commoncoin, commonsubset and honeybadger --- .../SerializationTest.cs | 123 ++++++++++-------- test/Lachain.ConsensusTest/TestUtils.cs | 49 +++++++ 2 files changed, 115 insertions(+), 57 deletions(-) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index c5a2bd8a6..07949a888 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; using Lachain.Consensus.CommonSubset; @@ -64,47 +65,89 @@ private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList me } - private MessageEnvelope TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList messageList) { - var binaryBroadcastId = new BinaryBroadcastId(random.Next(), random.Next(), random.Next()); + var binaryBroadcastId = TestUtils.GenerateBinaryBroadcastId(random); Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); - - var bs = TestUtils.GenerateBoolSet(random); - Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); - - + var request = new ProtocolRequest - (TestUtils.GenerateCommonSubsetId(random), binaryBroadcastId, true); + (TestUtils.GenerateBinaryAgreementId(random), binaryBroadcastId, true); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); - Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); - - var message = new MessageEnvelope(request, random.Next(1, 100)); - Assert.AreEqual(message, MessageEnvelope.FromByteArray(message.ToByteArray())); - - return message; + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var result = new ProtocolResult (binaryBroadcastId, true); + Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } - private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList messageList) { - var coinId = new CoinId(random.Next(), random.Next(), random.Next()); + var coinId = TestUtils.GenerateCoinId(random); Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); - // var cr = TestUtils.Gene(MessageEnvelopeList _messageList); + var request = new ProtocolRequest + (TestUtils.GenerateBinaryAgreementId(random), coinId, null); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var coinResult = TestUtils.GenerateCoinResult(random); + Assert.AreEqual(coinResult, CoinResult.FromByteArray(coinResult.ToByteArray())); + + var result = new ProtocolResult (coinId, coinResult); + Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } - private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messageList) { - var commonSubsetId = new CommonSubsetId(random.Next()); + var commonSubsetId = TestUtils.GenerateCommonSubsetId(random); Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); - var share = TestSerializationAndGetEncryptedShare(); + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), commonSubsetId, TestUtils.GenerateEncryptedShare(random)); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var result = new ProtocolResult> (commonSubsetId, TestUtils.GenerateSetOfEncryptedShare(random)); + Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } - private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList messageList) { - var honeyBadgerId = new HoneyBadgerId(random.Next()); + var honeyBadgerId = TestUtils.GenerateHoneyBadgerId(random); Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); + + var request = new ProtocolRequest + (TestUtils.GenerateHoneyBadgerId(random), honeyBadgerId, TestUtils.GenerateIRawShare(random)); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); - var share = TestSerializationAndGetIRawShare(); + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var result = new ProtocolResult> (honeyBadgerId, TestUtils.GenerateSetOfIRawShare(random)); + Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList _messageList) { @@ -116,41 +159,7 @@ private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList _mess var rootProtocolId = new RootProtocolId(random.Next()); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); } - - private EncryptedShare TestSerializationAndGetEncryptedShare() - { - var rnd = new byte[32]; - random.NextBytes(rnd); - var share = new EncryptedShare(G1.Generator, rnd, G2.Generator, random.Next()); - Assert.AreEqual(share, EncryptedShare.FromByteArray(share.ToByteArray())); - return share; - } - private IRawShare TestSerializationAndGetIRawShare() - { - var rnd = new byte[32]; - random.NextBytes(rnd); - var share = new RawShare(rnd, random.Next()); - Assert.AreEqual(share, RawShare.FromByteArray(share.ToByteArray())); - return share; - } - private CoinResult TestSerializationAndGetCoinResult() - { - var rnd = new byte[32]; - random.NextBytes(rnd); - var coinResult = new CoinResult(rnd); - Assert.AreEqual(coinResult, CoinResult.FromByteArray(coinResult.ToByteArray())); - return coinResult; - } - - private BoolSet TestSerializationAndGetBoolSet() - { - bool[] bools = { random.Next(0, 1) == 1, random.Next(0, 1) == 1 }; - var bs = new BoolSet(bools); - Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); - return bs; - } - } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 19e1badc4..95f148901 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.Serialization; using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; @@ -7,8 +8,11 @@ using Lachain.Consensus.HoneyBadger; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; +using Lachain.Crypto; +using Lachain.Crypto.TPKE; using Lachain.Proto; using Lachain.Utility.Utils; +using MCL.BLS12_381.Net; using NUnit.Framework; namespace Lachain.ConsensusTest @@ -74,5 +78,50 @@ public static BoolSet GenerateBoolSet(Random random) bs.Add(false); return bs; } + + public static CoinResult GenerateCoinResult(Random random) + { + return new CoinResult(G2.Generator.ToBytes()); + } + + public static EncryptedShare GenerateEncryptedShare(Random random) + { + var rnd = new byte[32]; + random.NextBytes(rnd); + var share = new EncryptedShare(G1.Generator, rnd, G2.Generator, random.Next()); + Assert.AreEqual(share, EncryptedShare.FromByteArray(share.ToByteArray())); + return share; + } + + public static IRawShare GenerateIRawShare(Random random) + { + var rnd = new byte[32]; + random.NextBytes(rnd); + return new RawShare(rnd, random.Next()); + } + + public static ISet GenerateSetOfEncryptedShare(Random random) + { + var count = random.Next(1, 10); + var set = new HashSet(); + for (var i = 0; i < count; i++) + { + set.Add(GenerateEncryptedShare(random)); + } + + return set; + } + public static ISet GenerateSetOfIRawShare(Random random) + { + var count = random.Next(1, 10); + var set = new HashSet(); + for (var i = 0; i < count; i++) + { + set.Add(GenerateIRawShare(random)); + } + + return set; + } + } } } \ No newline at end of file From 4ab3d6a7afe897150e07b1bc7481e1ff229f4cdb Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 10 Nov 2022 18:44:35 +0600 Subject: [PATCH 032/133] Fix bugs in serialization and equality checks --- .../Messages/MessageEnvelopeList.cs | 14 ++---- .../Messages/ProtocolRequest.cs | 6 +-- .../Messages/ProtocolResult.cs | 49 ++++++++++++++++--- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index 4d7ab686f..c39bbbee0 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -25,16 +25,12 @@ public void AddMessage(MessageEnvelope messageEnvelope) public byte[] ToByteArray() { - var list = new List(); - - list.Add(Era.ToBytes().ToArray()); - list.Add(MessageList.Count.ToBytes().ToArray()); - - foreach (var message in MessageList) + var list = new List { - list.Add(message.ToByteArray()); - } - + Era.ToBytes().ToArray(), + MessageList.Count.ToBytes().ToArray() + }; + list.AddRange(MessageList.ToList().Select(message => message.ToByteArray())); return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 8fd672d1a..44d50aaf0 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -102,10 +102,10 @@ public static ProtocolRequest FromByteArray(byte[] bytes) var toType = (ProtocolType)decoded[2].RLPData.AsReadOnlySpan().ToInt32(); var to = GetProtocolIdentifier(toType, decoded[3].RLPData); - var input = GetInputData(toType, decoded[4]?.RLPData); + var input = decoded.Count >= 5 ? GetInputData(toType, decoded[4]?.RLPData): null; - return new ProtocolRequest(from, (TIdType)Convert.ChangeType(to, typeof(TIdType)), - (TInputType) Convert.ChangeType(input, typeof(TInputType))); + + return new ProtocolRequest(from, (TIdType) to, (TInputType) input ); } private static object? GetInputData(ProtocolType toType, byte[]? bytes) diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index e307041bf..4c254a175 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -97,18 +97,17 @@ public static ProtocolResult FromByteArray(byte[] bytes) { var decoded = (RLPCollection)RLP.Decode(bytes.ToArray()); - var toType = (ProtocolType)decoded[2].RLPData.AsReadOnlySpan().ToInt32(); - var from = GetProtocolIdentifier(toType, decoded[3].RLPData); + var toType = (ProtocolType)decoded[0].RLPData.AsReadOnlySpan().ToInt32(); + var from = GetProtocolIdentifier(toType, decoded[1].RLPData); var result = GetResultData(toType, decoded); - return new ProtocolResult((TIdType)Convert.ChangeType(from, typeof(TIdType)), - (TResultType)Convert.ChangeType(result, typeof(TResultType))); + return new ProtocolResult((TIdType) from,(TResultType) result); } private static object? GetResultData(ProtocolType toType, RLPCollection decoded) { - var bytes = decoded[4].RLPData; + var bytes = decoded[2].RLPData; return toType switch { ProtocolType.BinaryAgreement => bytes.AsReadOnlySpan().ToInt32() == 1, @@ -137,11 +136,11 @@ public static ProtocolResult FromByteArray(byte[] bytes) private static ISet GetSetOfEncryptedShareFromBytes(RLPCollection decoded) { - var count = decoded[5].RLPData.AsReadOnlySpan().ToInt32(); + var count = decoded[2].RLPData.AsReadOnlySpan().ToInt32(); ISet set = new HashSet(); for (var i = 0; i < count; i++) { - var share = EncryptedShare.FromByteArray(decoded[6+i].RLPData); + var share = EncryptedShare.FromByteArray(decoded[3+i].RLPData); set.Add(share); } @@ -162,5 +161,41 @@ private static IProtocolIdentifier GetProtocolIdentifier(ProtocolType type, byte _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {type.ToString()}") }; } + + protected bool Equals(ProtocolResult other) + { + return EqualityComparer.Default.Equals(Id, other.Id) && ResultEquals(Result, other.Result); + } + + private bool ResultEquals(TResultType result, TResultType otherResult) + { + if (result is null || otherResult is null) { + return result is null && otherResult is null; + } + + switch (result) + { + case ISet encryptedShares: + return encryptedShares.SetEquals((ISet) otherResult); + case ISet rawShares: + return rawShares.SetEquals((ISet) otherResult); + default: + return EqualityComparer.Default.Equals(result, otherResult); + + } + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((ProtocolResult)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(Id, Result); + } } } \ No newline at end of file From aeffb759b9e7f576ecd8f077cb4761f194e513f8 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 10 Nov 2022 18:44:58 +0600 Subject: [PATCH 033/133] Add tests for all internal messages --- .../SerializationTest.cs | 64 ++++++++++++++----- test/Lachain.ConsensusTest/TestUtils.cs | 7 +- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 07949a888..02a4cbf30 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; using Lachain.Consensus.CommonSubset; @@ -7,10 +8,10 @@ using Lachain.Consensus.Messages; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; +using Lachain.Core.Consensus; using Lachain.Crypto; using Lachain.Crypto.TPKE; using Lachain.Utility.Utils; -using MCL.BLS12_381.Net; using NUnit.Framework; namespace Lachain.ConsensusTest @@ -57,7 +58,7 @@ private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList me messageList.AddMessage(requestMessage); var result = new ProtocolResult (binaryAgreementId, true); - Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); @@ -78,8 +79,8 @@ private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList me Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); messageList.AddMessage(requestMessage); - var result = new ProtocolResult (binaryBroadcastId, true); - Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + var result = new ProtocolResult (binaryBroadcastId, TestUtils.GenerateBoolSet(random)); + Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); @@ -93,7 +94,7 @@ private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList message var request = new ProtocolRequest (TestUtils.GenerateBinaryAgreementId(random), coinId, null); - Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); @@ -103,7 +104,7 @@ private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList message Assert.AreEqual(coinResult, CoinResult.FromByteArray(coinResult.ToByteArray())); var result = new ProtocolResult (coinId, coinResult); - Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); @@ -115,15 +116,15 @@ private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messa Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); var request = new ProtocolRequest - (TestUtils.GenerateCommonSubsetId(random), commonSubsetId, TestUtils.GenerateEncryptedShare(random)); - Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + (TestUtils.GenerateHoneyBadgerId(random), commonSubsetId, TestUtils.GenerateEncryptedShare(random, false)); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); messageList.AddMessage(requestMessage); var result = new ProtocolResult> (commonSubsetId, TestUtils.GenerateSetOfEncryptedShare(random)); - Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); @@ -135,29 +136,60 @@ private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList messag Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); var request = new ProtocolRequest - (TestUtils.GenerateHoneyBadgerId(random), honeyBadgerId, TestUtils.GenerateIRawShare(random)); - Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + (TestUtils.GenerateRootProtocolId(random), honeyBadgerId, TestUtils.GenerateIRawShare(random)); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); messageList.AddMessage(requestMessage); var result = new ProtocolResult> (honeyBadgerId, TestUtils.GenerateSetOfIRawShare(random)); - Assert.AreEqual(request, ProtocolResult.FromByteArray(result.ToByteArray())); + Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } - private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList messageList) { - var reliableBroadcastId = new ReliableBroadcastId(random.Next(), random.Next()); + var reliableBroadcastId = TestUtils.GenerateReliableBroadcastId(random); Assert.AreEqual(reliableBroadcastId, ReliableBroadcastId.FromByteArray(reliableBroadcastId.ToByteArray())); + + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), reliableBroadcastId, TestUtils.GenerateEncryptedShare(random, true)); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var result = new ProtocolResult + (reliableBroadcastId, TestUtils.GenerateEncryptedShare(random, false)!); + Assert.AreEqual(result, ProtocolResult .FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } - private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList _messageList) + private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messageList) { - var rootProtocolId = new RootProtocolId(random.Next()); + var rootProtocolId = TestUtils.GenerateRootProtocolId(random); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); + + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), rootProtocolId, null); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + + var result = new ProtocolResult (rootProtocolId, null); + Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); + + var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); + messageList.AddMessage(resultMessage); } diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 95f148901..2ac7b678d 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -84,8 +84,10 @@ public static CoinResult GenerateCoinResult(Random random) return new CoinResult(G2.Generator.ToBytes()); } - public static EncryptedShare GenerateEncryptedShare(Random random) + public static EncryptedShare? GenerateEncryptedShare(Random random, bool canBeNull) { + if (canBeNull && random.Next(0, 1) == 1) + return null; var rnd = new byte[32]; random.NextBytes(rnd); var share = new EncryptedShare(G1.Generator, rnd, G2.Generator, random.Next()); @@ -106,7 +108,7 @@ public static ISet GenerateSetOfEncryptedShare(Random random) var set = new HashSet(); for (var i = 0; i < count; i++) { - set.Add(GenerateEncryptedShare(random)); + set.Add(GenerateEncryptedShare(random, false)); } return set; @@ -123,5 +125,4 @@ public static ISet GenerateSetOfIRawShare(Random random) return set; } } - } } \ No newline at end of file From 0bf76c8cb52f420cc0ea8235b133bbaadc920c39 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 04:06:44 +0600 Subject: [PATCH 034/133] Fix bugs and refactor --- .../Messages/MessageEnvelope.cs | 10 ++++---- .../Messages/ProtocolResult.cs | 24 +++++++++++++------ src/Lachain.Crypto/RawShare.cs | 6 ++--- src/Lachain.Crypto/TPKE/EncryptedShare.cs | 4 +++- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index 879a167b9..a872895e1 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -54,10 +54,12 @@ public string TypeString() public byte[] ToByteArray() { - var list = new List(); - list.Add(ValidatorIndex.ToBytes().ToArray()); - list.Add((External ? 1 : 0).ToBytes().ToArray()); - + var list = new List + { + ValidatorIndex.ToBytes().ToArray(), + (External ? 1 : 0).ToBytes().ToArray() + }; + if (External) { list.Add(ExternalMessage.ToByteArray()); diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index 4c254a175..fd1f3d97f 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -107,15 +107,14 @@ public static ProtocolResult FromByteArray(byte[] bytes) private static object? GetResultData(ProtocolType toType, RLPCollection decoded) { - var bytes = decoded[2].RLPData; return toType switch { - ProtocolType.BinaryAgreement => bytes.AsReadOnlySpan().ToInt32() == 1, - ProtocolType.BinaryBroadcast => BoolSet.FromByteArray(bytes), - ProtocolType.CommonCoin => CoinResult.FromByteArray(bytes), + ProtocolType.BinaryAgreement => decoded[2].RLPData.AsReadOnlySpan().ToInt32() == 1, + ProtocolType.BinaryBroadcast => BoolSet.FromByteArray(decoded[2].RLPData), + ProtocolType.CommonCoin => CoinResult.FromByteArray(decoded[2].RLPData), ProtocolType.CommonSubset => GetSetOfEncryptedShareFromBytes(decoded), ProtocolType.HoneyBadger => GetSetOfIRawShareFromBytes(decoded), - ProtocolType.ReliableBroadcast => EncryptedShare.FromBytes(bytes), + ProtocolType.ReliableBroadcast => EncryptedShare.FromBytes(decoded[2].RLPData), ProtocolType.RootProtocol => null, _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {toType.ToString()}") }; @@ -123,11 +122,11 @@ public static ProtocolResult FromByteArray(byte[] bytes) private static object? GetSetOfIRawShareFromBytes(RLPCollection decoded) { - var count = decoded[5].RLPData.AsReadOnlySpan().ToInt32(); + var count = decoded[2].RLPData.AsReadOnlySpan().ToInt32(); ISet set = new HashSet(); for (var i = 0; i < count; i++) { - var share = RawShare.FromByteArray(decoded[6+i].RLPData); + var share = RawShare.FromByteArray(decoded[3+i].RLPData); set.Add(share); } @@ -178,6 +177,17 @@ private bool ResultEquals(TResultType result, TResultType otherResult) case ISet encryptedShares: return encryptedShares.SetEquals((ISet) otherResult); case ISet rawShares: + foreach (var s1 in rawShares) + { + foreach (var s2 in (ISet) otherResult) + { + if (s1.Equals(s2)) + { + var hashCode = s1.GetHashCode(); + var code = s2.GetHashCode(); + } + } + } return rawShares.SetEquals((ISet) otherResult); default: return EqualityComparer.Default.Equals(result, otherResult); diff --git a/src/Lachain.Crypto/RawShare.cs b/src/Lachain.Crypto/RawShare.cs index 0635c3dd6..17fda5440 100644 --- a/src/Lachain.Crypto/RawShare.cs +++ b/src/Lachain.Crypto/RawShare.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using Lachain.Utility.Serialization; @@ -27,10 +28,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - unchecked - { - return (Id * 397) ^ (Data != null ? Data.GetHashCode() : 0); - } + return HashCode.Combine(Id, Data.Length); } public byte[] ToByteArray() diff --git a/src/Lachain.Crypto/TPKE/EncryptedShare.cs b/src/Lachain.Crypto/TPKE/EncryptedShare.cs index 98aa98082..56c0d4407 100644 --- a/src/Lachain.Crypto/TPKE/EncryptedShare.cs +++ b/src/Lachain.Crypto/TPKE/EncryptedShare.cs @@ -50,7 +50,9 @@ public override bool Equals(object? obj) public override int GetHashCode() { - return HashCode.Combine(U, V, W, Id); + // U.GetHashCode() and V.GetHashCode() is buggy + // The following bypasses these calls and also is an performance optimization. + return HashCode.Combine(U.ToBytes().Length, V.Length, W.ToBytes().Length, Id); } public byte[] ToByteArray() From 001c9fd1ab940b7a042e05327055a356522239d3 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 04:16:30 +0600 Subject: [PATCH 035/133] Add GetProtocolType() method --- src/Lachain.Consensus/Messages/IInternalMessage.cs | 2 ++ src/Lachain.Consensus/Messages/MessageEnvelope.cs | 4 ++-- src/Lachain.Consensus/Messages/ProtocolRequest.cs | 5 +++++ src/Lachain.Consensus/Messages/ProtocolResult.cs | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/Messages/IInternalMessage.cs b/src/Lachain.Consensus/Messages/IInternalMessage.cs index f5b5d767d..282c0454b 100644 --- a/src/Lachain.Consensus/Messages/IInternalMessage.cs +++ b/src/Lachain.Consensus/Messages/IInternalMessage.cs @@ -6,5 +6,7 @@ public interface IInternalMessage: IByteSerializable { IProtocolIdentifier From { get; } IProtocolIdentifier? To { get; } + + ProtocolType GetProtocolType(); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/Messages/MessageEnvelope.cs b/src/Lachain.Consensus/Messages/MessageEnvelope.cs index a872895e1..057752298 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelope.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelope.cs @@ -66,7 +66,7 @@ public byte[] ToByteArray() } else { list.Add( (IsProtocolRequest ? 1 : 0).ToBytes().ToArray()); - var protocolType = (int) ProtocolTypeMethods.GetProtocolType(InternalMessage.To); + var protocolType = (int) InternalMessage.GetProtocolType(); list.Add(protocolType.ToBytes().ToArray()); list.Add(InternalMessage.ToByteArray()); } @@ -142,7 +142,7 @@ private static IInternalMessage GetProtocolResponseFromByteArray(ProtocolType pr case ProtocolType.CommonSubset: return ProtocolResult>.FromByteArray(bytes); case ProtocolType.HoneyBadger: - return ProtocolResult.FromByteArray(bytes); + return ProtocolResult>.FromByteArray(bytes); case ProtocolType.ReliableBroadcast: return ProtocolResult.FromByteArray(bytes); case ProtocolType.RootProtocol: diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 44d50aaf0..4eb3c2668 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -29,6 +29,11 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) public IProtocolIdentifier From { get; } public IProtocolIdentifier To { get; } + public ProtocolType GetProtocolType() + { + return ProtocolTypeMethods.GetProtocolType(To); + } + public byte[] ToByteArray() { var list = new List diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index fd1f3d97f..351f9e3c6 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -28,6 +28,11 @@ public ProtocolResult(TIdType id, TResultType value) public TResultType Result { get; } public IProtocolIdentifier From => Id; public IProtocolIdentifier? To => null; + public ProtocolType GetProtocolType() + { + return ProtocolTypeMethods.GetProtocolType(Id); + } + public byte[] ToByteArray() { var list = new List From 2850a12c4a31b414735f48df6550f52d5e4ccba2 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 04:22:58 +0600 Subject: [PATCH 036/133] Fix bug in messageenvelopelist equals --- src/Lachain.Consensus/Messages/MessageEnvelopeList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index c39bbbee0..a38079cbc 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -62,7 +62,7 @@ public override bool Equals(object? obj) public bool Equals(MessageEnvelopeList other) { - return Era == other.Era && MessageList.Equals(other.MessageList); + return Era == other.Era && MessageList.SequenceEqual(other.MessageList); } public override int GetHashCode() From 71ada5c3591660eddfc59fc99bf8afaa72888410 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 04:23:41 +0600 Subject: [PATCH 037/133] Fix all serialization tests --- .../SerializationTest.cs | 69 ++++++++++--------- test/Lachain.ConsensusTest/TestUtils.cs | 4 +- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 02a4cbf30..cc75e04ae 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Reflection; using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; @@ -8,7 +10,11 @@ using Lachain.Consensus.Messages; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; -using Lachain.Core.Consensus; +using Lachain.Core.CLI; +using Lachain.Core.Config; +using Lachain.Core.DI; +using Lachain.Core.DI.Modules; +using Lachain.Core.DI.SimpleInjector; using Lachain.Crypto; using Lachain.Crypto.TPKE; using Lachain.Utility.Utils; @@ -18,30 +24,32 @@ namespace Lachain.ConsensusTest { public class SerializationTest { + private IContainer _container; private MessageEnvelopeList _messageList; - private Random random; + private Random random; [SetUp] public void SetUp() { var seed = 123456; random = new Random(seed); _messageList = new MessageEnvelopeList(random.Next()); - } [Test] + [Repeat(100)] public void Test_Serialization() { - for (int i = 0; i < 100; i++) - { - TestSerializationAndAddToListBinaryAgreement(_messageList); - TestSerializationAndAddToListBinaryBroadcast(_messageList); - TestSerializationAndAddToListCommonCoin(_messageList); - TestSerializationAndAddToListCommonSubset(_messageList); - TestSerializationAndAddToListHoneyBadger(_messageList); - TestSerializationAndAddToListReliableBroadcast(_messageList); - TestSerializationAndAddToListRootProtocol(_messageList); - } + TestSerializationAndAddToListBinaryAgreement(_messageList); + TestSerializationAndAddToListBinaryBroadcast(_messageList); + TestSerializationAndAddToListCommonCoin(_messageList); + TestSerializationAndAddToListCommonSubset(_messageList); + TestSerializationAndAddToListHoneyBadger(_messageList); + TestSerializationAndAddToListReliableBroadcast(_messageList); + TestSerializationAndAddToListRootProtocol(_messageList); + + var recovered = MessageEnvelopeList.FromByteArray(_messageList.ToByteArray()); + Assert.AreEqual(_messageList, recovered); + Assert.AreEqual(_messageList.ToByteArray(), recovered.ToByteArray()); } private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList messageList) @@ -60,7 +68,7 @@ private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList me var result = new ProtocolResult (binaryAgreementId, true); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } @@ -78,11 +86,14 @@ private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList me var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); messageList.AddMessage(requestMessage); + + var bs = TestUtils.GenerateBoolSet(random); + Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); - var result = new ProtocolResult (binaryBroadcastId, TestUtils.GenerateBoolSet(random)); + var result = new ProtocolResult (binaryBroadcastId, bs); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } @@ -106,7 +117,7 @@ private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList message var result = new ProtocolResult (coinId, coinResult); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } @@ -115,8 +126,11 @@ private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messa var commonSubsetId = TestUtils.GenerateCommonSubsetId(random); Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); + var share = TestUtils.GenerateEncryptedShare(random, false); + Assert.AreEqual(EncryptedShare.FromByteArray(share.ToByteArray()), share); + var request = new ProtocolRequest - (TestUtils.GenerateHoneyBadgerId(random), commonSubsetId, TestUtils.GenerateEncryptedShare(random, false)); + (TestUtils.GenerateHoneyBadgerId(random), commonSubsetId, share); Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); @@ -126,7 +140,7 @@ private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messa var result = new ProtocolResult> (commonSubsetId, TestUtils.GenerateSetOfEncryptedShare(random)); Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } @@ -146,7 +160,7 @@ private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList messag var result = new ProtocolResult> (honeyBadgerId, TestUtils.GenerateSetOfIRawShare(random)); Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } @@ -167,31 +181,24 @@ private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList (reliableBroadcastId, TestUtils.GenerateEncryptedShare(random, false)!); Assert.AreEqual(result, ProtocolResult .FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messageList) { + /// Only checking Result as IBlockProducer will not be same in Request var rootProtocolId = TestUtils.GenerateRootProtocolId(random); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); - - var request = new ProtocolRequest - (TestUtils.GenerateCommonSubsetId(random), rootProtocolId, null); - Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); - var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); - Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); - var result = new ProtocolResult (rootProtocolId, null); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); - var resultMessage = new MessageEnvelope(request, random.Next(1, 100)); + var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); messageList.AddMessage(resultMessage); } - + } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 2ac7b678d..653c93c4e 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -73,9 +73,9 @@ public static BoolSet GenerateBoolSet(Random random) { var bs = new BoolSet(); if (random.Next(0, 1) == 1) - bs.Add(true); + bs = bs.Add(true); if (random.Next(0, 1) == 1) - bs.Add(false); + bs = bs.Add(false); return bs; } From c001b020bf9a968654bcfe197f11a89bcf994f90 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 04:46:47 +0600 Subject: [PATCH 038/133] Add tests for root protocol and repository --- .../MessageEnvelopeRepositoryManagerTest.cs | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index e12d3a428..33941dddf 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -1,5 +1,8 @@ +using System; using System.IO; using System.Reflection; +using Lachain.Consensus; +using Lachain.Consensus.BinaryAgreement; using Lachain.Core.CLI; using Lachain.Core.Config; using Lachain.Core.DI; @@ -8,6 +11,9 @@ using Lachain.Storage; using NUnit.Framework; using Lachain.Consensus.Messages; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; +using Lachain.Crypto.TPKE; using Lachain.Storage.Repositories; @@ -17,7 +23,8 @@ public class MessageEnvelopeRepositoryManagerTest { private IContainer _container; private IRocksDbContext _dbContext; - + private Random _random; + private IBlockProducer _blockProducer; [SetUp] public void Setup() { @@ -25,18 +32,26 @@ public void Setup() Path.Join(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json"), new RunOptions() )); - + + containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + _container = containerBuilder.Build(); _dbContext = _container.Resolve(); + _blockProducer = _container.Resolve(); + + const int seed = 12334; + _random = new Random(seed); } [TearDown] public void TearDown() { _container.Dispose(); - Lachain.UtilityTest.TestUtils.DeleteTestChainData(); + UtilityTest.TestUtils.DeleteTestChainData(); } @@ -53,6 +68,14 @@ public void Test_MessageEnvelopeRepositoryManager() manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77)); manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23)); + + var request = new ProtocolRequest( + TestUtils.GenerateCommonSubsetId(_random), + TestUtils.GenerateReliableBroadcastId(_random), + TestUtils.GenerateEncryptedShare(_random, true)); + + var requestMessage = new MessageEnvelope(request, 55); + manager.AddMessage(requestMessage); var era = manager.GetEra(); var list = manager.GetMessages(); @@ -60,7 +83,41 @@ public void Test_MessageEnvelopeRepositoryManager() manager = new MessageEnvelopeRepositoryManager(repo); Assert.AreEqual(manager.GetEra(), era); CollectionAssert.AreEqual(manager.GetMessages(), list); + } + + + [Test] + [Repeat(10)] + public void TestRootProtocolSerialization() + { + var rootProtocolId = TestUtils.GenerateRootProtocolId(_random); + Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); + + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(_random), rootProtocolId, _blockProducer); + var recoveredRequest = ProtocolRequest.FromByteArray(request.ToByteArray()); + + Assert.AreEqual(recoveredRequest.From, request.From); + Assert.AreEqual(recoveredRequest.To, request.To); + Assert.IsNull(recoveredRequest.Input); + + var requestMessage = new MessageEnvelope(request, _random.Next(1, 100)); + var recoveredMessage = MessageEnvelope.FromByteArray(requestMessage.ToByteArray()); + + Assert.AreEqual(recoveredMessage.External, requestMessage.External); + Assert.AreEqual(recoveredMessage.ExternalMessage, requestMessage.ExternalMessage); + Assert.AreEqual(recoveredMessage.ValidatorIndex, requestMessage.ValidatorIndex); + Assert.AreEqual(recoveredMessage.InternalMessage.From, requestMessage.InternalMessage.From); + Assert.AreEqual(recoveredMessage.InternalMessage.To, recoveredMessage.InternalMessage.To); + Assert.IsInstanceOf(typeof(ProtocolRequest), recoveredMessage.InternalMessage); + Assert.IsNull(((ProtocolRequest) recoveredMessage.InternalMessage).Input); + + var result = new ProtocolResult + (rootProtocolId, null); + Assert.AreEqual(result, ProtocolResult .FromByteArray(result.ToByteArray())); + var resultMessage = new MessageEnvelope(result, _random.Next(1, 100)); + Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); } } } \ No newline at end of file From b0762753143609876acf4bb2e5edb57585ff1a43 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 05:27:59 +0600 Subject: [PATCH 039/133] Code cleanup --- .../BinaryAgreement/BinaryAgreementId.cs | 9 +++--- src/Lachain.Consensus/CommonCoin/CoinId.cs | 1 - .../HoneyBadger/HoneyBadgerId.cs | 1 - .../MessageEnvelopeRepositoryManager.cs | 20 ++++--------- .../Messages/ProtocolResult.cs | 13 +------- src/Lachain.Consensus/ProtocolType.cs | 30 +++++++------------ .../ReliableBroadcast/ReliableBroadcastId.cs | 1 - src/Lachain.Core/Consensus/EraBroadcaster.cs | 3 +- .../IMessageEnvelopeRepository.cs | 2 +- .../Repositories/MessageEnvelopeRepository.cs | 4 +-- .../Serialization/IByteSerializable.cs | 2 -- 11 files changed, 26 insertions(+), 60 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs index a0c1d5a25..2470f7bde 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryAgreementId.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.Messages; using Lachain.Utility.Serialization; using Nethereum.RLP; @@ -48,9 +47,11 @@ public override string ToString() public byte[] ToByteArray() { - var list = new List(); - list.Add(Era.ToBytes().ToArray()); - list.Add(AssociatedValidatorId.ToBytes().ToArray()); + var list = new List + { + Era.ToBytes().ToArray(), + AssociatedValidatorId.ToBytes().ToArray() + }; return RLP.EncodeList(list.Select(RLP.EncodeElement).ToArray()); } diff --git a/src/Lachain.Consensus/CommonCoin/CoinId.cs b/src/Lachain.Consensus/CommonCoin/CoinId.cs index b03a4d849..41b32c875 100644 --- a/src/Lachain.Consensus/CommonCoin/CoinId.cs +++ b/src/Lachain.Consensus/CommonCoin/CoinId.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.BinaryAgreement; using Lachain.Utility.Serialization; using Nethereum.RLP; diff --git a/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs b/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs index 07d56bf8d..cba507568 100644 --- a/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs +++ b/src/Lachain.Consensus/HoneyBadger/HoneyBadgerId.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.CommonSubset; using Lachain.Utility.Serialization; using Nethereum.RLP; diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 97a208914..2531525c5 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using Lachain.Logger; using Lachain.Storage.Repositories; @@ -9,26 +8,20 @@ namespace Lachain.Consensus.Messages public class MessageEnvelopeRepositoryManager { private IMessageEnvelopeRepository _repository; - private MessageEnvelopeList _messageEnvelopeList; + private MessageEnvelopeList? _messageEnvelopeList; private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); - public bool isPresent { get; private set; } + public bool IsPresent => !(_messageEnvelopeList is null); public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { _repository = repository; var bytes = repository.LoadMessages(); - isPresent = !(bytes is null); - - if (isPresent) - { - _messageEnvelopeList = MessageEnvelopeList.FromByteArray(bytes); - } - + _messageEnvelopeList = !(bytes is null) ? MessageEnvelopeList.FromByteArray(bytes) : null; } public long GetEra() { - if (!isPresent) + if (!IsPresent) { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } @@ -37,19 +30,18 @@ public long GetEra() public void StartEra(long era) { - if (isPresent && _messageEnvelopeList.Era == era) + if (IsPresent && _messageEnvelopeList.Era == era) { throw new ArgumentException($"Start Era called with same era number {era}"); } _messageEnvelopeList = new MessageEnvelopeList(era); SaveToDb(_messageEnvelopeList); - isPresent = true; } public void AddMessage(MessageEnvelope message) { - if (!isPresent) + if (!IsPresent) { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index 351f9e3c6..1d9130849 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -125,7 +125,7 @@ public static ProtocolResult FromByteArray(byte[] bytes) }; } - private static object? GetSetOfIRawShareFromBytes(RLPCollection decoded) + private static ISet GetSetOfIRawShareFromBytes(RLPCollection decoded) { var count = decoded[2].RLPData.AsReadOnlySpan().ToInt32(); ISet set = new HashSet(); @@ -182,17 +182,6 @@ private bool ResultEquals(TResultType result, TResultType otherResult) case ISet encryptedShares: return encryptedShares.SetEquals((ISet) otherResult); case ISet rawShares: - foreach (var s1 in rawShares) - { - foreach (var s2 in (ISet) otherResult) - { - if (s1.Equals(s2)) - { - var hashCode = s1.GetHashCode(); - var code = s2.GetHashCode(); - } - } - } return rawShares.SetEquals((ISet) otherResult); default: return EqualityComparer.Default.Equals(result, otherResult); diff --git a/src/Lachain.Consensus/ProtocolType.cs b/src/Lachain.Consensus/ProtocolType.cs index c7b15adb1..3b5ae384b 100644 --- a/src/Lachain.Consensus/ProtocolType.cs +++ b/src/Lachain.Consensus/ProtocolType.cs @@ -8,7 +8,7 @@ namespace Lachain.Consensus { - public enum ProtocolType: int + public enum ProtocolType { BinaryAgreement = 1, BinaryBroadcast = 2, @@ -23,25 +23,17 @@ public static class ProtocolTypeMethods { public static ProtocolType GetProtocolType(IProtocolIdentifier id) { - switch (id) + return id switch { - case BinaryAgreementId _: - return ProtocolType.BinaryAgreement; - case BinaryBroadcastId _: - return ProtocolType.BinaryBroadcast; - case CoinId _: - return ProtocolType.CommonCoin; - case CommonSubsetId _: - return ProtocolType.CommonSubset; - case HoneyBadgerId _: - return ProtocolType.HoneyBadger; - case ReliableBroadcastId _: - return ProtocolType.ReliableBroadcast; - case RootProtocolId _: - return ProtocolType.RootProtocol; - default: - throw new ArgumentException("Unknown protocol type"); - } + BinaryAgreementId _ => ProtocolType.BinaryAgreement, + BinaryBroadcastId _ => ProtocolType.BinaryBroadcast, + CoinId _ => ProtocolType.CommonCoin, + CommonSubsetId _ => ProtocolType.CommonSubset, + HoneyBadgerId _ => ProtocolType.HoneyBadger, + ReliableBroadcastId _ => ProtocolType.ReliableBroadcast, + RootProtocolId _ => ProtocolType.RootProtocol, + _ => throw new ArgumentException("Unknown protocol type") + }; } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs index f337a899e..0cfb5d866 100644 --- a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs +++ b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcastId.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.CommonSubset; using Lachain.Utility.Serialization; using Nethereum.RLP; diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index aa13105bd..78747c6dd 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -13,7 +13,6 @@ using Lachain.Consensus.RootProtocol; using Lachain.Core.Blockchain.Hardfork; using Lachain.Core.Blockchain.SystemContracts; -using Lachain.Core.Blockchain.Validators; using Lachain.Core.Vault; using Lachain.Crypto; using Lachain.Crypto.TPKE; @@ -115,7 +114,7 @@ public void Broadcast(ConsensusMessage message) public void RestoreState() { - if (!_messageEnvelopeRepositoryManager.isPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) + if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); _messageEnvelopeRepositoryManager.StartEra(_era); diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index cd4a9621d..f860b6f71 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -5,6 +5,6 @@ namespace Lachain.Storage.Repositories public interface IMessageEnvelopeRepository { void SaveMessages(byte[] keygenState); - byte[] LoadMessages(); + byte[]? LoadMessages(); } } \ No newline at end of file diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 5b3b05042..0fe11e34f 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using Lachain.Proto; namespace Lachain.Storage.Repositories { @@ -19,7 +17,7 @@ public void SaveMessages(byte[] messages) _rocksDbContext.Save(key, messages); } - public byte[] LoadMessages() + public byte[]? LoadMessages() { var key = EntryPrefix.MessageEnvelope.BuildPrefix(); return _rocksDbContext.Get(key); diff --git a/src/Lachain.Utility/Serialization/IByteSerializable.cs b/src/Lachain.Utility/Serialization/IByteSerializable.cs index 640e1223f..1b35e9e02 100644 --- a/src/Lachain.Utility/Serialization/IByteSerializable.cs +++ b/src/Lachain.Utility/Serialization/IByteSerializable.cs @@ -1,5 +1,3 @@ -using System; - namespace Lachain.Utility.Serialization { public interface IByteSerializable From 778843ca6e09d6c93d244b85917f1824b7b100a1 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 05:48:29 +0600 Subject: [PATCH 040/133] Make Getmessages synced --- .../Messages/MessageEnvelopeRepositoryManager.cs | 4 ++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 6 ++++-- .../Repositories/MessageEnvelopeRepository.cs | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 2531525c5..44e1572f5 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -7,7 +7,7 @@ namespace Lachain.Consensus.Messages { public class MessageEnvelopeRepositoryManager { - private IMessageEnvelopeRepository _repository; + private readonly IMessageEnvelopeRepository _repository; private MessageEnvelopeList? _messageEnvelopeList; private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); @@ -53,7 +53,7 @@ public ICollection GetMessages() { return _messageEnvelopeList.MessageList; } - + private void SaveToDb(MessageEnvelopeList messageEnvelopeList) { Logger.LogTrace("Saving list to db: " + messageEnvelopeList.ToByteArray()); diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 78747c6dd..1c4ee0759 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; using Lachain.Logger; using Lachain.Consensus; @@ -121,8 +122,9 @@ public void RestoreState() } else { - Logger.LogInformation($"Restoring {_messageEnvelopeRepositoryManager.GetMessages().Count} Messages from era {_era}"); - foreach (var messageEnvelope in _messageEnvelopeRepositoryManager.GetMessages()) + var messages = _messageEnvelopeRepositoryManager.GetMessages().ToList(); + Logger.LogInformation($"Restoring {messages.Count} Messages from era {_era}"); + foreach (var messageEnvelope in messages) { if (messageEnvelope.External) { diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 0fe11e34f..3464c4f46 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace Lachain.Storage.Repositories { @@ -10,13 +11,15 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) { _rocksDbContext = rocksDbContext ?? throw new ArgumentNullException(nameof(rocksDbContext)); } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void SaveMessages(byte[] messages) { var key = EntryPrefix.MessageEnvelope.BuildPrefix(); _rocksDbContext.Save(key, messages); } + [MethodImpl(MethodImplOptions.Synchronized)] public byte[]? LoadMessages() { var key = EntryPrefix.MessageEnvelope.BuildPrefix(); From c669ccec759434e0086f9b862cfd43815d0c39aa Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Sat, 12 Nov 2022 05:48:48 +0600 Subject: [PATCH 041/133] tests cleanup --- .../MessageEnvelopeRepositoryManagerTest.cs | 16 ++++++++++++---- test/Lachain.ConsensusTest/SerializationTest.cs | 9 +-------- test/Lachain.ConsensusTest/TestUtils.cs | 7 +++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 33941dddf..c3b8955e3 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -2,7 +2,6 @@ using System.IO; using System.Reflection; using Lachain.Consensus; -using Lachain.Consensus.BinaryAgreement; using Lachain.Core.CLI; using Lachain.Core.Config; using Lachain.Core.DI; @@ -33,9 +32,10 @@ public void Setup() new RunOptions() )); - containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); + + containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); containerBuilder.RegisterModule(); @@ -52,7 +52,6 @@ public void TearDown() { _container.Dispose(); UtilityTest.TestUtils.DeleteTestChainData(); - } [Test] @@ -60,9 +59,10 @@ public void Test_MessageEnvelopeRepositoryManager() { var repo = new MessageEnvelopeRepository(_dbContext); var manager = new MessageEnvelopeRepositoryManager(repo); - Assert.AreEqual(manager.isPresent, false); + Assert.AreEqual(manager.IsPresent, false); manager.StartEra(23); + Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), 23); Assert.AreEqual(manager.GetMessages().Count, 0); @@ -81,8 +81,16 @@ public void Test_MessageEnvelopeRepositoryManager() var list = manager.GetMessages(); manager = new MessageEnvelopeRepositoryManager(repo); + Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), era); CollectionAssert.AreEqual(manager.GetMessages(), list); + + Assert.Throws(() => manager.StartEra(23)); + + manager.StartEra(24); + Assert.AreEqual(manager.IsPresent, true); + Assert.AreEqual(manager.GetEra(), 24); + Assert.AreEqual(manager.GetMessages().Count, 0); } diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index cc75e04ae..5aa6c678e 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; using Lachain.Consensus.CommonSubset; @@ -10,11 +7,7 @@ using Lachain.Consensus.Messages; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RootProtocol; -using Lachain.Core.CLI; -using Lachain.Core.Config; using Lachain.Core.DI; -using Lachain.Core.DI.Modules; -using Lachain.Core.DI.SimpleInjector; using Lachain.Crypto; using Lachain.Crypto.TPKE; using Lachain.Utility.Utils; @@ -187,7 +180,7 @@ private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList } private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messageList) { - /// Only checking Result as IBlockProducer will not be same in Request + // Only checking Result as IBlockProducer will not be same in Request var rootProtocolId = TestUtils.GenerateRootProtocolId(random); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); diff --git a/test/Lachain.ConsensusTest/TestUtils.cs b/test/Lachain.ConsensusTest/TestUtils.cs index 653c93c4e..15c925aa0 100644 --- a/test/Lachain.ConsensusTest/TestUtils.cs +++ b/test/Lachain.ConsensusTest/TestUtils.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; @@ -27,13 +26,13 @@ public static IPrivateConsensusKeySet EmptyWallet(int n, int f) public static ConsensusMessage GenerateBinaryBroadcastConsensusMessage() { - var _broadcastId = new BinaryBroadcastId(2142, 42342, 13124312); + var broadcastId = new BinaryBroadcastId(2142, 42342, 13124312); var message = new ConsensusMessage { Bval = new BValMessage { - Agreement = _broadcastId.Agreement, - Epoch = _broadcastId.Epoch, + Agreement = broadcastId.Agreement, + Epoch = broadcastId.Epoch, Value = true } }; From 34f3c22986042e56ddebcb895ca8839e535a20b7 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 14 Nov 2022 14:47:48 +0600 Subject: [PATCH 042/133] Write saving and restoring to logs and restore in HandleMessages --- .../Messages/MessageEnvelopeRepositoryManager.cs | 4 ++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 44e1572f5..26489c82a 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -9,7 +9,7 @@ public class MessageEnvelopeRepositoryManager { private readonly IMessageEnvelopeRepository _repository; private MessageEnvelopeList? _messageEnvelopeList; - private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private static readonly ILogger logger = LoggerFactory.GetLoggerForClass(); public bool IsPresent => !(_messageEnvelopeList is null); public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) @@ -47,6 +47,7 @@ public void AddMessage(MessageEnvelope message) } _messageEnvelopeList.AddMessage(message); SaveToDb(_messageEnvelopeList); + logger.LogTrace($"Saved message to db, type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } public ICollection GetMessages() @@ -56,7 +57,6 @@ public ICollection GetMessages() private void SaveToDb(MessageEnvelopeList messageEnvelopeList) { - Logger.LogTrace("Saving list to db: " + messageEnvelopeList.ToByteArray()); _repository.SaveMessages(messageEnvelopeList.ToByteArray()); } } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 1c4ee0759..8582d231d 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -126,6 +126,7 @@ public void RestoreState() Logger.LogInformation($"Restoring {messages.Count} Messages from era {_era}"); foreach (var messageEnvelope in messages) { + Logger.LogTrace($"Restoring message from db, type = {messageEnvelope.TypeString()}, hashcode = {messageEnvelope.GetHashCode()}"); if (messageEnvelope.External) { Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); @@ -281,7 +282,6 @@ public void Dispatch(ConsensusMessage message, int from) } var messageEnvelope = new MessageEnvelope(message, from); - _messageEnvelopeRepositoryManager.AddMessage(messageEnvelope); HandleExternalMessage(protocolId, messageEnvelope); } @@ -307,6 +307,7 @@ private void HandleExternalMessage(IProtocolIdentifier protocolId, MessageEnvelo .Add(message); } } + _messageEnvelopeRepositoryManager.AddMessage(message); if (!(protocol is null)) protocol.ReceiveMessage(message); } else Logger.LogWarning("Internal message should not be here"); From c03a90387440cd93c51d62499d64bbd339eef30b Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 14 Nov 2022 17:22:11 +0600 Subject: [PATCH 043/133] Reset block producer when restoring --- src/Lachain.Consensus/Messages/ProtocolRequest.cs | 2 +- src/Lachain.Core/Consensus/ConsensusManager.cs | 4 ++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index 4eb3c2668..e35445785 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -24,7 +24,7 @@ public ProtocolRequest(IProtocolIdentifier from, TIdType id, TInputType input) Input = input; } - public TInputType Input { get; } + public TInputType Input { get; set; } public IProtocolIdentifier From { get; } diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index eb799c4bb..def7ba0dc 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -185,7 +185,7 @@ private void FinishEra() CurrentEra += 1; _eras[CurrentEra] = new EraBroadcaster( CurrentEra, _consensusMessageDeliverer, _privateWallet, - _validatorAttendanceRepository, _messageEnvelopeRepository + _validatorAttendanceRepository, _messageEnvelopeRepository, _blockProducer ); Logger.LogTrace($"Current Era is advanced. Current Era: {CurrentEra}"); } @@ -201,7 +201,7 @@ private void Run(ulong startingEra) Logger.LogTrace("Create EraBroadcaster"); _eras[CurrentEra] = new EraBroadcaster( CurrentEra, _consensusMessageDeliverer, _privateWallet, - _validatorAttendanceRepository, _messageEnvelopeRepository + _validatorAttendanceRepository, _messageEnvelopeRepository, _blockProducer ); } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 8582d231d..8ad465607 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -42,6 +42,7 @@ public class EraBroadcaster : IConsensusBroadcaster private bool _terminated; private int _myIdx; private IPublicConsensusKeySet? _validators; + private IBlockProducer _blockProducer; public bool Ready => _validators != null; @@ -63,7 +64,7 @@ public class EraBroadcaster : IConsensusBroadcaster public EraBroadcaster( long era, IConsensusMessageDeliverer consensusMessageDeliverer, IPrivateWallet wallet, IValidatorAttendanceRepository validatorAttendanceRepository, - IMessageEnvelopeRepository messageEnvelopeRepository + IMessageEnvelopeRepository messageEnvelopeRepository, IBlockProducer blockProducer ) { _consensusMessageDeliverer = consensusMessageDeliverer; @@ -74,6 +75,7 @@ IMessageEnvelopeRepository messageEnvelopeRepository _myIdx = -1; _validatorAttendanceRepository = validatorAttendanceRepository; _messageEnvelopeRepositoryManager = new MessageEnvelopeRepositoryManager(messageEnvelopeRepository); + _blockProducer = blockProducer; } public void SetValidatorKeySet(IPublicConsensusKeySet keySet) @@ -154,6 +156,7 @@ public void RestoreState() InternalRequest(request); break; case ProtocolRequest request: + request.Input = _blockProducer; InternalRequest(request); break; default: From f865acb3178b8bf0f7884f588e9c3a1ec4a85370 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 14 Nov 2022 23:10:34 +0600 Subject: [PATCH 044/133] Fix equality comp for rootprotocol id --- src/Lachain.Consensus/Messages/ProtocolRequest.cs | 15 ++++++++++++--- test/Lachain.ConsensusTest/SerializationTest.cs | 9 +++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/ProtocolRequest.cs b/src/Lachain.Consensus/Messages/ProtocolRequest.cs index e35445785..dd30ae1a4 100644 --- a/src/Lachain.Consensus/Messages/ProtocolRequest.cs +++ b/src/Lachain.Consensus/Messages/ProtocolRequest.cs @@ -87,7 +87,7 @@ public byte[] ToByteArray() list.Add(reliableBroadcastInput.ToByteArray()); break; case RootProtocolId _: - if (!(Input is IBlockProducer)) + if (!(Input is IBlockProducer) && !(Input is null)) throw new ArgumentException( $"Unexpected Input type ({Input?.GetType()}) for ProtocolId {To.GetType()}"); break; @@ -145,7 +145,12 @@ private static IProtocolIdentifier GetProtocolIdentifier(ProtocolType type, byte protected bool Equals(ProtocolRequest other) { - return EqualityComparer.Default.Equals(Input, other.Input) && From.Equals(other.From) && To.Equals(other.To); + return To switch + { + RootProtocolId _ => From.Equals(other.From) && To.Equals(other.To), + _ => EqualityComparer.Default.Equals(Input, other.Input) && From.Equals(other.From) && + To.Equals(other.To) + }; } public override bool Equals(object? obj) @@ -158,7 +163,11 @@ public override bool Equals(object? obj) public override int GetHashCode() { - return HashCode.Combine(Input, From, To); + return To switch + { + RootProtocolId _ => HashCode.Combine(From, To), + _ => HashCode.Combine(Input, From, To) + }; } } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 5aa6c678e..192a4cd6a 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Lachain.Consensus; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; using Lachain.Consensus.CommonSubset; @@ -184,6 +185,14 @@ private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messa var rootProtocolId = TestUtils.GenerateRootProtocolId(random); Assert.AreEqual(rootProtocolId, RootProtocolId.FromByteArray(rootProtocolId.ToByteArray())); + var request = new ProtocolRequest + (TestUtils.GenerateCommonSubsetId(random), rootProtocolId, null); + Assert.AreEqual(request, ProtocolRequest.FromByteArray(request.ToByteArray())); + + var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); + Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); + messageList.AddMessage(requestMessage); + var result = new ProtocolResult (rootProtocolId, null); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); From 2f580f5bdf2a89ca8f958bf7039ed0b2561225c1 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Tue, 15 Nov 2022 15:45:51 +0600 Subject: [PATCH 045/133] save internal request and response messages --- .../Messages/MessageEnvelopeRepositoryManager.cs | 3 ++- src/Lachain.Core/Consensus/EraBroadcaster.cs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 26489c82a..e158fcacf 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -47,7 +47,8 @@ public void AddMessage(MessageEnvelope message) } _messageEnvelopeList.AddMessage(message); SaveToDb(_messageEnvelopeList); - logger.LogTrace($"Saved message to db, type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_messageEnvelopeList.Era}), " + + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } public ICollection GetMessages() diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 8ad465607..0517f971f 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -350,6 +350,8 @@ public void InternalRequest(ProtocolRequest re var messageEnvelope = new MessageEnvelope(request, GetMyId()); + _messageEnvelopeRepositoryManager.AddMessage(messageEnvelope); + if (_registry.TryGetValue(request.To, out var protocol)) protocol?.ReceiveMessage(messageEnvelope); @@ -395,6 +397,8 @@ public void InternalResponse(ProtocolResult // message is also delivered to self // Logger.LogTrace($"Result from protocol {result.From} delivered to itself"); var messageEnvelope = new MessageEnvelope(result, GetMyId()); + _messageEnvelopeRepositoryManager.AddMessage(messageEnvelope); + if (_registry.TryGetValue(result.From, out var protocol)) protocol?.ReceiveMessage(messageEnvelope); } From 5bb0f74c9e42eba0d51219552efbe12fbcf76082 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Tue, 15 Nov 2022 18:11:19 +0600 Subject: [PATCH 046/133] Detect and reject duplicate message when saving to db --- .../Messages/MessageEnvelopeList.cs | 10 +++++++++- .../MessageEnvelopeRepositoryManager.cs | 19 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index a38079cbc..d0531213b 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -10,17 +10,25 @@ public class MessageEnvelopeList : IByteSerializable { public long Era { get; } public ICollection MessageList { get; } - + public ISet MessageSet { get; } + public MessageEnvelopeList(long era) { this.Era = era; this.MessageList = new List(); + this.MessageSet = new HashSet(); } public void AddMessage(MessageEnvelope messageEnvelope) { + if (MessageSet.Contains(messageEnvelope)) + { + throw new ArgumentException("Message already in list"); + } MessageList.Add(messageEnvelope); + MessageSet.Add(messageEnvelope); + } public byte[] ToByteArray() diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index e158fcacf..8966947c0 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -45,10 +45,21 @@ public void AddMessage(MessageEnvelope message) { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } - _messageEnvelopeList.AddMessage(message); - SaveToDb(_messageEnvelopeList); - logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_messageEnvelopeList.Era}), " + - $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + + try + { + _messageEnvelopeList.AddMessage(message); + SaveToDb(_messageEnvelopeList); + logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_messageEnvelopeList.Era}), " + + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + } + catch (ArgumentException e) + { + logger.LogTrace($"Not saving duplicate {(message.External ? "external" : "internal")} " + + $"message to db (era {_messageEnvelopeList.Era}), " + + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + } + } public ICollection GetMessages() From 71fd2c8e9a677632e109f7e171fb566e4f69b336 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Tue, 15 Nov 2022 21:04:25 +0600 Subject: [PATCH 047/133] Handle duplicate message when upon restart --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 0517f971f..089e7ed71 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -336,10 +336,17 @@ public void InternalRequest(ProtocolRequest re { if (_callback.TryGetValue(request.To, out var existingCallback)) { - throw new InvalidOperationException( - $"Cannot have two requests from different protocols ({request.From}, " + + Logger.LogWarning( + $"Two requests from different protocols ({request.From}, " + $"{existingCallback}) to one protocol {request.To}" ); + + // throw new InvalidOperationException( + // $"Cannot have two requests from different protocols ({request.From}, " + + // $"{existingCallback}) to one protocol {request.To}" + // ); + + return; } _callback[request.To] = request.From; From c988097672115638ca835ed2e3709d4b64931230 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 16 Nov 2022 19:52:48 +0600 Subject: [PATCH 048/133] Add flag for restoring state to command line --- src/Lachain.Console/Application.cs | 2 +- src/Lachain.Core/CLI/CommandLineOptions.cs | 3 +++ src/Lachain.Core/Consensus/ConsensusManager.cs | 9 +++++---- src/Lachain.Core/Consensus/IConsensusManager.cs | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Lachain.Console/Application.cs b/src/Lachain.Console/Application.cs index 35184cbdf..785ea3027 100644 --- a/src/Lachain.Console/Application.cs +++ b/src/Lachain.Console/Application.cs @@ -183,7 +183,7 @@ public void Start(RunOptions options) .Where(key => !key.Equals(wallet.EcdsaKeyPair.PublicKey)) ); Logger.LogInformation("Block synchronization finished, starting consensus..."); - consensusManager.Start(blockManager.GetHeight() + 1); + consensusManager.Start(blockManager.GetHeight() + 1, options.RestoreState); validatorStatusManager.Start(false); System.Console.CancelKeyPress += (sender, e) => diff --git a/src/Lachain.Core/CLI/CommandLineOptions.cs b/src/Lachain.Core/CLI/CommandLineOptions.cs index d20a03b46..1bbc4d8d7 100644 --- a/src/Lachain.Core/CLI/CommandLineOptions.cs +++ b/src/Lachain.Core/CLI/CommandLineOptions.cs @@ -99,6 +99,9 @@ public class RunOptions [Option('s', "fastsync", Required = false, Separator = ' ', HelpText = "Performs fast-sync to a specific block on start")] public IEnumerable SetStateTo { get; set; } = Enumerable.Empty(); + + [Option('r', "restorestate", Required = false, Separator = ' ', HelpText = "Restores node after event of crash")] + public bool RestoreState { get; set; } = false; } [Verb("db", HelpText = "cleanups in db")] diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index def7ba0dc..ce8162de3 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -157,10 +157,10 @@ private bool IsEraNearFuture(long era, long currentEra) return false; } - public void Start(ulong startingEra) + public void Start(ulong startingEra, bool restoreState) { _networkManager.AdvanceEra(startingEra); - new Thread(() => Run(startingEra)).Start(); + new Thread(() => Run(startingEra, restoreState)).Start(); } private void FinishEra() @@ -192,7 +192,7 @@ private void FinishEra() } } - private void Run(ulong startingEra) + private void Run(ulong startingEra, bool restoreState) { Logger.LogTrace($"Starting, startingEra {startingEra}"); CurrentEra = (long) startingEra; @@ -232,7 +232,8 @@ private void Run(ulong startingEra) { broadcaster = _eras[CurrentEra]; broadcaster.SetValidatorKeySet(validators); - broadcaster.RestoreState(); + if (restoreState) + broadcaster.RestoreState(); } bool weAreValidator; diff --git a/src/Lachain.Core/Consensus/IConsensusManager.cs b/src/Lachain.Core/Consensus/IConsensusManager.cs index 302b3ccc7..796479960 100644 --- a/src/Lachain.Core/Consensus/IConsensusManager.cs +++ b/src/Lachain.Core/Consensus/IConsensusManager.cs @@ -6,7 +6,7 @@ namespace Lachain.Core.Consensus public interface IConsensusManager { void Dispatch(ConsensusMessage message, ECDSAPublicKey publicKey); - void Start(ulong startingEra); + void Start(ulong startingEra, bool restoreState); void Terminate(); EraBroadcaster? GetEraBroadcaster(); } From 8c1e73c6e48db2b82e8957288e95e093b4d20cb2 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 15:36:46 +0600 Subject: [PATCH 049/133] Synchronize Add messages method --- src/Lachain.Consensus/Messages/MessageEnvelopeList.cs | 4 +++- src/Lachain.Console/Application.cs | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs index d0531213b..74cbaa0a9 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeList.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using Lachain.Utility.Serialization; using Nethereum.RLP; @@ -19,7 +20,8 @@ public MessageEnvelopeList(long era) this.MessageList = new List(); this.MessageSet = new HashSet(); } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void AddMessage(MessageEnvelope messageEnvelope) { if (MessageSet.Contains(messageEnvelope)) diff --git a/src/Lachain.Console/Application.cs b/src/Lachain.Console/Application.cs index 785ea3027..0ce7cab01 100644 --- a/src/Lachain.Console/Application.cs +++ b/src/Lachain.Console/Application.cs @@ -183,6 +183,8 @@ public void Start(RunOptions options) .Where(key => !key.Equals(wallet.EcdsaKeyPair.PublicKey)) ); Logger.LogInformation("Block synchronization finished, starting consensus..."); + if (options.RestoreState) Logger.LogInformation("RestoreState Option is set. Will attempt to Restore State"); + consensusManager.Start(blockManager.GetHeight() + 1, options.RestoreState); validatorStatusManager.Start(false); From c3b54ab92368e1372fc28e73a8ac5a6bc028421e Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 16:48:38 +0600 Subject: [PATCH 050/133] create new message repo if restore state is false --- .../Messages/MessageEnvelopeRepositoryManager.cs | 5 ----- src/Lachain.Core/Consensus/ConsensusManager.cs | 3 +-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 8966947c0..91894c079 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -30,11 +30,6 @@ public long GetEra() public void StartEra(long era) { - if (IsPresent && _messageEnvelopeList.Era == era) - { - throw new ArgumentException($"Start Era called with same era number {era}"); - } - _messageEnvelopeList = new MessageEnvelopeList(era); SaveToDb(_messageEnvelopeList); } diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index ce8162de3..cabb5d5d8 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -232,8 +232,7 @@ private void Run(ulong startingEra, bool restoreState) { broadcaster = _eras[CurrentEra]; broadcaster.SetValidatorKeySet(validators); - if (restoreState) - broadcaster.RestoreState(); + broadcaster.RestoreState(restoreState); } bool weAreValidator; diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 089e7ed71..df8adbe57 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -115,9 +115,9 @@ public void Broadcast(ConsensusMessage message) } } - public void RestoreState() + public void RestoreState(bool restore) { - if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) + if (!restore || !_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); _messageEnvelopeRepositoryManager.StartEra(_era); From e405ed5b4465e62d200e1efc255deb92d718032d Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 17:01:41 +0600 Subject: [PATCH 051/133] refactor RestoreState --- .../Messages/MessageEnvelopeRepositoryManager.cs | 7 ++++++- src/Lachain.Core/Consensus/EraBroadcaster.cs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 91894c079..1fa9524a8 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -28,8 +28,13 @@ public long GetEra() return _messageEnvelopeList.Era; } - public void StartEra(long era) + public void StartEra(long era, bool canBeSame = false) { + if (!canBeSame && IsPresent && _messageEnvelopeList.Era == era) + { + throw new ArgumentException($"Start Era called with same era number {era}"); + } + _messageEnvelopeList = new MessageEnvelopeList(era); SaveToDb(_messageEnvelopeList); } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index df8adbe57..4c7faeded 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -117,7 +117,12 @@ public void Broadcast(ConsensusMessage message) public void RestoreState(bool restore) { - if (!restore || !_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) + if (!restore) + { + Logger.LogInformation($"Starting new era {_era}."); + _messageEnvelopeRepositoryManager.StartEra(_era, true); + } + if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); _messageEnvelopeRepositoryManager.StartEra(_era); From 685711308033bd165c358b1f80ee7a3485cefb3c Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 18:42:12 +0600 Subject: [PATCH 052/133] Separate start thread from constructor --- src/Lachain.Consensus/AbstractProtocol.cs | 10 +++++++++- src/Lachain.Consensus/IConsensusProtocol.cs | 2 ++ src/Lachain.Core/Consensus/EraBroadcaster.cs | 8 ++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index eb8d7c220..8246e37e8 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Runtime.CompilerServices; using System.Threading; using Lachain.Logger; using Lachain.Consensus.Messages; @@ -36,6 +37,7 @@ public abstract class AbstractProtocol : IConsensusProtocol protected string _lastMessage = ""; private ulong _startTime = 0; private const ulong _alertTime = 60 * 1000; + public bool Started { get; private set; } = false; protected AbstractProtocol( IPublicConsensusKeySet wallet, @@ -44,12 +46,18 @@ IConsensusBroadcaster broadcaster ) { _thread = new Thread(Start) {IsBackground = true}; - _thread.Start(); Broadcaster = broadcaster; Id = id; Wallet = wallet; } + [MethodImpl(MethodImplOptions.Synchronized)] + public void StartThread() + { + _thread.Start(); + Started = true; + } + public int GetMyId() { return Broadcaster.GetMyId(); diff --git a/src/Lachain.Consensus/IConsensusProtocol.cs b/src/Lachain.Consensus/IConsensusProtocol.cs index 5015f3b47..f056d3ac9 100644 --- a/src/Lachain.Consensus/IConsensusProtocol.cs +++ b/src/Lachain.Consensus/IConsensusProtocol.cs @@ -9,6 +9,8 @@ public interface IConsensusProtocol void ReceiveMessage(MessageEnvelope message); void Start(); + + void StartThread(); void WaitFinish(); bool WaitFinish(TimeSpan timeout); void WaitResult(); diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 4c7faeded..51329a952 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -457,10 +457,14 @@ public void Terminate() // Protocol will also be created only once, after achieving result, Protocol terminate and no longer process any // messages. [MethodImpl(MethodImplOptions.Synchronized)] - private IConsensusProtocol? EnsureProtocol(IProtocolIdentifier id) + private IConsensusProtocol? EnsureProtocol(IProtocolIdentifier id, bool start = true) { ValidateId(id); - if (_registry.TryGetValue(id, out var existingProtocol)) return existingProtocol; + if (_registry.TryGetValue(id, out var existingProtocol)) + { + + return existingProtocol; + } if (_terminated) { Logger.LogTrace($"Protocol {id} not created since broadcaster is terminated"); From f46a71de377587c8c71508f3671f379774c4534a Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 19:43:52 +0600 Subject: [PATCH 053/133] Start thread seperately if it hasn't started already --- src/Lachain.Consensus/AbstractProtocol.cs | 11 +++++++++++ src/Lachain.Consensus/IConsensusProtocol.cs | 3 ++- src/Lachain.Core/Consensus/EraBroadcaster.cs | 6 +++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index 8246e37e8..c8d29ac82 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -54,10 +54,21 @@ IConsensusBroadcaster broadcaster [MethodImpl(MethodImplOptions.Synchronized)] public void StartThread() { + if (Started) + { + throw new InvalidOperationException("StartThread() already called previously"); + } + _thread.Start(); Started = true; } + public bool HasThreadStarted() + { + return Started; + } + + public int GetMyId() { return Broadcaster.GetMyId(); diff --git a/src/Lachain.Consensus/IConsensusProtocol.cs b/src/Lachain.Consensus/IConsensusProtocol.cs index f056d3ac9..c20ff684b 100644 --- a/src/Lachain.Consensus/IConsensusProtocol.cs +++ b/src/Lachain.Consensus/IConsensusProtocol.cs @@ -9,8 +9,9 @@ public interface IConsensusProtocol void ReceiveMessage(MessageEnvelope message); void Start(); - + void StartThread(); + bool HasThreadStarted(); void WaitFinish(); bool WaitFinish(TimeSpan timeout); void WaitResult(); diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 51329a952..8a6903c4c 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -462,7 +462,8 @@ public void Terminate() ValidateId(id); if (_registry.TryGetValue(id, out var existingProtocol)) { - + if (!existingProtocol.HasThreadStarted()) + existingProtocol.StartThread(); return existingProtocol; } if (_terminated) @@ -474,6 +475,9 @@ public void Terminate() var protocol = CreateProtocol(id); if (!(protocol is null)) Logger.LogTrace($"Created protocol {id} on demand"); + + if (!(protocol is null) && !protocol.HasThreadStarted()) + protocol.StartThread(); return protocol; } From 67b352266133b48fd783126bb8d9496d99661cd4 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 20:24:41 +0600 Subject: [PATCH 054/133] Add restoration Phase parameter to InternalRequest --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 39 +++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 8a6903c4c..c2dc414e4 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -143,26 +143,26 @@ public void RestoreState(bool restore) switch (messageEnvelope.InternalMessage) { case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: - InternalRequest(request); + InternalRequest(request, true); break; case ProtocolRequest request: request.Input = _blockProducer; - InternalRequest(request); + InternalRequest(request, true); break; default: throw new InvalidOperationException( @@ -293,6 +293,7 @@ public void Dispatch(ConsensusMessage message, int from) HandleExternalMessage(protocolId, messageEnvelope); } + private void HandleExternalMessage(IProtocolIdentifier protocolId, MessageEnvelope message) { // For external message we don't create new protocols. each protocol is requested for some result @@ -326,9 +327,13 @@ private void HandleExternalMessage(IProtocolIdentifier protocolId, MessageEnvelo Logger.LogWarning($"Invalid protocol id {protocolId} from validator {GetPublicKeyById(from)!.ToHex()} ({from})"); } } + public void InternalRequest(ProtocolRequest request) where TId : IProtocolIdentifier + { + InternalRequest(request, false); + } [MethodImpl(MethodImplOptions.Synchronized)] - public void InternalRequest(ProtocolRequest request) + public void InternalRequest(ProtocolRequest request, bool restorationPhase) where TId : IProtocolIdentifier { if (_terminated) @@ -358,7 +363,15 @@ public void InternalRequest(ProtocolRequest re } Logger.LogTrace($"Protocol {request.From} requested result from protocol {request.To}"); - EnsureProtocol(request.To); + if (restorationPhase) + { + EnsureProtocol(request.To, false); + } + else + { + EnsureProtocol(request.To, true); + } + var messageEnvelope = new MessageEnvelope(request, GetMyId()); @@ -457,12 +470,12 @@ public void Terminate() // Protocol will also be created only once, after achieving result, Protocol terminate and no longer process any // messages. [MethodImpl(MethodImplOptions.Synchronized)] - private IConsensusProtocol? EnsureProtocol(IProtocolIdentifier id, bool start = true) + private IConsensusProtocol? EnsureProtocol(IProtocolIdentifier id, bool start) { ValidateId(id); if (_registry.TryGetValue(id, out var existingProtocol)) { - if (!existingProtocol.HasThreadStarted()) + if (start && !existingProtocol.HasThreadStarted()) existingProtocol.StartThread(); return existingProtocol; } @@ -476,7 +489,7 @@ public void Terminate() if (!(protocol is null)) Logger.LogTrace($"Created protocol {id} on demand"); - if (!(protocol is null) && !protocol.HasThreadStarted()) + if (!(protocol is null) && start && !protocol.HasThreadStarted()) protocol.StartThread(); return protocol; } @@ -658,7 +671,7 @@ private bool ValidateBinaryBroadcastId(BinaryBroadcastId binaryBroadcastId) public bool WaitFinish(TimeSpan timeout) { - return EnsureProtocol(new RootProtocolId(_era))?.WaitFinish(timeout) ?? true; + return EnsureProtocol(new RootProtocolId(_era), true)?.WaitFinish(timeout) ?? true; } public IDictionary GetRegistry() From e374b0674edf263ee04b58ef2ac3f0f646f7cfcc Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 17 Nov 2022 21:17:25 +0600 Subject: [PATCH 055/133] change flag so that default behaviour is restoring state --- src/Lachain.Console/Application.cs | 4 ++-- src/Lachain.Core/CLI/CommandLineOptions.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Lachain.Console/Application.cs b/src/Lachain.Console/Application.cs index 0ce7cab01..a4f456e59 100644 --- a/src/Lachain.Console/Application.cs +++ b/src/Lachain.Console/Application.cs @@ -183,9 +183,9 @@ public void Start(RunOptions options) .Where(key => !key.Equals(wallet.EcdsaKeyPair.PublicKey)) ); Logger.LogInformation("Block synchronization finished, starting consensus..."); - if (options.RestoreState) Logger.LogInformation("RestoreState Option is set. Will attempt to Restore State"); + if (options.NoRestoreState) Logger.LogInformation("NoRestoreState Option is set. Will not attempt to Restore State"); - consensusManager.Start(blockManager.GetHeight() + 1, options.RestoreState); + consensusManager.Start(blockManager.GetHeight() + 1, !options.NoRestoreState); validatorStatusManager.Start(false); System.Console.CancelKeyPress += (sender, e) => diff --git a/src/Lachain.Core/CLI/CommandLineOptions.cs b/src/Lachain.Core/CLI/CommandLineOptions.cs index 1bbc4d8d7..3a9ee680a 100644 --- a/src/Lachain.Core/CLI/CommandLineOptions.cs +++ b/src/Lachain.Core/CLI/CommandLineOptions.cs @@ -100,8 +100,8 @@ public class RunOptions [Option('s', "fastsync", Required = false, Separator = ' ', HelpText = "Performs fast-sync to a specific block on start")] public IEnumerable SetStateTo { get; set; } = Enumerable.Empty(); - [Option('r', "restorestate", Required = false, Separator = ' ', HelpText = "Restores node after event of crash")] - public bool RestoreState { get; set; } = false; + [Option('r', "norestorestate", Required = false, Separator = ' ', HelpText = "Restores node after event of crash")] + public bool NoRestoreState { get; set; } = false; } [Verb("db", HelpText = "cleanups in db")] From 79de3c166640d8ad3363aae62ecff29afd403972 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 18 Nov 2022 14:55:10 +0600 Subject: [PATCH 056/133] Fix failing tests --- test/Lachain.ConsensusTest/ProtocolInvoker.cs | 10 ++++++++++ test/Lachain.ConsensusTest/SilentProtocol.cs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/test/Lachain.ConsensusTest/ProtocolInvoker.cs b/test/Lachain.ConsensusTest/ProtocolInvoker.cs index 9bf4dec79..d8fc45c67 100644 --- a/test/Lachain.ConsensusTest/ProtocolInvoker.cs +++ b/test/Lachain.ConsensusTest/ProtocolInvoker.cs @@ -89,6 +89,16 @@ public void Start() { } + public void StartThread() + { + throw new NotImplementedException(); + } + + public bool HasThreadStarted() + { + throw new NotImplementedException(); + } + public void WaitFinish() { } diff --git a/test/Lachain.ConsensusTest/SilentProtocol.cs b/test/Lachain.ConsensusTest/SilentProtocol.cs index 54ddd628c..c73f0633a 100644 --- a/test/Lachain.ConsensusTest/SilentProtocol.cs +++ b/test/Lachain.ConsensusTest/SilentProtocol.cs @@ -20,6 +20,16 @@ public void Start() { } + public void StartThread() + { + throw new NotImplementedException(); + } + + public bool HasThreadStarted() + { + throw new NotImplementedException(); + } + public void WaitFinish() { } From 337bb2bcd0f772b5cd769392962a21bab36d9abc Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 18 Nov 2022 18:55:35 +0600 Subject: [PATCH 057/133] Add tests for root protocol equality --- .../MessageEnvelopeRepositoryManagerTest.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index c3b8955e3..46ae5cb42 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Reflection; using Lachain.Consensus; +using Lachain.Consensus.CommonSubset; using Lachain.Core.CLI; using Lachain.Core.Config; using Lachain.Core.DI; @@ -93,6 +94,32 @@ public void Test_MessageEnvelopeRepositoryManager() Assert.AreEqual(manager.GetMessages().Count, 0); } + [Test] + [Repeat(2)] + public void TestRootProtocolEquality() + { + var commonSubsetId1 = new CommonSubsetId(123); + var commonSubsetId2 = new RootProtocolId(123); + Assert.AreEqual(commonSubsetId1, commonSubsetId2); + + var rootProtocolId1 = new RootProtocolId(123); + var rootProtocolId2 = new RootProtocolId(123); + Assert.AreEqual(rootProtocolId1, rootProtocolId2); + + var request1 = new ProtocolRequest + (commonSubsetId1, rootProtocolId1, _blockProducer); + + var request2 = new ProtocolRequest + (commonSubsetId2, rootProtocolId2, null); + + Assert.AreEqual(request1, request2); + Assert.AreEqual(request1.GetHashCode(), request2.GetHashCode()); + + var e1 = new MessageEnvelope(request1, 909); + var e2 = new MessageEnvelope(request2, 909); + Assert.AreEqual(e1, e2); + Assert.AreEqual(e1.GetHashCode(), e2.GetHashCode()); + } [Test] [Repeat(10)] From ccba29da587a44587ca0bfb5be5eed01960f7c88 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 21 Nov 2022 17:12:12 +0600 Subject: [PATCH 058/133] Update tests to call Start Thread() --- test/Lachain.ConsensusTest/BroadcastSimulator.cs | 1 + .../MessageEnvelopeRepositoryManagerTest.cs | 2 +- test/Lachain.ConsensusTest/ProtocolInvoker.cs | 4 ++-- test/Lachain.ConsensusTest/SilentProtocol.cs | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/Lachain.ConsensusTest/BroadcastSimulator.cs b/test/Lachain.ConsensusTest/BroadcastSimulator.cs index 7d3824803..d4b341ef5 100644 --- a/test/Lachain.ConsensusTest/BroadcastSimulator.cs +++ b/test/Lachain.ConsensusTest/BroadcastSimulator.cs @@ -69,6 +69,7 @@ public void RegisterProtocols(IEnumerable protocols) { if (Registry.ContainsKey(protocol.Id)) throw new InvalidOperationException($"Protocol with id ({protocol.Id}) already registered"); + if (! protocol.HasThreadStarted()) protocol.StartThread(); Registry[protocol.Id] = protocol; } } diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 46ae5cb42..83511761b 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -99,7 +99,7 @@ public void Test_MessageEnvelopeRepositoryManager() public void TestRootProtocolEquality() { var commonSubsetId1 = new CommonSubsetId(123); - var commonSubsetId2 = new RootProtocolId(123); + var commonSubsetId2 = new CommonSubsetId(123); Assert.AreEqual(commonSubsetId1, commonSubsetId2); var rootProtocolId1 = new RootProtocolId(123); diff --git a/test/Lachain.ConsensusTest/ProtocolInvoker.cs b/test/Lachain.ConsensusTest/ProtocolInvoker.cs index d8fc45c67..5fa340eec 100644 --- a/test/Lachain.ConsensusTest/ProtocolInvoker.cs +++ b/test/Lachain.ConsensusTest/ProtocolInvoker.cs @@ -91,12 +91,12 @@ public void Start() public void StartThread() { - throw new NotImplementedException(); + } public bool HasThreadStarted() { - throw new NotImplementedException(); + return true; } public void WaitFinish() diff --git a/test/Lachain.ConsensusTest/SilentProtocol.cs b/test/Lachain.ConsensusTest/SilentProtocol.cs index c73f0633a..083a6f715 100644 --- a/test/Lachain.ConsensusTest/SilentProtocol.cs +++ b/test/Lachain.ConsensusTest/SilentProtocol.cs @@ -22,12 +22,12 @@ public void Start() public void StartThread() { - throw new NotImplementedException(); + } public bool HasThreadStarted() { - throw new NotImplementedException(); + return true; } public void WaitFinish() From 41066eea57fd2b88e1e0e1147b8d640073d21bd7 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 23 Nov 2022 18:44:53 +0600 Subject: [PATCH 059/133] Fix PR reviews --- src/Lachain.Consensus/CommonCoin/CoinResult.cs | 2 +- src/Lachain.Consensus/Messages/ProtocolResult.cs | 2 +- src/Lachain.Core/Consensus/ConsensusManager.cs | 12 +++++++++++- src/Lachain.Core/Consensus/EraBroadcaster.cs | 2 +- .../Repositories/IMessageEnvelopeRepository.cs | 2 +- .../Repositories/MessageEnvelopeRepository.cs | 4 ++-- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Lachain.Consensus/CommonCoin/CoinResult.cs b/src/Lachain.Consensus/CommonCoin/CoinResult.cs index f57454f90..489d64a6e 100644 --- a/src/Lachain.Consensus/CommonCoin/CoinResult.cs +++ b/src/Lachain.Consensus/CommonCoin/CoinResult.cs @@ -40,7 +40,7 @@ public override int GetHashCode() public byte[] ToByteArray() { - return RawBytes; + return RawBytes.ToArray(); } public static CoinResult FromByteArray(byte[] bytes) diff --git a/src/Lachain.Consensus/Messages/ProtocolResult.cs b/src/Lachain.Consensus/Messages/ProtocolResult.cs index 1d9130849..9791ecf87 100644 --- a/src/Lachain.Consensus/Messages/ProtocolResult.cs +++ b/src/Lachain.Consensus/Messages/ProtocolResult.cs @@ -121,7 +121,7 @@ public static ProtocolResult FromByteArray(byte[] bytes) ProtocolType.HoneyBadger => GetSetOfIRawShareFromBytes(decoded), ProtocolType.ReliableBroadcast => EncryptedShare.FromBytes(decoded[2].RLPData), ProtocolType.RootProtocol => null, - _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of From {toType.ToString()}") + _ => throw new ArgumentOutOfRangeException($"Unrecognized Type of To {toType.ToString()}") }; } diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index cabb5d5d8..d0ce9c3c2 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -232,7 +232,17 @@ private void Run(ulong startingEra, bool restoreState) { broadcaster = _eras[CurrentEra]; broadcaster.SetValidatorKeySet(validators); - broadcaster.RestoreState(restoreState); + + if ((long) startingEra == CurrentEra) + { + broadcaster.LoadState(restoreState); + } + else + { + broadcaster.LoadState(false); + } + + } bool weAreValidator; diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index c2dc414e4..8b4713bd2 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -115,7 +115,7 @@ public void Broadcast(ConsensusMessage message) } } - public void RestoreState(bool restore) + public void LoadState(bool restore) { if (!restore) { diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index f860b6f71..a6246986c 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -4,7 +4,7 @@ namespace Lachain.Storage.Repositories { public interface IMessageEnvelopeRepository { - void SaveMessages(byte[] keygenState); + void SaveMessages(byte[] messageEnvelopeListBytes); byte[]? LoadMessages(); } } \ No newline at end of file diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 3464c4f46..76ae07a1c 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -13,10 +13,10 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) } [MethodImpl(MethodImplOptions.Synchronized)] - public void SaveMessages(byte[] messages) + public void SaveMessages(byte[] messageEnvelopeListBytes) { var key = EntryPrefix.MessageEnvelope.BuildPrefix(); - _rocksDbContext.Save(key, messages); + _rocksDbContext.Save(key, messageEnvelopeListBytes); } [MethodImpl(MethodImplOptions.Synchronized)] From 7bbaef6271734a7ff98751648f0d2c3589029762 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 23 Nov 2022 20:00:06 +0600 Subject: [PATCH 060/133] Load from db only when restoring --- .../Messages/MessageEnvelopeRepositoryManager.cs | 10 +++++++--- src/Lachain.Core/Consensus/EraBroadcaster.cs | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 1fa9524a8..219d1f971 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -15,15 +15,19 @@ public class MessageEnvelopeRepositoryManager public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { _repository = repository; - var bytes = repository.LoadMessages(); + } + + public void LoadFromDb() + { + var bytes = _repository.LoadMessages(); _messageEnvelopeList = !(bytes is null) ? MessageEnvelopeList.FromByteArray(bytes) : null; } - + public long GetEra() { if (!IsPresent) { - throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); + throw new InvalidOperationException("Could not find MessageEnvelopeList in repository"); } return _messageEnvelopeList.Era; } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 8b4713bd2..78e92cc12 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -122,13 +122,14 @@ public void LoadState(bool restore) Logger.LogInformation($"Starting new era {_era}."); _messageEnvelopeRepositoryManager.StartEra(_era, true); } - if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) + else if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); _messageEnvelopeRepositoryManager.StartEra(_era); } else { + _messageEnvelopeRepositoryManager.LoadFromDb(); var messages = _messageEnvelopeRepositoryManager.GetMessages().ToList(); Logger.LogInformation($"Restoring {messages.Count} Messages from era {_era}"); foreach (var messageEnvelope in messages) From 8fbd53694ed10f00e1951d8496bd8bfceab031f2 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 23 Nov 2022 20:41:49 +0600 Subject: [PATCH 061/133] Update tests for repo manager reloading --- .../MessageEnvelopeRepositoryManagerTest.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 83511761b..ace77fd5f 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -60,6 +60,8 @@ public void Test_MessageEnvelopeRepositoryManager() { var repo = new MessageEnvelopeRepository(_dbContext); var manager = new MessageEnvelopeRepositoryManager(repo); + + manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, false); manager.StartEra(23); @@ -82,6 +84,7 @@ public void Test_MessageEnvelopeRepositoryManager() var list = manager.GetMessages(); manager = new MessageEnvelopeRepositoryManager(repo); + manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), era); CollectionAssert.AreEqual(manager.GetMessages(), list); @@ -93,6 +96,37 @@ public void Test_MessageEnvelopeRepositoryManager() Assert.AreEqual(manager.GetEra(), 24); Assert.AreEqual(manager.GetMessages().Count, 0); } + + [Test] + public void Test_MessageEnvelopeRepositoryManagerReloading() + { + var repo = new MessageEnvelopeRepository(_dbContext); + var manager = new MessageEnvelopeRepositoryManager(repo); + + Assert.AreEqual(manager.IsPresent, false); + Assert.Throws(() => manager.GetEra()); + Assert.Throws( + () => manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77))); + + manager.StartEra(45); + Assert.AreEqual(manager.IsPresent, true); + Assert.AreEqual(manager.GetEra(), 45); + + manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23)); + var list = manager.GetMessages(); + var era = manager.GetEra(); + + manager = new MessageEnvelopeRepositoryManager(repo); + Assert.AreEqual(manager.IsPresent, false); + Assert.Throws(() => manager.GetEra()); + Assert.Throws( + () => manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77))); + + manager.LoadFromDb(); + Assert.AreEqual(manager.IsPresent, true); + Assert.AreEqual(manager.GetEra(), era); + Assert.AreEqual(manager.GetMessages(), list); + } [Test] [Repeat(2)] From 565ff9aac1f269be1b332132856fdf6381ba1b2a Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Wed, 23 Nov 2022 21:42:18 +0600 Subject: [PATCH 062/133] Fix bug in loading repo --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 78e92cc12..c7a1d3a32 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -121,15 +121,17 @@ public void LoadState(bool restore) { Logger.LogInformation($"Starting new era {_era}."); _messageEnvelopeRepositoryManager.StartEra(_era, true); + return; } - else if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) + + _messageEnvelopeRepositoryManager.LoadFromDb(); + if (!_messageEnvelopeRepositoryManager.IsPresent || _messageEnvelopeRepositoryManager.GetEra() != _era) { - Logger.LogInformation($"No outstanding messages from era {_era} found. Starting new era."); + Logger.LogWarning($"No outstanding messages from era {_era} found. Starting new era."); _messageEnvelopeRepositoryManager.StartEra(_era); } else { - _messageEnvelopeRepositoryManager.LoadFromDb(); var messages = _messageEnvelopeRepositoryManager.GetMessages().ToList(); Logger.LogInformation($"Restoring {messages.Count} Messages from era {_era}"); foreach (var messageEnvelope in messages) From 7711fd732e672b884542cd2c7ee144aec51109e0 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 24 Nov 2022 14:08:06 +0600 Subject: [PATCH 063/133] Explicitly start protocols after restoration --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index c7a1d3a32..6d1a97a98 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -206,10 +206,20 @@ public void LoadState(bool restore) { throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); } + StartProtocols(); } } } + private void StartProtocols() + { + foreach (var entry in _registry) + { + var protocol = entry.Value; + protocol.StartThread(); + } + } + public void SendToValidator(ConsensusMessage message, int index) { message.Validator = new Validator {Era = _era}; From 26ff10c2a88a2ffce82f5a40a4fa60682f3f9a40 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Thu, 24 Nov 2022 14:11:21 +0600 Subject: [PATCH 064/133] Refactor LoadState() function into submethods --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 148 ++++++++++--------- 1 file changed, 77 insertions(+), 71 deletions(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 6d1a97a98..0e49d260b 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -136,79 +136,85 @@ public void LoadState(bool restore) Logger.LogInformation($"Restoring {messages.Count} Messages from era {_era}"); foreach (var messageEnvelope in messages) { - Logger.LogTrace($"Restoring message from db, type = {messageEnvelope.TypeString()}, hashcode = {messageEnvelope.GetHashCode()}"); - if (messageEnvelope.External) - { - Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); - } - else if (messageEnvelope.IsProtocolRequest) - { - switch (messageEnvelope.InternalMessage) - { - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - InternalRequest(request, true); - break; - case ProtocolRequest request: - request.Input = _blockProducer; - InternalRequest(request, true); - break; - default: - throw new InvalidOperationException( - "Unexpected template parameters for ProtocolRequest"); - } - } - else if (messageEnvelope.IsProtocolResponse) - { - switch (messageEnvelope.InternalMessage) - { - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult> result: - InternalResponse(result); - break; - case ProtocolResult> result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - case ProtocolResult result: - InternalResponse(result); - break; - default: - throw new InvalidOperationException( - "Unexpected template parameters for ProtocolResponse"); - } - } - else - { - throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); - } - StartProtocols(); + RestoreMessage(messageEnvelope); + } + StartProtocols(); + } + } + + private void RestoreMessage(MessageEnvelope messageEnvelope) + { + Logger.LogTrace( + $"Restoring message from db, type = {messageEnvelope.TypeString()}, hashcode = {messageEnvelope.GetHashCode()}"); + if (messageEnvelope.External) + { + Dispatch(messageEnvelope.ExternalMessage, messageEnvelope.ValidatorIndex); + } + else if (messageEnvelope.IsProtocolRequest) + { + switch (messageEnvelope.InternalMessage) + { + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + InternalRequest(request, true); + break; + case ProtocolRequest request: + request.Input = _blockProducer; + InternalRequest(request, true); + break; + default: + throw new InvalidOperationException( + "Unexpected template parameters for ProtocolRequest"); } } + else if (messageEnvelope.IsProtocolResponse) + { + switch (messageEnvelope.InternalMessage) + { + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult> result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + case ProtocolResult result: + InternalResponse(result); + break; + default: + throw new InvalidOperationException( + "Unexpected template parameters for ProtocolResponse"); + } + } + else + { + throw new InvalidOperationException($"Unknown message type {messageEnvelope.TypeString()}"); + } } private void StartProtocols() From ab5235039b99287063f496c7ef776748cb34a20d Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 24 Nov 2022 16:52:03 +0600 Subject: [PATCH 065/133] fixed bug in channel creation and added comments --- src/Lachain.Networking/NetworkManagerBase.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Lachain.Networking/NetworkManagerBase.cs b/src/Lachain.Networking/NetworkManagerBase.cs index 3e5f79c67..c54e17764 100644 --- a/src/Lachain.Networking/NetworkManagerBase.cs +++ b/src/Lachain.Networking/NetworkManagerBase.cs @@ -74,6 +74,8 @@ public void Start() _hubConnector.Start(); } + // returns existing worker or create a new one if worker does not exists + // not synchronized for the sake of performance private ClientWorker? GetClientWorker(ECDSAPublicKey publicKey) { if (_messageFactory.GetPublicKey().Equals(publicKey)) return null; @@ -83,9 +85,13 @@ public void Start() return CreateMsgChannel(publicKey); } + // check if worker exists before creating and adding one + // synchronized to avoid exception of adding existing key to dictionary [MethodImpl(MethodImplOptions.Synchronized)] private ClientWorker? CreateMsgChannel(ECDSAPublicKey publicKey) { + if (_clientWorkers.TryGetValue(publicKey, out var existingWorker)) + return existingWorker; Logger.LogTrace($"Connecting to peer {publicKey.ToHex()}"); var worker = new ClientWorker(publicKey, _messageFactory, _hubConnector); _clientWorkers.Add(publicKey, worker); From 13476d50460ea3c4b5dc8b979fc690ca507b80a4 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 15:03:11 +0600 Subject: [PATCH 066/133] Make IMessageEnvelopeRepo incremental --- .../IMessageEnvelopeRepository.cs | 8 +++- .../Repositories/MessageEnvelopeRepository.cs | 40 ++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index a6246986c..770af7e50 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -4,7 +4,11 @@ namespace Lachain.Storage.Repositories { public interface IMessageEnvelopeRepository { - void SaveMessages(byte[] messageEnvelopeListBytes); - byte[]? LoadMessages(); + void SaveMessages(List messageEnvelopeListBytes); + void AddMessage(byte[] messageEnvelopeBytes); + List LoadMessages(); + + ulong GetEra(); + void SetEra(ulong era); } } \ No newline at end of file diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 76ae07a1c..b5b3dc6dc 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -1,6 +1,15 @@ using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; +using Lachain.Utility.Serialization; +/** + * Message Envelopes are kept in this repository + * Format: + * prefix + "0": era + * prefix + "1": count + * prefix + "2+i": ith message + */ namespace Lachain.Storage.Repositories { public class MessageEnvelopeRepository : IMessageEnvelopeRepository @@ -12,18 +21,31 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) _rocksDbContext = rocksDbContext ?? throw new ArgumentNullException(nameof(rocksDbContext)); } - [MethodImpl(MethodImplOptions.Synchronized)] - public void SaveMessages(byte[] messageEnvelopeListBytes) + public void SaveMessages(List messageEnvelopeListBytes) { - var key = EntryPrefix.MessageEnvelope.BuildPrefix(); - _rocksDbContext.Save(key, messageEnvelopeListBytes); + throw new NotImplementedException(); } - [MethodImpl(MethodImplOptions.Synchronized)] - public byte[]? LoadMessages() - { - var key = EntryPrefix.MessageEnvelope.BuildPrefix(); - return _rocksDbContext.Get(key); + public void AddMessage(byte[] messageEnvelopeBytes) + { + throw new NotImplementedException(); + } + + List IMessageEnvelopeRepository.LoadMessages() + { + throw new NotImplementedException(); + } + + public ulong GetEra() + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(0.ToBytes()); + return _rocksDbContext.Get(key).AsReadOnlySpan().ToUInt64(); + } + + public void SetEra(ulong era) + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(0.ToBytes()); + _rocksDbContext.Save(key, era.ToBytes()); } } } \ No newline at end of file From cb28fe591a00dab605c27df68bfd7c8fb065b9ce Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 15:24:15 +0600 Subject: [PATCH 067/133] Save messages one by one in db --- .../Repositories/MessageEnvelopeRepository.cs | 25 ++++++++++++++++--- .../MessageEnvelopeRepositoryManagerTest.cs | 19 +++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index b5b3dc6dc..0e6616efe 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -23,14 +23,20 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) public void SaveMessages(List messageEnvelopeListBytes) { - throw new NotImplementedException(); + foreach (var envelope in messageEnvelopeListBytes) + { + AddMessage(envelope); + } } public void AddMessage(byte[] messageEnvelopeBytes) { - throw new NotImplementedException(); + var count = GetCount(); + var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+count).ToBytes()); + _rocksDbContext.Save(key, messageEnvelopeBytes); + SetCount(count+1); } - + List IMessageEnvelopeRepository.LoadMessages() { throw new NotImplementedException(); @@ -47,5 +53,18 @@ public void SetEra(ulong era) var key = EntryPrefix.MessageEnvelope.BuildPrefix(0.ToBytes()); _rocksDbContext.Save(key, era.ToBytes()); } + + + public int GetCount() + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); + return _rocksDbContext.Get(key).AsReadOnlySpan().ToInt32(); + } + + public void SetCount(int count) + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); + _rocksDbContext.Save(key, count.ToBytes()); + } } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index ace77fd5f..7b496d11c 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Reflection; using Lachain.Consensus; @@ -68,10 +69,17 @@ public void Test_MessageEnvelopeRepositoryManager() Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), 23); Assert.AreEqual(manager.GetMessages().Count, 0); - - manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77)); - manager.AddMessage(new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23)); - + + List messageEnvelopes = new List(); + + var message = new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77); + manager.AddMessage(message); + messageEnvelopes.Add(message); + + message = new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23); + manager.AddMessage(message); + messageEnvelopes.Add(message); + var request = new ProtocolRequest( TestUtils.GenerateCommonSubsetId(_random), TestUtils.GenerateReliableBroadcastId(_random), @@ -79,15 +87,18 @@ public void Test_MessageEnvelopeRepositoryManager() var requestMessage = new MessageEnvelope(request, 55); manager.AddMessage(requestMessage); + messageEnvelopes.Add(message); var era = manager.GetEra(); var list = manager.GetMessages(); + CollectionAssert.AreEqual(list, messageEnvelopes); manager = new MessageEnvelopeRepositoryManager(repo); manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), era); CollectionAssert.AreEqual(manager.GetMessages(), list); + CollectionAssert.AreEqual(manager.GetMessages(), messageEnvelopes); Assert.Throws(() => manager.StartEra(23)); From 5d9ab0901a4d425879e397c1a1e86251f9ab59e9 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 15:59:56 +0600 Subject: [PATCH 068/133] Implement load messages --- .../Repositories/MessageEnvelopeRepository.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 0e6616efe..66103393b 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data; using System.Runtime.CompilerServices; using Lachain.Utility.Serialization; @@ -37,9 +38,22 @@ public void AddMessage(byte[] messageEnvelopeBytes) SetCount(count+1); } - List IMessageEnvelopeRepository.LoadMessages() + public List LoadMessages() { - throw new NotImplementedException(); + var count = GetCount(); + var messages = new List(count); + + for (int i = 0; i < count; i++) + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+i).ToBytes()); + var message = _rocksDbContext.Get(key); + if (message is null) + { + throw new DataException("Cannot find $i$th message in repository"); + } + messages.Add(message); + } + return messages; } public ulong GetEra() From 1c7a90c1f938319bb898168af1bf9209ae76c703 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 16:57:50 +0600 Subject: [PATCH 069/133] Make methods synchronized and atomic --- .../Repositories/MessageEnvelopeRepository.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 66103393b..5cd4ea588 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -1,16 +1,18 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Runtime.CompilerServices; using Lachain.Utility.Serialization; -/** +/* * Message Envelopes are kept in this repository * Format: * prefix + "0": era * prefix + "1": count * prefix + "2+i": ith message */ + namespace Lachain.Storage.Repositories { public class MessageEnvelopeRepository : IMessageEnvelopeRepository @@ -29,15 +31,22 @@ public void SaveMessages(List messageEnvelopeListBytes) AddMessage(envelope); } } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void AddMessage(byte[] messageEnvelopeBytes) { + var rocksDbAtomicWrite = new RocksDbAtomicWrite(_rocksDbContext); + var count = GetCount(); var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+count).ToBytes()); - _rocksDbContext.Save(key, messageEnvelopeBytes); - SetCount(count+1); + rocksDbAtomicWrite.Put(key, messageEnvelopeBytes); + + var countKey = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); + rocksDbAtomicWrite.Put(countKey, (count+1).ToBytes().ToArray()); + rocksDbAtomicWrite.Commit(); } + [MethodImpl(MethodImplOptions.Synchronized)] public List LoadMessages() { var count = GetCount(); @@ -74,11 +83,5 @@ public int GetCount() var key = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); return _rocksDbContext.Get(key).AsReadOnlySpan().ToInt32(); } - - public void SetCount(int count) - { - var key = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); - _rocksDbContext.Save(key, count.ToBytes()); - } } } \ No newline at end of file From c02830554bf5f6e6dc6a5408feb7dfc13d8970f1 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 18:00:21 +0600 Subject: [PATCH 070/133] Implement clear messages --- .../IMessageEnvelopeRepository.cs | 1 + .../Repositories/MessageEnvelopeRepository.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index 770af7e50..5ce216c61 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -5,6 +5,7 @@ namespace Lachain.Storage.Repositories public interface IMessageEnvelopeRepository { void SaveMessages(List messageEnvelopeListBytes); + void ClearMessages(); void AddMessage(byte[] messageEnvelopeBytes); List LoadMessages(); diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 5cd4ea588..7aec97907 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -26,12 +26,31 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) public void SaveMessages(List messageEnvelopeListBytes) { + foreach (var envelope in messageEnvelopeListBytes) { AddMessage(envelope); } } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void ClearMessages() + { + var count = GetCount(); + var rocksDbAtomicWrite = new RocksDbAtomicWrite(_rocksDbContext); + + for (int i = 0; i < count; i++) + { + var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+count).ToBytes()); + rocksDbAtomicWrite.Delete(key); + } + + var countKey = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); + rocksDbAtomicWrite.Put(countKey, 0.ToBytes().ToArray()); + rocksDbAtomicWrite.Commit(); + } + [MethodImpl(MethodImplOptions.Synchronized)] public void AddMessage(byte[] messageEnvelopeBytes) { From 021e892bac4e88c88dd14df9f72ea10d83812148 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 19:25:37 +0600 Subject: [PATCH 071/133] Update messageEnveleopeRepoManager to be incremental --- .../MessageEnvelopeRepositoryManager.cs | 70 ++++++++++++------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 219d1f971..cd268e931 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Lachain.Logger; using Lachain.Storage.Repositories; @@ -8,19 +9,37 @@ namespace Lachain.Consensus.Messages public class MessageEnvelopeRepositoryManager { private readonly IMessageEnvelopeRepository _repository; - private MessageEnvelopeList? _messageEnvelopeList; - private static readonly ILogger logger = LoggerFactory.GetLoggerForClass(); + private List? MessageEnvelopeList { get; set; } + private ISet? MessageEnvelopeSet; + private long Era { get; set; } + + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); - public bool IsPresent => !(_messageEnvelopeList is null); + public bool IsPresent => !(MessageEnvelopeList is null); public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { _repository = repository; } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void LoadFromDb() { - var bytes = _repository.LoadMessages(); - _messageEnvelopeList = !(bytes is null) ? MessageEnvelopeList.FromByteArray(bytes) : null; + Era = (long) _repository.GetEra(); + MessageEnvelopeList = new List(); + MessageEnvelopeSet = new HashSet(); + + foreach (var bytes in _repository.LoadMessages()) + { + var envelope = MessageEnvelope.FromByteArray(bytes); + + if (MessageEnvelopeSet.Contains(envelope)) + { + throw new InvalidOperationException("Duplicate message in repository" + envelope); + } + + MessageEnvelopeSet.Add(envelope); + MessageEnvelopeList.Add(envelope); + } } public long GetEra() @@ -29,38 +48,40 @@ public long GetEra() { throw new InvalidOperationException("Could not find MessageEnvelopeList in repository"); } - return _messageEnvelopeList.Era; + return Era; } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void StartEra(long era, bool canBeSame = false) { - if (!canBeSame && IsPresent && _messageEnvelopeList.Era == era) + if (!canBeSame && IsPresent && Era == era) { throw new ArgumentException($"Start Era called with same era number {era}"); } - - _messageEnvelopeList = new MessageEnvelopeList(era); - SaveToDb(_messageEnvelopeList); + + _repository.ClearMessages(); + _repository.SetEra((ulong) era); } - + + [MethodImpl(MethodImplOptions.Synchronized)] public void AddMessage(MessageEnvelope message) { if (!IsPresent) { throw new InvalidOperationException("Could not find MessageEnvelopeList in db"); } - - try + if (!MessageEnvelopeSet.Contains(message)) { - _messageEnvelopeList.AddMessage(message); - SaveToDb(_messageEnvelopeList); - logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_messageEnvelopeList.Era}), " + + MessageEnvelopeSet.Add(message); + MessageEnvelopeList.Add(message); + _repository.AddMessage(message.ToByteArray()); + Logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {Era}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } - catch (ArgumentException e) + else { - logger.LogTrace($"Not saving duplicate {(message.External ? "external" : "internal")} " + - $"message to db (era {_messageEnvelopeList.Era}), " + + Logger.LogTrace($"Not saving duplicate {(message.External ? "external" : "internal")} " + + $"message to db (era {Era}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } @@ -68,12 +89,7 @@ public void AddMessage(MessageEnvelope message) public ICollection GetMessages() { - return _messageEnvelopeList.MessageList; - } - - private void SaveToDb(MessageEnvelopeList messageEnvelopeList) - { - _repository.SaveMessages(messageEnvelopeList.ToByteArray()); + return MessageEnvelopeList; } } } \ No newline at end of file From e22d846977ac908dbe898983e81e4b1fd98fd96c Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 20:20:31 +0600 Subject: [PATCH 072/133] Fix bugs --- .../MessageEnvelopeRepositoryManager.cs | 21 +++++++++----- .../IMessageEnvelopeRepository.cs | 2 +- .../Repositories/MessageEnvelopeRepository.cs | 28 +++++++++++-------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index cd268e931..475858437 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -11,7 +11,6 @@ public class MessageEnvelopeRepositoryManager private readonly IMessageEnvelopeRepository _repository; private List? MessageEnvelopeList { get; set; } private ISet? MessageEnvelopeSet; - private long Era { get; set; } private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); @@ -24,10 +23,14 @@ public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) [MethodImpl(MethodImplOptions.Synchronized)] public void LoadFromDb() { - Era = (long) _repository.GetEra(); + if (_repository.GetEra() is null) + { + return; + } + MessageEnvelopeList = new List(); MessageEnvelopeSet = new HashSet(); - + foreach (var bytes in _repository.LoadMessages()) { var envelope = MessageEnvelope.FromByteArray(bytes); @@ -48,19 +51,23 @@ public long GetEra() { throw new InvalidOperationException("Could not find MessageEnvelopeList in repository"); } - return Era; + + return (long) _repository.GetEra(); } [MethodImpl(MethodImplOptions.Synchronized)] public void StartEra(long era, bool canBeSame = false) { - if (!canBeSame && IsPresent && Era == era) + if (!canBeSame && IsPresent && (long) _repository.GetEra() == era) + { throw new ArgumentException($"Start Era called with same era number {era}"); } _repository.ClearMessages(); _repository.SetEra((ulong) era); + MessageEnvelopeList = new List(); + MessageEnvelopeSet = new HashSet(); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -75,13 +82,13 @@ public void AddMessage(MessageEnvelope message) MessageEnvelopeSet.Add(message); MessageEnvelopeList.Add(message); _repository.AddMessage(message.ToByteArray()); - Logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {Era}), " + + Logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_repository.GetEra()}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } else { Logger.LogTrace($"Not saving duplicate {(message.External ? "external" : "internal")} " + - $"message to db (era {Era}), " + + $"message to db (era {_repository.GetEra()}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); } diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index 5ce216c61..b52c20dfa 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -9,7 +9,7 @@ public interface IMessageEnvelopeRepository void AddMessage(byte[] messageEnvelopeBytes); List LoadMessages(); - ulong GetEra(); + ulong? GetEra(); void SetEra(ulong era); } } \ No newline at end of file diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 7aec97907..cb6279d77 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -37,12 +37,16 @@ public void SaveMessages(List messageEnvelopeListBytes) [MethodImpl(MethodImplOptions.Synchronized)] public void ClearMessages() { + var era = GetEra(); + if (era is null) { + return; + } var count = GetCount(); var rocksDbAtomicWrite = new RocksDbAtomicWrite(_rocksDbContext); for (int i = 0; i < count; i++) { - var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+count).ToBytes()); + var key = EntryPrefix.MessageEnvelope.BuildPrefix(((int)(2+count)).ToBytes()); rocksDbAtomicWrite.Delete(key); } @@ -55,21 +59,20 @@ public void ClearMessages() public void AddMessage(byte[] messageEnvelopeBytes) { var rocksDbAtomicWrite = new RocksDbAtomicWrite(_rocksDbContext); - var count = GetCount(); - var key = EntryPrefix.MessageEnvelope.BuildPrefix((2+count).ToBytes()); + var key = EntryPrefix.MessageEnvelope.BuildPrefix(((int)(2+count)).ToBytes()); rocksDbAtomicWrite.Put(key, messageEnvelopeBytes); var countKey = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); - rocksDbAtomicWrite.Put(countKey, (count+1).ToBytes().ToArray()); + rocksDbAtomicWrite.Put(countKey, ((int)(count+1)).ToBytes().ToArray()); rocksDbAtomicWrite.Commit(); } [MethodImpl(MethodImplOptions.Synchronized)] - public List LoadMessages() + public List? LoadMessages() { var count = GetCount(); - var messages = new List(count); + var messages = new List((int)count); for (int i = 0; i < count; i++) { @@ -84,23 +87,26 @@ public List LoadMessages() return messages; } - public ulong GetEra() + public ulong? GetEra() { var key = EntryPrefix.MessageEnvelope.BuildPrefix(0.ToBytes()); - return _rocksDbContext.Get(key).AsReadOnlySpan().ToUInt64(); + return _rocksDbContext.Get(key)?.AsReadOnlySpan().ToUInt64(); } public void SetEra(ulong era) { var key = EntryPrefix.MessageEnvelope.BuildPrefix(0.ToBytes()); _rocksDbContext.Save(key, era.ToBytes()); + + // throw new Exception(string.Concat(era.ToBytes().Select(b => Convert.ToString(b, 2).PadLeft(8, '0')))); } - public int GetCount() + private int GetCount() { var key = EntryPrefix.MessageEnvelope.BuildPrefix(1.ToBytes()); - return _rocksDbContext.Get(key).AsReadOnlySpan().ToInt32(); + var val = _rocksDbContext.Get(key); + return val is null ? 0 : val.AsReadOnlySpan().ToInt32(); } } -} \ No newline at end of file +} From e97eb4cbbfc1fa52749cd1a86d53bea5bd3c7d90 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 21:56:58 +0600 Subject: [PATCH 073/133] Update tests for messageEnvelopeRepoManager --- .../MessageEnvelopeRepositoryManagerTest.cs | 2 +- .../SerializationTest.cs | 64 +++++++++---------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 7b496d11c..4cadd4fa8 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -87,7 +87,7 @@ public void Test_MessageEnvelopeRepositoryManager() var requestMessage = new MessageEnvelope(request, 55); manager.AddMessage(requestMessage); - messageEnvelopes.Add(message); + messageEnvelopes.Add(requestMessage); var era = manager.GetEra(); var list = manager.GetMessages(); diff --git a/test/Lachain.ConsensusTest/SerializationTest.cs b/test/Lachain.ConsensusTest/SerializationTest.cs index 192a4cd6a..0091d97db 100644 --- a/test/Lachain.ConsensusTest/SerializationTest.cs +++ b/test/Lachain.ConsensusTest/SerializationTest.cs @@ -19,34 +19,30 @@ namespace Lachain.ConsensusTest public class SerializationTest { private IContainer _container; - private MessageEnvelopeList _messageList; + private List _messageList; private Random random; [SetUp] public void SetUp() { var seed = 123456; random = new Random(seed); - _messageList = new MessageEnvelopeList(random.Next()); + _messageList = new List(); } [Test] [Repeat(100)] public void Test_Serialization() { - TestSerializationAndAddToListBinaryAgreement(_messageList); - TestSerializationAndAddToListBinaryBroadcast(_messageList); - TestSerializationAndAddToListCommonCoin(_messageList); - TestSerializationAndAddToListCommonSubset(_messageList); - TestSerializationAndAddToListHoneyBadger(_messageList); - TestSerializationAndAddToListReliableBroadcast(_messageList); - TestSerializationAndAddToListRootProtocol(_messageList); - - var recovered = MessageEnvelopeList.FromByteArray(_messageList.ToByteArray()); - Assert.AreEqual(_messageList, recovered); - Assert.AreEqual(_messageList.ToByteArray(), recovered.ToByteArray()); + TestSerializationAndAddToListBinaryAgreement(); + TestSerializationAndAddToListBinaryBroadcast(); + TestSerializationAndAddToListCommonCoin(); + TestSerializationAndAddToListCommonSubset(); + TestSerializationAndAddToListHoneyBadger(); + TestSerializationAndAddToListReliableBroadcast(); + TestSerializationAndAddToListRootProtocol(); } - private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListBinaryAgreement() { var binaryAgreementId = TestUtils.GenerateBinaryAgreementId(random); Assert.AreEqual(binaryAgreementId, BinaryAgreementId.FromByteArray(binaryAgreementId.ToByteArray())); @@ -57,18 +53,18 @@ private void TestSerializationAndAddToListBinaryAgreement(MessageEnvelopeList me var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var result = new ProtocolResult (binaryAgreementId, true); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListBinaryBroadcast() { var binaryBroadcastId = TestUtils.GenerateBinaryBroadcastId(random); Assert.AreEqual(binaryBroadcastId, BinaryBroadcastId.FromByteArray(binaryBroadcastId.ToByteArray())); @@ -79,7 +75,7 @@ private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList me var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var bs = TestUtils.GenerateBoolSet(random); Assert.AreEqual(bs, BoolSet.FromByteArray(bs.ToByteArray())); @@ -89,10 +85,10 @@ private void TestSerializationAndAddToListBinaryBroadcast(MessageEnvelopeList me var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListCommonCoin() { var coinId = TestUtils.GenerateCoinId(random); Assert.AreEqual(coinId, CoinId.FromByteArray(coinId.ToByteArray())); @@ -103,7 +99,7 @@ private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList message var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var coinResult = TestUtils.GenerateCoinResult(random); Assert.AreEqual(coinResult, CoinResult.FromByteArray(coinResult.ToByteArray())); @@ -113,9 +109,9 @@ private void TestSerializationAndAddToListCommonCoin(MessageEnvelopeList message var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListCommonSubset() { var commonSubsetId = TestUtils.GenerateCommonSubsetId(random); Assert.AreEqual(commonSubsetId, CommonSubsetId.FromByteArray(commonSubsetId.ToByteArray())); @@ -129,16 +125,16 @@ private void TestSerializationAndAddToListCommonSubset(MessageEnvelopeList messa var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var result = new ProtocolResult> (commonSubsetId, TestUtils.GenerateSetOfEncryptedShare(random)); Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListHoneyBadger() { var honeyBadgerId = TestUtils.GenerateHoneyBadgerId(random); Assert.AreEqual(honeyBadgerId, HoneyBadgerId.FromByteArray(honeyBadgerId.ToByteArray())); @@ -149,16 +145,16 @@ private void TestSerializationAndAddToListHoneyBadger(MessageEnvelopeList messag var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var result = new ProtocolResult> (honeyBadgerId, TestUtils.GenerateSetOfIRawShare(random)); Assert.AreEqual(result, ProtocolResult>.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListReliableBroadcast() { var reliableBroadcastId = TestUtils.GenerateReliableBroadcastId(random); Assert.AreEqual(reliableBroadcastId, ReliableBroadcastId.FromByteArray(reliableBroadcastId.ToByteArray())); @@ -169,7 +165,7 @@ private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var result = new ProtocolResult (reliableBroadcastId, TestUtils.GenerateEncryptedShare(random, false)!); @@ -177,9 +173,9 @@ private void TestSerializationAndAddToListReliableBroadcast(MessageEnvelopeList var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } - private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messageList) + private void TestSerializationAndAddToListRootProtocol() { // Only checking Result as IBlockProducer will not be same in Request var rootProtocolId = TestUtils.GenerateRootProtocolId(random); @@ -191,14 +187,14 @@ private void TestSerializationAndAddToListRootProtocol(MessageEnvelopeList messa var requestMessage = new MessageEnvelope(request, random.Next(1, 100)); Assert.AreEqual(requestMessage, MessageEnvelope.FromByteArray(requestMessage.ToByteArray())); - messageList.AddMessage(requestMessage); + var result = new ProtocolResult (rootProtocolId, null); Assert.AreEqual(result, ProtocolResult.FromByteArray(result.ToByteArray())); var resultMessage = new MessageEnvelope(result, random.Next(1, 100)); Assert.AreEqual(resultMessage, MessageEnvelope.FromByteArray(resultMessage.ToByteArray())); - messageList.AddMessage(resultMessage); + } From b7eb35ce04ad74b19b248cc5b1582dab65e5f249 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Fri, 25 Nov 2022 22:03:36 +0600 Subject: [PATCH 074/133] Add boolean return value for add message --- .../Messages/MessageEnvelopeRepositoryManager.cs | 4 +++- .../MessageEnvelopeRepositoryManagerTest.cs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 475858437..52066b92e 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -71,7 +71,7 @@ public void StartEra(long era, bool canBeSame = false) } [MethodImpl(MethodImplOptions.Synchronized)] - public void AddMessage(MessageEnvelope message) + public bool AddMessage(MessageEnvelope message) { if (!IsPresent) { @@ -84,12 +84,14 @@ public void AddMessage(MessageEnvelope message) _repository.AddMessage(message.ToByteArray()); Logger.LogTrace($"Saved {(message.External ? "external" : "internal")} message to db (era {_repository.GetEra()}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + return true; } else { Logger.LogTrace($"Not saving duplicate {(message.External ? "external" : "internal")} " + $"message to db (era {_repository.GetEra()}), " + $"type = ({message.TypeString()}), hashcode = {message.GetHashCode()}"); + return false; } } diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 4cadd4fa8..7ca9aca10 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -73,7 +73,7 @@ public void Test_MessageEnvelopeRepositoryManager() List messageEnvelopes = new List(); var message = new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 77); - manager.AddMessage(message); + Assert.IsTrue(manager.AddMessage(message)); messageEnvelopes.Add(message); message = new MessageEnvelope(TestUtils.GenerateBinaryBroadcastConsensusMessage(), 23); @@ -86,9 +86,11 @@ public void Test_MessageEnvelopeRepositoryManager() TestUtils.GenerateEncryptedShare(_random, true)); var requestMessage = new MessageEnvelope(request, 55); - manager.AddMessage(requestMessage); + Assert.IsTrue(manager.AddMessage(requestMessage)); messageEnvelopes.Add(requestMessage); + Assert.IsFalse(manager.AddMessage(message)); + var era = manager.GetEra(); var list = manager.GetMessages(); CollectionAssert.AreEqual(list, messageEnvelopes); From cfaf90aa8efa771f987d762f997fce3001f91972 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Mon, 28 Nov 2022 15:21:32 +0600 Subject: [PATCH 075/133] Add test to message-repo --- .../IMessageEnvelopeRepository.cs | 2 +- .../Repositories/MessageEnvelopeRepository.cs | 4 +- .../Lachain.StorageTest.csproj | 10 +- .../MessageRepositoryTest.cs | 117 ++++++++++++++++++ 4 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 test/Lachain.StorageTest/MessageRepositoryTest.cs diff --git a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs index b52c20dfa..3d4c10b68 100644 --- a/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/IMessageEnvelopeRepository.cs @@ -4,7 +4,7 @@ namespace Lachain.Storage.Repositories { public interface IMessageEnvelopeRepository { - void SaveMessages(List messageEnvelopeListBytes); + void AddMessages(List messageEnvelopeListBytes); void ClearMessages(); void AddMessage(byte[] messageEnvelopeBytes); List LoadMessages(); diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index cb6279d77..6a04e5f1b 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -8,7 +8,7 @@ /* * Message Envelopes are kept in this repository * Format: - * prefix + "0": era + * prefix + "0": era * prefix + "1": count * prefix + "2+i": ith message */ @@ -24,7 +24,7 @@ public MessageEnvelopeRepository(IRocksDbContext rocksDbContext) _rocksDbContext = rocksDbContext ?? throw new ArgumentNullException(nameof(rocksDbContext)); } - public void SaveMessages(List messageEnvelopeListBytes) + public void AddMessages(List messageEnvelopeListBytes) { foreach (var envelope in messageEnvelopeListBytes) diff --git a/test/Lachain.StorageTest/Lachain.StorageTest.csproj b/test/Lachain.StorageTest/Lachain.StorageTest.csproj index e62ec36d4..60acb6fd0 100644 --- a/test/Lachain.StorageTest/Lachain.StorageTest.csproj +++ b/test/Lachain.StorageTest/Lachain.StorageTest.csproj @@ -5,13 +5,13 @@ enable - - - + + + - - + + diff --git a/test/Lachain.StorageTest/MessageRepositoryTest.cs b/test/Lachain.StorageTest/MessageRepositoryTest.cs new file mode 100644 index 000000000..f9cfaf2dd --- /dev/null +++ b/test/Lachain.StorageTest/MessageRepositoryTest.cs @@ -0,0 +1,117 @@ +using System; +using System.IO; +using System.Reflection; +using Lachain.Core.CLI; +using Lachain.Core.Config; +using Lachain.Core.DI; +using Lachain.Core.DI.Modules; +using Lachain.Core.DI.SimpleInjector; +using Lachain.Storage.State; +using Lachain.Utility.Utils; +using Lachain.UtilityTest; +using NUnit.Framework; +using Lachain.Proto; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus; +using Lachain.Storage; +using Lachain.Storage.Repositories; + + +namespace Lachain.StorageTest +{ + public class MessageRepositoryTest + { + private IContainer _container; + private IRocksDbContext _dbContext; + private IBlockProducer _blockProducer; + + [SetUp] + public void Setup() + { + var containerBuilder = new SimpleInjectorContainerBuilder(new ConfigManager( + Path.Join(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json"), + new RunOptions() + )); + + containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + + containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + containerBuilder.RegisterModule(); + + _container = containerBuilder.Build(); + _dbContext = _container.Resolve(); + _blockProducer = _container.Resolve(); + } + + [TearDown] + public void TearDown() + { + _container.Dispose(); + TestUtils.DeleteTestChainData(); + } + + [Test] + [Repeat(10)] + public void TestMessageRepository() + { + IMessageEnvelopeRepository repo = new MessageEnvelopeRepository(_dbContext); + + Assert.IsNull(repo.GetEra()); + Assert.IsEmpty(repo.LoadMessages()); + + repo.ClearMessages(); + Assert.IsNull(repo.GetEra()); + Assert.IsEmpty(repo.LoadMessages()); + + repo.SetEra(23); + Assert.AreEqual(repo.GetEra(), 23); + Assert.IsEmpty(repo.LoadMessages()); + + var messages = new List(); + for (var i = 1; i <= 5; i++) + { + messages.Add(TestUtils.GetRandomBytes(i)); + } + + foreach (var message in messages) + { + repo.AddMessage(message); + } + repo.SetEra(24); + + Assert.AreEqual(repo.GetEra(), 24); + Assert.AreEqual(repo.LoadMessages().Count, messages.Count); + + repo.ClearMessages(); + Assert.AreEqual(repo.GetEra(), 24); + Assert.IsEmpty(repo.LoadMessages()); + + repo.AddMessages(messages); + Assert.AreEqual(repo.GetEra(), 24); + Assert.AreEqual(repo.LoadMessages().Count, messages.Count); + + foreach (var message in messages) + { + repo.AddMessage(message); + + } + + Assert.AreEqual(repo.GetEra(), 24); + Assert.AreEqual(repo.LoadMessages().Count, 2*messages.Count); + + repo.ClearMessages(); + Assert.AreEqual(repo.GetEra(), 24); + Assert.AreEqual(repo.LoadMessages().Count, 0); + + + repo.AddMessages(messages); + Assert.AreEqual(repo.GetEra(), 24); + Assert.AreEqual(repo.LoadMessages().Count, messages.Count); + + } + + } +} \ No newline at end of file From b3c8529db6330ad48651d384ee1f00300db757f8 Mon Sep 17 00:00:00 2001 From: Pritom Kundu Date: Tue, 29 Nov 2022 13:09:42 +0600 Subject: [PATCH 076/133] Fix bug in repository --- src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs index 6a04e5f1b..5e6ca9767 100644 --- a/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs +++ b/src/Lachain.Storage/Repositories/MessageEnvelopeRepository.cs @@ -46,7 +46,7 @@ public void ClearMessages() for (int i = 0; i < count; i++) { - var key = EntryPrefix.MessageEnvelope.BuildPrefix(((int)(2+count)).ToBytes()); + var key = EntryPrefix.MessageEnvelope.BuildPrefix(((2+i)).ToBytes()); rocksDbAtomicWrite.Delete(key); } From 3d443788678ad8490c513032e7d6a7991a41f9d0 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 16:03:49 +0600 Subject: [PATCH 077/133] added event to catch external msg --- src/Lachain.Consensus/AbstractProtocol.cs | 9 +++++++++ src/Lachain.Consensus/IConsensusProtocol.cs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index c8d29ac82..bbe29132b 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -4,6 +4,7 @@ using System.Threading; using Lachain.Logger; using Lachain.Consensus.Messages; +using Lachain.Proto; using Lachain.Utility.Utils; using Prometheus; @@ -183,6 +184,14 @@ public void ReceiveMessage(MessageEnvelope message) } } + protected void InvokeReceivedExternalMessage(int from, ConsensusMessage msg) + { + // received a valid msg from validator + _receivedExternalMessage?.Invoke(this, (from, msg)); + } + public abstract void ProcessMessage(MessageEnvelope envelope); + + public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; } } \ No newline at end of file diff --git a/src/Lachain.Consensus/IConsensusProtocol.cs b/src/Lachain.Consensus/IConsensusProtocol.cs index c20ff684b..7a8ba0374 100644 --- a/src/Lachain.Consensus/IConsensusProtocol.cs +++ b/src/Lachain.Consensus/IConsensusProtocol.cs @@ -1,5 +1,6 @@ using System; using Lachain.Consensus.Messages; +using Lachain.Proto; namespace Lachain.Consensus { @@ -19,5 +20,7 @@ public interface IConsensusProtocol void Terminate(); bool Terminated { get; } + + event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; } } \ No newline at end of file From ad56d7257f6bfc7330b7f171a1c06a58b4bbef18 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 16:04:37 +0600 Subject: [PATCH 078/133] invoke event when received valid external msg --- .../BinaryAgreement/BinaryBroadcast.cs | 3 +++ src/Lachain.Consensus/CommonCoin/CommonCoin.cs | 11 ++++++++--- src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs | 4 ++++ .../ReliableBroadcast/ReliableBroadcast.cs | 3 +++ src/Lachain.Consensus/RootProtocol/RootProtocol.cs | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs index 39110cd49..d981dc4d4 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs @@ -139,6 +139,7 @@ private void HandleBValMessage(int sender, BValMessage bval) _receivedValues[sender].Add(b == 1); ++_receivedCount[b]; + InvokeReceivedExternalMessage(sender, new ConsensusMessage { Bval = bval }); if (!_wasBvalBroadcasted[b] && _receivedCount[b] >= F + 1) { @@ -173,6 +174,7 @@ private void HandleAuxMessage(int sender, AuxMessage aux) _playerSentAux[sender] = true; _receivedAux[b]++; + InvokeReceivedExternalMessage(sender, new ConsensusMessage { Aux = aux }); RevisitAuxMessages(); } @@ -191,6 +193,7 @@ private void HandleConfMessage(int sender, ConfMessage conf) _validatorSentConf[sender] = true; _confReceived.Add(new BoolSet(conf.Values)); + InvokeReceivedExternalMessage(sender, new ConsensusMessage { Conf = conf }); RevisitConfMessages(); } diff --git a/src/Lachain.Consensus/CommonCoin/CommonCoin.cs b/src/Lachain.Consensus/CommonCoin/CommonCoin.cs index a81a58f64..c86913eb9 100644 --- a/src/Lachain.Consensus/CommonCoin/CommonCoin.cs +++ b/src/Lachain.Consensus/CommonCoin/CommonCoin.cs @@ -72,6 +72,7 @@ public override void ProcessMessage(MessageEnvelope envelope) // To create signature from the message, some requirements need to be fulfilled, otherwise it can // throw exception (for example maybe a fixed length of the input bytes or maybe valid array of bytes) + bool validMsg = false; try { Logger.LogTrace($"Received share from {envelope.ValidatorIndex}"); @@ -85,23 +86,27 @@ public override void ProcessMessage(MessageEnvelope envelope) $"Faulty behaviour from player {envelope.ValidatorIndex}, {message.PrettyTypeString()}, {message.Coin.SignatureShare.ToByteArray().ToHex()}: bad signature share"); return; // potential fault evidence } + validMsg = true; if (signature == null) { _lastMessage = "signature == null"; - return; } - - _result = new CoinResult(signature.RawSignature.ToBytes()); + else + _result = new CoinResult(signature.RawSignature.ToBytes()); } catch (Exception exception) { + validMsg = false; var pubKey = Broadcaster.GetPublicKeyById(envelope.ValidatorIndex)!.ToHex(); Logger.LogWarning( $"Exception occured while handling message from validator {envelope.ValidatorIndex} " + $"({pubKey}). Exception: {exception}"); } + if (validMsg) + InvokeReceivedExternalMessage(envelope.ValidatorIndex, message); + CheckResult(); } else diff --git a/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs b/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs index 9809d47b1..928869395 100644 --- a/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs +++ b/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs @@ -224,7 +224,11 @@ private void HandleDecryptedMessage(TPKEPartiallyDecryptedShareMessage msg, int } if (!(share is null)) + { CheckDecryptedShares(share.ShareId); + // received a valid message from senderId for the first time + InvokeReceivedExternalMessage(senderId, new ConsensusMessage { Decrypted = msg }); + } } // There are several potential issues in Wallet.TpkePublicKey.FullDecrypt() that needs to be resolved. diff --git a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcast.cs b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcast.cs index adfe7a325..68a2e398f 100644 --- a/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcast.cs +++ b/src/Lachain.Consensus/ReliableBroadcast/ReliableBroadcast.cs @@ -147,6 +147,7 @@ private void HandleValMessage(ValMessage val, int validator) // because the correct echo for each pair is received only once. if (validator == val.SenderId) { + InvokeReceivedExternalMessage(validator, new ConsensusMessage { ValMessage = val }); Broadcaster.Broadcast(CreateEchoMessage(val)); } else @@ -178,6 +179,7 @@ private void HandleEchoMessage(ECHOMessage echo, int validator) Logger.LogTrace($"Protocol {Id} got ECHO message from {validator} ({validatorPubKey})"); _echoMessages[validator] = echo; + InvokeReceivedExternalMessage(validator, new ConsensusMessage { EchoMessage = echo }); TrySendReadyMessageFromEchos(); CheckResult(); } @@ -193,6 +195,7 @@ private void HandleReadyMessage(ReadyMessage readyMessage, int validator) Logger.LogTrace($"Protocol {Id} got READY message from {validator} ({validatorPubKey})"); _readyMessages[validator] = readyMessage; + InvokeReceivedExternalMessage(validator, new ConsensusMessage { ReadyMessage = readyMessage }); TrySendReadyMessageFromReady(); CheckResult(); // Logger.LogDebug($"{Id}: got ready message from {validator}"); diff --git a/src/Lachain.Consensus/RootProtocol/RootProtocol.cs b/src/Lachain.Consensus/RootProtocol/RootProtocol.cs index c85252b0b..743124944 100644 --- a/src/Lachain.Consensus/RootProtocol/RootProtocol.cs +++ b/src/Lachain.Consensus/RootProtocol/RootProtocol.cs @@ -134,6 +134,7 @@ public override void ProcessMessage(MessageEnvelope envelope) var validatorAttendance = GetOrCreateValidatorAttendance(message.SignedHeaderMessage.Header.Index); validatorAttendance!.IncrementAttendanceForCycle(Wallet.EcdsaPublicKeySet[idx].EncodeCompressed(), message.SignedHeaderMessage.Header.Index / _cycleDuration); + InvokeReceivedExternalMessage(idx, message); } else { From 61a72cd69393e0ed6125a6a99849da3535898b65 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 16:05:07 +0600 Subject: [PATCH 079/133] added method to catch external msg and register protocol --- .../Messages/MessageEnvelopeRepositoryManager.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index 52066b92e..c0dc6d767 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Lachain.Logger; +using Lachain.Proto; using Lachain.Storage.Repositories; namespace Lachain.Consensus.Messages @@ -100,5 +101,17 @@ public ICollection GetMessages() { return MessageEnvelopeList; } + + private void HandleExternalMessage(object? sender, (int from, ConsensusMessage msg) @event) + { + var (from, msg) = @event; + var messageEnvelope = new MessageEnvelope(msg, from); + AddMessage(messageEnvelope); + } + + public void RegisterProtocol(IConsensusProtocol protocol) + { + protocol._receivedExternalMessage += HandleExternalMessage; + } } } \ No newline at end of file From 6a4b4335a8249cf2ead8dc7eea992c7f85173637 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 16:05:30 +0600 Subject: [PATCH 080/133] registering protocol --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 0e49d260b..32dcdd195 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -89,6 +89,7 @@ public void RegisterProtocols(IEnumerable protocols) foreach (var protocol in protocols) { _registry[protocol.Id] = protocol; + _messageEnvelopeRepositoryManager.RegisterProtocol(protocol); } } @@ -335,7 +336,6 @@ private void HandleExternalMessage(IProtocolIdentifier protocolId, MessageEnvelo .Add(message); } } - _messageEnvelopeRepositoryManager.AddMessage(message); if (!(protocol is null)) protocol.ReceiveMessage(message); } else Logger.LogWarning("Internal message should not be here"); From fe26234cb438255a2a0ad7ed4cb2cb5182ffc6e9 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 16:05:41 +0600 Subject: [PATCH 081/133] fixed tests --- test/Lachain.ConsensusTest/ProtocolInvoker.cs | 3 +++ test/Lachain.ConsensusTest/SilentProtocol.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test/Lachain.ConsensusTest/ProtocolInvoker.cs b/test/Lachain.ConsensusTest/ProtocolInvoker.cs index 5fa340eec..4e901e203 100644 --- a/test/Lachain.ConsensusTest/ProtocolInvoker.cs +++ b/test/Lachain.ConsensusTest/ProtocolInvoker.cs @@ -5,6 +5,7 @@ using Lachain.Consensus; using Lachain.Consensus.Messages; using Lachain.Logger; +using Lachain.Proto; namespace Lachain.ConsensusTest { @@ -117,5 +118,7 @@ public void WaitResult() { throw new NotImplementedException(); } + + public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/SilentProtocol.cs b/test/Lachain.ConsensusTest/SilentProtocol.cs index 083a6f715..1d197bad6 100644 --- a/test/Lachain.ConsensusTest/SilentProtocol.cs +++ b/test/Lachain.ConsensusTest/SilentProtocol.cs @@ -1,6 +1,7 @@ using System; using Lachain.Consensus; using Lachain.Consensus.Messages; +using Lachain.Proto; namespace Lachain.ConsensusTest { @@ -50,5 +51,7 @@ public void Terminate() } public bool Terminated => true; + + public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; } } \ No newline at end of file From 4d5390a073357276cc260d5e0f42602d23381b8e Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 17:41:40 +0600 Subject: [PATCH 082/133] fixed bug --- .../Messages/MessageEnvelopeRepositoryManager.cs | 7 +++++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index c0dc6d767..aafcaf1ae 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -12,12 +12,14 @@ public class MessageEnvelopeRepositoryManager private readonly IMessageEnvelopeRepository _repository; private List? MessageEnvelopeList { get; set; } private ISet? MessageEnvelopeSet; + private readonly long _era; private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); public bool IsPresent => !(MessageEnvelopeList is null); - public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) + public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository, long era) { + _era = era; _repository = repository; } @@ -59,8 +61,8 @@ public long GetEra() [MethodImpl(MethodImplOptions.Synchronized)] public void StartEra(long era, bool canBeSame = false) { + if (era != _era) throw new ArgumentException($"We are in era {_era}, but starting era {era}"); if (!canBeSame && IsPresent && (long) _repository.GetEra() == era) - { throw new ArgumentException($"Start Era called with same era number {era}"); } @@ -105,6 +107,7 @@ public ICollection GetMessages() private void HandleExternalMessage(object? sender, (int from, ConsensusMessage msg) @event) { var (from, msg) = @event; + msg.Validator = new Validator {Era = _era}; var messageEnvelope = new MessageEnvelope(msg, from); AddMessage(messageEnvelope); } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 32dcdd195..511ce5f8f 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -74,7 +74,7 @@ public EraBroadcaster( _era = era; _myIdx = -1; _validatorAttendanceRepository = validatorAttendanceRepository; - _messageEnvelopeRepositoryManager = new MessageEnvelopeRepositoryManager(messageEnvelopeRepository); + _messageEnvelopeRepositoryManager = new MessageEnvelopeRepositoryManager(messageEnvelopeRepository, _era); _blockProducer = blockProducer; } From 6ba30bf7e979bff80af0ed3e37dc79cbee1a331f Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 17:41:49 +0600 Subject: [PATCH 083/133] fixed tests --- .../MessageEnvelopeRepositoryManagerTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 7ca9aca10..90cbed793 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -60,7 +60,7 @@ public void TearDown() public void Test_MessageEnvelopeRepositoryManager() { var repo = new MessageEnvelopeRepository(_dbContext); - var manager = new MessageEnvelopeRepositoryManager(repo); + var manager = new MessageEnvelopeRepositoryManager(repo, 23); manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, false); @@ -95,7 +95,7 @@ public void Test_MessageEnvelopeRepositoryManager() var list = manager.GetMessages(); CollectionAssert.AreEqual(list, messageEnvelopes); - manager = new MessageEnvelopeRepositoryManager(repo); + manager = new MessageEnvelopeRepositoryManager(repo, 24); manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), era); @@ -114,7 +114,7 @@ public void Test_MessageEnvelopeRepositoryManager() public void Test_MessageEnvelopeRepositoryManagerReloading() { var repo = new MessageEnvelopeRepository(_dbContext); - var manager = new MessageEnvelopeRepositoryManager(repo); + var manager = new MessageEnvelopeRepositoryManager(repo, 45); Assert.AreEqual(manager.IsPresent, false); Assert.Throws(() => manager.GetEra()); @@ -129,7 +129,7 @@ public void Test_MessageEnvelopeRepositoryManagerReloading() var list = manager.GetMessages(); var era = manager.GetEra(); - manager = new MessageEnvelopeRepositoryManager(repo); + manager = new MessageEnvelopeRepositoryManager(repo, era); Assert.AreEqual(manager.IsPresent, false); Assert.Throws(() => manager.GetEra()); Assert.Throws( From 49cf4476db79e98d8308fbeed9747d7e6dc8a147 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 21:15:09 +0600 Subject: [PATCH 084/133] added interface for repo manager --- .../Messages/IMessageEnvelopeRepositoryManager.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Lachain.Consensus/Messages/IMessageEnvelopeRepositoryManager.cs diff --git a/src/Lachain.Consensus/Messages/IMessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/IMessageEnvelopeRepositoryManager.cs new file mode 100644 index 000000000..821d71e71 --- /dev/null +++ b/src/Lachain.Consensus/Messages/IMessageEnvelopeRepositoryManager.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Lachain.Consensus.Messages +{ + public interface IMessageEnvelopeRepositoryManager + { + bool IsPresent { get; } + void LoadFromDb(); + long GetEra(); + void StartEra(long era, bool canBeSame = false); + bool AddMessage(MessageEnvelope message); + ICollection GetMessages(); + } +} \ No newline at end of file From e3ad848a99175e431f02acabb6c61cc7e2b4dc91 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 21:15:30 +0600 Subject: [PATCH 085/133] using fixed bug --- .../MessageEnvelopeRepositoryManager.cs | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs index aafcaf1ae..8011c8927 100644 --- a/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs +++ b/src/Lachain.Consensus/Messages/MessageEnvelopeRepositoryManager.cs @@ -2,24 +2,21 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Lachain.Logger; -using Lachain.Proto; using Lachain.Storage.Repositories; namespace Lachain.Consensus.Messages { - public class MessageEnvelopeRepositoryManager + public class MessageEnvelopeRepositoryManager : IMessageEnvelopeRepositoryManager { private readonly IMessageEnvelopeRepository _repository; private List? MessageEnvelopeList { get; set; } private ISet? MessageEnvelopeSet; - private readonly long _era; private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); public bool IsPresent => !(MessageEnvelopeList is null); - public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository, long era) + public MessageEnvelopeRepositoryManager(IMessageEnvelopeRepository repository) { - _era = era; _repository = repository; } @@ -34,7 +31,8 @@ public void LoadFromDb() MessageEnvelopeList = new List(); MessageEnvelopeSet = new HashSet(); - foreach (var bytes in _repository.LoadMessages()) + var dbMsgs = _repository.LoadMessages(); + foreach (var bytes in dbMsgs) { var envelope = MessageEnvelope.FromByteArray(bytes); @@ -61,7 +59,6 @@ public long GetEra() [MethodImpl(MethodImplOptions.Synchronized)] public void StartEra(long era, bool canBeSame = false) { - if (era != _era) throw new ArgumentException($"We are in era {_era}, but starting era {era}"); if (!canBeSame && IsPresent && (long) _repository.GetEra() == era) { throw new ArgumentException($"Start Era called with same era number {era}"); @@ -103,18 +100,5 @@ public ICollection GetMessages() { return MessageEnvelopeList; } - - private void HandleExternalMessage(object? sender, (int from, ConsensusMessage msg) @event) - { - var (from, msg) = @event; - msg.Validator = new Validator {Era = _era}; - var messageEnvelope = new MessageEnvelope(msg, from); - AddMessage(messageEnvelope); - } - - public void RegisterProtocol(IConsensusProtocol protocol) - { - protocol._receivedExternalMessage += HandleExternalMessage; - } } } \ No newline at end of file From 02e406e094a620413020ee4dd7779337ca2bfecf Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 21:15:47 +0600 Subject: [PATCH 086/133] registered instance --- src/Lachain.Core/DI/Modules/ConsensusModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Lachain.Core/DI/Modules/ConsensusModule.cs b/src/Lachain.Core/DI/Modules/ConsensusModule.cs index 2e2b0d315..93a4329c4 100644 --- a/src/Lachain.Core/DI/Modules/ConsensusModule.cs +++ b/src/Lachain.Core/DI/Modules/ConsensusModule.cs @@ -1,4 +1,5 @@ using Lachain.Consensus; +using Lachain.Consensus.Messages; using Lachain.Core.Blockchain.Validators; using Lachain.Core.Config; using Lachain.Core.Consensus; @@ -16,6 +17,7 @@ public void Register(IContainerBuilder containerBuilder, IConfigManager configMa containerBuilder.RegisterSingleton(); containerBuilder.RegisterSingleton(); containerBuilder.RegisterSingleton(); + containerBuilder.RegisterSingleton(); } } } \ No newline at end of file From f0762182e01799a07b0f57a358789daa7a6dd471 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 21:16:15 +0600 Subject: [PATCH 087/133] using single instance instead of new class for each era --- .../Consensus/ConsensusManager.cs | 7 +++++-- src/Lachain.Core/Consensus/EraBroadcaster.cs | 20 ++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Lachain.Core/Consensus/ConsensusManager.cs b/src/Lachain.Core/Consensus/ConsensusManager.cs index d0ce9c3c2..a7914e67d 100644 --- a/src/Lachain.Core/Consensus/ConsensusManager.cs +++ b/src/Lachain.Core/Consensus/ConsensusManager.cs @@ -38,6 +38,7 @@ public class ConsensusManager : IConsensusManager private bool _terminated; private readonly IPrivateWallet _privateWallet; private readonly IKeyGenManager _keyGenManager; + private readonly IMessageEnvelopeRepositoryManager _messageRepoManager; private readonly IDictionary> _postponedMessages = new Dictionary>(); @@ -52,6 +53,7 @@ public class ConsensusManager : IConsensusManager private readonly ulong _targetBlockInterval; public ConsensusManager( + IMessageEnvelopeRepositoryManager messageRepoManager, IConsensusMessageDeliverer consensusMessageDeliverer, IValidatorManager validatorManager, IBlockProducer blockProducer, @@ -65,6 +67,7 @@ public ConsensusManager( IKeyGenManager keyGenManager ) { + _messageRepoManager = messageRepoManager; _consensusMessageDeliverer = consensusMessageDeliverer; _validatorManager = validatorManager; _blockProducer = blockProducer; @@ -184,7 +187,7 @@ private void FinishEra() CurrentEra += 1; _eras[CurrentEra] = new EraBroadcaster( - CurrentEra, _consensusMessageDeliverer, _privateWallet, + _messageRepoManager, CurrentEra, _consensusMessageDeliverer, _privateWallet, _validatorAttendanceRepository, _messageEnvelopeRepository, _blockProducer ); Logger.LogTrace($"Current Era is advanced. Current Era: {CurrentEra}"); @@ -200,7 +203,7 @@ private void Run(ulong startingEra, bool restoreState) { Logger.LogTrace("Create EraBroadcaster"); _eras[CurrentEra] = new EraBroadcaster( - CurrentEra, _consensusMessageDeliverer, _privateWallet, + _messageRepoManager, CurrentEra, _consensusMessageDeliverer, _privateWallet, _validatorAttendanceRepository, _messageEnvelopeRepository, _blockProducer ); } diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 511ce5f8f..0ac9981bc 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -38,7 +38,7 @@ public class EraBroadcaster : IConsensusBroadcaster private readonly IMessageFactory _messageFactory; private readonly IPrivateWallet _wallet; private readonly IValidatorAttendanceRepository _validatorAttendanceRepository; - private readonly MessageEnvelopeRepositoryManager _messageEnvelopeRepositoryManager; + private readonly IMessageEnvelopeRepositoryManager _messageEnvelopeRepositoryManager; private bool _terminated; private int _myIdx; private IPublicConsensusKeySet? _validators; @@ -62,6 +62,7 @@ public class EraBroadcaster : IConsensusBroadcaster new ConcurrentDictionary>(); public EraBroadcaster( + IMessageEnvelopeRepositoryManager messageEnvelopeRepositoryManager, long era, IConsensusMessageDeliverer consensusMessageDeliverer, IPrivateWallet wallet, IValidatorAttendanceRepository validatorAttendanceRepository, IMessageEnvelopeRepository messageEnvelopeRepository, IBlockProducer blockProducer @@ -74,7 +75,7 @@ public EraBroadcaster( _era = era; _myIdx = -1; _validatorAttendanceRepository = validatorAttendanceRepository; - _messageEnvelopeRepositoryManager = new MessageEnvelopeRepositoryManager(messageEnvelopeRepository, _era); + _messageEnvelopeRepositoryManager = messageEnvelopeRepositoryManager; _blockProducer = blockProducer; } @@ -89,10 +90,23 @@ public void RegisterProtocols(IEnumerable protocols) foreach (var protocol in protocols) { _registry[protocol.Id] = protocol; - _messageEnvelopeRepositoryManager.RegisterProtocol(protocol); + protocol._receivedExternalMessage += PersistExternalMessae; } } + private void PersistExternalMessae(object? sender, (int from, ConsensusMessage msg) @event) + { + if (_terminated) + { + Logger.LogTrace($"Era {_era} is already finished, skipping persist"); + return; + } + var (from, msg) = @event; + msg.Validator = new Validator {Era = _era}; + var messageEnvelope = new MessageEnvelope(msg, from); + _messageEnvelopeRepositoryManager.AddMessage(messageEnvelope); + } + public void Broadcast(ConsensusMessage message) { message.Validator = new Validator {Era = _era}; From 7143dfd0b9288a3d9928b2a21ff253ad50c85bc5 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 30 Nov 2022 21:16:24 +0600 Subject: [PATCH 088/133] fixed test --- .../MessageEnvelopeRepositoryManagerTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs index 90cbed793..7ca9aca10 100644 --- a/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs +++ b/test/Lachain.ConsensusTest/MessageEnvelopeRepositoryManagerTest.cs @@ -60,7 +60,7 @@ public void TearDown() public void Test_MessageEnvelopeRepositoryManager() { var repo = new MessageEnvelopeRepository(_dbContext); - var manager = new MessageEnvelopeRepositoryManager(repo, 23); + var manager = new MessageEnvelopeRepositoryManager(repo); manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, false); @@ -95,7 +95,7 @@ public void Test_MessageEnvelopeRepositoryManager() var list = manager.GetMessages(); CollectionAssert.AreEqual(list, messageEnvelopes); - manager = new MessageEnvelopeRepositoryManager(repo, 24); + manager = new MessageEnvelopeRepositoryManager(repo); manager.LoadFromDb(); Assert.AreEqual(manager.IsPresent, true); Assert.AreEqual(manager.GetEra(), era); @@ -114,7 +114,7 @@ public void Test_MessageEnvelopeRepositoryManager() public void Test_MessageEnvelopeRepositoryManagerReloading() { var repo = new MessageEnvelopeRepository(_dbContext); - var manager = new MessageEnvelopeRepositoryManager(repo, 45); + var manager = new MessageEnvelopeRepositoryManager(repo); Assert.AreEqual(manager.IsPresent, false); Assert.Throws(() => manager.GetEra()); @@ -129,7 +129,7 @@ public void Test_MessageEnvelopeRepositoryManagerReloading() var list = manager.GetMessages(); var era = manager.GetEra(); - manager = new MessageEnvelopeRepositoryManager(repo, era); + manager = new MessageEnvelopeRepositoryManager(repo); Assert.AreEqual(manager.IsPresent, false); Assert.Throws(() => manager.GetEra()); Assert.Throws( From ee2939a0f00160bf91f5ff36f279d51b05a1c3a3 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:11:26 +0600 Subject: [PATCH 089/133] added messages for request --- src/Lachain.Proto/consensus.proto | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/Lachain.Proto/consensus.proto b/src/Lachain.Proto/consensus.proto index 892b28fd8..4eb943e01 100644 --- a/src/Lachain.Proto/consensus.proto +++ b/src/Lachain.Proto/consensus.proto @@ -87,6 +87,62 @@ message ConsensusMessage { ECHOMessage echo_message = 14; ReadyMessage ready_message = 15; SignedHeaderMessage signed_header_message = 16; + RequestConsensusMessage request_consensus = 17; } reserved 7, 9 to 12; +} + +// add request type for consensus messages + +message RequestBValMessage { + int32 agreement = 1; + int32 epoch = 2; +} + +message RequestAuxMessage { + int32 agreement = 1; + int32 epoch = 2; +} + +message RequestConfMessage { + int32 agreement = 1; + int32 epoch = 2; +} + +message RequestCommonCoinMessage { + int32 agreement = 1; + int32 epoch = 2; +} + +message RequestTPKEPartiallyDecryptedShareMessage { + int32 share_id = 1; +} + +message RequestValMessage { + int32 senderId = 1; +} + +message RequestECHOMessage { + int32 sender_id = 1; +} + +message RequestReadyMessage { + int32 sender_id = 1; +} + +message RequestSignedHeaderMessage { +} + +message RequestConsensusMessage { + oneof payload { + RequestBValMessage request_bval = 1; + RequestAuxMessage request_aux = 2; + RequestConfMessage request_conf = 3; + RequestCommonCoinMessage request_coin = 4; + RequestTPKEPartiallyDecryptedShareMessage request_decrypted = 5; + RequestValMessage request_val = 6; + RequestECHOMessage request_echo = 7; + RequestReadyMessage request_ready = 8; + RequestSignedHeaderMessage request_signed_header = 9; + } } \ No newline at end of file From 579a483ff6f26dadbb0367e91892acc6228d2d0e Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:19:40 +0600 Subject: [PATCH 090/133] added request type for each message type --- .../RequestProtocols/Messages/RequestType.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs b/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs new file mode 100644 index 000000000..f724bc220 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs @@ -0,0 +1,15 @@ +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public enum RequestType : byte + { + Aux = 0, + Bval = 1, + Conf = 2, + Coin = 3, + Val = 4, + SignedHeader = 5, + Ready = 6, + Decrypted = 7, + Echo = 8, + } +} \ No newline at end of file From fa4a4dd64cdeb278a853fae5397f19800c5718fb Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:20:07 +0600 Subject: [PATCH 091/133] added status for request --- .../RequestProtocols/Messages/MessageStatus.cs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/MessageStatus.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageStatus.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageStatus.cs new file mode 100644 index 000000000..16a84604f --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageStatus.cs @@ -0,0 +1,9 @@ +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public enum MessageStatus : byte + { + Received = 0, + Requested = 1, + NotReceived = 2, + } +} \ No newline at end of file From c3bd7259567937c7940e88879394ce61d0ded4f3 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:20:29 +0600 Subject: [PATCH 092/133] added message request handler --- .../Messages/IMessageRequestHandler.cs | 14 + .../Messages/MessageRequestHandler.cs | 392 ++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs new file mode 100644 index 000000000..7b7064331 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public interface IMessageRequestHandler + { + RequestType Type { get; } + void Terminate(); + void MessageReceived(int from, ConsensusMessage msg); + bool IsProtocolComplete(); + List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount); + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs new file mode 100644 index 000000000..f4bab646d --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RootProtocol; +using Lachain.Logger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public class MessageRequestHandler : IMessageRequestHandler + { + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private MessageStatus[][] _status; + private readonly int _msgCount; + private readonly RequestType _type; + private readonly int _validators; + private readonly int _msgPerValidator; + private int _remainingMsges; + private readonly Queue<(int,int)> _messageRequests; + public RequestType Type => _type; + public MessageRequestHandler(RequestType type, int validatorCount, int msgPerValidator) + { + _type = type; + _validators = validatorCount; + _msgCount = validatorCount * msgPerValidator; + _msgPerValidator = msgPerValidator; + _status = new MessageStatus[_validators][]; + _messageRequests = new Queue<(int, int)>(); + for (int i = 0 ; i < _validators ; i++) + { + _status[i] = new MessageStatus[msgPerValidator]; + for (int j = 0; j < msgPerValidator; j++) + { + _status[i][j] = MessageStatus.NotReceived; + _messageRequests.Enqueue((i,j)); + } + } + _remainingMsges = _msgCount; + } + + public void Terminate() + { + _messageRequests.Clear(); + _status = new MessageStatus[0][]; + } + + public void MessageReceived(int from, ConsensusMessage msg) + { + var type = GetRequestTypeForMessageType(msg); + if (type != _type) + throw new Exception($"message type {type} routed to message handler {_type}"); + switch (type) + { + case RequestType.Aux: + HandleAuxMessage(from, msg.Aux); + break; + case RequestType.Bval: + HandleBValMessage(from, msg.Bval); + break; + case RequestType.Coin: + HandleCoinMessage(from, msg.Coin); + break; + case RequestType.Conf: + HandleConfMessage(from, msg.Conf); + break; + case RequestType.Decrypted: + HandleDecryptedMessage(from, msg.Decrypted); + break; + case RequestType.Echo: + HandleEchoMessage(from, msg.EchoMessage); + break; + case RequestType.Ready: + HandleReadyMessage(from, msg.ReadyMessage); + break; + case RequestType.SignedHeader: + HandleSignedHeaderMessage(from, msg.SignedHeaderMessage); + break; + case RequestType.Val: + HandleValMessage(from, msg.ValMessage); + break; + default: + throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); + } + } + + private void MessageReceived(int validatorId, int msgId) + { + if (_status[validatorId][msgId] != MessageStatus.Received) + _remainingMsges--; + _status[validatorId][msgId] = MessageStatus.Received; + } + + private void HandleAuxMessage(int from, AuxMessage _) + { + MessageReceived(from, 0); + } + + private void HandleBValMessage(int from, BValMessage msg) + { + MessageReceived(from, msg.Value ? 1 : 0); + } + + private void HandleConfMessage(int from, ConfMessage _) + { + MessageReceived(from, 0); + } + + private void HandleCoinMessage(int from, CommonCoinMessage _) + { + MessageReceived(from, 0); + } + + private void HandleEchoMessage(int from, ECHOMessage _) + { + MessageReceived(from, 0); + } + + private void HandleReadyMessage(int from, ReadyMessage _) + { + MessageReceived(from, 0); + } + + private void HandleValMessage(int _from, ValMessage _) + { + MessageReceived(0, 0); + } + + private void HandleDecryptedMessage(int from, TPKEPartiallyDecryptedShareMessage msg) + { + MessageReceived(from, msg.ShareId); + } + + private void HandleSignedHeaderMessage(int from, SignedHeaderMessage _) + { + MessageReceived(from, 0); + } + + public bool IsProtocolComplete() + { + return _remainingMsges == _msgCount; + } + + public List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount) + { + var requests = new List<(ConsensusMessage, int)>(); + if (IsProtocolComplete()) return requests; + + if (requestCount > _remainingMsges) + requestCount = _remainingMsges; + + while (requestCount > 0) + { + var (validtorId, msgId) = _messageRequests.Dequeue(); + if (_status[validtorId][msgId] == MessageStatus.Received) + continue; + requestCount--; + if (_status[validtorId][msgId] == MessageStatus.Requested) + { + Logger.LogWarning( + $"Requesting consensus msg {_type} with id {msgId} to validator {validtorId} again. Validator not replying." + ); + } + else + { + _status[validtorId][msgId] = MessageStatus.Requested; + Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {validtorId}."); + } + var msg = CreateConsensusMessage(protocolId, msgId); + if (_type == RequestType.Val) + requests.Add((msg, msg.ValMessage.SenderId)); + else + requests.Add((msg, validtorId)); + + // put this back so we can request it again + _messageRequests.Enqueue((validtorId, msgId)); + } + return requests; + } + + private ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) + { + var wrongProtocolWarning = $"wrong protcolId {protocolId} for request type {_type}"; + switch (_type) + { + case RequestType.Aux: + return CreateAuxRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Bval: + return CreateBValRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Conf: + return CreateConfRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Coin: + return CreateCoinRequest(protocolId as CoinId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Decrypted: + return CreateDecryptedRequest(protocolId as HoneyBadgerId ?? throw new Exception(wrongProtocolWarning), msgId); + case RequestType.Echo: + return CreateEchoRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Ready: + return CreateReadyRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.Val: + return CreateValRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); + case RequestType.SignedHeader: + return CreateSignedHeaderRequest(protocolId as RootProtocolId ?? throw new Exception(wrongProtocolWarning)); + default: + throw new Exception($"Not implemented request type {_type}"); + } + } + + private ConsensusMessage CreateAuxRequest(BinaryBroadcastId id) + { + if (_type != RequestType.Aux) + throw new Exception($"Aux request routed to {_type} message handler"); + var auxRequest = new RequestAuxMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestAux = auxRequest + } + }; + } + + private ConsensusMessage CreateBValRequest(BinaryBroadcastId id) + { + if (_type != RequestType.Bval) + throw new Exception($"BVal request routed to {_type} message handler"); + var bvalRequest = new RequestBValMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestBval = bvalRequest + } + }; + } + + private ConsensusMessage CreateConfRequest(BinaryBroadcastId id) + { + if (_type != RequestType.Conf) + throw new Exception($"Conf request routed to {_type} message handler"); + var confRequest = new RequestConfMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestConf = confRequest + } + }; + } + + private ConsensusMessage CreateCoinRequest(CoinId id) + { + if (_type != RequestType.Coin) + throw new Exception($"Coin request routed to {_type} message handler"); + var coinRequest = new RequestCommonCoinMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestCoin = coinRequest + } + }; + } + + private ConsensusMessage CreateValRequest(ReliableBroadcastId id) + { + if (_type != RequestType.Val) + throw new Exception($"Val request routed to {_type} message handler"); + var valRequest = new RequestValMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestVal = valRequest + } + }; + } + + private ConsensusMessage CreateEchoRequest(ReliableBroadcastId id) + { + if (_type != RequestType.Echo) + throw new Exception($"Echo request routed to {_type} message handler"); + var echoRequest = new RequestECHOMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestEcho = echoRequest + } + }; + } + + private ConsensusMessage CreateReadyRequest(ReliableBroadcastId id) + { + if (_type != RequestType.Ready) + throw new Exception($"Ready request routed to {_type} message handler"); + var readyRequest = new RequestReadyMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestReady = readyRequest + } + }; + } + + private ConsensusMessage CreateDecryptedRequest(HoneyBadgerId _, int shareId) + { + if (_type != RequestType.Decrypted) + throw new Exception($"Decrypted request routed to {_type} message handler"); + var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage + { + ShareId = shareId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestDecrypted = decryptedRequest + } + }; + } + + private ConsensusMessage CreateSignedHeaderRequest(RootProtocolId _) + { + if (_type != RequestType.SignedHeader) + throw new Exception($"Signed header request routed to {_type} message handler"); + var headerRequest = new RequestSignedHeaderMessage(); + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestSignedHeader = headerRequest + } + }; + } + + public static RequestType GetRequestTypeForMessageType(ConsensusMessage msg) + { + switch (msg.PayloadCase) + { + case ConsensusMessage.PayloadOneofCase.Aux: + return RequestType.Aux;; + case ConsensusMessage.PayloadOneofCase.Bval: + return RequestType.Bval; + case ConsensusMessage.PayloadOneofCase.Coin: + return RequestType.Coin; + case ConsensusMessage.PayloadOneofCase.Conf: + return RequestType.Conf; + case ConsensusMessage.PayloadOneofCase.Decrypted: + return RequestType.Decrypted; + case ConsensusMessage.PayloadOneofCase.EchoMessage: + return RequestType.Echo; + case ConsensusMessage.PayloadOneofCase.ReadyMessage: + return RequestType.Ready; + case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage: + return RequestType.SignedHeader; + case ConsensusMessage.PayloadOneofCase.ValMessage: + return RequestType.Val; + default: + throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); + } + } + } +} \ No newline at end of file From 60d9849d462dd37a1676384548a4f8fb3bd8f538 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:20:55 +0600 Subject: [PATCH 093/133] added type for protocols --- .../RequestProtocols/Protocols/ProtocolType.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs new file mode 100644 index 000000000..987981caa --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs @@ -0,0 +1,11 @@ +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public enum ProtocolType : byte + { + Root = 0, + HoneyBadger = 1, + ReliableBroadcast = 2, + BinaryBroadcast = 3, + CommonCoin = 4, + } +} \ No newline at end of file From 21d5f98737df3900dec04b5a247a805b234c2ac5 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:21:20 +0600 Subject: [PATCH 094/133] added protocol request handler --- .../Protocols/IProtocolRequestHandler.cs | 12 ++ .../Protocols/ProtocolRequestHandler.cs | 164 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs new file mode 100644 index 000000000..ad2c82a89 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public interface IProtocolRequestHandler + { + void Terminate(); + void MessageReceived(int from, ConsensusMessage msg); + List<(ConsensusMessage, int)> GetRequests(int requestCount); + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs new file mode 100644 index 000000000..fd360eb36 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RequestProtocols.Messages; +using Lachain.Consensus.RootProtocol; +using Lachain.Logger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public class ProtocolRequestHandler : IProtocolRequestHandler + { + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private readonly IProtocolIdentifier _protocolId; + private readonly ProtocolType _type; + private readonly int _validatorsCount; + private readonly List _messageHandlers; + public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) + { + _validatorsCount = validatorsCount; + _protocolId = id; + _type = GetMyType(id); + _messageHandlers = new List(); + var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); + foreach (var type in requestTypes) + { + if (GetProtocolTypeForRequestType(type) == _type) + { + _messageHandlers.Add(RegisterMessageHandler(type)); + } + } + } + + public void Terminate() + { + foreach (var handler in _messageHandlers) + handler.Terminate(); + _messageHandlers.Clear(); + Logger.LogTrace($"Protocol handler for protocol {_protocolId} terminated"); + } + + public void MessageReceived(int from, ConsensusMessage msg) + { + var type = MessageRequestHandler.GetRequestTypeForMessageType(msg); + foreach (var handler in _messageHandlers) + { + if (handler.Type == type) + { + handler.MessageReceived(from, msg); + } + } + } + + public List<(ConsensusMessage, int)> GetRequests(int requestCount) + { + var allRequests = new List<(ConsensusMessage, int)>(); + foreach (var handler in _messageHandlers) + { + var requests = handler.GetRequests(_protocolId, requestCount); + requestCount -= requests.Count; + allRequests.AddRange(requests); + } + return allRequests; + } + + private ProtocolType GetMyType(IProtocolIdentifier id) + { + switch (id) + { + case RootProtocolId _: + return ProtocolType.Root; + case HoneyBadgerId _: + return ProtocolType.HoneyBadger; + case ReliableBroadcastId _: + return ProtocolType.ReliableBroadcast; + case BinaryBroadcastId _: + return ProtocolType.BinaryBroadcast; + case CoinId _: + return ProtocolType.CommonCoin; + default: + throw new Exception($"Not implemented type for protocol id {id}"); + } + } + + private ProtocolType GetProtocolTypeForRequestType(RequestType requestType) + { + switch (requestType) + { + case RequestType.Aux: + return ProtocolType.BinaryBroadcast; + case RequestType.Bval: + return ProtocolType.BinaryBroadcast; + case RequestType.Coin: + return ProtocolType.CommonCoin; + case RequestType.Conf: + return ProtocolType.BinaryBroadcast; + case RequestType.Decrypted: + return ProtocolType.HoneyBadger; + case RequestType.Echo: + return ProtocolType.ReliableBroadcast; + case RequestType.Ready: + return ProtocolType.ReliableBroadcast; + case RequestType.SignedHeader: + return ProtocolType.Root; + case RequestType.Val: + return ProtocolType.ReliableBroadcast; + default: + throw new Exception($"No protocol type for request type {requestType}"); + } + } + + private IMessageRequestHandler RegisterMessageHandler(RequestType type) + { + int validators, msgPerValidator; + switch (type) + { + case RequestType.Aux: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Bval: + validators = _validatorsCount; + msgPerValidator = 2; + break; + case RequestType.Coin: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Conf: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Decrypted: + validators = _validatorsCount; + msgPerValidator = _validatorsCount; + break; + case RequestType.Echo: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Val: + validators = 1; + msgPerValidator = 1; + break; + case RequestType.Ready: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.SignedHeader: + validators = _validatorsCount; + msgPerValidator = 1; + break; + default: + throw new Exception($"RegisterMessageHandler Not implemented for request type {type}"); + } + + return new MessageRequestHandler(type, validators, msgPerValidator); + } + } +} \ No newline at end of file From bce739ae2a205dbc3a25cb3d3243b09fa2618bb9 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:22:14 +0600 Subject: [PATCH 095/133] =?UTF-8?q?added=20request=20manager=20to=20direct?= =?UTF-8?q?=20requests=20to=20=C2=96appropriate=20protocol=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RequestProtocols/IRequestManager.cs | 12 ++++ .../RequestProtocols/RequestManager.cs | 61 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/IRequestManager.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/RequestManager.cs diff --git a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs new file mode 100644 index 000000000..4423247c5 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs @@ -0,0 +1,12 @@ +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols +{ + public interface IRequestManager + { + void Terminate(); + void SetValidators(int validatorsCount); + void RegisterProtocol(IProtocolIdentifier protocolId); + void MessageReceived(IProtocolIdentifier protocolId, int from, ConsensusMessage msg); + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs new file mode 100644 index 000000000..6b71f7aed --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using Lachain.Consensus.RequestProtocols.Protocols; +using Lachain.Logger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols +{ + public class RequestManager : IRequestManager + { + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private int _validators = -1; + private readonly long _era; + private readonly IConsensusBroadcaster _broadcaster; + private readonly IDictionary _protocolHandler; + public RequestManager(IConsensusBroadcaster broadcaster, long era) + { + _broadcaster = broadcaster; + _era = era; + _protocolHandler = new ConcurrentDictionary(); + } + + public void Terminate() + { + foreach (var (_, handler) in _protocolHandler) + { + handler.Terminate(); + } + _protocolHandler.Clear(); + Logger.LogTrace($"Request manager for era {_era} terminated"); + } + + public void SetValidators(int validatorsCount) + { + _validators = validatorsCount; + } + + public void RegisterProtocol(IProtocolIdentifier protocolId) + { + if (_validators == -1) + throw new Exception($"RequestManager not ready yet, validators count {_validators}"); + if (_protocolHandler.TryGetValue(protocolId, out var _)) + { + throw new Exception($"Protocol handler for protocolId {protocolId} already registered"); + } + + _protocolHandler[protocolId] = new ProtocolRequestHandler(protocolId, _validators); + } + + public void MessageReceived(IProtocolIdentifier protocolId, int from, ConsensusMessage msg) + { + if (_protocolHandler.TryGetValue(protocolId, out var handler)) + { + handler.MessageReceived(from, msg); + } + else + throw new Exception($"Protocol handler for protocolId {protocolId} not registered but External message is received"); + } + } +} \ No newline at end of file From 218142e41e3977419793a5fde64476225ce43f64 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:22:54 +0600 Subject: [PATCH 096/133] added request manager in era broadcaster and registered protocols in request manager --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 0ac9981bc..3748224a9 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -11,6 +11,7 @@ using Lachain.Consensus.HoneyBadger; using Lachain.Consensus.Messages; using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RequestProtocols; using Lachain.Consensus.RootProtocol; using Lachain.Core.Blockchain.Hardfork; using Lachain.Core.Blockchain.SystemContracts; @@ -39,6 +40,7 @@ public class EraBroadcaster : IConsensusBroadcaster private readonly IPrivateWallet _wallet; private readonly IValidatorAttendanceRepository _validatorAttendanceRepository; private readonly IMessageEnvelopeRepositoryManager _messageEnvelopeRepositoryManager; + private readonly IRequestManager _requestManager; private bool _terminated; private int _myIdx; private IPublicConsensusKeySet? _validators; @@ -77,12 +79,14 @@ public EraBroadcaster( _validatorAttendanceRepository = validatorAttendanceRepository; _messageEnvelopeRepositoryManager = messageEnvelopeRepositoryManager; _blockProducer = blockProducer; + _requestManager = new RequestManager(this, _era); } public void SetValidatorKeySet(IPublicConsensusKeySet keySet) { _validators = keySet; _myIdx = _validators.GetValidatorIndex(_wallet.EcdsaKeyPair.PublicKey); + _requestManager.SetValidators(_validators.N); } public void RegisterProtocols(IEnumerable protocols) @@ -91,6 +95,7 @@ public void RegisterProtocols(IEnumerable protocols) { _registry[protocol.Id] = protocol; protocol._receivedExternalMessage += PersistExternalMessae; + _requestManager.RegisterProtocol(protocol.Id); } } From d36b15dc280a9167ddd27060eb147876d729de33 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 00:26:36 +0600 Subject: [PATCH 097/133] terminating request manager --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 3748224a9..78643b2c9 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -502,6 +502,8 @@ public void Terminate() { _postponedMessages.Clear(); } + + _requestManager.Terminate(); } // Each ProtocolId is created only once to prevent spamming, Protocols are mapped against ProtocolId, so each From b7f3fc6fcbdde74594aba08a5304b5ced24cdfbb Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 02:24:10 +0600 Subject: [PATCH 098/133] fixed test: creating new array to get iterator --- src/Lachain.Storage/RocksDbContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Storage/RocksDbContext.cs b/src/Lachain.Storage/RocksDbContext.cs index 43d0ce7fe..bd8d7581b 100644 --- a/src/Lachain.Storage/RocksDbContext.cs +++ b/src/Lachain.Storage/RocksDbContext.cs @@ -97,7 +97,7 @@ public void Delete(byte[] key) private Iterator? GetIterator(byte[] key, ReadOptions? readOptions) { - return _rocksDb.NewIterator(null, readOptions).Seek(key); + return _rocksDb.NewIterator(null, readOptions).Seek(new List(key).ToArray()); } public void CompactAll() From e4858071e6ff53870d2a631a6ecc19b57b855300 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 20:57:50 +0600 Subject: [PATCH 099/133] added termination --- .../RequestProtocols/Messages/MessageRequestHandler.cs | 8 +++++++- .../RequestProtocols/Protocols/ProtocolRequestHandler.cs | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index f4bab646d..0fa824939 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -18,6 +18,7 @@ public class MessageRequestHandler : IMessageRequestHandler private readonly RequestType _type; private readonly int _validators; private readonly int _msgPerValidator; + private bool _terminated = false; private int _remainingMsges; private readonly Queue<(int,int)> _messageRequests; public RequestType Type => _type; @@ -43,12 +44,17 @@ public MessageRequestHandler(RequestType type, int validatorCount, int msgPerVal public void Terminate() { + if (_terminated) + return; + _terminated = true; _messageRequests.Clear(); _status = new MessageStatus[0][]; } public void MessageReceived(int from, ConsensusMessage msg) { + if (_terminated) + return; var type = GetRequestTypeForMessageType(msg); if (type != _type) throw new Exception($"message type {type} routed to message handler {_type}"); @@ -146,7 +152,7 @@ public bool IsProtocolComplete() public List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount) { var requests = new List<(ConsensusMessage, int)>(); - if (IsProtocolComplete()) return requests; + if (IsProtocolComplete() || _terminated) return requests; if (requestCount > _remainingMsges) requestCount = _remainingMsges; diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index fd360eb36..ac173632d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -19,6 +19,7 @@ public class ProtocolRequestHandler : IProtocolRequestHandler private readonly ProtocolType _type; private readonly int _validatorsCount; private readonly List _messageHandlers; + private bool _terminated = false; public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) { _validatorsCount = validatorsCount; @@ -37,6 +38,9 @@ public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) public void Terminate() { + if (_terminated) + return; + _terminated = true; foreach (var handler in _messageHandlers) handler.Terminate(); _messageHandlers.Clear(); @@ -45,6 +49,8 @@ public void Terminate() public void MessageReceived(int from, ConsensusMessage msg) { + if (_terminated) + return; var type = MessageRequestHandler.GetRequestTypeForMessageType(msg); foreach (var handler in _messageHandlers) { @@ -58,6 +64,8 @@ public void MessageReceived(int from, ConsensusMessage msg) public List<(ConsensusMessage, int)> GetRequests(int requestCount) { var allRequests = new List<(ConsensusMessage, int)>(); + if (_terminated) + return allRequests; foreach (var handler in _messageHandlers) { var requests = handler.GetRequests(_protocolId, requestCount); From 312269c0082f579ffed328f55575e26a362bf3e9 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 21:11:23 +0600 Subject: [PATCH 100/133] using static class for utilities --- .../Messages/IMessageRequestHandler.cs | 2 +- .../Messages/MessageRequestHandler.cs | 30 +--------- .../RequestProtocols/Messages/MessageUtils.cs | 35 +++++++++++ .../Protocols/ProtocolRequestHandler.cs | 54 ++--------------- .../Protocols/ProtocolUtils.cs | 59 +++++++++++++++++++ .../RequestProtocols/RequestManager.cs | 8 +++ 6 files changed, 108 insertions(+), 80 deletions(-) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/MessageUtils.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs index 7b7064331..c86a1def2 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs @@ -7,7 +7,7 @@ public interface IMessageRequestHandler { RequestType Type { get; } void Terminate(); - void MessageReceived(int from, ConsensusMessage msg); + void MessageReceived(int from, ConsensusMessage msg, RequestType type); bool IsProtocolComplete(); List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount); } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 0fa824939..d85db6a1b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -51,11 +51,10 @@ public void Terminate() _status = new MessageStatus[0][]; } - public void MessageReceived(int from, ConsensusMessage msg) + public void MessageReceived(int from, ConsensusMessage msg, RequestType type) { if (_terminated) return; - var type = GetRequestTypeForMessageType(msg); if (type != _type) throw new Exception($"message type {type} routed to message handler {_type}"); switch (type) @@ -367,32 +366,5 @@ private ConsensusMessage CreateSignedHeaderRequest(RootProtocolId _) } }; } - - public static RequestType GetRequestTypeForMessageType(ConsensusMessage msg) - { - switch (msg.PayloadCase) - { - case ConsensusMessage.PayloadOneofCase.Aux: - return RequestType.Aux;; - case ConsensusMessage.PayloadOneofCase.Bval: - return RequestType.Bval; - case ConsensusMessage.PayloadOneofCase.Coin: - return RequestType.Coin; - case ConsensusMessage.PayloadOneofCase.Conf: - return RequestType.Conf; - case ConsensusMessage.PayloadOneofCase.Decrypted: - return RequestType.Decrypted; - case ConsensusMessage.PayloadOneofCase.EchoMessage: - return RequestType.Echo; - case ConsensusMessage.PayloadOneofCase.ReadyMessage: - return RequestType.Ready; - case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage: - return RequestType.SignedHeader; - case ConsensusMessage.PayloadOneofCase.ValMessage: - return RequestType.Val; - default: - throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); - } - } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageUtils.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageUtils.cs new file mode 100644 index 000000000..3554f01f5 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageUtils.cs @@ -0,0 +1,35 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public static class MessageUtils + { + public static RequestType GetRequestTypeForMessageType(ConsensusMessage msg) + { + switch (msg.PayloadCase) + { + case ConsensusMessage.PayloadOneofCase.Aux: + return RequestType.Aux;; + case ConsensusMessage.PayloadOneofCase.Bval: + return RequestType.Bval; + case ConsensusMessage.PayloadOneofCase.Coin: + return RequestType.Coin; + case ConsensusMessage.PayloadOneofCase.Conf: + return RequestType.Conf; + case ConsensusMessage.PayloadOneofCase.Decrypted: + return RequestType.Decrypted; + case ConsensusMessage.PayloadOneofCase.EchoMessage: + return RequestType.Echo; + case ConsensusMessage.PayloadOneofCase.ReadyMessage: + return RequestType.Ready; + case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage: + return RequestType.SignedHeader; + case ConsensusMessage.PayloadOneofCase.ValMessage: + return RequestType.Val; + default: + throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); + } + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index ac173632d..6f52bd511 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -24,12 +24,12 @@ public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) { _validatorsCount = validatorsCount; _protocolId = id; - _type = GetMyType(id); + _type = ProtocolUtils.GetProtocolType(id); _messageHandlers = new List(); var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); foreach (var type in requestTypes) { - if (GetProtocolTypeForRequestType(type) == _type) + if (ProtocolUtils.GetProtocolTypeForRequestType(type) == _type) { _messageHandlers.Add(RegisterMessageHandler(type)); } @@ -51,12 +51,12 @@ public void MessageReceived(int from, ConsensusMessage msg) { if (_terminated) return; - var type = MessageRequestHandler.GetRequestTypeForMessageType(msg); + var type = MessageUtils.GetRequestTypeForMessageType(msg); foreach (var handler in _messageHandlers) { if (handler.Type == type) { - handler.MessageReceived(from, msg); + handler.MessageReceived(from, msg, type); } } } @@ -75,52 +75,6 @@ public void MessageReceived(int from, ConsensusMessage msg) return allRequests; } - private ProtocolType GetMyType(IProtocolIdentifier id) - { - switch (id) - { - case RootProtocolId _: - return ProtocolType.Root; - case HoneyBadgerId _: - return ProtocolType.HoneyBadger; - case ReliableBroadcastId _: - return ProtocolType.ReliableBroadcast; - case BinaryBroadcastId _: - return ProtocolType.BinaryBroadcast; - case CoinId _: - return ProtocolType.CommonCoin; - default: - throw new Exception($"Not implemented type for protocol id {id}"); - } - } - - private ProtocolType GetProtocolTypeForRequestType(RequestType requestType) - { - switch (requestType) - { - case RequestType.Aux: - return ProtocolType.BinaryBroadcast; - case RequestType.Bval: - return ProtocolType.BinaryBroadcast; - case RequestType.Coin: - return ProtocolType.CommonCoin; - case RequestType.Conf: - return ProtocolType.BinaryBroadcast; - case RequestType.Decrypted: - return ProtocolType.HoneyBadger; - case RequestType.Echo: - return ProtocolType.ReliableBroadcast; - case RequestType.Ready: - return ProtocolType.ReliableBroadcast; - case RequestType.SignedHeader: - return ProtocolType.Root; - case RequestType.Val: - return ProtocolType.ReliableBroadcast; - default: - throw new Exception($"No protocol type for request type {requestType}"); - } - } - private IMessageRequestHandler RegisterMessageHandler(RequestType type) { int validators, msgPerValidator; diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs new file mode 100644 index 000000000..40b8f23f6 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs @@ -0,0 +1,59 @@ +using System; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RequestProtocols.Messages; +using Lachain.Consensus.RootProtocol; + +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public static class ProtocolUtils + { + public static ProtocolType GetProtocolType(IProtocolIdentifier id) + { + switch (id) + { + case RootProtocolId _: + return ProtocolType.Root; + case HoneyBadgerId _: + return ProtocolType.HoneyBadger; + case ReliableBroadcastId _: + return ProtocolType.ReliableBroadcast; + case BinaryBroadcastId _: + return ProtocolType.BinaryBroadcast; + case CoinId _: + return ProtocolType.CommonCoin; + default: + throw new Exception($"Not implemented type for protocol id {id}"); + } + } + + public static ProtocolType GetProtocolTypeForRequestType(RequestType requestType) + { + switch (requestType) + { + case RequestType.Aux: + return ProtocolType.BinaryBroadcast; + case RequestType.Bval: + return ProtocolType.BinaryBroadcast; + case RequestType.Coin: + return ProtocolType.CommonCoin; + case RequestType.Conf: + return ProtocolType.BinaryBroadcast; + case RequestType.Decrypted: + return ProtocolType.HoneyBadger; + case RequestType.Echo: + return ProtocolType.ReliableBroadcast; + case RequestType.Ready: + return ProtocolType.ReliableBroadcast; + case RequestType.SignedHeader: + return ProtocolType.Root; + case RequestType.Val: + return ProtocolType.ReliableBroadcast; + default: + throw new Exception($"No protocol type for request type {requestType}"); + } + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index 6b71f7aed..6a478e61b 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -14,6 +14,7 @@ public class RequestManager : IRequestManager private readonly long _era; private readonly IConsensusBroadcaster _broadcaster; private readonly IDictionary _protocolHandler; + private bool _terminated = false; public RequestManager(IConsensusBroadcaster broadcaster, long era) { _broadcaster = broadcaster; @@ -23,6 +24,9 @@ public RequestManager(IConsensusBroadcaster broadcaster, long era) public void Terminate() { + if (_terminated) + return; + _terminated = true; foreach (var (_, handler) in _protocolHandler) { handler.Terminate(); @@ -38,6 +42,8 @@ public void SetValidators(int validatorsCount) public void RegisterProtocol(IProtocolIdentifier protocolId) { + if (_terminated) + return; if (_validators == -1) throw new Exception($"RequestManager not ready yet, validators count {_validators}"); if (_protocolHandler.TryGetValue(protocolId, out var _)) @@ -50,6 +56,8 @@ public void RegisterProtocol(IProtocolIdentifier protocolId) public void MessageReceived(IProtocolIdentifier protocolId, int from, ConsensusMessage msg) { + if (_terminated) + return; if (_protocolHandler.TryGetValue(protocolId, out var handler)) { handler.MessageReceived(from, msg); From 3811725929919801f9d61a748dd324ccd0bd1f7d Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:20:21 +0600 Subject: [PATCH 101/133] added separate classes for each messagy type --- .../Messages/Requests/AuxRequest.cs | 39 +++++++++++++++++++ .../Messages/Requests/BValRequest.cs | 39 +++++++++++++++++++ .../Messages/Requests/CoinRequest.cs | 39 +++++++++++++++++++ .../Messages/Requests/ConfRequest.cs | 39 +++++++++++++++++++ .../Messages/Requests/DecryptedRequest.cs | 38 ++++++++++++++++++ .../Messages/Requests/EchoRequest.cs | 38 ++++++++++++++++++ .../Messages/Requests/ReadyRequest.cs | 38 ++++++++++++++++++ .../Messages/Requests/SignedHeaderRequest.cs | 35 +++++++++++++++++ .../Messages/Requests/ValRequest.cs | 38 ++++++++++++++++++ 9 files changed, 343 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs new file mode 100644 index 000000000..ef3139f7a --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs @@ -0,0 +1,39 @@ +using System; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class AuxRequest : MessageRequestHandler + { + public AuxRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Aux) + throw new Exception($"{msg.PayloadCase} message routed to Aux request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Aux request"); + var auxRequest = new RequestAuxMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestAux = auxRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs new file mode 100644 index 000000000..627bbca1d --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs @@ -0,0 +1,39 @@ +using System; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class BValRequest : MessageRequestHandler + { + public BValRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Bval) + throw new Exception($"{msg.PayloadCase} message routed to Bval request"); + MessageReceived(from, msg.Bval.Value ? 1 : 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Bval request"); + var bvalRequest = new RequestBValMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestBval = bvalRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs new file mode 100644 index 000000000..4076a7bf8 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs @@ -0,0 +1,39 @@ +using System; +using Lachain.Consensus.CommonCoin; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class CoinRequest : MessageRequestHandler + { + public CoinRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Coin) + throw new Exception($"{msg.PayloadCase} message routed to Coin request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as CoinId ?? throw new Exception($"wrong protcolId {protocolId} for Coin request"); + var coinRequest = new RequestCommonCoinMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestCoin = coinRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs new file mode 100644 index 000000000..8099eca90 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs @@ -0,0 +1,39 @@ +using System; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class ConfRequest : MessageRequestHandler + { + public ConfRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Conf) + throw new Exception($"{msg.PayloadCase} message routed to Conf request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Conf request"); + var confRequest = new RequestConfMessage + { + Agreement = (int) id.Agreement, + Epoch = (int) id.Epoch + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestConf = confRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs new file mode 100644 index 000000000..d409d1fed --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs @@ -0,0 +1,38 @@ +using System; +using Lachain.Consensus.HoneyBadger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class DecryptedRequest : MessageRequestHandler + { + public DecryptedRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) + throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); + MessageReceived(from, msg.Decrypted.ShareId); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) + { + var id = protocolId as HoneyBadgerId ?? throw new Exception($"wrong protcolId {protocolId} for Decrypted request"); + var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage + { + ShareId = msgId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestDecrypted = decryptedRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs new file mode 100644 index 000000000..c9b19a068 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs @@ -0,0 +1,38 @@ +using System; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class EchoRequest : MessageRequestHandler + { + public EchoRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.EchoMessage) + throw new Exception($"{msg.PayloadCase} message routed to Echo request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Echo request"); + var echoRequest = new RequestECHOMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestEcho = echoRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs new file mode 100644 index 000000000..360471bac --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs @@ -0,0 +1,38 @@ +using System; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class ReadyRequest : MessageRequestHandler + { + public ReadyRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ReadyMessage) + throw new Exception($"{msg.PayloadCase} message routed to Ready request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Ready request"); + var readyRequest = new RequestReadyMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestReady = readyRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs new file mode 100644 index 000000000..44ddf294e --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs @@ -0,0 +1,35 @@ +using System; +using Lachain.Consensus.RootProtocol; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class SignedHeaderRequest : MessageRequestHandler + { + public SignedHeaderRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.SignedHeaderMessage) + throw new Exception($"{msg.PayloadCase} message routed to Signed Header request"); + MessageReceived(from, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as RootProtocolId ?? throw new Exception($"wrong protcolId {protocolId} for Signed Header request"); + var headerRequest = new RequestSignedHeaderMessage(); + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestSignedHeader = headerRequest + } + }; + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs new file mode 100644 index 000000000..0a8862363 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs @@ -0,0 +1,38 @@ +using System; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Requests +{ + public class ValRequest : MessageRequestHandler + { + public ValRequest(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int _from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ValMessage) + throw new Exception($"{msg.PayloadCase} message routed to Val request"); + MessageReceived(0, 0); + } + + public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + { + var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Val request"); + var valRequest = new RequestValMessage + { + SenderId = id.SenderId + }; + return new ConsensusMessage + { + RequestConsensus = new RequestConsensusMessage + { + RequestVal = valRequest + } + }; + } + } +} \ No newline at end of file From 54fa681088a5270f7cba5edfdc4a64487374f692 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:20:57 +0600 Subject: [PATCH 102/133] made abstract class and added sync attr --- .../Messages/MessageRequestHandler.cs | 274 +----------------- 1 file changed, 9 insertions(+), 265 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index d85db6a1b..5ff41d057 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -1,16 +1,12 @@ using System; using System.Collections.Generic; -using Lachain.Consensus.BinaryAgreement; -using Lachain.Consensus.CommonCoin; -using Lachain.Consensus.HoneyBadger; -using Lachain.Consensus.ReliableBroadcast; -using Lachain.Consensus.RootProtocol; +using System.Runtime.CompilerServices; using Lachain.Logger; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages { - public class MessageRequestHandler : IMessageRequestHandler + public abstract class MessageRequestHandler : IMessageRequestHandler { private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); private MessageStatus[][] _status; @@ -42,6 +38,7 @@ public MessageRequestHandler(RequestType type, int validatorCount, int msgPerVal _remainingMsges = _msgCount; } + [MethodImpl(MethodImplOptions.Synchronized)] public void Terminate() { if (_terminated) @@ -51,103 +48,29 @@ public void Terminate() _status = new MessageStatus[0][]; } + [MethodImpl(MethodImplOptions.Synchronized)] public void MessageReceived(int from, ConsensusMessage msg, RequestType type) { if (_terminated) return; if (type != _type) throw new Exception($"message type {type} routed to message handler {_type}"); - switch (type) - { - case RequestType.Aux: - HandleAuxMessage(from, msg.Aux); - break; - case RequestType.Bval: - HandleBValMessage(from, msg.Bval); - break; - case RequestType.Coin: - HandleCoinMessage(from, msg.Coin); - break; - case RequestType.Conf: - HandleConfMessage(from, msg.Conf); - break; - case RequestType.Decrypted: - HandleDecryptedMessage(from, msg.Decrypted); - break; - case RequestType.Echo: - HandleEchoMessage(from, msg.EchoMessage); - break; - case RequestType.Ready: - HandleReadyMessage(from, msg.ReadyMessage); - break; - case RequestType.SignedHeader: - HandleSignedHeaderMessage(from, msg.SignedHeaderMessage); - break; - case RequestType.Val: - HandleValMessage(from, msg.ValMessage); - break; - default: - throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); - } + HandleReceivedMessage(from, msg); } - private void MessageReceived(int validatorId, int msgId) + public void MessageReceived(int validatorId, int msgId) { if (_status[validatorId][msgId] != MessageStatus.Received) _remainingMsges--; _status[validatorId][msgId] = MessageStatus.Received; } - private void HandleAuxMessage(int from, AuxMessage _) - { - MessageReceived(from, 0); - } - - private void HandleBValMessage(int from, BValMessage msg) - { - MessageReceived(from, msg.Value ? 1 : 0); - } - - private void HandleConfMessage(int from, ConfMessage _) - { - MessageReceived(from, 0); - } - - private void HandleCoinMessage(int from, CommonCoinMessage _) - { - MessageReceived(from, 0); - } - - private void HandleEchoMessage(int from, ECHOMessage _) - { - MessageReceived(from, 0); - } - - private void HandleReadyMessage(int from, ReadyMessage _) - { - MessageReceived(from, 0); - } - - private void HandleValMessage(int _from, ValMessage _) - { - MessageReceived(0, 0); - } - - private void HandleDecryptedMessage(int from, TPKEPartiallyDecryptedShareMessage msg) - { - MessageReceived(from, msg.ShareId); - } - - private void HandleSignedHeaderMessage(int from, SignedHeaderMessage _) - { - MessageReceived(from, 0); - } - public bool IsProtocolComplete() { return _remainingMsges == _msgCount; } + [MethodImpl(MethodImplOptions.Synchronized)] public List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount) { var requests = new List<(ConsensusMessage, int)>(); @@ -185,186 +108,7 @@ public bool IsProtocolComplete() return requests; } - private ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) - { - var wrongProtocolWarning = $"wrong protcolId {protocolId} for request type {_type}"; - switch (_type) - { - case RequestType.Aux: - return CreateAuxRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Bval: - return CreateBValRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Conf: - return CreateConfRequest(protocolId as BinaryBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Coin: - return CreateCoinRequest(protocolId as CoinId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Decrypted: - return CreateDecryptedRequest(protocolId as HoneyBadgerId ?? throw new Exception(wrongProtocolWarning), msgId); - case RequestType.Echo: - return CreateEchoRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Ready: - return CreateReadyRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.Val: - return CreateValRequest(protocolId as ReliableBroadcastId ?? throw new Exception(wrongProtocolWarning)); - case RequestType.SignedHeader: - return CreateSignedHeaderRequest(protocolId as RootProtocolId ?? throw new Exception(wrongProtocolWarning)); - default: - throw new Exception($"Not implemented request type {_type}"); - } - } - - private ConsensusMessage CreateAuxRequest(BinaryBroadcastId id) - { - if (_type != RequestType.Aux) - throw new Exception($"Aux request routed to {_type} message handler"); - var auxRequest = new RequestAuxMessage - { - Agreement = (int) id.Agreement, - Epoch = (int) id.Epoch - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestAux = auxRequest - } - }; - } - - private ConsensusMessage CreateBValRequest(BinaryBroadcastId id) - { - if (_type != RequestType.Bval) - throw new Exception($"BVal request routed to {_type} message handler"); - var bvalRequest = new RequestBValMessage - { - Agreement = (int) id.Agreement, - Epoch = (int) id.Epoch - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestBval = bvalRequest - } - }; - } - - private ConsensusMessage CreateConfRequest(BinaryBroadcastId id) - { - if (_type != RequestType.Conf) - throw new Exception($"Conf request routed to {_type} message handler"); - var confRequest = new RequestConfMessage - { - Agreement = (int) id.Agreement, - Epoch = (int) id.Epoch - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestConf = confRequest - } - }; - } - - private ConsensusMessage CreateCoinRequest(CoinId id) - { - if (_type != RequestType.Coin) - throw new Exception($"Coin request routed to {_type} message handler"); - var coinRequest = new RequestCommonCoinMessage - { - Agreement = (int) id.Agreement, - Epoch = (int) id.Epoch - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestCoin = coinRequest - } - }; - } - - private ConsensusMessage CreateValRequest(ReliableBroadcastId id) - { - if (_type != RequestType.Val) - throw new Exception($"Val request routed to {_type} message handler"); - var valRequest = new RequestValMessage - { - SenderId = id.SenderId - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestVal = valRequest - } - }; - } - - private ConsensusMessage CreateEchoRequest(ReliableBroadcastId id) - { - if (_type != RequestType.Echo) - throw new Exception($"Echo request routed to {_type} message handler"); - var echoRequest = new RequestECHOMessage - { - SenderId = id.SenderId - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestEcho = echoRequest - } - }; - } - - private ConsensusMessage CreateReadyRequest(ReliableBroadcastId id) - { - if (_type != RequestType.Ready) - throw new Exception($"Ready request routed to {_type} message handler"); - var readyRequest = new RequestReadyMessage - { - SenderId = id.SenderId - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestReady = readyRequest - } - }; - } - - private ConsensusMessage CreateDecryptedRequest(HoneyBadgerId _, int shareId) - { - if (_type != RequestType.Decrypted) - throw new Exception($"Decrypted request routed to {_type} message handler"); - var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage - { - ShareId = shareId - }; - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestDecrypted = decryptedRequest - } - }; - } - - private ConsensusMessage CreateSignedHeaderRequest(RootProtocolId _) - { - if (_type != RequestType.SignedHeader) - throw new Exception($"Signed header request routed to {_type} message handler"); - var headerRequest = new RequestSignedHeaderMessage(); - return new ConsensusMessage - { - RequestConsensus = new RequestConsensusMessage - { - RequestSignedHeader = headerRequest - } - }; - } + public abstract ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId); + public abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file From 82dc679c53173717acc99087a320e57565bb141b Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:21:48 +0600 Subject: [PATCH 103/133] updated registration and using dictionary instead of list --- .../Protocols/ProtocolRequestHandler.cs | 72 +++++++------------ 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index 6f52bd511..6b527732d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -1,12 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.BinaryAgreement; -using Lachain.Consensus.CommonCoin; -using Lachain.Consensus.HoneyBadger; -using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RequestProtocols.Messages; -using Lachain.Consensus.RootProtocol; +using Lachain.Consensus.RequestProtocols.Messages.Requests; using Lachain.Logger; using Lachain.Proto; @@ -18,20 +15,24 @@ public class ProtocolRequestHandler : IProtocolRequestHandler private readonly IProtocolIdentifier _protocolId; private readonly ProtocolType _type; private readonly int _validatorsCount; - private readonly List _messageHandlers; + private readonly IDictionary _messageHandlers; private bool _terminated = false; public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) { _validatorsCount = validatorsCount; _protocolId = id; _type = ProtocolUtils.GetProtocolType(id); - _messageHandlers = new List(); + _messageHandlers = new ConcurrentDictionary(); var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); - foreach (var type in requestTypes) + foreach (var requestType in requestTypes) { - if (ProtocolUtils.GetProtocolTypeForRequestType(type) == _type) + if (ProtocolUtils.GetProtocolTypeForRequestType(requestType) == _type) { - _messageHandlers.Add(RegisterMessageHandler(type)); + if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + { + throw new Exception($"{requestType} already registered with handler {handler.Type} and trying to register again"); + } + _messageHandlers[(byte) requestType] = RegisterMessageHandler(requestType); } } } @@ -41,7 +42,7 @@ public void Terminate() if (_terminated) return; _terminated = true; - foreach (var handler in _messageHandlers) + foreach (var (_, handler) in _messageHandlers) handler.Terminate(); _messageHandlers.Clear(); Logger.LogTrace($"Protocol handler for protocol {_protocolId} terminated"); @@ -52,13 +53,11 @@ public void MessageReceived(int from, ConsensusMessage msg) if (_terminated) return; var type = MessageUtils.GetRequestTypeForMessageType(msg); - foreach (var handler in _messageHandlers) + if (_messageHandlers.TryGetValue((byte) type, out var handler)) { - if (handler.Type == type) - { - handler.MessageReceived(from, msg, type); - } + handler.MessageReceived(from, msg, type); } + else throw new Exception($"MessageRequestHandler {type} not registered"); } public List<(ConsensusMessage, int)> GetRequests(int requestCount) @@ -66,7 +65,7 @@ public void MessageReceived(int from, ConsensusMessage msg) var allRequests = new List<(ConsensusMessage, int)>(); if (_terminated) return allRequests; - foreach (var handler in _messageHandlers) + foreach (var (_, handler) in _messageHandlers) { var requests = handler.GetRequests(_protocolId, requestCount); requestCount -= requests.Count; @@ -77,50 +76,29 @@ public void MessageReceived(int from, ConsensusMessage msg) private IMessageRequestHandler RegisterMessageHandler(RequestType type) { - int validators, msgPerValidator; switch (type) { case RequestType.Aux: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new AuxRequest(type, _validatorsCount, 1); case RequestType.Bval: - validators = _validatorsCount; - msgPerValidator = 2; - break; + return new BValRequest(type, _validatorsCount, 2); case RequestType.Coin: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new CoinRequest(type, _validatorsCount, 1); case RequestType.Conf: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new ConfRequest(type, _validatorsCount, 1); case RequestType.Decrypted: - validators = _validatorsCount; - msgPerValidator = _validatorsCount; - break; + return new DecryptedRequest(type, _validatorsCount, _validatorsCount); case RequestType.Echo: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new EchoRequest(type, _validatorsCount, 1); case RequestType.Val: - validators = 1; - msgPerValidator = 1; - break; + return new ValRequest(type, 1, 1); case RequestType.Ready: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new ReadyRequest(type, _validatorsCount, 1); case RequestType.SignedHeader: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new SignedHeaderRequest(type, _validatorsCount, 1); default: throw new Exception($"RegisterMessageHandler Not implemented for request type {type}"); } - - return new MessageRequestHandler(type, validators, msgPerValidator); } } } \ No newline at end of file From 096678771eceb60a610974795ca733390d11b47e Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 18:20:19 +0600 Subject: [PATCH 104/133] made abstract class constructor protected --- .../RequestProtocols/Messages/MessageRequestHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 5ff41d057..81280b7e5 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -18,7 +18,7 @@ public abstract class MessageRequestHandler : IMessageRequestHandler private int _remainingMsges; private readonly Queue<(int,int)> _messageRequests; public RequestType Type => _type; - public MessageRequestHandler(RequestType type, int validatorCount, int msgPerValidator) + protected MessageRequestHandler(RequestType type, int validatorCount, int msgPerValidator) { _type = type; _validators = validatorCount; From 0789f344a02dceb6690ca1fb23a9fcd53a920dc2 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:50:04 +0600 Subject: [PATCH 105/133] made abstract methods protected --- .../RequestProtocols/Messages/MessageRequestHandler.cs | 6 +++--- .../RequestProtocols/Messages/Requests/AuxRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/BValRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/CoinRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/ConfRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/DecryptedRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/EchoRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/ReadyRequest.cs | 4 ++-- .../Messages/Requests/SignedHeaderRequest.cs | 4 ++-- .../RequestProtocols/Messages/Requests/ValRequest.cs | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 81280b7e5..36d5884b2 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -58,7 +58,7 @@ public void MessageReceived(int from, ConsensusMessage msg, RequestType type) HandleReceivedMessage(from, msg); } - public void MessageReceived(int validatorId, int msgId) + protected void MessageReceived(int validatorId, int msgId) { if (_status[validatorId][msgId] != MessageStatus.Received) _remainingMsges--; @@ -108,7 +108,7 @@ public bool IsProtocolComplete() return requests; } - public abstract ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId); - public abstract void HandleReceivedMessage(int from, ConsensusMessage msg); + protected abstract ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId); + protected abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs index ef3139f7a..4fd034080 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs @@ -12,14 +12,14 @@ public AuxRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Aux) throw new Exception($"{msg.PayloadCase} message routed to Aux request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Aux request"); var auxRequest = new RequestAuxMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs index 627bbca1d..82a22784a 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs @@ -12,14 +12,14 @@ public BValRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Bval) throw new Exception($"{msg.PayloadCase} message routed to Bval request"); MessageReceived(from, msg.Bval.Value ? 1 : 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Bval request"); var bvalRequest = new RequestBValMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs index 4076a7bf8..3e94a436b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs @@ -12,14 +12,14 @@ public CoinRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Coin) throw new Exception($"{msg.PayloadCase} message routed to Coin request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as CoinId ?? throw new Exception($"wrong protcolId {protocolId} for Coin request"); var coinRequest = new RequestCommonCoinMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs index 8099eca90..808399060 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs @@ -12,14 +12,14 @@ public ConfRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Conf) throw new Exception($"{msg.PayloadCase} message routed to Conf request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Conf request"); var confRequest = new RequestConfMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs index d409d1fed..9d06fab86 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs @@ -12,14 +12,14 @@ public DecryptedRequest(RequestType type, int validatorCount, int msgPerValidato } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); MessageReceived(from, msg.Decrypted.ShareId); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) { var id = protocolId as HoneyBadgerId ?? throw new Exception($"wrong protcolId {protocolId} for Decrypted request"); var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs index c9b19a068..9e64d25cc 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs @@ -12,14 +12,14 @@ public EchoRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.EchoMessage) throw new Exception($"{msg.PayloadCase} message routed to Echo request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Echo request"); var echoRequest = new RequestECHOMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs index 360471bac..382b0f19c 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs @@ -12,14 +12,14 @@ public ReadyRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ReadyMessage) throw new Exception($"{msg.PayloadCase} message routed to Ready request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Ready request"); var readyRequest = new RequestReadyMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs index 44ddf294e..15b3a023f 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs @@ -12,14 +12,14 @@ public SignedHeaderRequest(RequestType type, int validatorCount, int msgPerValid } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.SignedHeaderMessage) throw new Exception($"{msg.PayloadCase} message routed to Signed Header request"); MessageReceived(from, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as RootProtocolId ?? throw new Exception($"wrong protcolId {protocolId} for Signed Header request"); var headerRequest = new RequestSignedHeaderMessage(); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs index 0a8862363..7a66fa3cd 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs @@ -12,14 +12,14 @@ public ValRequest(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int _from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int _from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ValMessage) throw new Exception($"{msg.PayloadCase} message routed to Val request"); MessageReceived(0, 0); } - public override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Val request"); var valRequest = new RequestValMessage From 18da126428062743ce082e92acbcee9ce7cceddf Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 21:17:55 +0600 Subject: [PATCH 106/133] added message resend handler to store and resend sent messages properly --- .../Messages/IMessageResendHandler.cs | 12 ++ .../Messages/MessageResendHandler.cs | 133 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs new file mode 100644 index 000000000..8af1c1973 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public interface IMessageResendHandler + { + RequestType Type { get; } + void Terminate(); + void MessageReceived(int from, ConsensusMessage msg, RequestType type); + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs new file mode 100644 index 000000000..98153da67 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using Lachain.Logger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages +{ + public class MessageResendHandler : IMessageResendHandler + { + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private ConsensusMessage?[][] _sentMessages; + private readonly RequestType _type; + private readonly int _validators; + private readonly int _msgPerValidator; + public RequestType Type => _type; + private bool _terminated = false; + public MessageResendHandler(RequestType type, int validatorCount, int msgPerValidator) + { + _type = type; + _validators = validatorCount; + _msgPerValidator = msgPerValidator; + _sentMessages = new ConsensusMessage?[_validators][]; + for (int i = 0 ; i < _validators ; i++) + { + _sentMessages[i] = new ConsensusMessage?[msgPerValidator]; + for (int j = 0; j < msgPerValidator; j++) + { + _sentMessages[i][j] = null; + } + } + } + + public void Terminate() + { + if (_terminated) + return; + _terminated = true; + _sentMessages = new ConsensusMessage?[0][]; + } + + public void MessageReceived(int from, ConsensusMessage msg, RequestType type) + { + if (_terminated) + return; + if (type != _type) + throw new Exception($"message type {type} routed to MessageResendHandler {_type}"); + switch (type) + { + case RequestType.Aux: + HandleAuxMessage(from, msg); + break; + case RequestType.Bval: + HandleBValMessage(from, msg); + break; + case RequestType.Coin: + HandleCoinMessage(from, msg); + break; + case RequestType.Conf: + HandleConfMessage(from, msg); + break; + case RequestType.Decrypted: + HandleDecryptedMessage(from, msg); + break; + case RequestType.Echo: + HandleEchoMessage(from, msg); + break; + case RequestType.Ready: + HandleReadyMessage(from, msg); + break; + case RequestType.SignedHeader: + HandleSignedHeaderMessage(from, msg); + break; + case RequestType.Val: + HandleValMessage(from, msg); + break; + default: + throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); + } + } + + private void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) + { + if (!(_sentMessages[validatorId][msgId] is null)) + throw new Exception($"Sending duplicate message {msg.ToString()} to validator {validatorId}"); + _sentMessages[validatorId][msgId] = msg; + } + + private void HandleAuxMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleBValMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, msg.Bval.Value ? 1 : 0, msg); + } + + private void HandleConfMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleCoinMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleEchoMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleReadyMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleValMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + + private void HandleDecryptedMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, msg.Decrypted.ShareId, msg); + } + + private void HandleSignedHeaderMessage(int from, ConsensusMessage msg) + { + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file From 12fdd10be416e4731520a1a562d7a45e5449062f Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 21:31:17 +0600 Subject: [PATCH 107/133] added protocol handler for resending msges --- .../Protocols/IProtocolResendHandler.cs | 11 ++ .../Protocols/ProtocolResendHandler.cs | 116 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs new file mode 100644 index 000000000..b906af767 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public interface IProtocolResendHandler + { + void Terminate(); + void MessageReceived(int from, ConsensusMessage msg); + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs new file mode 100644 index 000000000..4bbbf7171 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Lachain.Consensus.BinaryAgreement; +using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.HoneyBadger; +using Lachain.Consensus.ReliableBroadcast; +using Lachain.Consensus.RequestProtocols.Messages; +using Lachain.Consensus.RootProtocol; +using Lachain.Logger; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Protocols +{ + public class ProtocolResendHandler : IProtocolResendHandler + { + private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); + private readonly IProtocolIdentifier _protocolId; + private readonly int _validatorsCount; + private readonly ProtocolType _type; + private readonly List _messageHandlers; + private bool _terminated = false; + public ProtocolResendHandler(IProtocolIdentifier id, int validators) + { + _protocolId = id; + _validatorsCount = validators; + _type = ProtocolUtils.GetProtocolType(id); + _messageHandlers = new List(); + var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); + foreach (var type in requestTypes) + { + if (ProtocolUtils.GetProtocolTypeForRequestType(type) == _type) + { + _messageHandlers.Add(RegisterMessageHandler(type)); + } + } + } + + public void Terminate() + { + if (_terminated) + return; + _terminated = true; + foreach (var handler in _messageHandlers) + { + handler.Terminate(); + } + _messageHandlers.Clear(); + Logger.LogTrace($"ProtocolResendHandler for protocol {_protocolId} terminated"); + } + + public void MessageReceived(int from, ConsensusMessage msg) + { + if (_terminated) + return; + var type = MessageUtils.GetRequestTypeForMessageType(msg); + foreach (var handler in _messageHandlers) + { + if (type == handler.Type) + { + handler.MessageReceived(from, msg, type); + return; + } + } + throw new Exception($"Message type {type} routed to ProtocolResendHandler {_type}"); + } + + private IMessageResendHandler RegisterMessageHandler(RequestType type) + { + int validators, msgPerValidator; + switch (type) + { + case RequestType.Aux: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Bval: + validators = _validatorsCount; + msgPerValidator = 2; + break; + case RequestType.Coin: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Conf: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Decrypted: + validators = _validatorsCount; + msgPerValidator = _validatorsCount; + break; + case RequestType.Echo: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.Val: + validators = 1; + msgPerValidator = 1; + break; + case RequestType.Ready: + validators = _validatorsCount; + msgPerValidator = 1; + break; + case RequestType.SignedHeader: + validators = _validatorsCount; + msgPerValidator = 1; + break; + default: + throw new Exception($"RegisterMessageHandler Not implemented for request type {type}"); + } + + return new MessageResendHandler(type, validators, msgPerValidator); + } + } +} \ No newline at end of file From acff9161cc53e26a8aaa5e99832c158054dfdfc7 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 15 Nov 2022 22:16:03 +0600 Subject: [PATCH 108/133] registered resend protocols in request manager --- .../RequestProtocols/IRequestManager.cs | 1 - .../RequestProtocols/RequestManager.cs | 32 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs index 4423247c5..3a502bc4d 100644 --- a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs @@ -7,6 +7,5 @@ public interface IRequestManager void Terminate(); void SetValidators(int validatorsCount); void RegisterProtocol(IProtocolIdentifier protocolId); - void MessageReceived(IProtocolIdentifier protocolId, int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index 6a478e61b..c22a9bf1f 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -13,13 +13,15 @@ public class RequestManager : IRequestManager private int _validators = -1; private readonly long _era; private readonly IConsensusBroadcaster _broadcaster; - private readonly IDictionary _protocolHandler; + private readonly IDictionary _protocolRequestHandler; + private readonly IDictionary _protocolResendHandler; private bool _terminated = false; public RequestManager(IConsensusBroadcaster broadcaster, long era) { _broadcaster = broadcaster; _era = era; - _protocolHandler = new ConcurrentDictionary(); + _protocolRequestHandler = new ConcurrentDictionary(); + _protocolResendHandler = new ConcurrentDictionary(); } public void Terminate() @@ -27,11 +29,16 @@ public void Terminate() if (_terminated) return; _terminated = true; - foreach (var (_, handler) in _protocolHandler) + foreach (var (_, handler) in _protocolRequestHandler) { handler.Terminate(); } - _protocolHandler.Clear(); + _protocolRequestHandler.Clear(); + foreach (var (_, handler) in _protocolResendHandler) + { + handler.Terminate(); + } + _protocolResendHandler.Clear(); Logger.LogTrace($"Request manager for era {_era} terminated"); } @@ -46,24 +53,19 @@ public void RegisterProtocol(IProtocolIdentifier protocolId) return; if (_validators == -1) throw new Exception($"RequestManager not ready yet, validators count {_validators}"); - if (_protocolHandler.TryGetValue(protocolId, out var _)) + if (_protocolRequestHandler.TryGetValue(protocolId, out var _)) { throw new Exception($"Protocol handler for protocolId {protocolId} already registered"); } - _protocolHandler[protocolId] = new ProtocolRequestHandler(protocolId, _validators); - } + _protocolRequestHandler[protocolId] = new ProtocolRequestHandler(protocolId, _validators); - public void MessageReceived(IProtocolIdentifier protocolId, int from, ConsensusMessage msg) - { - if (_terminated) - return; - if (_protocolHandler.TryGetValue(protocolId, out var handler)) + if (_protocolResendHandler.TryGetValue(protocolId, out var _)) { - handler.MessageReceived(from, msg); + throw new Exception($"Protocol handler for protocolId {protocolId} already registered"); } - else - throw new Exception($"Protocol handler for protocolId {protocolId} not registered but External message is received"); + + _protocolResendHandler[protocolId] = new ProtocolResendHandler(protocolId, _validators); } } } \ No newline at end of file From 74a5c25788e1cbc0b36b4278659ea280af495ebc Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:52:42 +0600 Subject: [PATCH 109/133] added separate class for each message --- .../Messages/Resends/AuxResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/BValResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/CoinResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/ConfResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/DecryptedResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/EchoResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/ReadyResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/SignedHeaderResend.cs | 21 +++++++++++++++++++ .../Messages/Resends/ValResend.cs | 21 +++++++++++++++++++ 9 files changed, 189 insertions(+) create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs create mode 100644 src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs new file mode 100644 index 000000000..6efa6ed19 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class AuxResend : MessageResendHandler + { + public AuxResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Aux) + throw new Exception($"{msg.PayloadCase} message routed to Aux Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs new file mode 100644 index 000000000..c8c2ab30e --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class BValResend : MessageResendHandler + { + public BValResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Bval) + throw new Exception($"{msg.PayloadCase} message routed to Bval Resend"); + MessageReceived(from, msg.Bval.Value ? 1 : 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs new file mode 100644 index 000000000..df77c5b7f --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class CoinResend : MessageResendHandler + { + public CoinResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Coin) + throw new Exception($"{msg.PayloadCase} message routed to Coin Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs new file mode 100644 index 000000000..679551441 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class ConfResend : MessageResendHandler + { + public ConfResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Conf) + throw new Exception($"{msg.PayloadCase} message routed to Conf Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs new file mode 100644 index 000000000..be5a9e7dd --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class DecryptedResend : MessageResendHandler + { + public DecryptedResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) + throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); + MessageReceived(from, msg.Decrypted.ShareId, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs new file mode 100644 index 000000000..36c0584a1 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class EchoResend : MessageResendHandler + { + public EchoResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.EchoMessage) + throw new Exception($"{msg.PayloadCase} message routed to Echo Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs new file mode 100644 index 000000000..b3c002846 --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class ReadyResend : MessageResendHandler + { + public ReadyResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ReadyMessage) + throw new Exception($"{msg.PayloadCase} message routed to Ready resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs new file mode 100644 index 000000000..c284c6f9d --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class SignedHeaderResend : MessageResendHandler + { + public SignedHeaderResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.SignedHeaderMessage) + throw new Exception($"{msg.PayloadCase} message routed to Signed Header Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs new file mode 100644 index 000000000..86887122d --- /dev/null +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs @@ -0,0 +1,21 @@ +using System; +using Lachain.Proto; + +namespace Lachain.Consensus.RequestProtocols.Messages.Resends +{ + public class ValResend : MessageResendHandler + { + public ValResend(RequestType type, int validatorCount, int msgPerValidator) + : base(type, validatorCount, msgPerValidator) + { + + } + + public override void HandleReceivedMessage(int from, ConsensusMessage msg) + { + if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ValMessage) + throw new Exception($"{msg.PayloadCase} message routed to Val Resend"); + MessageReceived(from, 0, msg); + } + } +} \ No newline at end of file From 813f9e67c54b1015ee9e1d67360960ef51bd253a Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:53:20 +0600 Subject: [PATCH 110/133] added sync attr and made abstract class --- .../Messages/IMessageResendHandler.cs | 1 - .../Messages/MessageResendHandler.cs | 86 ++----------------- 2 files changed, 7 insertions(+), 80 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs index 8af1c1973..42280a685 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs index 98153da67..8fa506913 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -1,11 +1,11 @@ using System; -using System.Collections.Generic; +using System.Runtime.CompilerServices; using Lachain.Logger; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages { - public class MessageResendHandler : IMessageResendHandler + public abstract class MessageResendHandler : IMessageResendHandler { private static readonly ILogger Logger = LoggerFactory.GetLoggerForClass(); private ConsensusMessage?[][] _sentMessages; @@ -30,6 +30,7 @@ public MessageResendHandler(RequestType type, int validatorCount, int msgPerVali } } + [MethodImpl(MethodImplOptions.Synchronized)] public void Terminate() { if (_terminated) @@ -38,96 +39,23 @@ public void Terminate() _sentMessages = new ConsensusMessage?[0][]; } + [MethodImpl(MethodImplOptions.Synchronized)] public void MessageReceived(int from, ConsensusMessage msg, RequestType type) { if (_terminated) return; if (type != _type) throw new Exception($"message type {type} routed to MessageResendHandler {_type}"); - switch (type) - { - case RequestType.Aux: - HandleAuxMessage(from, msg); - break; - case RequestType.Bval: - HandleBValMessage(from, msg); - break; - case RequestType.Coin: - HandleCoinMessage(from, msg); - break; - case RequestType.Conf: - HandleConfMessage(from, msg); - break; - case RequestType.Decrypted: - HandleDecryptedMessage(from, msg); - break; - case RequestType.Echo: - HandleEchoMessage(from, msg); - break; - case RequestType.Ready: - HandleReadyMessage(from, msg); - break; - case RequestType.SignedHeader: - HandleSignedHeaderMessage(from, msg); - break; - case RequestType.Val: - HandleValMessage(from, msg); - break; - default: - throw new Exception($"Not implemented consensus message {msg.PayloadCase}"); - } + HandleReceivedMessage(from, msg); } - private void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) + public void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) { if (!(_sentMessages[validatorId][msgId] is null)) throw new Exception($"Sending duplicate message {msg.ToString()} to validator {validatorId}"); _sentMessages[validatorId][msgId] = msg; } - private void HandleAuxMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleBValMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, msg.Bval.Value ? 1 : 0, msg); - } - - private void HandleConfMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleCoinMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleEchoMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleReadyMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleValMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } - - private void HandleDecryptedMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, msg.Decrypted.ShareId, msg); - } - - private void HandleSignedHeaderMessage(int from, ConsensusMessage msg) - { - MessageReceived(from, 0, msg); - } + public abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file From 0a0cb39ae57021b339d411b4b315d2c97e4dacf8 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 17:54:04 +0600 Subject: [PATCH 111/133] updated registration and using dictionary --- .../Protocols/IProtocolResendHandler.cs | 1 - .../Protocols/ProtocolResendHandler.cs | 72 +++++++------------ 2 files changed, 24 insertions(+), 49 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs index b906af767..7a3cae5c1 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Protocols diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs index 4bbbf7171..e8da872c6 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs @@ -1,12 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using Lachain.Consensus.BinaryAgreement; -using Lachain.Consensus.CommonCoin; -using Lachain.Consensus.HoneyBadger; -using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RequestProtocols.Messages; -using Lachain.Consensus.RootProtocol; +using Lachain.Consensus.RequestProtocols.Messages.Resends; using Lachain.Logger; using Lachain.Proto; @@ -18,20 +15,24 @@ public class ProtocolResendHandler : IProtocolResendHandler private readonly IProtocolIdentifier _protocolId; private readonly int _validatorsCount; private readonly ProtocolType _type; - private readonly List _messageHandlers; + private readonly IDictionary _messageHandlers; private bool _terminated = false; public ProtocolResendHandler(IProtocolIdentifier id, int validators) { _protocolId = id; _validatorsCount = validators; _type = ProtocolUtils.GetProtocolType(id); - _messageHandlers = new List(); + _messageHandlers = new ConcurrentDictionary(); var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); - foreach (var type in requestTypes) + foreach (var requestType in requestTypes) { - if (ProtocolUtils.GetProtocolTypeForRequestType(type) == _type) + if (ProtocolUtils.GetProtocolTypeForRequestType(requestType) == _type) { - _messageHandlers.Add(RegisterMessageHandler(type)); + if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + { + throw new Exception($"{requestType} already registered with handler {handler.Type} and trying to register again"); + } + _messageHandlers[(byte) requestType] = RegisterMessageHandler(requestType); } } } @@ -41,7 +42,7 @@ public void Terminate() if (_terminated) return; _terminated = true; - foreach (var handler in _messageHandlers) + foreach (var (_, handler) in _messageHandlers) { handler.Terminate(); } @@ -54,63 +55,38 @@ public void MessageReceived(int from, ConsensusMessage msg) if (_terminated) return; var type = MessageUtils.GetRequestTypeForMessageType(msg); - foreach (var handler in _messageHandlers) + if (_messageHandlers.TryGetValue((byte) type, out var handler)) { - if (type == handler.Type) - { - handler.MessageReceived(from, msg, type); - return; - } + handler.MessageReceived(from, msg, type); } - throw new Exception($"Message type {type} routed to ProtocolResendHandler {_type}"); + else throw new Exception($"MessageResendHandler {type} not registered"); } private IMessageResendHandler RegisterMessageHandler(RequestType type) { - int validators, msgPerValidator; switch (type) { case RequestType.Aux: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new AuxResend(type, _validatorsCount, 1); case RequestType.Bval: - validators = _validatorsCount; - msgPerValidator = 2; - break; + return new BValResend(type, _validatorsCount, 2); case RequestType.Coin: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new CoinResend(type, _validatorsCount, 1); case RequestType.Conf: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new ConfResend(type, _validatorsCount, 1); case RequestType.Decrypted: - validators = _validatorsCount; - msgPerValidator = _validatorsCount; - break; + return new DecryptedResend(type, _validatorsCount, _validatorsCount); case RequestType.Echo: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new EchoResend(type, _validatorsCount, 1); case RequestType.Val: - validators = 1; - msgPerValidator = 1; - break; + return new ValResend(type, _validatorsCount, 1); case RequestType.Ready: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new ReadyResend(type, _validatorsCount, 1); case RequestType.SignedHeader: - validators = _validatorsCount; - msgPerValidator = 1; - break; + return new SignedHeaderResend(type, _validatorsCount, 1); default: throw new Exception($"RegisterMessageHandler Not implemented for request type {type}"); } - - return new MessageResendHandler(type, validators, msgPerValidator); } } } \ No newline at end of file From 1639ca61af76d31840e0ee075ed6eaad0e4b4b17 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 18:21:10 +0600 Subject: [PATCH 112/133] made abstract class constructor protected --- .../RequestProtocols/Messages/MessageResendHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs index 8fa506913..1099be0d5 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -14,7 +14,7 @@ public abstract class MessageResendHandler : IMessageResendHandler private readonly int _msgPerValidator; public RequestType Type => _type; private bool _terminated = false; - public MessageResendHandler(RequestType type, int validatorCount, int msgPerValidator) + protected MessageResendHandler(RequestType type, int validatorCount, int msgPerValidator) { _type = type; _validators = validatorCount; From 7b54fec4fcf662e6c495942a38f98843fc587448 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:51:42 +0600 Subject: [PATCH 113/133] made abstract methods protected --- .../RequestProtocols/Messages/MessageResendHandler.cs | 4 ++-- .../RequestProtocols/Messages/Resends/AuxResend.cs | 2 +- .../RequestProtocols/Messages/Resends/BValResend.cs | 2 +- .../RequestProtocols/Messages/Resends/CoinResend.cs | 2 +- .../RequestProtocols/Messages/Resends/ConfResend.cs | 2 +- .../RequestProtocols/Messages/Resends/DecryptedResend.cs | 2 +- .../RequestProtocols/Messages/Resends/EchoResend.cs | 2 +- .../RequestProtocols/Messages/Resends/ReadyResend.cs | 2 +- .../RequestProtocols/Messages/Resends/SignedHeaderResend.cs | 2 +- .../RequestProtocols/Messages/Resends/ValResend.cs | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs index 1099be0d5..3cfb6d81b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -49,13 +49,13 @@ public void MessageReceived(int from, ConsensusMessage msg, RequestType type) HandleReceivedMessage(from, msg); } - public void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) + protected void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) { if (!(_sentMessages[validatorId][msgId] is null)) throw new Exception($"Sending duplicate message {msg.ToString()} to validator {validatorId}"); _sentMessages[validatorId][msgId] = msg; } - public abstract void HandleReceivedMessage(int from, ConsensusMessage msg); + protected abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs index 6efa6ed19..50d23efbb 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs @@ -11,7 +11,7 @@ public AuxResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Aux) throw new Exception($"{msg.PayloadCase} message routed to Aux Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs index c8c2ab30e..22527cffe 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs @@ -11,7 +11,7 @@ public BValResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Bval) throw new Exception($"{msg.PayloadCase} message routed to Bval Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs index df77c5b7f..f555e7f71 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs @@ -11,7 +11,7 @@ public CoinResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Coin) throw new Exception($"{msg.PayloadCase} message routed to Coin Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs index 679551441..4b39588c0 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs @@ -11,7 +11,7 @@ public ConfResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Conf) throw new Exception($"{msg.PayloadCase} message routed to Conf Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs index be5a9e7dd..11e9668e1 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs @@ -11,7 +11,7 @@ public DecryptedResend(RequestType type, int validatorCount, int msgPerValidator } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs index 36c0584a1..0aadd889d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs @@ -11,7 +11,7 @@ public EchoResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.EchoMessage) throw new Exception($"{msg.PayloadCase} message routed to Echo Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs index b3c002846..d27835fda 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs @@ -11,7 +11,7 @@ public ReadyResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ReadyMessage) throw new Exception($"{msg.PayloadCase} message routed to Ready resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs index c284c6f9d..01932954a 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs @@ -11,7 +11,7 @@ public SignedHeaderResend(RequestType type, int validatorCount, int msgPerValida } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.SignedHeaderMessage) throw new Exception($"{msg.PayloadCase} message routed to Signed Header Resend"); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs index 86887122d..4db4ae782 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs @@ -11,7 +11,7 @@ public ValResend(RequestType type, int validatorCount, int msgPerValidator) } - public override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleReceivedMessage(int from, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ValMessage) throw new Exception($"{msg.PayloadCase} message routed to Val Resend"); From 9bade8512c8f55ef8f364bb023e129c603e41618 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 17 Nov 2022 18:59:04 +0600 Subject: [PATCH 114/133] changed method name to convinient name --- .../RequestProtocols/Messages/IMessageResendHandler.cs | 2 +- .../RequestProtocols/Messages/MessageResendHandler.cs | 8 ++++---- .../RequestProtocols/Messages/Resends/AuxResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/BValResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/CoinResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/ConfResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/DecryptedResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/EchoResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/ReadyResend.cs | 4 ++-- .../Messages/Resends/SignedHeaderResend.cs | 4 ++-- .../RequestProtocols/Messages/Resends/ValResend.cs | 4 ++-- .../RequestProtocols/Protocols/IProtocolResendHandler.cs | 1 - .../RequestProtocols/Protocols/ProtocolResendHandler.cs | 4 ++-- 13 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs index 42280a685..6c591acfd 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs @@ -6,6 +6,6 @@ public interface IMessageResendHandler { RequestType Type { get; } void Terminate(); - void MessageReceived(int from, ConsensusMessage msg, RequestType type); + void MessageSent(int validator, ConsensusMessage msg, RequestType type); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs index 3cfb6d81b..bb30f897e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -40,22 +40,22 @@ public void Terminate() } [MethodImpl(MethodImplOptions.Synchronized)] - public void MessageReceived(int from, ConsensusMessage msg, RequestType type) + public void MessageSent(int validator, ConsensusMessage msg, RequestType type) { if (_terminated) return; if (type != _type) throw new Exception($"message type {type} routed to MessageResendHandler {_type}"); - HandleReceivedMessage(from, msg); + HandleSentMessage(validator, msg); } - protected void MessageReceived(int validatorId, int msgId, ConsensusMessage msg) + protected void SaveMessage(int validatorId, int msgId, ConsensusMessage msg) { if (!(_sentMessages[validatorId][msgId] is null)) throw new Exception($"Sending duplicate message {msg.ToString()} to validator {validatorId}"); _sentMessages[validatorId][msgId] = msg; } - protected abstract void HandleReceivedMessage(int from, ConsensusMessage msg); + protected abstract void HandleSentMessage(int validator, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs index 50d23efbb..7a1e18a0f 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs @@ -11,11 +11,11 @@ public AuxResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Aux) throw new Exception($"{msg.PayloadCase} message routed to Aux Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs index 22527cffe..b55618603 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs @@ -11,11 +11,11 @@ public BValResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Bval) throw new Exception($"{msg.PayloadCase} message routed to Bval Resend"); - MessageReceived(from, msg.Bval.Value ? 1 : 0, msg); + SaveMessage(validator, msg.Bval.Value ? 1 : 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs index f555e7f71..05166aba9 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs @@ -11,11 +11,11 @@ public CoinResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Coin) throw new Exception($"{msg.PayloadCase} message routed to Coin Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs index 4b39588c0..ae5eeccb3 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs @@ -11,11 +11,11 @@ public ConfResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Conf) throw new Exception($"{msg.PayloadCase} message routed to Conf Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs index 11e9668e1..da91e9c1e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs @@ -11,11 +11,11 @@ public DecryptedResend(RequestType type, int validatorCount, int msgPerValidator } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); - MessageReceived(from, msg.Decrypted.ShareId, msg); + SaveMessage(validator, msg.Decrypted.ShareId, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs index 0aadd889d..00db4786c 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs @@ -11,11 +11,11 @@ public EchoResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.EchoMessage) throw new Exception($"{msg.PayloadCase} message routed to Echo Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs index d27835fda..b83d63486 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs @@ -11,11 +11,11 @@ public ReadyResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ReadyMessage) throw new Exception($"{msg.PayloadCase} message routed to Ready resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs index 01932954a..b11b03839 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs @@ -11,11 +11,11 @@ public SignedHeaderResend(RequestType type, int validatorCount, int msgPerValida } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.SignedHeaderMessage) throw new Exception($"{msg.PayloadCase} message routed to Signed Header Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs index 4db4ae782..fe200f043 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs @@ -11,11 +11,11 @@ public ValResend(RequestType type, int validatorCount, int msgPerValidator) } - protected override void HandleReceivedMessage(int from, ConsensusMessage msg) + protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.ValMessage) throw new Exception($"{msg.PayloadCase} message routed to Val Resend"); - MessageReceived(from, 0, msg); + SaveMessage(validator, 0, msg); } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs index 7a3cae5c1..ac40a1a88 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs @@ -5,6 +5,5 @@ namespace Lachain.Consensus.RequestProtocols.Protocols public interface IProtocolResendHandler { void Terminate(); - void MessageReceived(int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs index e8da872c6..0940424c5 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs @@ -50,14 +50,14 @@ public void Terminate() Logger.LogTrace($"ProtocolResendHandler for protocol {_protocolId} terminated"); } - public void MessageReceived(int from, ConsensusMessage msg) + public void MessageSent(int validator, ConsensusMessage msg) { if (_terminated) return; var type = MessageUtils.GetRequestTypeForMessageType(msg); if (_messageHandlers.TryGetValue((byte) type, out var handler)) { - handler.MessageReceived(from, msg, type); + handler.MessageSent(validator, msg, type); } else throw new Exception($"MessageResendHandler {type} not registered"); } From dc95ac67940318d2b8fab187461941fa2b741e35 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:25:08 +0600 Subject: [PATCH 115/133] added method to handle request --- .../Messages/Resends/AuxResend.cs | 15 +++++++++++++++ .../Messages/Resends/BValResend.cs | 16 ++++++++++++++++ .../Messages/Resends/CoinResend.cs | 15 +++++++++++++++ .../Messages/Resends/ConfResend.cs | 15 +++++++++++++++ .../Messages/Resends/DecryptedResend.cs | 15 +++++++++++++++ .../Messages/Resends/EchoResend.cs | 15 +++++++++++++++ .../Messages/Resends/ReadyResend.cs | 15 +++++++++++++++ .../Messages/Resends/SignedHeaderResend.cs | 15 +++++++++++++++ .../Messages/Resends/ValResend.cs | 15 +++++++++++++++ 9 files changed, 136 insertions(+) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs index 7a1e18a0f..ff819e31e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/AuxResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Aux Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs index b55618603..0d15d7715 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/BValResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,20 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Bval Resend"); SaveMessage(validator, msg.Bval.Value ? 1 : 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestBval) + throw new Exception($"{msg.PayloadCase} routed to BVal Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + msgIds.Add(1); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs index 05166aba9..471633700 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/CoinResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Coin Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestCoin) + throw new Exception($"{msg.PayloadCase} routed to Coin Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs index ae5eeccb3..eb4d40e9d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ConfResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Conf Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestConf) + throw new Exception($"{msg.PayloadCase} routed to Conf Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs index da91e9c1e..c0531238b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); SaveMessage(validator, msg.Decrypted.ShareId, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestDecrypted) + throw new Exception($"{msg.PayloadCase} routed to Decrypted Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(msg.RequestDecrypted.ShareId); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs index 00db4786c..655fa7b25 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/EchoResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Echo Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestEcho) + throw new Exception($"{msg.PayloadCase} routed to Echo Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs index b83d63486..7e7c4b4f5 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ReadyResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Ready resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestReady) + throw new Exception($"{msg.PayloadCase} routed to Ready Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs index b11b03839..2b65603ae 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/SignedHeaderResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Signed Header Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestSignedHeader) + throw new Exception($"{msg.PayloadCase} routed to Signed Header Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs index fe200f043..e27db783b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/ValResend.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages.Resends @@ -17,5 +18,19 @@ protected override void HandleSentMessage(int validator, ConsensusMessage msg) throw new Exception($"{msg.PayloadCase} message routed to Val Resend"); SaveMessage(validator, 0, msg); } + + protected override List HandleRequestMessage(int from, RequestConsensusMessage msg) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestVal) + throw new Exception($"{msg.PayloadCase} routed to Val Resend"); + var msgs = new List(); + var msgIds = new List(); + msgIds.Add(0); + foreach (var id in msgIds) + { + msgs.Add(GetMessage(from, id)); + } + return msgs; + } } } \ No newline at end of file From 283c91750c247025f134b5e150e0b3373a619c8c Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:26:30 +0600 Subject: [PATCH 116/133] added method to create protocolId on request --- .../RequestProtocols/Messages/Requests/AuxRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/BValRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/CoinRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/ConfRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/DecryptedRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/EchoRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/ReadyRequest.cs | 7 +++++++ .../Messages/Requests/SignedHeaderRequest.cs | 7 +++++++ .../RequestProtocols/Messages/Requests/ValRequest.cs | 7 +++++++ 9 files changed, 63 insertions(+) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs index 4fd034080..c3864a2db 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs @@ -35,5 +35,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static BinaryBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new BinaryBroadcastId(era, msg.RequestAux.Agreement, msg.RequestAux.Epoch); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs index 82a22784a..65fe9fa96 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs @@ -35,5 +35,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static BinaryBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new BinaryBroadcastId(era, msg.RequestBval.Agreement, msg.RequestBval.Epoch); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs index 3e94a436b..7b8721afd 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs @@ -35,5 +35,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static CoinId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new CoinId(era, msg.RequestCoin.Agreement, msg.RequestCoin.Epoch); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs index 808399060..de9d0cc09 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs @@ -35,5 +35,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static BinaryBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new BinaryBroadcastId(era, msg.RequestConf.Agreement, msg.RequestConf.Epoch); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs index 9d06fab86..a005f1675 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs @@ -34,5 +34,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static HoneyBadgerId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new HoneyBadgerId(era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs index 9e64d25cc..82b87934d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs @@ -34,5 +34,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static ReliableBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new ReliableBroadcastId(msg.RequestEcho.SenderId, (int) era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs index 382b0f19c..e2d7344a4 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs @@ -34,5 +34,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static ReliableBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new ReliableBroadcastId(msg.RequestReady.SenderId, (int) era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs index 15b3a023f..74f321af9 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs @@ -31,5 +31,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static RootProtocolId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) + throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + return new RootProtocolId(era); + } } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs index 7a66fa3cd..a65f4b4f3 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs @@ -34,5 +34,12 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p } }; } + + public static ReliableBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) + { + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestVal) + throw new Exception($"{msg.PayloadCase} routed to Val Request"); + return new ReliableBroadcastId(msg.RequestVal.SenderId, (int) era); + } } } \ No newline at end of file From f26853544437add015c4914980ceee01ab87dcd0 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:43:21 +0600 Subject: [PATCH 117/133] handing request --- .../Messages/IMessageResendHandler.cs | 2 ++ .../Messages/MessageResendHandler.cs | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs index 6c591acfd..b0d84d69e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageResendHandler.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages @@ -7,5 +8,6 @@ public interface IMessageResendHandler RequestType Type { get; } void Terminate(); void MessageSent(int validator, ConsensusMessage msg, RequestType type); + List HandleRequest(int from, RequestConsensusMessage request, RequestType type); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs index bb30f897e..50839653c 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageResendHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; using Lachain.Logger; using Lachain.Proto; @@ -56,6 +57,32 @@ protected void SaveMessage(int validatorId, int msgId, ConsensusMessage msg) _sentMessages[validatorId][msgId] = msg; } + [MethodImpl(MethodImplOptions.Synchronized)] + public List HandleRequest(int from, RequestConsensusMessage request, RequestType type) + { + if (_terminated) + return new List(); + + if (type != _type) + throw new Exception($"Request message {type} routed to MessageResendHandler {_type}"); + + if (from >= _validators) + throw new Exception($"Got request from validator {from}. But we have total {_validators} validators"); + + return HandleRequestMessage(from, request); + } + + protected ConsensusMessage? GetMessage(int from, int msgId) + { + if (from >= _validators) + throw new Exception($"Got request from validator {from}. But we have total {_validators} validators"); + if (msgId >= _msgPerValidator) + throw new Exception($"Got request for msgId {msgId}. But we have total {_msgPerValidator} messages per validator"); + return _sentMessages[from][msgId]; + } + + protected abstract List HandleRequestMessage(int from, RequestConsensusMessage msg); + protected abstract void HandleSentMessage(int validator, ConsensusMessage msg); } } \ No newline at end of file From c802821dbf8ef02e769e33d039ce908233240d79 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:43:50 +0600 Subject: [PATCH 118/133] handling request per protocol --- .../Protocols/IProtocolResendHandler.cs | 3 +++ .../Protocols/ProtocolResendHandler.cs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs index ac40a1a88..a3aae3223 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolResendHandler.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using Lachain.Consensus.RequestProtocols.Messages; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Protocols @@ -5,5 +7,6 @@ namespace Lachain.Consensus.RequestProtocols.Protocols public interface IProtocolResendHandler { void Terminate(); + List HandleRequest(int from, RequestConsensusMessage request, RequestType requestType); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs index 0940424c5..1328ec144 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs @@ -62,6 +62,22 @@ public void MessageSent(int validator, ConsensusMessage msg) else throw new Exception($"MessageResendHandler {type} not registered"); } + public List HandleRequest(int from, RequestConsensusMessage request, RequestType requestType) + { + if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + { + var response = handler.HandleRequest(from, request, requestType); + var validResponse = new List(); + foreach (var msg in response) + { + if (!(msg is null)) + validResponse.Add(msg); + } + return validResponse; + } + throw new Exception($"MessageResendHandler {requestType} not registered"); + } + private IMessageResendHandler RegisterMessageHandler(RequestType type) { switch (type) From a4db155d1fdb0a3b4837c99b53953729100b3cee Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:44:21 +0600 Subject: [PATCH 119/133] added separate thread and queue to process request --- .../RequestProtocols/IRequestManager.cs | 1 + .../RequestProtocols/RequestManager.cs | 150 ++++++++++++++++-- 2 files changed, 139 insertions(+), 12 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs index 3a502bc4d..83925c7d7 100644 --- a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs @@ -7,5 +7,6 @@ public interface IRequestManager void Terminate(); void SetValidators(int validatorsCount); void RegisterProtocol(IProtocolIdentifier protocolId); + void HandleRequest(int from, ConsensusMessage request); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index c22a9bf1f..19762d909 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Threading; +using Lachain.Consensus.RequestProtocols.Messages; +using Lachain.Consensus.RequestProtocols.Messages.Requests; using Lachain.Consensus.RequestProtocols.Protocols; using Lachain.Logger; using Lachain.Proto; @@ -15,6 +18,9 @@ public class RequestManager : IRequestManager private readonly IConsensusBroadcaster _broadcaster; private readonly IDictionary _protocolRequestHandler; private readonly IDictionary _protocolResendHandler; + private readonly Thread _thread; + private readonly object _queueLock = new object(); + private readonly Queue<(int, ConsensusMessage)> _queue; private bool _terminated = false; public RequestManager(IConsensusBroadcaster broadcaster, long era) { @@ -22,24 +28,32 @@ public RequestManager(IConsensusBroadcaster broadcaster, long era) _era = era; _protocolRequestHandler = new ConcurrentDictionary(); _protocolResendHandler = new ConcurrentDictionary(); + _queue = new Queue<(int, ConsensusMessage)>(); + _thread = new Thread(Start) {IsBackground = true}; + _thread.Start(); } public void Terminate() { - if (_terminated) - return; - _terminated = true; - foreach (var (_, handler) in _protocolRequestHandler) - { - handler.Terminate(); - } - _protocolRequestHandler.Clear(); - foreach (var (_, handler) in _protocolResendHandler) + lock (_queueLock) { - handler.Terminate(); + if (_terminated) + return; + _terminated = true; + foreach (var (_, handler) in _protocolRequestHandler) + { + handler.Terminate(); + } + _protocolRequestHandler.Clear(); + foreach (var (_, handler) in _protocolResendHandler) + { + handler.Terminate(); + } + _protocolResendHandler.Clear(); + _queue.Clear(); + Monitor.PulseAll(_queueLock); + Logger.LogTrace($"Request manager for era {_era} terminated"); } - _protocolResendHandler.Clear(); - Logger.LogTrace($"Request manager for era {_era} terminated"); } public void SetValidators(int validatorsCount) @@ -67,5 +81,117 @@ public void RegisterProtocol(IProtocolIdentifier protocolId) _protocolResendHandler[protocolId] = new ProtocolResendHandler(protocolId, _validators); } + + public void HandleRequest(int from, ConsensusMessage request) + { + lock (_queueLock) + { + if (_terminated) + { + Monitor.PulseAll(_queueLock); + return; + } + _queue.Enqueue((from, request)); + Monitor.PulseAll(_queueLock); + } + } + + public void Start() + { + while (!_terminated) + { + ConsensusMessage msg; + int from; + lock (_queueLock) + { + while (_queue.Count == 0 && !_terminated) + { + Monitor.Wait(_queueLock); + } + + if (_terminated) + return; + + (from, msg) = _queue.Dequeue(); + } + + try + { + ProcessRequest(from, msg.RequestConsensus, msg.Validator.Era); + } + catch (Exception e) + { + Logger.LogError($"RequestManager: exception occured while processing message: {e}"); + Terminate(); + break; + } + } + } + + private void ProcessRequest(int from, RequestConsensusMessage request, long era) + { + IProtocolIdentifier protocolId; + RequestType type; + switch (request.PayloadCase) + { + case RequestConsensusMessage.PayloadOneofCase.RequestAux: + protocolId = AuxRequest.CreateProtocolId(request, era); + type = RequestType.Aux; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestBval: + protocolId = BValRequest.CreateProtocolId(request, era); + type = RequestType.Bval; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestCoin: + protocolId = CoinRequest.CreateProtocolId(request, era); + type = RequestType.Coin; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestConf: + protocolId = ConfRequest.CreateProtocolId(request, era); + type = RequestType.Conf; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestDecrypted: + protocolId = DecryptedRequest.CreateProtocolId(request, era); + type = RequestType.Decrypted; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestEcho: + protocolId = EchoRequest.CreateProtocolId(request, era); + type = RequestType.Echo; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestReady: + protocolId = ReadyRequest.CreateProtocolId(request, era); + type = RequestType.Ready; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestSignedHeader: + protocolId = SignedHeaderRequest.CreateProtocolId(request, era); + type = RequestType.SignedHeader; + break; + case RequestConsensusMessage.PayloadOneofCase.RequestVal: + protocolId = ValRequest.CreateProtocolId(request, era); + type = RequestType.Val; + break; + default: + var publicKey = _broadcaster.GetPublicKeyById(from); + Logger.LogError($"validator {publicKey} ({from}) sent request {request.PayloadCase} but we do not implement this request"); + return; + } + + if (_protocolResendHandler.TryGetValue(protocolId, out var handler)) + { + try + { + var response = handler.HandleRequest(from, request, type); + foreach (var msg in response) + { + _broadcaster.SendToValidator(msg, from); + } + } + catch (Exception exc) + { + Logger.LogWarning($"Got exception trying to process request {type} for protocol {protocolId}: {exc}"); + } + } + else Logger.LogTrace($"{protocolId} not registered yet, discarding request {type}"); + } } } \ No newline at end of file From b7e48d3f4a09217f19dc12d36a26dfebc3f9b0fc Mon Sep 17 00:00:00 2001 From: tbssajal Date: Wed, 16 Nov 2022 20:44:41 +0600 Subject: [PATCH 120/133] handling request for era broadcaster --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 78643b2c9..7a2d84870 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -324,6 +324,9 @@ public void Dispatch(ConsensusMessage message, int from) case ConsensusMessage.PayloadOneofCase.SignedHeaderMessage: protocolId = new RootProtocolId(message.Validator.Era); break; + case ConsensusMessage.PayloadOneofCase.RequestConsensus: + _requestManager.HandleRequest(from, message); + return; default: throw new InvalidOperationException($"Unknown message type {message}"); } @@ -763,6 +766,11 @@ private bool ValidateMessage(ConsensusMessage message) if (header.MerkleRoot is null || header.PrevBlockHash is null || header.StateHash is null) return false; return true; + case ConsensusMessage.PayloadOneofCase.RequestConsensus: + // all request parameters have default value + // request manager can verify and discard request if necessary + // no additional check needed + return true; default: return false; } From ca677dba33b4911448fe7012a7a36990d4dc469d Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 17 Nov 2022 22:59:56 +0600 Subject: [PATCH 121/133] added event and invoke methods --- src/Lachain.Consensus/AbstractProtocol.cs | 27 ++++++++++++++++++++- src/Lachain.Consensus/IConsensusProtocol.cs | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index bbe29132b..b413920db 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -39,6 +39,10 @@ public abstract class AbstractProtocol : IConsensusProtocol private ulong _startTime = 0; private const ulong _alertTime = 60 * 1000; public bool Started { get; private set; } = false; + + // waiting for 10 block time + // NOTE: calculate _requestTime properly + private const ulong _requestTime = 10 * 4 * 1000; protected AbstractProtocol( IPublicConsensusKeySet wallet, @@ -124,6 +128,7 @@ public void Terminate() public void Start() { _startTime = TimeUtils.CurrentTimeMillis(); + var lastRequestTime = _startTime; while (!Terminated) { MessageEnvelope msg; @@ -131,12 +136,17 @@ public void Start() { while (_queue.IsEmpty && !Terminated) { - Monitor.Wait(_queueLock, 1000); + var queueUsed = Monitor.Wait(_queueLock, 1000); if (TimeUtils.CurrentTimeMillis() - _startTime > _alertTime) { Logger.LogWarning($"Protocol {Id} is waiting for _queueLock too long, last message" + $" is [{_lastMessage}]"); } + if (!queueUsed && TimeUtils.CurrentTimeMillis() - lastRequestTime > _requestTime) + { + _protocolWaitingTooLong?.Invoke(this, Id); + lastRequestTime = TimeUtils.CurrentTimeMillis(); + } } if (Terminated) @@ -190,8 +200,23 @@ protected void InvokeReceivedExternalMessage(int from, ConsensusMessage msg) _receivedExternalMessage?.Invoke(this, (from, msg)); } + protected void InvokeMessageBroadcasted(ConsensusMessage msg) + { + // an external message is broadcasted + _messageBroadcasted?.Invoke(this, msg); + } + + protected void InvokeMessageSent(int validator, ConsensusMessage msg) + { + // an external message is sent to validator + _messageSent?.Invoke(this, (validator, msg)); + } + public abstract void ProcessMessage(MessageEnvelope envelope); + public event EventHandler? _protocolWaitingTooLong; public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; + public event EventHandler? _messageBroadcasted; + public event EventHandler<(int validator, ConsensusMessage msg)>? _messageSent; } } \ No newline at end of file diff --git a/src/Lachain.Consensus/IConsensusProtocol.cs b/src/Lachain.Consensus/IConsensusProtocol.cs index 7a8ba0374..64cba1874 100644 --- a/src/Lachain.Consensus/IConsensusProtocol.cs +++ b/src/Lachain.Consensus/IConsensusProtocol.cs @@ -21,6 +21,9 @@ public interface IConsensusProtocol bool Terminated { get; } + event EventHandler? _protocolWaitingTooLong; event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; + event EventHandler? _messageBroadcasted; + event EventHandler<(int validator, ConsensusMessage msg)>? _messageSent; } } \ No newline at end of file From c8e8f725203416d1e97c1da14db205c62b556de0 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 17 Nov 2022 23:01:35 +0600 Subject: [PATCH 122/133] invoking event in necessary events --- .../BinaryAgreement/BinaryBroadcast.cs | 12 +++++++++--- src/Lachain.Consensus/CommonCoin/CommonCoin.cs | 1 + src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs | 4 +++- .../ReliableBroadcast/ReliableBroadcast.cs | 16 ++++++++++++---- .../RootProtocol/RootProtocol.cs | 4 +++- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs index d981dc4d4..8bc512b7d 100644 --- a/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs +++ b/src/Lachain.Consensus/BinaryAgreement/BinaryBroadcast.cs @@ -120,7 +120,9 @@ private void BroadcastBVal(bool value) { var b = value ? 1 : 0; _wasBvalBroadcasted[b] = true; - Broadcaster.Broadcast(CreateBValMessage(b)); + var msg = CreateBValMessage(b); + Broadcaster.Broadcast(msg); + InvokeMessageBroadcasted(msg); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -152,7 +154,9 @@ private void HandleBValMessage(int sender, BValMessage bval) _binValues = _binValues.Add(b == 1); if (_binValues.Count() == 1) { - Broadcaster.Broadcast(CreateAuxMessage(b)); + var msg = CreateAuxMessage(b); + Broadcaster.Broadcast(msg); + InvokeMessageBroadcasted(msg); } RevisitAuxMessages(); @@ -236,7 +240,9 @@ private void RevisitAuxMessages() if (_confSent) return; if (_binValues.Values().Sum(b => _receivedAux[b ? 1 : 0]) < N - F) return; Logger.LogTrace($"{_broadcastId}: conf message sent with set {_binValues}"); - Broadcaster.Broadcast(CreateConfMessage(_binValues)); + var msg = CreateConfMessage(_binValues); + Broadcaster.Broadcast(msg); + InvokeMessageBroadcasted(msg); _confSent = true; RevisitConfMessages(); } diff --git a/src/Lachain.Consensus/CommonCoin/CommonCoin.cs b/src/Lachain.Consensus/CommonCoin/CommonCoin.cs index c86913eb9..10b88a208 100644 --- a/src/Lachain.Consensus/CommonCoin/CommonCoin.cs +++ b/src/Lachain.Consensus/CommonCoin/CommonCoin.cs @@ -126,6 +126,7 @@ public override void ProcessMessage(MessageEnvelope envelope) CheckResult(); var msg = CreateCoinMessage(signatureShare); Broadcaster.Broadcast(msg); + InvokeMessageBroadcasted(msg); break; case ProtocolResult _: _lastMessage = "ProtocolResult"; diff --git a/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs b/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs index 928869395..679881550 100644 --- a/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs +++ b/src/Lachain.Consensus/HoneyBadger/HoneyBadger.cs @@ -161,7 +161,9 @@ private void HandleCommonSubset(ProtocolResult Date: Thu, 17 Nov 2022 23:02:04 +0600 Subject: [PATCH 123/133] subscribing to events and updated constructor --- .../RequestProtocols/IRequestManager.cs | 5 ++-- .../Protocols/IProtocolRequestHandler.cs | 1 - .../Protocols/ProtocolRequestHandler.cs | 7 +++-- .../Protocols/ProtocolResendHandler.cs | 20 +++++++++++-- .../RequestProtocols/RequestManager.cs | 29 +++++++++++++++++-- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs index 83925c7d7..084bbfd12 100644 --- a/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/IRequestManager.cs @@ -1,12 +1,13 @@ +using System; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols { - public interface IRequestManager + public interface IRequestManager : IDisposable { void Terminate(); void SetValidators(int validatorsCount); - void RegisterProtocol(IProtocolIdentifier protocolId); + void RegisterProtocol(IProtocolIdentifier protocolId, IConsensusProtocol protocol); void HandleRequest(int from, ConsensusMessage request); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs index ad2c82a89..f538fc12b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/IProtocolRequestHandler.cs @@ -6,7 +6,6 @@ namespace Lachain.Consensus.RequestProtocols.Protocols public interface IProtocolRequestHandler { void Terminate(); - void MessageReceived(int from, ConsensusMessage msg); List<(ConsensusMessage, int)> GetRequests(int requestCount); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index 6b527732d..35133dedc 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -17,7 +17,8 @@ public class ProtocolRequestHandler : IProtocolRequestHandler private readonly int _validatorsCount; private readonly IDictionary _messageHandlers; private bool _terminated = false; - public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) + private bool _subscribed = false; + public ProtocolRequestHandler(IProtocolIdentifier id, IConsensusProtocol protocol, int validatorsCount) { _validatorsCount = validatorsCount; _protocolId = id; @@ -35,6 +36,7 @@ public ProtocolRequestHandler(IProtocolIdentifier id, int validatorsCount) _messageHandlers[(byte) requestType] = RegisterMessageHandler(requestType); } } + protocol._receivedExternalMessage += MessageReceived; } public void Terminate() @@ -48,10 +50,11 @@ public void Terminate() Logger.LogTrace($"Protocol handler for protocol {_protocolId} terminated"); } - public void MessageReceived(int from, ConsensusMessage msg) + private void MessageReceived(object? sender, (int from, ConsensusMessage msg) @event) { if (_terminated) return; + var (from, msg) = @event; var type = MessageUtils.GetRequestTypeForMessageType(msg); if (_messageHandlers.TryGetValue((byte) type, out var handler)) { diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs index 1328ec144..0f8a4e34d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolResendHandler.cs @@ -17,7 +17,7 @@ public class ProtocolResendHandler : IProtocolResendHandler private readonly ProtocolType _type; private readonly IDictionary _messageHandlers; private bool _terminated = false; - public ProtocolResendHandler(IProtocolIdentifier id, int validators) + public ProtocolResendHandler(IProtocolIdentifier id, IConsensusProtocol protocol, int validators) { _protocolId = id; _validatorsCount = validators; @@ -35,6 +35,8 @@ public ProtocolResendHandler(IProtocolIdentifier id, int validators) _messageHandlers[(byte) requestType] = RegisterMessageHandler(requestType); } } + protocol._messageBroadcasted += MessageBroadcasted; + protocol._messageSent += MessageSent; } public void Terminate() @@ -50,12 +52,26 @@ public void Terminate() Logger.LogTrace($"ProtocolResendHandler for protocol {_protocolId} terminated"); } - public void MessageSent(int validator, ConsensusMessage msg) + private void MessageBroadcasted(object? sender, ConsensusMessage msg) { if (_terminated) return; var type = MessageUtils.GetRequestTypeForMessageType(msg); if (_messageHandlers.TryGetValue((byte) type, out var handler)) + { + for (int validator = 0 ; validator < _validatorsCount; validator++) + handler.MessageSent(validator, msg, type); + } + else throw new Exception($"MessageResendHandler {type} not registered"); + } + + private void MessageSent(object? sender, (int validator, ConsensusMessage msg) @event) + { + if (_terminated) + return; + var (validator, msg) = @event; + var type = MessageUtils.GetRequestTypeForMessageType(msg); + if (_messageHandlers.TryGetValue((byte) type, out var handler)) { handler.MessageSent(validator, msg, type); } diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index 19762d909..d844c4c03 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Threading; using Lachain.Consensus.RequestProtocols.Messages; using Lachain.Consensus.RequestProtocols.Messages.Requests; @@ -61,7 +62,8 @@ public void SetValidators(int validatorsCount) _validators = validatorsCount; } - public void RegisterProtocol(IProtocolIdentifier protocolId) + [MethodImpl(MethodImplOptions.Synchronized)] + public void RegisterProtocol(IProtocolIdentifier protocolId, IConsensusProtocol protocol) { if (_terminated) return; @@ -72,14 +74,15 @@ public void RegisterProtocol(IProtocolIdentifier protocolId) throw new Exception($"Protocol handler for protocolId {protocolId} already registered"); } - _protocolRequestHandler[protocolId] = new ProtocolRequestHandler(protocolId, _validators); + _protocolRequestHandler[protocolId] = new ProtocolRequestHandler(protocolId, protocol, _validators); if (_protocolResendHandler.TryGetValue(protocolId, out var _)) { throw new Exception($"Protocol handler for protocolId {protocolId} already registered"); } - _protocolResendHandler[protocolId] = new ProtocolResendHandler(protocolId, _validators); + _protocolResendHandler[protocolId] = new ProtocolResendHandler(protocolId, protocol, _validators); + protocol._protocolWaitingTooLong += MakeRequest; } public void HandleRequest(int from, ConsensusMessage request) @@ -193,5 +196,25 @@ private void ProcessRequest(int from, RequestConsensusMessage request, long era) } else Logger.LogTrace($"{protocolId} not registered yet, discarding request {type}"); } + + private void MakeRequest(object? sender, IProtocolIdentifier protocolId) + { + // lets not send too many requests + int maxRequestCount = 10; + if (_protocolRequestHandler.TryGetValue(protocolId, out var handler)) + { + var requests = handler.GetRequests(maxRequestCount); + foreach (var (msg, validator) in requests) + { + _broadcaster.SendToValidator(msg, validator); + } + } + else throw new Exception($"{protocolId} not registered"); + } + + public void Dispose() + { + Terminate(); + } } } \ No newline at end of file From 2921fffeb6376689cf278bb1899f3c7c297161e3 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 17 Nov 2022 23:02:21 +0600 Subject: [PATCH 124/133] updated registration --- src/Lachain.Core/Consensus/EraBroadcaster.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Core/Consensus/EraBroadcaster.cs b/src/Lachain.Core/Consensus/EraBroadcaster.cs index 7a2d84870..a3a2d5136 100644 --- a/src/Lachain.Core/Consensus/EraBroadcaster.cs +++ b/src/Lachain.Core/Consensus/EraBroadcaster.cs @@ -95,7 +95,7 @@ public void RegisterProtocols(IEnumerable protocols) { _registry[protocol.Id] = protocol; protocol._receivedExternalMessage += PersistExternalMessae; - _requestManager.RegisterProtocol(protocol.Id); + _requestManager.RegisterProtocol(protocol.Id, protocol); } } From a226c5dfaab499b1feab016aaad1b87b78a4cded Mon Sep 17 00:00:00 2001 From: tbssajal Date: Thu, 17 Nov 2022 23:02:31 +0600 Subject: [PATCH 125/133] fixed tests --- test/Lachain.ConsensusTest/ProtocolInvoker.cs | 3 +++ test/Lachain.ConsensusTest/SilentProtocol.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test/Lachain.ConsensusTest/ProtocolInvoker.cs b/test/Lachain.ConsensusTest/ProtocolInvoker.cs index 4e901e203..571f32639 100644 --- a/test/Lachain.ConsensusTest/ProtocolInvoker.cs +++ b/test/Lachain.ConsensusTest/ProtocolInvoker.cs @@ -119,6 +119,9 @@ public void WaitResult() throw new NotImplementedException(); } + public event EventHandler? _protocolWaitingTooLong; public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; + public event EventHandler? _messageBroadcasted; + public event EventHandler<(int validator, ConsensusMessage msg)>? _messageSent; } } \ No newline at end of file diff --git a/test/Lachain.ConsensusTest/SilentProtocol.cs b/test/Lachain.ConsensusTest/SilentProtocol.cs index 1d197bad6..ee32d4128 100644 --- a/test/Lachain.ConsensusTest/SilentProtocol.cs +++ b/test/Lachain.ConsensusTest/SilentProtocol.cs @@ -52,6 +52,9 @@ public void Terminate() public bool Terminated => true; + public event EventHandler? _protocolWaitingTooLong; public event EventHandler<(int from, ConsensusMessage msg)>? _receivedExternalMessage; + public event EventHandler? _messageBroadcasted; + public event EventHandler<(int validator, ConsensusMessage msg)>? _messageSent; } } \ No newline at end of file From c9dc8a2f347e6b9e2d10133f250389acc1c01786 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Fri, 18 Nov 2022 18:11:50 +0600 Subject: [PATCH 126/133] fixed tests --- test/Lachain.StorageTest/RocksDbTest.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/Lachain.StorageTest/RocksDbTest.cs b/test/Lachain.StorageTest/RocksDbTest.cs index d5f9d66b3..b7d6b3262 100644 --- a/test/Lachain.StorageTest/RocksDbTest.cs +++ b/test/Lachain.StorageTest/RocksDbTest.cs @@ -255,6 +255,18 @@ public void Test_IteratorValid() InsertRandomPrefixKeyValue(noOfPrefix, noOfTest, out var prefixKeyValues, out var keyValues); prefixKeyValues = prefixKeyValues.OrderBy(item => item.Item1, new ByteKeyComparer()).ToList(); var existNextPrefix = GetNextValue(prefixKeyValues.Last().Item1, out var prefix); + if (!existNextPrefix) + { + var lastPrefix = prefixKeyValues.Last().Item1; + foreach (var (pref, (key, value)) in prefixKeyValues) + { + if (pref.SequenceEqual(lastPrefix)) + { + _dbContext.Delete(BuildPrefix(pref, key)); + } + } + existNextPrefix = GetNextValue(prefixKeyValues.Last().Item1, out prefix); + } Assert.That(existNextPrefix); var iterator = _dbContext.GetIteratorForValidKeys(prefix); if (iterator is null) From 693f1641bd55f71dec2ccb6370426ee57b52e07c Mon Sep 17 00:00:00 2001 From: tbssajal Date: Fri, 18 Nov 2022 18:14:21 +0600 Subject: [PATCH 127/133] updated logs --- src/Lachain.Consensus/AbstractProtocol.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index b413920db..73e53aa6b 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -41,7 +41,7 @@ public abstract class AbstractProtocol : IConsensusProtocol public bool Started { get; private set; } = false; // waiting for 10 block time - // NOTE: calculate _requestTime properly + // TODO: calculate _requestTime properly private const ulong _requestTime = 10 * 4 * 1000; protected AbstractProtocol( From db6048d97336689a3169ee734a27370fc762eaa3 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Fri, 18 Nov 2022 18:15:01 +0600 Subject: [PATCH 128/133] added ordered types for message --- .../Protocols/ProtocolRequestHandler.cs | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index 35133dedc..8c9a1c7a4 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -16,6 +16,7 @@ public class ProtocolRequestHandler : IProtocolRequestHandler private readonly ProtocolType _type; private readonly int _validatorsCount; private readonly IDictionary _messageHandlers; + private readonly List _orderedRequestTypes; private bool _terminated = false; private bool _subscribed = false; public ProtocolRequestHandler(IProtocolIdentifier id, IConsensusProtocol protocol, int validatorsCount) @@ -25,6 +26,7 @@ public ProtocolRequestHandler(IProtocolIdentifier id, IConsensusProtocol protoco _type = ProtocolUtils.GetProtocolType(id); _messageHandlers = new ConcurrentDictionary(); var requestTypes = Enum.GetValues(typeof(RequestType)).Cast().ToArray(); + _orderedRequestTypes = new List(); foreach (var requestType in requestTypes) { if (ProtocolUtils.GetProtocolTypeForRequestType(requestType) == _type) @@ -34,8 +36,10 @@ public ProtocolRequestHandler(IProtocolIdentifier id, IConsensusProtocol protoco throw new Exception($"{requestType} already registered with handler {handler.Type} and trying to register again"); } _messageHandlers[(byte) requestType] = RegisterMessageHandler(requestType); + _orderedRequestTypes.Add(requestType); } } + _orderedRequestTypes = _orderedRequestTypes.OrderBy(type => type).ToList(); protocol._receivedExternalMessage += MessageReceived; } @@ -68,11 +72,29 @@ private void MessageReceived(object? sender, (int from, ConsensusMessage msg) @e var allRequests = new List<(ConsensusMessage, int)>(); if (_terminated) return allRequests; - foreach (var (_, handler) in _messageHandlers) + + // first do new requests + foreach (var requestType in _orderedRequestTypes) + { + if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + { + var requests = handler.GetNewRequests(_protocolId, requestCount); + requestCount -= requests.Count; + allRequests.AddRange(requests); + } + else throw new Exception($"MessageRequestHandler {requestType} not registered"); + } + + // then do repeated requests + foreach (var requestType in _orderedRequestTypes) { - var requests = handler.GetRequests(_protocolId, requestCount); - requestCount -= requests.Count; - allRequests.AddRange(requests); + if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + { + var requests = handler.GetRequests(_protocolId, requestCount); + requestCount -= requests.Count; + allRequests.AddRange(requests); + } + else throw new Exception($"MessageRequestHandler {requestType} not registered"); } return allRequests; } From 04f0ad4b57be316db1c862c53a1998ebe3e9905c Mon Sep 17 00:00:00 2001 From: tbssajal Date: Fri, 18 Nov 2022 18:15:26 +0600 Subject: [PATCH 129/133] fixed bug --- .../Messages/IMessageRequestHandler.cs | 1 + .../Messages/MessageRequestHandler.cs | 26 +++++++++++++++---- .../RequestProtocols/Messages/RequestType.cs | 25 +++++++++++++----- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs index c86a1def2..cb3330d96 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs @@ -9,6 +9,7 @@ public interface IMessageRequestHandler void Terminate(); void MessageReceived(int from, ConsensusMessage msg, RequestType type); bool IsProtocolComplete(); + List<(ConsensusMessage, int)> GetNewRequests(IProtocolIdentifier protocolId, int requestCount); List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 36d5884b2..228e6438a 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -70,8 +70,19 @@ public bool IsProtocolComplete() return _remainingMsges == _msgCount; } + [MethodImpl(MethodImplOptions.Synchronized)] + public List<(ConsensusMessage, int)> GetNewRequests(IProtocolIdentifier protocolId, int requestCount) + { + return GetRequests(protocolId, requestCount, true); + } + [MethodImpl(MethodImplOptions.Synchronized)] public List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount) + { + return GetRequests(protocolId, requestCount, false); + } + + private List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount, bool excludeRequested) { var requests = new List<(ConsensusMessage, int)>(); if (IsProtocolComplete() || _terminated) return requests; @@ -81,9 +92,15 @@ public bool IsProtocolComplete() while (requestCount > 0) { - var (validtorId, msgId) = _messageRequests.Dequeue(); + var (validtorId, msgId) = _messageRequests.Peek(); if (_status[validtorId][msgId] == MessageStatus.Received) + { + _messageRequests.Dequeue(); continue; + } + + if (_status[validtorId][msgId] == MessageStatus.Requested && excludeRequested) + break; requestCount--; if (_status[validtorId][msgId] == MessageStatus.Requested) { @@ -97,11 +114,10 @@ public bool IsProtocolComplete() Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {validtorId}."); } var msg = CreateConsensusMessage(protocolId, msgId); - if (_type == RequestType.Val) - requests.Add((msg, msg.ValMessage.SenderId)); - else - requests.Add((msg, validtorId)); + var requestingTo = _type == RequestType.Val ? msg.ValMessage.SenderId : validtorId; + requests.Add((msg, requestingTo)); + _messageRequests.Dequeue(); // put this back so we can request it again _messageRequests.Enqueue((validtorId, msgId)); } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs b/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs index f724bc220..7b5122b45 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/RequestType.cs @@ -2,14 +2,25 @@ namespace Lachain.Consensus.RequestProtocols.Messages { public enum RequestType : byte { - Aux = 0, - Bval = 1, + // the lower valaue assigned, the more priority for each protocol + + // messages for BB + Bval = 0, + Aux = 1, Conf = 2, + + // messages for CC Coin = 3, - Val = 4, - SignedHeader = 5, - Ready = 6, - Decrypted = 7, - Echo = 8, + + // messages for Root + SignedHeader = 4, + + // messages for RBC + Val = 5, + Echo = 6, + Ready = 7, + + // messages for HB + Decrypted = 8, } } \ No newline at end of file From e7f3cc4cbbfb480dd1c82102fa8d1a9f6174a57c Mon Sep 17 00:00:00 2001 From: tbssajal Date: Fri, 18 Nov 2022 18:15:52 +0600 Subject: [PATCH 130/133] set myId, skip request for self --- src/Lachain.Consensus/RequestProtocols/RequestManager.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index d844c4c03..549af713f 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -23,6 +23,7 @@ public class RequestManager : IRequestManager private readonly object _queueLock = new object(); private readonly Queue<(int, ConsensusMessage)> _queue; private bool _terminated = false; + private int _myId = -1; public RequestManager(IConsensusBroadcaster broadcaster, long era) { _broadcaster = broadcaster; @@ -60,6 +61,7 @@ public void Terminate() public void SetValidators(int validatorsCount) { _validators = validatorsCount; + _myId = _broadcaster.GetMyId(); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -200,13 +202,19 @@ private void ProcessRequest(int from, RequestConsensusMessage request, long era) private void MakeRequest(object? sender, IProtocolIdentifier protocolId) { // lets not send too many requests + // TODO: Caluclate request size int maxRequestCount = 10; if (_protocolRequestHandler.TryGetValue(protocolId, out var handler)) { var requests = handler.GetRequests(maxRequestCount); foreach (var (msg, validator) in requests) { + if (validator == _myId) continue; _broadcaster.SendToValidator(msg, validator); + var publicKey = _broadcaster.GetPublicKeyById(validator); + Logger.LogTrace( + $"Sending request for consensus message {msg.RequestConsensus.PayloadCase} to validator {publicKey} ({validator})" + ); } } else throw new Exception($"{protocolId} not registered"); From 76772492d92095f12f09ce6c58abc4b7c4186db9 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 22 Nov 2022 01:04:44 +0600 Subject: [PATCH 131/133] added logs and fixed bugs --- .../Messages/IMessageRequestHandler.cs | 1 + .../Messages/MessageRequestHandler.cs | 11 ++++++----- .../RequestProtocols/Messages/Requests/AuxRequest.cs | 2 +- .../RequestProtocols/Messages/Requests/BValRequest.cs | 6 +++--- .../RequestProtocols/Messages/Requests/CoinRequest.cs | 6 +++--- .../RequestProtocols/Messages/Requests/ConfRequest.cs | 6 +++--- .../Messages/Requests/DecryptedRequest.cs | 6 +++--- .../RequestProtocols/Messages/Requests/EchoRequest.cs | 6 +++--- .../Messages/Requests/ReadyRequest.cs | 6 +++--- .../Messages/Requests/SignedHeaderRequest.cs | 6 +++--- .../RequestProtocols/Messages/Requests/ValRequest.cs | 2 +- .../Messages/Resends/DecryptedResend.cs | 2 +- .../Protocols/ProtocolRequestHandler.cs | 11 +++++++++-- .../RequestProtocols/Protocols/ProtocolType.cs | 2 ++ .../RequestProtocols/Protocols/ProtocolUtils.cs | 5 +++++ .../RequestProtocols/RequestManager.cs | 6 +++++- 16 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs index cb3330d96..b9cbe1f5e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs @@ -6,6 +6,7 @@ namespace Lachain.Consensus.RequestProtocols.Messages public interface IMessageRequestHandler { RequestType Type { get; } + int RemainingMsgCount { get; } void Terminate(); void MessageReceived(int from, ConsensusMessage msg, RequestType type); bool IsProtocolComplete(); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 228e6438a..0fbcfccc3 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -16,8 +16,9 @@ public abstract class MessageRequestHandler : IMessageRequestHandler private readonly int _msgPerValidator; private bool _terminated = false; private int _remainingMsges; - private readonly Queue<(int,int)> _messageRequests; + private readonly Queue<(int validatorId, int msgId)> _messageRequests; public RequestType Type => _type; + public int RemainingMsgCount => _remainingMsges; protected MessageRequestHandler(RequestType type, int validatorCount, int msgPerValidator) { _type = type; @@ -67,7 +68,7 @@ protected void MessageReceived(int validatorId, int msgId) public bool IsProtocolComplete() { - return _remainingMsges == _msgCount; + return _remainingMsges == 0; } [MethodImpl(MethodImplOptions.Synchronized)] @@ -113,8 +114,8 @@ public bool IsProtocolComplete() _status[validtorId][msgId] = MessageStatus.Requested; Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {validtorId}."); } - var msg = CreateConsensusMessage(protocolId, msgId); - var requestingTo = _type == RequestType.Val ? msg.ValMessage.SenderId : validtorId; + var msg = CreateConsensusRequestMessage(protocolId, msgId); + var requestingTo = _type == RequestType.Val ? msg.RequestConsensus.RequestVal.SenderId : validtorId; requests.Add((msg, requestingTo)); _messageRequests.Dequeue(); @@ -124,7 +125,7 @@ public bool IsProtocolComplete() return requests; } - protected abstract ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId); + protected abstract ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId); protected abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs index c3864a2db..6767b0590 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Aux request"); var auxRequest = new RequestAuxMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs index 65fe9fa96..62b0ed332 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, msg.Bval.Value ? 1 : 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Bval request"); var bvalRequest = new RequestBValMessage @@ -38,8 +38,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static BinaryBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestBval) + throw new Exception($"{msg.PayloadCase} routed to Bval Request"); return new BinaryBroadcastId(era, msg.RequestBval.Agreement, msg.RequestBval.Epoch); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs index 7b8721afd..8969c0aaf 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as CoinId ?? throw new Exception($"wrong protcolId {protocolId} for Coin request"); var coinRequest = new RequestCommonCoinMessage @@ -38,8 +38,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static CoinId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestCoin) + throw new Exception($"{msg.PayloadCase} routed to Coin Request"); return new CoinId(era, msg.RequestCoin.Agreement, msg.RequestCoin.Epoch); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs index de9d0cc09..f1c26d379 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Conf request"); var confRequest = new RequestConfMessage @@ -38,8 +38,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static BinaryBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestConf) + throw new Exception($"{msg.PayloadCase} routed to Conf Request"); return new BinaryBroadcastId(era, msg.RequestConf.Agreement, msg.RequestConf.Epoch); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs index a005f1675..4f736bef4 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, msg.Decrypted.ShareId); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int msgId) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId) { var id = protocolId as HoneyBadgerId ?? throw new Exception($"wrong protcolId {protocolId} for Decrypted request"); var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage @@ -37,8 +37,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static HoneyBadgerId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestDecrypted) + throw new Exception($"{msg.PayloadCase} routed to Decrypted Request"); return new HoneyBadgerId(era); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs index 82b87934d..5bf4b00df 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Echo request"); var echoRequest = new RequestECHOMessage @@ -37,8 +37,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static ReliableBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestEcho) + throw new Exception($"{msg.PayloadCase} routed to Echo Request"); return new ReliableBroadcastId(msg.RequestEcho.SenderId, (int) era); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs index e2d7344a4..7497e4fd7 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Ready request"); var readyRequest = new RequestReadyMessage @@ -37,8 +37,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static ReliableBroadcastId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestReady) + throw new Exception($"{msg.PayloadCase} routed to Ready Request"); return new ReliableBroadcastId(msg.RequestReady.SenderId, (int) era); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs index 74f321af9..465a7178e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as RootProtocolId ?? throw new Exception($"wrong protcolId {protocolId} for Signed Header request"); var headerRequest = new RequestSignedHeaderMessage(); @@ -34,8 +34,8 @@ protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier p public static RootProtocolId CreateProtocolId(RequestConsensusMessage msg, long era) { - if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestAux) - throw new Exception($"{msg.PayloadCase} routed to Aux Request"); + if (msg.PayloadCase != RequestConsensusMessage.PayloadOneofCase.RequestSignedHeader) + throw new Exception($"{msg.PayloadCase} routed to Signed Header Request"); return new RootProtocolId(era); } } diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs index a65f4b4f3..86fb6b65b 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int _from, ConsensusMessage msg) MessageReceived(0, 0); } - protected override ConsensusMessage CreateConsensusMessage(IProtocolIdentifier protocolId, int _) + protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Val request"); var valRequest = new RequestValMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs index c0531238b..e7f2609b8 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Resends/DecryptedResend.cs @@ -15,7 +15,7 @@ public DecryptedResend(RequestType type, int validatorCount, int msgPerValidator protected override void HandleSentMessage(int validator, ConsensusMessage msg) { if (msg.PayloadCase != ConsensusMessage.PayloadOneofCase.Decrypted) - throw new Exception($"{msg.PayloadCase} message routed to Decrypted request"); + throw new Exception($"{msg.PayloadCase} message routed to Decrypted Resend"); SaveMessage(validator, msg.Decrypted.ShareId, msg); } diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index 8c9a1c7a4..54fbb2ffc 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -72,25 +72,32 @@ private void MessageReceived(object? sender, (int from, ConsensusMessage msg) @e var allRequests = new List<(ConsensusMessage, int)>(); if (_terminated) return allRequests; + + var remainingMsgCount = new List<(RequestType type, int count)>(); // first do new requests foreach (var requestType in _orderedRequestTypes) { if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) { + var count = handler.RemainingMsgCount; var requests = handler.GetNewRequests(_protocolId, requestCount); requestCount -= requests.Count; allRequests.AddRange(requests); + remainingMsgCount.Add((requestType, count - requests.Count)); } else throw new Exception($"MessageRequestHandler {requestType} not registered"); } // then do repeated requests - foreach (var requestType in _orderedRequestTypes) + foreach (var (requestType, count) in remainingMsgCount) { if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) { - var requests = handler.GetRequests(_protocolId, requestCount); + var msgToFetch = count; + if (count > requestCount) + msgToFetch = requestCount; + var requests = handler.GetRequests(_protocolId, msgToFetch); requestCount -= requests.Count; allRequests.AddRange(requests); } diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs index 987981caa..9df1fea3e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolType.cs @@ -7,5 +7,7 @@ public enum ProtocolType : byte ReliableBroadcast = 2, BinaryBroadcast = 3, CommonCoin = 4, + CommonSubset = 5, + BinaryAgreement = 6, } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs index 40b8f23f6..cd603dd07 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolUtils.cs @@ -1,6 +1,7 @@ using System; using Lachain.Consensus.BinaryAgreement; using Lachain.Consensus.CommonCoin; +using Lachain.Consensus.CommonSubset; using Lachain.Consensus.HoneyBadger; using Lachain.Consensus.ReliableBroadcast; using Lachain.Consensus.RequestProtocols.Messages; @@ -18,8 +19,12 @@ public static ProtocolType GetProtocolType(IProtocolIdentifier id) return ProtocolType.Root; case HoneyBadgerId _: return ProtocolType.HoneyBadger; + case CommonSubsetId _: + return ProtocolType.CommonSubset; case ReliableBroadcastId _: return ProtocolType.ReliableBroadcast; + case BinaryAgreementId _: + return ProtocolType.BinaryAgreement; case BinaryBroadcastId _: return ProtocolType.BinaryBroadcast; case CoinId _: diff --git a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs index 549af713f..4c69a5fbf 100644 --- a/src/Lachain.Consensus/RequestProtocols/RequestManager.cs +++ b/src/Lachain.Consensus/RequestProtocols/RequestManager.cs @@ -8,6 +8,7 @@ using Lachain.Consensus.RequestProtocols.Protocols; using Lachain.Logger; using Lachain.Proto; +using Lachain.Utility.Utils; namespace Lachain.Consensus.RequestProtocols { @@ -185,6 +186,8 @@ private void ProcessRequest(int from, RequestConsensusMessage request, long era) { try { + var pubKey = _broadcaster.GetPublicKeyById(from); + Logger.LogTrace($"Got consensus request {type} for {protocolId} from {pubKey!.ToHex()} ({from})"); var response = handler.HandleRequest(from, request, type); foreach (var msg in response) { @@ -207,13 +210,14 @@ private void MakeRequest(object? sender, IProtocolIdentifier protocolId) if (_protocolRequestHandler.TryGetValue(protocolId, out var handler)) { var requests = handler.GetRequests(maxRequestCount); + Logger.LogTrace($"{protocolId} is making {requests.Count} consensus requests"); foreach (var (msg, validator) in requests) { if (validator == _myId) continue; _broadcaster.SendToValidator(msg, validator); var publicKey = _broadcaster.GetPublicKeyById(validator); Logger.LogTrace( - $"Sending request for consensus message {msg.RequestConsensus.PayloadCase} to validator {publicKey} ({validator})" + $"Sending request for consensus message {msg.RequestConsensus.PayloadCase} to validator {publicKey!.ToHex()} ({validator})" ); } } From aba8fe3130683917cf3a2edec9b4417c5561f4b2 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 22 Nov 2022 01:24:45 +0600 Subject: [PATCH 132/133] fixed bug and reduced waiting time --- src/Lachain.Consensus/AbstractProtocol.cs | 2 +- .../RequestProtocols/Messages/MessageRequestHandler.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Lachain.Consensus/AbstractProtocol.cs b/src/Lachain.Consensus/AbstractProtocol.cs index 73e53aa6b..3836042ec 100644 --- a/src/Lachain.Consensus/AbstractProtocol.cs +++ b/src/Lachain.Consensus/AbstractProtocol.cs @@ -42,7 +42,7 @@ public abstract class AbstractProtocol : IConsensusProtocol // waiting for 10 block time // TODO: calculate _requestTime properly - private const ulong _requestTime = 10 * 4 * 1000; + private const ulong _requestTime = 5 * 4 * 1000; protected AbstractProtocol( IPublicConsensusKeySet wallet, diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index 0fbcfccc3..d8f2e458d 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -103,20 +103,20 @@ public bool IsProtocolComplete() if (_status[validtorId][msgId] == MessageStatus.Requested && excludeRequested) break; requestCount--; + var msg = CreateConsensusRequestMessage(protocolId, msgId); + var requestingTo = _type == RequestType.Val ? msg.RequestConsensus.RequestVal.SenderId : validtorId; + requests.Add((msg, requestingTo)); if (_status[validtorId][msgId] == MessageStatus.Requested) { Logger.LogWarning( - $"Requesting consensus msg {_type} with id {msgId} to validator {validtorId} again. Validator not replying." + $"Requesting consensus msg {_type} with id {msgId} to validator {requestingTo} again. Validator not replying." ); } else { _status[validtorId][msgId] = MessageStatus.Requested; - Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {validtorId}."); + Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {requestingTo}."); } - var msg = CreateConsensusRequestMessage(protocolId, msgId); - var requestingTo = _type == RequestType.Val ? msg.RequestConsensus.RequestVal.SenderId : validtorId; - requests.Add((msg, requestingTo)); _messageRequests.Dequeue(); // put this back so we can request it again From 623271f6e34b7414fbcf72da4ce3a43d309cbd60 Mon Sep 17 00:00:00 2001 From: tbssajal Date: Tue, 22 Nov 2022 21:53:12 +0600 Subject: [PATCH 133/133] fixed logic for periodic request of consensus messages --- .../Messages/IMessageRequestHandler.cs | 9 +- .../Messages/MessageRequestHandler.cs | 74 ++++++---------- .../Messages/Requests/AuxRequest.cs | 2 +- .../Messages/Requests/BValRequest.cs | 2 +- .../Messages/Requests/CoinRequest.cs | 2 +- .../Messages/Requests/ConfRequest.cs | 2 +- .../Messages/Requests/DecryptedRequest.cs | 2 +- .../Messages/Requests/EchoRequest.cs | 2 +- .../Messages/Requests/ReadyRequest.cs | 2 +- .../Messages/Requests/SignedHeaderRequest.cs | 2 +- .../Messages/Requests/ValRequest.cs | 2 +- .../Protocols/ProtocolRequestHandler.cs | 87 +++++++++++++------ 12 files changed, 105 insertions(+), 83 deletions(-) diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs index b9cbe1f5e..9997830d1 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/IMessageRequestHandler.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System; using Lachain.Proto; namespace Lachain.Consensus.RequestProtocols.Messages @@ -8,9 +8,12 @@ public interface IMessageRequestHandler RequestType Type { get; } int RemainingMsgCount { get; } void Terminate(); + Tuple? Peek(); + void Dequeue(); + void Enqueue(int validatorId, int msgId, ulong requestTime); + void MessageRequested(int validatorId, int msgId); void MessageReceived(int from, ConsensusMessage msg, RequestType type); bool IsProtocolComplete(); - List<(ConsensusMessage, int)> GetNewRequests(IProtocolIdentifier protocolId, int requestCount); - List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount); + ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs index d8f2e458d..817d225d4 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/MessageRequestHandler.cs @@ -16,7 +16,7 @@ public abstract class MessageRequestHandler : IMessageRequestHandler private readonly int _msgPerValidator; private bool _terminated = false; private int _remainingMsges; - private readonly Queue<(int validatorId, int msgId)> _messageRequests; + private readonly Queue<(int validatorId, int msgId, ulong requestTime)> _messageRequests; public RequestType Type => _type; public int RemainingMsgCount => _remainingMsges; protected MessageRequestHandler(RequestType type, int validatorCount, int msgPerValidator) @@ -26,14 +26,14 @@ protected MessageRequestHandler(RequestType type, int validatorCount, int msgPer _msgCount = validatorCount * msgPerValidator; _msgPerValidator = msgPerValidator; _status = new MessageStatus[_validators][]; - _messageRequests = new Queue<(int, int)>(); + _messageRequests = new Queue<(int, int, ulong)>(); for (int i = 0 ; i < _validators ; i++) { _status[i] = new MessageStatus[msgPerValidator]; for (int j = 0; j < msgPerValidator; j++) { _status[i][j] = MessageStatus.NotReceived; - _messageRequests.Enqueue((i,j)); + _messageRequests.Enqueue((i, j, 0)); } } _remainingMsges = _msgCount; @@ -72,60 +72,42 @@ public bool IsProtocolComplete() } [MethodImpl(MethodImplOptions.Synchronized)] - public List<(ConsensusMessage, int)> GetNewRequests(IProtocolIdentifier protocolId, int requestCount) + public Tuple? Peek() { - return GetRequests(protocolId, requestCount, true); - } - - [MethodImpl(MethodImplOptions.Synchronized)] - public List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount) - { - return GetRequests(protocolId, requestCount, false); - } - - private List<(ConsensusMessage, int)> GetRequests(IProtocolIdentifier protocolId, int requestCount, bool excludeRequested) - { - var requests = new List<(ConsensusMessage, int)>(); - if (IsProtocolComplete() || _terminated) return requests; - - if (requestCount > _remainingMsges) - requestCount = _remainingMsges; - - while (requestCount > 0) + while (_messageRequests.Count > 0) { - var (validtorId, msgId) = _messageRequests.Peek(); - if (_status[validtorId][msgId] == MessageStatus.Received) + var (validatorId, msgId, requestTime) = _messageRequests.Peek(); + if (_status[validatorId][msgId] == MessageStatus.Received) { _messageRequests.Dequeue(); - continue; - } - - if (_status[validtorId][msgId] == MessageStatus.Requested && excludeRequested) - break; - requestCount--; - var msg = CreateConsensusRequestMessage(protocolId, msgId); - var requestingTo = _type == RequestType.Val ? msg.RequestConsensus.RequestVal.SenderId : validtorId; - requests.Add((msg, requestingTo)); - if (_status[validtorId][msgId] == MessageStatus.Requested) - { - Logger.LogWarning( - $"Requesting consensus msg {_type} with id {msgId} to validator {requestingTo} again. Validator not replying." - ); } else { - _status[validtorId][msgId] = MessageStatus.Requested; - Logger.LogWarning($"Requesting consensus msg {_type} with id {msgId} to validator {requestingTo}."); + return Tuple.Create(validatorId, msgId, requestTime, _status[validatorId][msgId]); } - - _messageRequests.Dequeue(); - // put this back so we can request it again - _messageRequests.Enqueue((validtorId, msgId)); } - return requests; + return null; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void Dequeue() + { + _messageRequests.Dequeue(); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void Enqueue(int validatorId, int msgId, ulong requestTime) + { + _messageRequests.Enqueue((validatorId, msgId, requestTime)); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void MessageRequested(int validatorId, int msgId) + { + _status[validatorId][msgId] = MessageStatus.Requested; } - protected abstract ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId); + public abstract ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId); protected abstract void HandleReceivedMessage(int from, ConsensusMessage msg); } } \ No newline at end of file diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs index 6767b0590..ba5a05c6e 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/AuxRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Aux request"); var auxRequest = new RequestAuxMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs index 62b0ed332..7289199b0 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/BValRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, msg.Bval.Value ? 1 : 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Bval request"); var bvalRequest = new RequestBValMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs index 8969c0aaf..b0ce25528 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/CoinRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as CoinId ?? throw new Exception($"wrong protcolId {protocolId} for Coin request"); var coinRequest = new RequestCommonCoinMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs index f1c26d379..c4877c959 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ConfRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as BinaryBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Conf request"); var confRequest = new RequestConfMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs index 4f736bef4..d77c6a236 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/DecryptedRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, msg.Decrypted.ShareId); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int msgId) { var id = protocolId as HoneyBadgerId ?? throw new Exception($"wrong protcolId {protocolId} for Decrypted request"); var decryptedRequest = new RequestTPKEPartiallyDecryptedShareMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs index 5bf4b00df..2141f32d8 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/EchoRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Echo request"); var echoRequest = new RequestECHOMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs index 7497e4fd7..295ffcb52 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ReadyRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Ready request"); var readyRequest = new RequestReadyMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs index 465a7178e..43ef84b1a 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/SignedHeaderRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int from, ConsensusMessage msg) MessageReceived(from, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as RootProtocolId ?? throw new Exception($"wrong protcolId {protocolId} for Signed Header request"); var headerRequest = new RequestSignedHeaderMessage(); diff --git a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs index 86fb6b65b..556438767 100644 --- a/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs +++ b/src/Lachain.Consensus/RequestProtocols/Messages/Requests/ValRequest.cs @@ -19,7 +19,7 @@ protected override void HandleReceivedMessage(int _from, ConsensusMessage msg) MessageReceived(0, 0); } - protected override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) + public override ConsensusMessage CreateConsensusRequestMessage(IProtocolIdentifier protocolId, int _) { var id = protocolId as ReliableBroadcastId ?? throw new Exception($"wrong protcolId {protocolId} for Val request"); var valRequest = new RequestValMessage diff --git a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs index 54fbb2ffc..2daef4f5c 100644 --- a/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs +++ b/src/Lachain.Consensus/RequestProtocols/Protocols/ProtocolRequestHandler.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Linq; using Lachain.Consensus.RequestProtocols.Messages; using Lachain.Consensus.RequestProtocols.Messages.Requests; using Lachain.Logger; using Lachain.Proto; +using Lachain.Utility.Utils; namespace Lachain.Consensus.RequestProtocols.Protocols { @@ -60,52 +62,87 @@ private void MessageReceived(object? sender, (int from, ConsensusMessage msg) @e return; var (from, msg) = @event; var type = MessageUtils.GetRequestTypeForMessageType(msg); - if (_messageHandlers.TryGetValue((byte) type, out var handler)) - { - handler.MessageReceived(from, msg, type); - } - else throw new Exception($"MessageRequestHandler {type} not registered"); + var handler = GetMessageHandler(type); + handler.MessageReceived(from, msg, type); } + [MethodImpl(MethodImplOptions.Synchronized)] public List<(ConsensusMessage, int)> GetRequests(int requestCount) { var allRequests = new List<(ConsensusMessage, int)>(); if (_terminated) return allRequests; - var remainingMsgCount = new List<(RequestType type, int count)>(); - - // first do new requests + // Tuple + var processedRequest = new List>(); + // getting requests that are not requested yet foreach (var requestType in _orderedRequestTypes) { - if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + var handler = GetMessageHandler(requestType); + while (requestCount > 0) { - var count = handler.RemainingMsgCount; - var requests = handler.GetNewRequests(_protocolId, requestCount); - requestCount -= requests.Count; - allRequests.AddRange(requests); - remainingMsgCount.Add((requestType, count - requests.Count)); + var peekRequest = handler.Peek(); + if (peekRequest is null) break; + var (validatorId, msgId, _, status) = peekRequest; + if (status != MessageStatus.NotReceived) break; + processedRequest.Add(Tuple.Create(validatorId, msgId, requestType)); + handler.Dequeue(); + requestCount--; } - else throw new Exception($"MessageRequestHandler {requestType} not registered"); } - // then do repeated requests - foreach (var (requestType, count) in remainingMsgCount) + // getting requests that were requested but did not get any reply + while (requestCount > 0) { - if (_messageHandlers.TryGetValue((byte) requestType, out var handler)) + Tuple? request = null; + RequestType type = 0; // this is wrong, but for the sake of implementation + foreach (var requestType in _orderedRequestTypes) + { + var handler = GetMessageHandler(requestType); + var peekRequest = handler.Peek(); + if (!(peekRequest is null)) + { + // taking request that was not requested recently + if ((request is null) || request.Item3 > peekRequest.Item3) + { + request = peekRequest; + type = requestType; + } + } + } + if (!(request is null)) { - var msgToFetch = count; - if (count > requestCount) - msgToFetch = requestCount; - var requests = handler.GetRequests(_protocolId, msgToFetch); - requestCount -= requests.Count; - allRequests.AddRange(requests); + var (validatorId, msgId, _, _) = request; + processedRequest.Add(Tuple.Create(validatorId, msgId, type)); + var handler = GetMessageHandler(type); + handler.Dequeue(); + requestCount--; } - else throw new Exception($"MessageRequestHandler {requestType} not registered"); + else break; + } + + var currentTime = TimeUtils.CurrentTimeMillis(); + foreach (var (validatorId, msgId, type) in processedRequest) + { + var handler = GetMessageHandler(type); + // enqueueing them to request again + handler.Enqueue(validatorId, msgId, currentTime); + handler.MessageRequested(validatorId, msgId); + var msg = handler.CreateConsensusRequestMessage(_protocolId, msgId); + var requestingTo = type == RequestType.Val ? msg.RequestConsensus.RequestVal.SenderId : validatorId; + Logger.LogTrace($"Requesting consensus message {type} of id {msgId} for {_protocolId} to validator {requestingTo}"); + allRequests.Add((msg, requestingTo)); } return allRequests; } + private IMessageRequestHandler GetMessageHandler(RequestType type) + { + if (!_messageHandlers.TryGetValue((byte) type, out var handler)) + throw new Exception($"MessageRequestHandler {type} not registered"); + return handler; + } + private IMessageRequestHandler RegisterMessageHandler(RequestType type) { switch (type)