public bool GenerateSubmitResponse(ref JObject response, string jobId, string guid, byte[] nonce,
                                           string resultHash, string ipAddress)
        {
            ConnectedWorker worker = Statics.ConnectedClients[guid];

            Statics.TotalShares++;
            JObject result = new JObject();

            if (nonce == null || nonce.Length == 0)
            {
                response["error"] = "Invalid arguments!";
                return(false);
            }

            try
            {
                ShareJob shareJob = worker.JobSeed.First(x => x.Key == jobId).Value;
                if (!shareJob.SubmittedShares.Contains(BitConverter.ToInt32(nonce, 0)))
                {
                    shareJob.SubmittedShares.Add(BitConverter.ToInt32(nonce, 0));
                }
                else
                {
                    response["error"] = "Duplicate share";
                    return(false);
                }
                int jobSeed = shareJob.Seed;
                worker.ShareRequest(shareJob.CurrentDifficulty);
                Statics.RedisDb.MinerWorkers.First(x => x.Identifier == guid).ShareRequest(shareJob.CurrentDifficulty);
                byte[] prevJobBlock = Helpers.GenerateShareWork(jobSeed, true);

                Array.Copy(nonce, 0, prevJobBlock, 39, nonce.Length);
                byte[] blockHash = Hash.CryptoNight(prevJobBlock);

                Statics.ConnectedClients[guid].LastSeen = DateTime.Now;

                if (resultHash.ToUpper() != BitConverter.ToString(blockHash).Replace("-", ""))
                {
                    Logger.Log(Logger.LogLevel.General, "Hash mismatch from {0}", guid);

                    result["status"] = "Hash mismatch ";
                    //    throw new Exception();
                }
                else
                {
                    ShareProcess shareProcess =
                        Helpers.ProcessShare(blockHash, (int)Statics.CurrentBlockTemplate["difficulty"],
                                             (uint)shareJob.CurrentDifficulty);

                    string address = Statics.ConnectedClients[guid].Address;

                    worker.TotalShares++;

                    if (shareProcess == ShareProcess.ValidShare || shareProcess == ShareProcess.ValidBlock)
                    {
                        Statics.HashRate.Difficulty += (uint)shareJob.CurrentDifficulty;
                        Statics.HashRate.Time        = (ulong)((DateTime.Now - Statics.HashRate.Begin).TotalSeconds);
                        try
                        {
                            IncreaseShareCount(guid, (uint)shareJob.CurrentDifficulty);
                        }
                        catch (Exception e)
                        {
                            Logger.Log(Logger.LogLevel.Error, e.ToString());
                            throw;
                        }
                        if (shareProcess == ShareProcess.ValidBlock &&
                            !Statics.BlocksPendingSubmition.Any(x => x.BlockHeight == worker.CurrentBlock))
                        {
                            Logger.Log(Logger.LogLevel.Special, "Block found by {0}", guid);
                            byte[] shareWork = Helpers.GenerateShareWork(jobSeed, false);
                            Array.Copy(nonce, 0, shareWork, 39, nonce.Length);

                            Statics.BlocksPendingSubmition.Add(new PoolBlock(shareWork, worker.CurrentBlock, "",
                                                                             Statics.ConnectedClients[guid].Address));
                        }
                        result["status"] = "OK";
                    }
                    else
                    {
                        result["status"] = "Share failed valdiation!";
                        worker.RejectedShares++;
                        if ((double)worker.RejectedShares / worker.TotalShares >
                            int.Parse(Statics.Config.IniReadValue("ban-reject-percentage")) &&
                            worker.TotalShares > int.Parse(Statics.Config.IniReadValue("ban-after-shares")))
                        {
                            result["status"] = "You're banished!";
                            int minutes = int.Parse(Statics.Config.IniReadValue("ban-time-minutes"));
                            Logger.Log(Logger.LogLevel.General,
                                       "Client with address {0} ip {1} banned for {2} minutes for having a reject rate of {3}",
                                       worker.Address, ipAddress, minutes,
                                       (double)worker.RejectedShares / worker.TotalShares);
                            Ban ban = new Ban();
                            ban.AddressBan = worker.Address;
                            ban.IpBan      = ipAddress;
                            ban.Begin      = DateTime.Now;
                            ban.Minutes    = minutes;
                            Statics.RedisDb.SaveChanges(ban);
                            response["result"] = result;
                            return(true);
                        }
                    }
                }
            }
            catch
            {
                result["error"] = "Invalid job id";
            }
            response["result"] = result;

            return(false);
        }