private void getAddrMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { var data = new GetAddrMsg(); int index = 0; data.Deserialize(state.Command.Payload, ref index); if (data.Count <= 0 || data.Count > 100) { data.Count = 100; } var list = this.Peers.Where(p => p.IP != state.IP || p.Port != state.Port).OrderByDescending(p => p.LastHeartbeat).Take(data.Count).ToList(); var payload = new AddrMsg(); foreach (var item in list) { payload.AddressList.Add(new KeyValuePair <string, int>(item.IP, item.Port)); } var addrCommand = P2PCommand.CreateCommand(CommandNames.P2P.Addr, payload); this.Send(addrCommand, state.IP, state.Port); } }
private void raiseOtherException(P2PState state, string descrip) { if (OtherException != null) { OtherException(state); } }
private void raiseDataReceived(P2PState state) { if (DataReceived != null) { DataReceived(state); } }
private void getAddrMsgHandle(P2PState state) { var peers = this.p2pComponent.GetNodes(); var peer = peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { var data = new GetAddrMsg(); int index = 0; data.Deserialize(state.Command.Payload, ref index); if (data.Count <= 0 || data.Count > 100) { data.Count = 100; } var list = peers.Where(p => p.IP != state.IP || p.Port != state.Port).OrderByDescending(p => p.LastHeartbeat).Take(data.Count).ToList(); var payload = new AddrMsg(); foreach (var item in list) { payload.AddressList.Add(new AddrMsg.AddressInfo() { Ip = item.IP, Port = item.Port, Identity = item.Identity }); } var addrCommand = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.P2P.Addr, payload); this.p2pComponent.SendCommand(state.IP, state.Port, addrCommand); } }
private void raiseCompletedSend(P2PState state) { if (CompletedSend != null) { CompletedSend(state); } }
private void raisePrepareSend(P2PState state) { if (PrepareSend != null) { PrepareSend(state); } }
private void rejectMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { if (!peer.IsConnected) { this.RemovePeer(peer.IP, peer.Port); } else { raiseDataReceived(state); } } }
private void pongMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null) { var verPayload = new VersionMsg(); verPayload.Version = Versions.EngineVersion; verPayload.Timestamp = Time.EpochTime; var versionCommand = P2PCommand.CreateCommand(CommandNames.P2P.Version, verPayload); this.Send(versionCommand, state.IP, state.Port); //peer.IsConnected = true; //peer.ConnectedTime = Time.EpochTime; //peer.LatestHeartbeat = Time.EpochTime; } }
private void versionMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null) { var versionMsg = new VersionMsg(); int index = 0; versionMsg.Deserialize(state.Command.Payload, ref index); bool checkResult; if (versionMsg.Version < Versions.MinimumSupportVersion) { checkResult = false; var data = new RejectMsg(); data.ReasonCode = ErrorCode.Engine.P2P.Connection.P2P_VERSION_NOT_BE_SUPPORT_BY_REMOTE_PEER; var rejectCommand = P2PCommand.CreateCommand(CommandNames.Other.Reject, data); this.Send(rejectCommand, state.IP, state.Port); this.RemovePeer(state.IP, state.Port); } else if (Math.Abs(Time.EpochTime - versionMsg.Timestamp) > 2 * 60 * 60 * 1000) { checkResult = false; var data = new RejectMsg(); data.ReasonCode = ErrorCode.Engine.P2P.Connection.TIME_NOT_MATCH_WITH_RMOTE_PEER; var rejectCommand = P2PCommand.CreateCommand(CommandNames.Other.Reject, data); this.Send(rejectCommand, state.IP, state.Port); } else { peer.Version = versionMsg.Version; checkResult = true; } if (checkResult) { var verAckCommand = P2PCommand.CreateCommand(CommandNames.P2P.VerAck, null); this.Send(verAckCommand, state.IP, state.Port); } } }
private void receivedNewMiningPoolMessage(P2PState state, NewMiningPoolMsg msg) { if (msg == null || state == null) { return; } if (new MiningPoolComponent().AddMiningToPool(msg.MinerInfo)) { var nodes = this.p2pComponent.GetNodes(); nodes.ForEach(peer => { if (!peer.IsTrackerServer) { var command = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.MiningPool.NewMiningPool, msg); this.p2pComponent.SendCommand(peer.IP, peer.Port, command); } }); } }
private void addrMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { var payload = new AddrMsg(); int index = 0; payload.Deserialize(state.Command.Payload, ref index); foreach (var item in payload.AddressList) { if (this.Peers.Where(p => !p.IsTrackerServer && p.IP == item.Key && p.Port == item.Value && p.IsConnected).Count() == 0) { this.ConnectToNewPeer(item.Key, item.Value); } } } }
private void addrMsgHandle(P2PState state) { var peers = this.p2pComponent.GetNodes(); var peer = peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { var payload = new AddrMsg(); int index = 0; payload.Deserialize(state.Command.Payload, ref index); foreach (var item in payload.AddressList) { if (peers.Where(p => !p.IsTrackerServer && p.IP == item.Ip && p.Port == item.Port && p.IsConnected).Count() == 0) { this.p2pComponent.AddNode(item.Ip, item.Port); } } } }
private void heartbeatMsgHandle(P2PState state) { var peer = this.p2pComponent.GetNodes().Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null && peer.IsConnected) { var payload = new HeightMsg(); int index = 0; try { payload.Deserialize(state.Command.Payload, ref index); peer.LatestHeight = payload.Height; peer.LatestBlockTime = payload.BlockTime; } catch { } peer.LastHeartbeat = Time.EpochTime; } }
private void verAckMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer != null) { peer.IsConnected = true; peer.ConnectedTime = Time.EpochTime; peer.LastHeartbeat = Time.EpochTime; if (peer.IsTrackerServer) { var payload = new GetAddrMsg(); payload.Count = this.maxConnections; var command = P2PCommand.CreateCommand(CommandNames.P2P.GetAddr, payload); this.Send(command, peer.IP, peer.Port); } else { this.raiseNodeConnectionStateChanged(peer); } } }
private void dataReceived(P2PState state) { int index = 0; switch (state.Command.CommandName) { //case CommandNames.P2P.GetAddr: // this.getAddrMsgHandle(state); // break; //case CommandNames.P2P.Addr: // this.addrMsgHandle(state); // break; //case CommandNames.P2P.Heartbeat: // this.heartbeatMsgHandle(state); // break; case CommandNames.Transaction.GetTxPool: this.receivedGetTransactionPool(state.IP, state.Port, state.Command.Nonce); break; case CommandNames.Transaction.TxPool: var txPoolMsg = new TxPoolMsg(); txPoolMsg.Deserialize(state.Command.Payload, ref index); this.receivedTransacitonPoolMessage(state.IP, state.Port, txPoolMsg); break; case CommandNames.Transaction.GetTx: var getTxMsg = new GetTxsMsg(); getTxMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetTransaction(state.IP, state.Port, getTxMsg, state.Command.Nonce); break; case CommandNames.Transaction.Tx: var txsMsg = new TxsMsg(); txsMsg.Deserialize(state.Command.Payload, ref index); this.receivedTransactionMessage(state.IP, state.Port, txsMsg); break; case CommandNames.Transaction.NewTx: var newTxMsg = new NewTxMsg(); newTxMsg.Deserialize(state.Command.Payload, ref index); this.receivedNewTransactionMessage(state.IP, state.Port, newTxMsg); break; case CommandNames.Block.GetHeight: this.receivedGetHeight(state.IP, state.Port, state.Command.Nonce); break; case CommandNames.Block.Height: var heightMsg = new HeightMsg(); heightMsg.Deserialize(state.Command.Payload, ref index); this.receivedHeightMessage(state.IP, state.Port, heightMsg); break; case CommandNames.Block.GetHeaders: var getHeadersMsg = new GetHeadersMsg(); getHeadersMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetHeaders(state.IP, state.Port, getHeadersMsg, state.Command.Nonce); break; case CommandNames.Block.Headers: var headersMsg = new HeadersMsg(); headersMsg.Deserialize(state.Command.Payload, ref index); this.receivedHeadersMessage(state.IP, state.Port, headersMsg); break; case CommandNames.Block.GetBlocks: var getBlocksMsg = new GetBlocksMsg(); getBlocksMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetBlocks(state.IP, state.Port, getBlocksMsg, state.Command.Nonce); break; case CommandNames.Block.Blocks: var blocksMsg = new BlocksMsg(); blocksMsg.Deserialize(state.Command.Payload, ref index); this.receivedBlocksMessage(state.IP, state.Port, blocksMsg); break; case CommandNames.Block.NewBlock: var newBlockMsg = new NewBlockMsg(); newBlockMsg.Deserialize(state.Command.Payload, ref index); this.receivedNewBlockMessage(state.IP, state.Port, newBlockMsg, state.Command.Nonce); break; case CommandNames.Other.Reject: break; case CommandNames.Other.NotFound: break; default: break; } }
private void receiveDataAsync(IAsyncResult ar) { IPEndPoint remote = null; byte[] buffer = null; try { buffer = server.EndReceive(ar, ref remote); this.TotalBytesReceived += buffer.Length; var peer = this.Peers.Where(p => p.IP == remote.Address.ToString() && p.Port == remote.Port).FirstOrDefault(); if (peer != null) { peer.TotalBytesReceived += buffer.Length; peer.LastReceivedTime = Time.EpochTime; } LogHelper.Debug(DateTime.Now + " Received cmd from " + remote.Address + ", Data:" + Base16.Encode(buffer)); var prefix = new byte[4]; var suffix = new byte[4]; bool isBufferEnd = false; var key = remote.Address + ":" + remote.Port; if (buffer.Length > 4) { Array.Copy(buffer, 0, prefix, 0, 4); Array.Copy(buffer, buffer.Length - 4, suffix, 0, 4); if (!this.receivedMessageBuffer.ContainsKey(key)) { this.receivedMessageBuffer.Add(key, new List <byte>()); } //first data package if (P2PCommand.BytesEquals(P2PCommand.DefaultPrefixBytes, prefix)) { this.receivedMessageBuffer[key] = new List <byte>(); this.receivedMessageBuffer[key].AddRange(buffer); //last data package if (P2PCommand.BytesEquals(P2PCommand.DefaultSuffixBytes, suffix)) { isBufferEnd = true; } else { } } else if (P2PCommand.BytesEquals(P2PCommand.DefaultSuffixBytes, suffix)) { this.receivedMessageBuffer[key].AddRange(buffer); isBufferEnd = true; } //other data package else { this.receivedMessageBuffer[key].AddRange(buffer); } } else { this.receivedMessageBuffer[key].AddRange(buffer); isBufferEnd = true; } if (isBufferEnd) { var command = P2PCommand.ConvertBytesToMessage(this.receivedMessageBuffer[key].ToArray()); P2PState state = new P2PState(); state.IP = remote.Address.ToString(); state.Port = remote.Port; state.Command = command; if (command != null) { LogHelper.Debug(DateTime.Now + " Received cmd from " + remote.Address + ", Command:" + command.CommandName); if (peer == null && command.CommandName != CommandNames.P2P.Ping) { this.ConnectToNewPeer(remote.Address.ToString(), remote.Port); return; } switch (command.CommandName) { case CommandNames.P2P.Ping: this.pingMsgHandle(state); break; case CommandNames.P2P.Pong: this.pongMsgHandle(state); break; case CommandNames.P2P.Version: this.versionMsgHandle(state); break; case CommandNames.P2P.VerAck: this.verAckMsgHandle(state); break; case CommandNames.P2P.GetAddr: this.getAddrMsgHandle(state); break; case CommandNames.P2P.Addr: this.addrMsgHandle(state); break; case CommandNames.P2P.Heartbeat: this.heartbeatMsgHandle(state); break; case CommandNames.Other.Reject: this.rejectMsgHandle(state); break; default: raiseDataReceived(state); break; } } } } catch (Exception ex) { LogHelper.Error(ex.Message, ex); raiseOtherException(null); } finally { if (this.IsRunning && this.server != null) { server.BeginReceive(receiveDataAsync, null); } } }
//private void processLongTimeCommand() //{ // LogHelper.Warn("Thread : In to thread threadProcessLongTimeCommand's process action : processLongTimeCommand"); // P2PState state = default(P2PState); // //System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); // while (this.isRunning) // { // if (longTimeCommandQueue.TryDequeue(out state)) // { // if(state != null) // { // try // { // //stopwatch.Reset(); // //stopwatch.Start(); // int index = 0; // switch (state.Command.CommandName) // { // case CommandNames.Block.GetHeaders: // var getHeadersMsg = new GetHeadersMsg(); // getHeadersMsg.Deserialize(state.Command.Payload, ref index); // this.receivedGetHeaders(state.IP, state.Port, getHeadersMsg, state.Command.Nonce); // break; // case CommandNames.Block.GetBlocks: // var getBlocksMsg = new GetBlocksMsg(); // getBlocksMsg.Deserialize(state.Command.Payload, ref index); // this.receivedGetBlocks(state.IP, state.Port, getBlocksMsg, state.Command.Nonce); // break; // default: // break; // } // //stopwatch.Stop(); // //LogHelper.Warn($"processLongTimeCommand : {state.Command.CommandName} -- {stopwatch.ElapsedMilliseconds} , longTimeCommandQueue count = {longTimeCommandQueue.Count()}" ); // } // catch (Exception ex) // { // LogHelper.Error(ex.ToString()); // //LogHelper.Warn($"processLongTimeCommand : {state.Command.CommandName} -- {stopwatch.ElapsedMilliseconds} , longTimeCommandQueue count = {longTimeCommandQueue.Count()} -- Exception msg: {ex.ToString()} "); // } // } // Thread.Sleep(10); // } // else // { // Thread.Sleep(50); // } // } // LogHelper.Warn("Thread : out of thread threadProcessLongTimeCommand's process action : processLongTimeCommand"); //} #endregion private void dataReceived(P2PState state) { int index = 0; switch (state.Command.CommandName) { case CommandNames.Transaction.GetTxPool: this.receivedGetTransactionPool(state.IP, state.Port, state.Command.Nonce); break; case CommandNames.Transaction.TxPool: var txPoolMsg = new TxPoolMsg(); txPoolMsg.Deserialize(state.Command.Payload, ref index); this.receivedTransacitonPoolMessage(state.IP, state.Port, txPoolMsg); break; case CommandNames.Transaction.GetTx: var getTxMsg = new GetTxsMsg(); getTxMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetTransaction(state.IP, state.Port, getTxMsg, state.Command.Nonce); break; case CommandNames.Transaction.Tx: var txsMsg = new TxsMsg(); txsMsg.Deserialize(state.Command.Payload, ref index); this.receivedTransactionMessage(state.IP, state.Port, txsMsg); break; case CommandNames.Transaction.NewTx: var newTxMsg = new NewTxMsg(); newTxMsg.Deserialize(state.Command.Payload, ref index); this.receivedNewTransactionMessage(state.IP, state.Port, newTxMsg); break; case CommandNames.Block.GetHeight: this.receivedGetHeight(state.IP, state.Port, state.Command.Nonce); break; case CommandNames.Block.Height: var heightMsg = new HeightMsg(); heightMsg.Deserialize(state.Command.Payload, ref index); this.receivedHeightMessage(state.IP, state.Port, heightMsg); break; case CommandNames.Block.GetHeaders: var getHeadersMsg = new GetHeadersMsg(); getHeadersMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetHeaders(state.IP, state.Port, getHeadersMsg, state.Command.Nonce); //longTimeCommandQueue.Enqueue(state); break; case CommandNames.Block.Headers: var headersMsg = new HeadersMsg(); headersMsg.Deserialize(state.Command.Payload, ref index); this.receivedHeadersMessage(state.IP, state.Port, headersMsg); break; case CommandNames.Block.GetBlocks: var getBlocksMsg = new GetBlocksMsg(); getBlocksMsg.Deserialize(state.Command.Payload, ref index); this.receivedGetBlocks(state.IP, state.Port, getBlocksMsg, state.Command.Nonce); //longTimeCommandQueue.Enqueue(state); break; case CommandNames.Block.Blocks: var blocksMsg = new BlocksMsg(); blocksMsg.Deserialize(state.Command.Payload, ref index); this.receivedBlocksMessage(state.IP, state.Port, blocksMsg); break; case CommandNames.Block.NewBlock: var newBlockMsg = new NewBlockMsg(); newBlockMsg.Deserialize(state.Command.Payload, ref index); this.receivedNewBlockMessage(state.IP, state.Port, newBlockMsg, state.Command.Nonce); break; case CommandNames.MiningPool.GetMiningPools: this.receivedGetMiningPoolsMessage(state.IP, state.Port); break; case CommandNames.MiningPool.MiningPools: var miningPoolMsg = new MiningPoolMsg(); miningPoolMsg.Deserialize(state.Command.Payload, ref index); receivedMiningPoolsMessage(miningPoolMsg); break; case CommandNames.MiningPool.NewMiningPool: var newMiningPoolMsg = new NewMiningPoolMsg(); newMiningPoolMsg.Deserialize(state.Command.Payload, ref index); this.receivedNewMiningPoolMessage(state, newMiningPoolMsg); break; case CommandNames.Other.Reject: case CommandNames.Other.NotFound: default: break; } }
private void raiseOtherException(P2PState state) { raiseOtherException(state, ""); }
private void pingMsgHandle(P2PState state) { var peer = this.Peers.Where(p => p.IP == state.IP && p.Port == state.Port).FirstOrDefault(); if (peer == null) { if (this.Peers.Count < this.maxConnections) { var newPeer = new P2PNode(); newPeer.IP = state.IP; newPeer.Port = state.Port; newPeer.IsConnected = false; newPeer.ConnectedTime = Time.EpochTime; newPeer.IsTrackerServer = false; newPeer.IsInbound = true; this.Peers.Add(newPeer); if (this.receivedMessageBuffer.ContainsKey(state.IP + ":" + state.Port)) { this.receivedMessageBuffer[state.IP + ":" + state.Port] = new List <byte>(); } else { this.receivedMessageBuffer.Add(state.IP + ":" + state.Port, new List <byte>()); } var pongCommand = P2PCommand.CreateCommand(CommandNames.P2P.Pong, null); this.Send(pongCommand, newPeer.IP, newPeer.Port); var verPayload = new VersionMsg(); verPayload.Version = Versions.EngineVersion; verPayload.Timestamp = Time.EpochTime; var versionCommand = P2PCommand.CreateCommand(CommandNames.P2P.Version, verPayload); this.Send(versionCommand, state.IP, state.Port); } else { var payload = new RejectMsg(); payload.ReasonCode = ErrorCode.Engine.P2P.Connection.THE_NUMBER_OF_CONNECTIONS_IS_FULL; var rejectCommand = P2PCommand.CreateCommand(CommandNames.Other.Reject, payload); this.Send(rejectCommand, state.IP, state.Port); } } else { var pongCommand = P2PCommand.CreateCommand(CommandNames.P2P.Pong, null); this.Send(pongCommand, state.IP, state.Port); var verPayload = new VersionMsg(); verPayload.Version = Versions.EngineVersion; verPayload.Timestamp = Time.EpochTime; var versionCommand = P2PCommand.CreateCommand(CommandNames.P2P.Version, verPayload); this.Send(versionCommand, state.IP, state.Port); if (!this.receivedMessageBuffer.ContainsKey(state.IP + ":" + state.Port)) { this.receivedMessageBuffer.Add(state.IP + ":" + state.Port, new List <byte>()); } //var payload = new RejectMsg(); //payload.ReasonCode = ErrorCode.Engine.P2P.Connection.THE_PEER_IS_EXISTED; //var rejectCommand = P2PCommand.CreateCommand(CommandNames.Other.Reject, payload); //this.Send(rejectCommand, state.IP, state.Port); } }