private async Task DownloadBlockchainAsync(long startId)
        {
            var webInfo = await LicensorClient.Instance.GetBlockchainInfoAsync().ConfigureAwait(false);

            BlockchainDataRestorer dataRestorer = new BlockchainDataRestorer();

            try
            {
                BlockchainInfo ownInfo = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false);

                List <BlockVm> newBlocks = default;
                for (long i = startId; i < webInfo.Count; i += 100)
                {
                    if (webInfo.Count - ownInfo.Count > 100)
                    {
                        newBlocks = await LicensorClient.Instance.GetBlockchainBlocksAsync(i, i + 100).ConfigureAwait(false);
                    }
                    else
                    {
                        newBlocks = await LicensorClient.Instance.GetBlockchainBlocksAsync(ownInfo.Count, webInfo.Count).ConfigureAwait(false);
                    }
                    if (newBlocks != null)
                    {
                        foreach (BlockVm block in newBlocks)
                        {
                            using (BlockchainDbContext context = new BlockchainDbContext())
                            {
                                try
                                {
                                    await context.Blocks.AddAsync(BlockBuilder.GetBlock(block)).ConfigureAwait(false);

                                    await context.SaveChangesAsync().ConfigureAwait(false);

                                    await dataRestorer.SaveBlockDataAsync(block).ConfigureAwait(false);
                                }
                                catch (Exception ex)
                                {
                                    Logger.WriteLog(ex);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
            }
        }
        public async Task HandleAsync()
        {
            try
            {
                BlockchainInfo info = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false);

                BlockchainInfoNodeResponse response = new BlockchainInfoNodeResponse(request.RequestId, info);
                NodeWebSocketCommunicationManager.SendResponse(response, current);
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                NodeWebSocketCommunicationManager.SendResponse(new ResultNodeResponse(request.RequestId, ErrorCode.UnknownError), current);
            }
        }
        public async Task CheckAndSyncBlockchainAsync()
        {
            var startBlockId = await CommonBlockchainPartSearchAsync().ConfigureAwait(false);

            BlockchainInfo blockchainInfo = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false);

            var webInfo = await LicensorClient.Instance.GetBlockchainInfoAsync().ConfigureAwait(false);

            if (startBlockId < blockchainInfo.Count)
            {
                await SaveAndRemoveOldBlocksAsync(startBlockId).ConfigureAwait(false);
                await DownloadBlockchainAsync(startBlockId).ConfigureAwait(false);
                await RestoreOldBlockchainDataAsync().ConfigureAwait(false);
            }
            else if (startBlockId < webInfo.Count)
            {
                await DownloadBlockchainAsync(startBlockId).ConfigureAwait(false);
            }
        }
        public async Task <IActionResult> Index()
        {
            var model = new ConfigsModel
            {
                AllowedRegistration    = NodeSettings.Configs.AllowedRegistration,
                AnotherNodesUrls       = NodeSettings.Configs.AnotherNodesUrls,
                BlockchainDbConnection = NodeSettings.Configs.BlockchainDbConnection ?? new DatabaseConnectionInfo(),
                CacheServerConnection  = NodeSettings.Configs.CacheServerConnection ?? new CacheServerConnectionInfo(),
                Certificate            = NodeSettings.Configs.Certificate,
                ConfirmUsers           = NodeSettings.Configs.ConfirmUsers,
                LicensorUrl            = NodeSettings.Configs.LicensorUrl,
                MaxDbBackups           = NodeSettings.Configs.MaxDbBackups,
                MessengerDbConnection  = NodeSettings.Configs.MessengerDbConnection ?? new DatabaseConnectionInfo(),
                Node                      = NodeSettings.Configs.Node,
                NodesUrls                 = NodeSettings.Configs.NodesUrls,
                NotificationServerURL     = NodeSettings.Configs.NotificationServerURL,
                OpenStackOptions          = NodeSettings.Configs.OpenStackOptions ?? new OpenStackOptions(),
                SmtpClient                = NodeSettings.Configs.SmtpClient ?? new SmtpClientInfo(),
                NodeKeys                  = NodeData.Instance.NodeKeys,
                RecoveryMode              = NodeSettings.Configs.RecoveryMode,
                TrustedIps                = NodeSettings.Configs.TrustedIps,
                BlockchainInfo            = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false),
                ClientsPort               = NodeSettings.Configs.Node.ClientsPort,
                NodesPort                 = NodeSettings.Configs.Node.NodesPort,
                License                   = NodeSettings.Configs.License,
                S3FileStorageOptions      = NodeSettings.Configs.S3FileStorageOptions,
                ContriesISO               = GetCountriesISO(),
                SMSRUServiceConfiguration = NodeSettings.Configs.SmsServiceConfiguration is SMSRUServiceConfiguration
                    ? (SMSRUServiceConfiguration)NodeSettings.Configs.SmsServiceConfiguration : new SMSRUServiceConfiguration(),
                SMSIntelServiceConfiguration = NodeSettings.Configs.SmsServiceConfiguration is SMSIntelServiceConfiguration
                    ? (SMSIntelServiceConfiguration)NodeSettings.Configs.SmsServiceConfiguration : new SMSIntelServiceConfiguration(),
                BSGServiceConfiguration = NodeSettings.Configs.SmsServiceConfiguration is BSGServiceConfiguration
                    ? (BSGServiceConfiguration)NodeSettings.Configs.SmsServiceConfiguration : new BSGServiceConfiguration(),
                GolosAlohaServiceConfiguration = NodeSettings.Configs.SmsServiceConfiguration is VoiceServiceConfiguration
                    ? (VoiceServiceConfiguration)NodeSettings.Configs.SmsServiceConfiguration : new VoiceServiceConfiguration()
            };

            return(View(model));
        }
        private async Task <long> CommonBlockchainPartSearchAsync()
        {
            using (WebClient webClient = new WebClient())
            {
                BlockchainInfo blockchainInfo = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false);

                long   blockId      = -1;
                long   tempBlockId  = blockchainInfo.BlockHashes.Min(opt => opt.FirstValue);
                byte[] responseData = await webClient.UploadDataTaskAsync(
                    $"https://{NodeSettings.Configs.LicensorUrl}/api/Blockchain/FindMatch", ObjectSerializer.ObjectToByteArray(blockchainInfo)).ConfigureAwait(false);

                blockId = BitConverter.ToInt64(responseData);
                while (blockId == -1)
                {
                    blockchainInfo = await BlockchainReadService.GetBlockchainInformationAsync(tempBlockId).ConfigureAwait(false);

                    if (!blockchainInfo.BlockHashes.Any())
                    {
                        return(1);
                    }
                    if (blockchainInfo.BlockHashes.Min(opt => opt.FirstValue) == 1)
                    {
                        return(1);
                    }
                    responseData = await webClient.UploadDataTaskAsync(
                        $"https://{NodeSettings.Configs.LicensorUrl}/api/Blockchain/FindMatch", ObjectSerializer.ObjectToByteArray(blockchainInfo)).ConfigureAwait(false);

                    blockId     = BitConverter.ToInt64(responseData);
                    tempBlockId = blockchainInfo.BlockHashes.Min(opt => opt.FirstValue);
                }
                if (blockId != -1)
                {
                    return(blockId);
                }
                return(1);
            }
        }
        public async Task <ActionResult> Restore([FromForm] BlockchainRestoreModel model)
        {
            BlockchainInfo blockchainInfo = await BlockchainReadService.GetBlockchainInformationAsync().ConfigureAwait(false);

            if (model.Start == null)
            {
                model.Start = blockchainInfo.FirstBlockTime;
            }
            if (model.End == null)
            {
                model.End = blockchainInfo.LastBlockTime;
            }
            if (model.End < model.Start)
            {
                return(BadRequest());
            }

            List <BlockVm> blocks = await BlockchainReadService.GetBlocksAsync(
                model.Start.GetValueOrDefault().ToUnixTime(),
                model.End.GetValueOrDefault().ToUnixTime(),
                BLOCKS_LIMIT).ConfigureAwait(false);

            while (blocks.Count == BLOCKS_LIMIT &&
                   blocks.LastOrDefault().Header.CreationTime < model.End.GetValueOrDefault().ToUnixTime())
            {
                foreach (var block in blocks)
                {
                    await _blockchainDataRestorer.SaveBlockDataAsync(block).ConfigureAwait(false);
                }
                blocks = await BlockchainReadService.GetBlocksAsync(
                    blocks.LastOrDefault().Header.CreationTime,
                    null,
                    BLOCKS_LIMIT).ConfigureAwait(false);
            }
            return(RedirectToAction("Index", "Configuration"));
        }