public IActionResult Process(Transaction transaction)
        {
            try
            {
                lock (lockDns)
                {
                    var auths = Parse(transaction.Data);
                    var ids   = auths.Select(log => log.TranId).ToList();
                    using (_logger.BeginScope(ids))
                    {
                        if (!ids.Any())
                        {
                            return(new OkResult());
                        }

                        var pendingLogs = _blockchain.SelectPendingLogs(ids, _threshold - 1);
                        var toUpdate    = _blockchain.SelectLogs(ids);
                        var toUpdateIds = toUpdate.Select(log => log.TranId);

                        foreach (var log in toUpdate)
                        {
                            var pending = auths.SingleOrDefault(l => l.TranId == log.TranId);
                            if (pending.Successful)
                            {
                                log.SuccessfulOrks += "|" + pending.OrkId;
                            }
                            else
                            {
                                log.UnsuccessfulOrks += "|" + pending.OrkId;
                            }
                        }

                        var toInsert =
                            (from p in pendingLogs.Where(log => log.Count >= _threshold - 1 && !toUpdateIds.Contains(log.TranId))
                             join n in auths on new { p.TranId, p.Successful } equals new { n.TranId, n.Successful }
                             where p.Count + 1 >= _threshold
                             select new Auth()
                        {
                            TranId = p.TranId,
                            Successful = p.Successful,
                            Method = n.Method,
                            Uid = n.Uid,
                            SuccessfulOrks = p.Successful ? p.Orks + "|" + n.OrkId : string.Empty,
                            UnsuccessfulOrks = !p.Successful ? p.Orks + "|" + n.OrkId : string.Empty,
                            Time = DateTimeOffset.UtcNow
                        }).ToList();

                        foreach (var log in toInsert)
                        {
                            var pending = pendingLogs.SingleOrDefault(l => l.TranId == log.TranId && l.Successful != log.Successful);
                            if (pending == null)
                            {
                                continue;
                            }

                            if (pending.Successful)
                            {
                                log.SuccessfulOrks = pending.Orks;
                            }
                            else
                            {
                                log.UnsuccessfulOrks = pending.Orks;
                            }
                        }

                        var toPending = auths.Where(auth => !toInsert.Any(ins => ins.TranId == auth.TranId) && !toUpdate.Any(itm2 => itm2.TranId == auth.TranId)).ToList();

                        _logger.LogInformation($"To update: {string.Join(' ', toUpdate.Select(trn => trn.Id))}");
                        _logger.LogInformation($"To insert: {string.Join(' ', toInsert.Select(trn => trn.Id))}");

                        //TODO: add transaction in database
                        //TODO: delete or change pending processing status and use toPending instead of auths
                        _blockchain.UpdateLogs(toUpdate);
                        _blockchain.InsertLogs(toInsert);
                        _blockchain.InsertPendingLogs(auths);

                        return(new OkResult());
                    }
                }
            }
            catch (System.Exception e)
            {
                _logger.LogError(0, e, "Error processing transaction: {0}", transaction.Data);
                return(new ObjectResult(e.Message)
                {
                    StatusCode = 500
                });
            }
        }