internal static void Send(TcpState e) { var startMsg = new StartMsg(); PoolTask poolCache = GetFreeMinerTask(); var startCmd = PoolCommand.CreateCommand(CommandNames.Start, poolCache.CurrentStartMsg); }
//===================// Methods //===================// /** * Method: SendPoolCommand * Access: public * Description: Receive Commands from Interfaces and pass to S+ via TriggerSendCommand delegate */ public void SendPoolCommand(PoolCommand _cmd, ushort _state, string _text) { if (TriggerSendCommand != null) { TriggerSendCommand((ushort)_cmd, _state, _text); } }
internal static void Receive(TcpReceiveState e, PoolCommand cmd) { var msg = new NonceDataMsg(); int index = 0; msg.Deserialize(cmd.Payload, ref index); var miner = PoolCache.WorkingMiners.FirstOrDefault(m => m.ClientAddress == e.Address); if (miner == null) { RejectCommand.Send(e); return; } var data = POC.CalculateScoopData(miner.WalletAddress, msg.MaxNonce, miner.CheckScoopNumber); if (Base16.Encode(data) == Base16.Encode(msg.ScoopData)) { miner.IsConnected = true; miner.ConnectedTime = Time.EpochTime; miner.LatestHeartbeatTime = Time.EpochTime; LoginCommand.SendLoginResult(e, true); LogHelper.Info(miner.ClientAddress + " login success"); StartCommand.Send(e); } else { LoginCommand.SendLoginResult(e, false); RejectCommand.Send(e); LogHelper.Info(miner.ClientAddress + " login fail"); } }
internal static void Send(TcpState e, StartMsg startMsg) { var startCmd = PoolCommand.CreateCommand(CommandNames.Start, startMsg); if (PoolJob.TcpServer != null) { PoolJob.TcpServer.SendCommand(e, startCmd); } }
internal static void SendLoginResult(TcpState e, bool result) { if (PoolJob.TcpServer != null) { var msg = new LoginResultMsg(); msg.Result = result; var cmd = PoolCommand.CreateCommand(CommandNames.LoginResult, msg); PoolJob.TcpServer.SendCommand(e, cmd); } }
/// <summary> /// 发送Reject命令 /// 创建命令,发送命令,关闭连接 /// </summary> /// <param name="e"></param> internal static void Send(TcpState e) { var rejectCmd = PoolCommand.CreateCommand(CommandNames.Reject, null); if (PoolJob.TcpServer != null) { PoolJob.TcpServer.SendCommand(e, rejectCmd); PoolJob.TcpServer.CloseSocket(e); } }
public void SendCommand(AsyncSocketUserToken token, PoolCommand command) { try { var buffer = command.GetBytes(); this.SendAsyncEvent(token.ConnectSocket, token.SendEventArgs, buffer, 0, buffer.Length); } catch (Exception ex) { LogHelper.Error(ex.Message, ex); this.CloseSocket(token); } }
public void SendCommand(TcpState state, PoolCommand command) { tcpClientSend.Set(); try { var buffer = command.GetBytes(); state.Stream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(processSend), state); } catch (Exception ex) { LogHelper.Error(ex.Message, ex); this.CloseSocket(state); } tcpClientSend.WaitOne(); }
private void receivedCommand(TcpReceiveState state, PoolCommand cmd) { switch (cmd.CommandName) { case CommandNames.Login: Commands.LoginCommand.Receive(state, cmd); break; case CommandNames.NonceData: Commands.NonceDataCommand.Receive(state, cmd); break; case CommandNames.ScoopData: Commands.ScoopDataCommand.Received(state, cmd); break; case CommandNames.Heartbeat: Commands.HeartbeatCommand.Receive(state, cmd); break; default: break; } }
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); }
/** * Method: FeedbackEvent * Access: public * Description: Receive hardware feedback from S+, store in variable, and push value to subscribed Interfaces via event */ public void FeedbackEvent(ushort _action, ushort _state, string _text) { PoolCommand act = (PoolCommand)_action; switch (act) { case PoolCommand.ModeSelect_Pool_Fb: if (_state == 1) { currentMode = PoolMode.Pool; } break; case PoolCommand.ModeSelect_Spa_Fb: if (_state == 1) { currentMode = PoolMode.Spa; } break; case PoolCommand.Pool_Heater_Fb: poolHeaterOn = _state == 1 ? true : false; break; case PoolCommand.Spa_Heater_Fb: spaHeaterOn = _state == 1 ? true : false; break; case PoolCommand.FilterPump_Fb: filterPumpOn = _state == 1 ? true : false; break; case PoolCommand.Aux_Fb: currentAuxStatus[int.Parse(_text)] = _state == 1 ? true : false; break; case PoolCommand.Pool_Setpoint_Fb: currentPoolSetpoint = float.Parse(_text); break; case PoolCommand.Pool_Temp_Fb: currentPoolTemp = float.Parse(_text);; break; case PoolCommand.Spa_Setpoint_Fb: currentSpaSetpoint = float.Parse(_text);; break; case PoolCommand.Spa_Temp_Fb: currentSpaTemp = float.Parse(_text);; break; case PoolCommand.Ambient_Temp_Fb: currentAmbientTemp = float.Parse(_text);; break; case PoolCommand.System_Type: systemType = _state; break; } // Broadcast to UpdateEvent subscribers if (this.UpdateEvent != null) { UpdateEvent(act, _state, _text); } }
private void processReceive(IAsyncResult ar) { TcpReceiveState state = (TcpReceiveState)ar.AsyncState; try { //if (state.Stream == null || !state.Stream.CanRead) //{ // state.Buffer = new byte[m_receiveBufferSize]; // state.Stream.BeginRead(state.Buffer, 0, state.Buffer.Length, new AsyncCallback(processReceive), state); //} int numberOfBytesRead = state.Stream.EndRead(ar); if (numberOfBytesRead > 0) { //LogHelper.Debug($"Readed {numberOfBytesRead} byte data from {state.Address}"); var buffer = new byte[numberOfBytesRead]; Array.Copy(state.Buffer, 0, buffer, 0, buffer.Length); //this.receivedDataQueue.Enqueue(new KeyValuePair<TcpReceiveState, byte[]>(state, buffer)); var commandDataList = new List <byte[]>(); var index = 0; List <byte> bytes = null; while (index < buffer.Length) { if (bytes == null) { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultPrefixBytes[0] && buffer[index + 1] == PoolCommand.DefaultPrefixBytes[1] && buffer[index + 2] == PoolCommand.DefaultPrefixBytes[2] && buffer[index + 3] == PoolCommand.DefaultPrefixBytes[3]) { bytes = new List <byte>(); bytes.AddRange(PoolCommand.DefaultPrefixBytes); index += 4; } else { index++; } } else { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultSuffixBytes[0] && buffer[index + 1] == PoolCommand.DefaultSuffixBytes[1] && buffer[index + 2] == PoolCommand.DefaultSuffixBytes[2] && buffer[index + 3] == PoolCommand.DefaultSuffixBytes[3]) { bytes.AddRange(PoolCommand.DefaultSuffixBytes); commandDataList.Add(bytes.ToArray()); bytes = null; index += 4; } else { bytes.Add(buffer[index]); index++; } } } if (this.ReceivedCommandAction != null) { foreach (var data in commandDataList) { try { var cmd = PoolCommand.ConvertBytesToMessage(data); if (cmd != null) { HeartbeatCommand.UpdateHeartTime(state); this.ReceivedCommandAction(state, cmd); } } catch (Exception ex) { LogHelper.Error("Error occured on deserialize messgae: " + ex.Message, ex); } } } } state.Buffer = new byte[m_receiveBufferSize]; state.Stream.BeginRead(state.Buffer, 0, state.Buffer.Length, new AsyncCallback(processReceive), state); } catch (Exception ex) { LogHelper.Error("Error occured on receive messgae: " + ex.Message, ex); this.CloseSocket(state); } }
/// <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); } //})); }
internal void Start() { isStart = true; Task.Run(() => { while (isStart) { if (RunningTasks.Count < MaxTaskCount) { DataInfo analysisDataInfo; if (analysisDataIds.TryDequeue(out analysisDataInfo)) { Task task = new Task(() => { var analysisData = DbHelper.Current.Get <byte[]>(DataType.ReceiveType, analysisDataInfo.ID); var state = analysisDataInfo.State; var buffer = analysisData; var commandDataList = new List <byte[]>(); var index = 0; List <byte> bytes = null; while (index < buffer.Length) { if (bytes == null) { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultPrefixBytes[0] && buffer[index + 1] == PoolCommand.DefaultPrefixBytes[1] && buffer[index + 2] == PoolCommand.DefaultPrefixBytes[2] && buffer[index + 3] == PoolCommand.DefaultPrefixBytes[3]) { bytes = new List <byte>(); bytes.AddRange(PoolCommand.DefaultPrefixBytes); index += 4; } else { index++; } } else { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultSuffixBytes[0] && buffer[index + 1] == PoolCommand.DefaultSuffixBytes[1] && buffer[index + 2] == PoolCommand.DefaultSuffixBytes[2] && buffer[index + 3] == PoolCommand.DefaultSuffixBytes[3]) { bytes.AddRange(PoolCommand.DefaultSuffixBytes); commandDataList.Add(bytes.ToArray()); bytes = null; index += 4; } else { bytes.Add(buffer[index]); index++; } } } foreach (var data in commandDataList) { try { var cmd = PoolCommand.ConvertBytesToMessage(data); if (cmd != null) { MsgPool.Current.AddCommand(new CommandState { State = state, Command = cmd }); } } catch (Exception ex) { LogHelper.Error("Error occured on deserialize messgae: " + ex.Message, ex); } } }); task.ContinueWith(t => { RunningTasks.Remove(task); }); RunningTasks.Add(task); task.Start(); } } } }); }
private void processReceivedDataQueue() { while (isStarted) { if (this.receivedDataQueue.Count > 0) { var item = receivedDataQueue.Dequeue(); Task.Run(() => { var state = item.Key; var buffer = item.Value; var commandDataList = new List <byte[]>(); var index = 0; List <byte> bytes = null; while (index < buffer.Length) { if (bytes == null) { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultPrefixBytes[0] && buffer[index + 1] == PoolCommand.DefaultPrefixBytes[1] && buffer[index + 2] == PoolCommand.DefaultPrefixBytes[2] && buffer[index + 3] == PoolCommand.DefaultPrefixBytes[3]) { bytes = new List <byte>(); bytes.AddRange(PoolCommand.DefaultPrefixBytes); index += 4; } else { index++; } } else { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultSuffixBytes[0] && buffer[index + 1] == PoolCommand.DefaultSuffixBytes[1] && buffer[index + 2] == PoolCommand.DefaultSuffixBytes[2] && buffer[index + 3] == PoolCommand.DefaultSuffixBytes[3]) { bytes.AddRange(PoolCommand.DefaultSuffixBytes); commandDataList.Add(bytes.ToArray()); bytes = null; index += 4; } else { bytes.Add(buffer[index]); index++; } } } if (this.ReceivedCommandAction != null) { foreach (var data in commandDataList) { try { var cmd = PoolCommand.ConvertBytesToMessage(data); if (cmd != null) { HeartbeatCommand.UpdateHeartTime(state); this.ReceivedCommandAction(state, cmd); } } catch (Exception ex) { LogHelper.Error("Error occured on deserialize messgae: " + ex.Message, ex); } } } }); } } }
/// <summary> /// 接收事件响应函数,接收的逻辑 /// </summary> /// <param name="receiveEventArgs"></param> private void ProcessReceive(SocketAsyncEventArgs receiveEventArgs) { AsyncSocketUserToken userToken = receiveEventArgs.UserToken as AsyncSocketUserToken; if (userToken.ConnectSocket == null) { return; } userToken.ActiveDateTime = DateTime.Now; if (userToken.ReceiveEventArgs.BytesTransferred > 0 && userToken.ReceiveEventArgs.SocketError == SocketError.Success) { HeartbeatCommand.UpdateHeartTime(userToken); int offset = userToken.ReceiveEventArgs.Offset; int count = userToken.ReceiveEventArgs.BytesTransferred; if (count > 0) //处理接收数据 { var buffer = userToken.ReceiveEventArgs.Buffer; var commandDataList = new List <byte[]>(); var index = 0; List <byte> bytes = null; while (index < buffer.Length) { if (bytes == null) { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultPrefixBytes[0] && buffer[index + 1] == PoolCommand.DefaultPrefixBytes[1] && buffer[index + 2] == PoolCommand.DefaultPrefixBytes[2] && buffer[index + 3] == PoolCommand.DefaultPrefixBytes[3]) { bytes = new List <byte>(); bytes.AddRange(PoolCommand.DefaultPrefixBytes); index += 4; } else { index++; } } else { if ((index + 3) < buffer.Length && buffer[index] == PoolCommand.DefaultSuffixBytes[0] && buffer[index + 1] == PoolCommand.DefaultSuffixBytes[1] && buffer[index + 2] == PoolCommand.DefaultSuffixBytes[2] && buffer[index + 3] == PoolCommand.DefaultSuffixBytes[3]) { bytes.AddRange(PoolCommand.DefaultSuffixBytes); commandDataList.Add(bytes.ToArray()); bytes = null; index += 4; } else { bytes.Add(buffer[index]); index++; } } } if (this.ReceivedCommandAction != null) { foreach (var data in commandDataList) { try { var cmd = PoolCommand.ConvertBytesToMessage(data); if (cmd != null) { this.ReceivedCommandAction(userToken, cmd); } } catch (Exception ex) { LogHelper.Warn($"Error Data from {userToken.Address}:{Base16.Encode(data)}"); LogHelper.Error("Error occured on deserialize messgae: " + ex.Message, ex); } } } if (userToken.ConnectSocket == null || userToken.ReceiveEventArgs == null) { return; } bool willRaiseEvent = userToken.ConnectSocket.ReceiveAsync(userToken.ReceiveEventArgs); //投递接收请求 if (!willRaiseEvent) { ProcessReceive(userToken.ReceiveEventArgs); } } else { CloseSocket(userToken); } } }
internal static void Receive(TcpReceiveState e, PoolCommand cmd) { UpdateHeartTime(e); }