public async Task <string> AddNewOperationAsync(long nodeId, long userId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                long currentTime          = DateTime.UtcNow.ToUnixTime();
                var  uncomplededOperation = await context.ChangeUserNodeOperations
                                            .FirstOrDefaultAsync(opt => !opt.Completed && opt.UserId == userId && opt.ExpirationTime > currentTime).ConfigureAwait(false);

                if (uncomplededOperation != null)
                {
                    context.Remove(uncomplededOperation);
                }
                ChangeUserNodeOperation operation = new ChangeUserNodeOperation
                {
                    NodeId         = nodeId,
                    UserId         = userId,
                    OperationId    = RandomExtensions.NextString(64),
                    Completed      = false,
                    RequestTime    = currentTime,
                    ExpirationTime = currentTime + (long)TimeSpan.FromDays(1).TotalSeconds
                };
                await context.AddAsync(operation).ConfigureAwait(false);

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

                return(operation.OperationId);
            }
        }
        public async Task <ChangeUserNodeOperation> CompleteOperationAsync(string operationId, long nodeId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                ChangeUserNodeOperation operation = await context.ChangeUserNodeOperations
                                                    .FirstOrDefaultAsync(opt => opt.NodeId == nodeId && opt.OperationId == operationId)
                                                    .ConfigureAwait(false);

                operation.Completed = true;
                context.ChangeUserNodeOperations.Update(operation);
                await context.SaveChangesAsync().ConfigureAwait(false);

                return(operation);
            }
        }
        public async Task <long> GetOperationUserIdAsync(string operationId, long nodeId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                ChangeUserNodeOperation operation = await context.ChangeUserNodeOperations
                                                    .AsNoTracking()
                                                    .FirstOrDefaultAsync(opt => opt.NodeId == nodeId && opt.OperationId == operationId)
                                                    .ConfigureAwait(false);

                if (operation != null)
                {
                    return(operation.UserId);
                }
                else
                {
                    throw new ArgumentNullException(nameof(operationId));
                }
            }
        }
        public async Task <IActionResult> OperationCompleted([FromHeader] string encryptedOperationId, [FromHeader] string nodeId)
        {
            try
            {
                var nodeConnection = connectionsService.GetNodeConnection(Convert.ToInt64(nodeId));
                if (nodeConnection != null)
                {
                    byte[] decryptedRequestData = Encryptor.SymmetricDataDecrypt(
                        Convert.FromBase64String(encryptedOperationId),
                        nodeConnection.SignPublicKey,
                        nodeConnection.SymmetricKey,
                        NodeData.Instance.NodeKeys.Password).DecryptedData;
                    string operationId = Encoding.UTF8.GetString(decryptedRequestData);
                    ChangeUserNodeOperation operation = await changeNodeOperationsService.CompleteOperationAsync(operationId, nodeConnection.Node.Id).ConfigureAwait(false);

                    await updateUsersService.EditUserNodeAsync(operation.UserId, nodeConnection.Node.Id).ConfigureAwait(false);

                    await deleteUsersService.DeleteUserInformationAsync(operation.UserId).ConfigureAwait(false);

                    nodeNoticeService.SendUserNodeChangedNodeNoticeAsync(operation.UserId, nodeConnection.Node.Id);
                    noticeService.SendUserNodeChangedNoticeAsync(operation.UserId, nodeConnection.Node.Id);
                    BlockSegmentVm segment = await BlockSegmentsService.Instance.CreateUserNodeChangedSegmentAsync(
                        operation.UserId,
                        nodeConnection.Node.Id,
                        NodeSettings.Configs.Node.Id).ConfigureAwait(false);

                    BlockGenerationHelper.Instance.AddSegment(segment);
                    return(StatusCode(StatusCodes.Status200OK));
                }
                return(StatusCode(StatusCodes.Status400BadRequest));
            }
            catch (CryptographicException)
            {
                return(StatusCode(StatusCodes.Status403Forbidden));
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                return(StatusCode(StatusCodes.Status500InternalServerError));
            }
        }