private List <string> ValidateNode(ServerNode serverNode)
        {
            var validationErrors = new List <string>();

            if (serverNode == null)
            {
                validationErrors.Add("The node can not be null!");
                return(validationErrors);
            }

            if (serverNode.Id == null)
            {
                validationErrors.Add("The node's id can not be null!");
            }

            if (serverNode.HttpAddress == null)
            {
                validationErrors.Add("The node's HTTP address cannot be null!");
            }

            if (serverNode.Id != null && ServerNodes.ContainsKey(serverNode.Id))
            {
                validationErrors.Add($"The node's id already exists id: {serverNode.Id}!");
            }

            return(validationErrors);
        }
        private void CreateNodeConnection(ServerNode serverNode)
        {
            _backgroundQueue.Enqueue(async token =>
            {
                var url = $"{serverNode.HttpAddress}/consensusHub";
                serverNode.HubConnection = new HubConnectionBuilder().WithUrl(url).Build();

                // Reconnect when connection is closing
                serverNode.HubConnection.Closed += async error =>
                {
                    await Task.Delay(new Random().Next(0, 5) * 1000, token);
                    await serverNode.HubConnection.StartAsync(token);
                };

                // Register action: acceptance of external block
                const string methodName = nameof(IConsensusClient.ReceiveBlock);
                serverNode.HubConnection.On <EncodedBlock>(methodName, AcceptExternalBlock);

                // Start the connection
                await serverNode.HubConnection.StartAsync(token);

                // Sets the connection status
                serverNode.IsConnected = true;
            });
        }
        public BaseResponse <ServerNode> ConnectNode(ServerNode serverNode)
        {
            var validationErrors = ValidateNode(serverNode);

            if (validationErrors.Any())
            {
                return(new ErrorResponse <ServerNode>("Invalid input node", serverNode, validationErrors.ToArray()));
            }

            serverNode.IsConnected = null;
            CreateNodeConnection(serverNode);

            if (!_serverNodesStorage.ServerNodes.TryAdd(serverNode.Id, serverNode))
            {
                return(new ErrorResponse <ServerNode>($"Could not add a node with id: {serverNode.Id}", serverNode));
            }

            return(new SuccessResponse <ServerNode>("The node has been added successfully!", serverNode));
        }