Example #1
0
        public void ReceiveStopMsg(string json)
        {
            try
            {
                var msg = JsonConvert.DeserializeObject <StopMiningMsg>(json);

                LogHelper.Info("Receive StopMsg");

                if (this.miners == null || !this.miners.Any())
                {
                    return;
                }

                StopMsg stopMsg = new StopMsg();
                stopMsg.Result = msg.StopReason == StopReason.MiningSucesses;
                if (stopMsg.Result)
                {
                    var height = Convert.ToInt32(stopMsg.BlockHeight);
                    var key    = KeyHelper.GetMinerEffortKey(ID, height);

                    var efforts = this.miners.Select(x => new EffortInfo {
                        Account = x.Address, BlockHeight = height, Effort = x.MaxNonce
                    }).ToList();
                    RedisManager.Current.SaveDataToRedis(key, efforts);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.ToString());
            }
        }
Example #2
0
        internal static void Send(TcpState e, StopMsg stopMsg)
        {
            var stopCmd = PoolCommand.CreateCommand(CommandNames.Stop, stopMsg);

            if (PoolJob.TcpServer != null)
            {
                PoolJob.TcpServer.SendCommand(e, stopCmd);
            }
        }
Example #3
0
        /// <summary>
        /// 接收停止命令
        /// 接收到的json反序列化StopMiningMsg对象,构造StopMsg类,遍历所有的矿工发送TCP停止命令
        /// </summary>
        /// <param name="json"></param>
        public void ReceiveStopMsg(string json)
        {
            try
            {
                var msg = JsonConvert.DeserializeObject <StopMiningMsg>(json);

                LogHelper.Info("Receive StopMsg");

                if (msg == null || PoolCache.CurrentTask == null)
                {
                    return;
                }

                StopMsg stopMsg = new StopMsg();
                stopMsg.Result      = msg.StopReason == StopReason.MiningSucesses;
                stopMsg.BlockHeight = msg.CurrentHeight;
                stopMsg.StopTime    = msg.StopTime;


                var miners = PoolCache.WorkingMiners.ToArray();
                foreach (Miner item in miners)
                {
                    try
                    {
                        TcpState tcpState = new TcpState()
                        {
                            Client = item.Client, Stream = item.Stream, Address = item.ClientAddress
                        };
                        StopCommand.Send(tcpState, stopMsg);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error(ex.ToString());
                    }
                }

                var stopTask = PoolCache.CurrentTask;
                //计算每个账户的工作量
                if (PoolCache.Efforts.ContainsKey(stopTask.CurrentBlockHeight))
                {
                    var items = PoolCache.Efforts[stopTask.CurrentBlockHeight];
                    stopTask.MinerEfforts.ForEach(x =>
                    {
                        var item = items.FirstOrDefault(p => p.Account == x.Account);
                        if (item == null)
                        {
                            items.Add(new EffortInfo {
                                Account = x.Account, Effort = x.Effort, BlockHeight = stopTask.CurrentBlockHeight
                            });
                        }
                        else
                        {
                            item.Effort += x.Effort;
                        }
                    });
                }
                else
                {
                    var efforts = stopTask.MinerEfforts.Select(x => new EffortInfo {
                        Account = x.Account, Effort = x.Effort, BlockHeight = stopTask.CurrentBlockHeight
                    }).ToList();
                    PoolCache.Efforts.Add(stopTask.CurrentBlockHeight, efforts);
                }
                //成功挖到区块,工作量保存在redis中,清空以前区块的Task
                if (msg.StopReason == StopReason.MiningSucesses)
                {
                    TimerTasks.Current.SaveMinerEffortToRedis(msg.CurrentHeight);
                    PoolCache.poolTasks.RemoveAll(x => x.CurrentBlockHeight <= stopMsg.BlockHeight);
                }
                PoolCache.CurrentTask = null;
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.ToString());
            }
        }
Example #4
0
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="e"></param>
        /// <param name="cmd"></param>
        internal static void Receive(TcpReceiveState e, PoolCommand cmd)
        {
            //TaskWork.Current.Add(new Task(() =>
            //{
            var loginMsg = new LoginMsg();
            int index    = 0;

            loginMsg.Deserialize(cmd.Payload, ref index);
            //验证矿工身份
            if (!MinerApi.ValidateMiner(loginMsg.WalletAddress, loginMsg.SerialNo))
            {
                RejectCommand.Send(e);
                return;
            }

            //TODO: address and SerialNo and account only for one Minner 第一个与条件匹配的矿工
            var miner = PoolCache.WorkingMiners.FirstOrDefault(m => m.WalletAddress == loginMsg.WalletAddress || m.ClientAddress == e.Address || m.SerialNo == loginMsg.SerialNo);

            //矿工不为空,发送stop命令
            if (miner != null)
            {
                StopMsg stopMsg = new StopMsg();
                stopMsg.Result = false;
                if (PoolCache.CurrentTask == null)
                {
                    return;
                }
                stopMsg.BlockHeight = PoolCache.CurrentTask.CurrentBlockHeight;
                stopMsg.StartTime   = PoolCache.CurrentTask.StartTime;
                stopMsg.StopTime    = Time.EpochTime;

                TcpSendState tcpSendState = new TcpSendState()
                {
                    Client = miner.Client, Stream = miner.Stream, Address = miner.ClientAddress
                };
                StopCommand.Send(tcpSendState, stopMsg);

                PoolCache.WorkingMiners.Remove(miner);
            }

            miner               = new Miner();
            miner.SerialNo      = loginMsg.SerialNo;
            miner.WalletAddress = loginMsg.WalletAddress;
            miner.ClientAddress = e.Address;
            miner.Client        = e.Client;
            miner.Stream        = e.Stream;

            Random random = new Random();

            miner.CheckScoopNumber = random.Next(0, POC.MAX_SCOOP_NUMBER + 1);
            PoolCache.WorkingMiners.Add(miner);

            miner.IsConnected         = true;
            miner.ConnectedTime       = Time.EpochTime;
            miner.LatestHeartbeatTime = Time.EpochTime;
            SendLoginResult(e, true);
            LogHelper.Info(miner.ClientAddress + " login success");

            MinerLoginMsg loginMinerMsg = new MinerLoginMsg();

            loginMinerMsg.Account  = loginMsg.WalletAddress;
            loginMinerMsg.SN       = loginMsg.SerialNo;
            loginMinerMsg.ServerId = Setting.PoolId;

            //MQApi.Current.SendLoginMsg(loginMinerMsg);
            RabbitMQApi.Current.SendLoginMsg(loginMinerMsg);
            if (PoolCache.CurrentTask != null)
            {
                StartCommand.Send(e, PoolCache.CurrentTask.CurrentStartMsg);
            }
            //}));
        }
Example #5
0
        internal static void Received(TcpReceiveState e, PoolCommand cmd)
        {
            var miner = PoolCache.WorkingMiners.FirstOrDefault(m => m.ClientAddress == e.Address && m.IsConnected);

            if (miner == null)
            {
                LogHelper.Info("Received invalid scoop data from " + e.Address);
                LogHelper.Info("Miner logout");
                PoolJob.TcpServer.CloseSocket(e);
                return;
            }

            if (PoolCache.CurrentTask == null || PoolCache.CurrentTask.State != MiningState.Mining)
            {
                return;
            }

            var msg   = new ScoopDataMsg();
            int index = 0;

            msg.Deserialize(cmd.Payload, ref index);


            PoolCache.CurrentTask.LastReceiveTime = Time.EpochTime;

            var minerinfo = PoolCache.CurrentTask.MinerEfforts.FirstOrDefault(x => x.Account == miner.WalletAddress);

            if (minerinfo == null)
            {
                PoolCache.CurrentTask.MinerEfforts.Add(new Models.MinerEffort {
                    Account = miner.WalletAddress, Effort = 1
                });
            }
            else
            {
                if (minerinfo.Effort == Setting.MaxNonceCount)
                {
                    RejectCommand.Send(e);
                    return;
                }
                minerinfo.Effort++;
            }

            if (msg.BlockHeight != PoolCache.CurrentTask.CurrentBlockHeight)
            {
                LogHelper.Info("Received invalid scoop data from " + e.Address + ", nonce is " + msg.Nonce + ", height is " + msg.BlockHeight);
                LogHelper.Info("Block Height invalid , Stop and Send StartMsg");

                var stopMsg = new StopMsg
                {
                    BlockHeight = msg.BlockHeight,
                    Result      = false,
                    StartTime   = Time.EpochTime,
                    StopTime    = Time.EpochTime
                };
                StopCommand.Send(e, stopMsg);
                Task.Delay(1000).Wait();
                var startMsg = PoolCache.CurrentTask.CurrentStartMsg;
                if (startMsg != null)
                {
                    StartCommand.Send(e, startMsg);
                }
                return;
            }

            LogHelper.Info("Received scoop data from " + miner.ClientAddress + ", nonce is " + msg.Nonce + ", scoop number is " + msg.ScoopNumber + ", block height is " + msg.BlockHeight);

            if (msg.ScoopNumber != PoolCache.CurrentTask.CurrentScoopNumber)
            {
                LogHelper.Info("Received invalid scoop data from " + e.Address + ", nonce is " + msg.Nonce + ", ScoopNumber is " + PoolCache.CurrentTask.CurrentScoopNumber + "/" + msg.ScoopNumber);
                LogHelper.Info("Scoop Number invalid");
                return;
            }

            var verResult = POC.Verify(PoolCache.CurrentTask.BaseTarget, msg.Target);

            LogHelper.Debug("Bits:" + POC.ConvertBitsToBigInt(PoolCache.CurrentTask.BaseTarget).ToString("X").PadLeft(64, '0'));
            LogHelper.Debug("Hash:" + Base16.Encode(msg.Target));
            LogHelper.Debug("Verify Result is " + verResult);

            if (!verResult)
            {
                return;
            }

            ForgeMsg forgeMsg = new ForgeMsg();

            forgeMsg.Account    = msg.WalletAddress;
            forgeMsg.Nonce      = msg.Nonce;
            forgeMsg.StartMsgId = PoolCache.CurrentTask.Id;

            //MQApi.SendForgeBlock(msg.WalletAddress, msg.Nonce, PoolCache.CurrentTask.Id);
            RabbitMQApi.SendForgeBlock(msg.WalletAddress, msg.Nonce, PoolCache.CurrentTask.Id);
        }