/// <summary> /// 匹配对应的Command命令 /// </summary> /// <param name="tcpClient"></param> /// <param name="packet"></param> /// <returns></returns> public static P2PCommand FindCommand(P2PTcpClient tcpClient, ReceivePacket packet) { P2PCommand command = null; if (Global.AllowAnonymous.Contains(packet.CommandType) || tcpClient.IsAuth) { if (Global.CommandDict.ContainsKey(packet.CommandType)) { Type type = Global.CommandDict[packet.CommandType]; command = Activator.CreateInstance(type, tcpClient, packet.GetBytes()) as P2PCommand; } else { LogUtils.Warning($"{tcpClient.RemoteEndPoint}请求了未知命令{packet.CommandType}"); } } else { tcpClient.Close(); if (tcpClient.ToClient != null && tcpClient.ToClient.Connected) { tcpClient.ToClient.Close(); } LogUtils.Warning($"拦截{tcpClient.RemoteEndPoint}未授权命令"); } return(command); }
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 receivedGetTransaction(string address, int port, GetTxsMsg msg, int nonce) { if (!GlobalParameters.IsPool) { var txList = new List <TransactionMsg>(); foreach (var hash in msg.Hashes) { var tx = this.txComponent.GetTransactionMsgByHash(hash); if (tx != null) { txList.Add(tx); } } if (txList.Count > 0) { var payload = new TxsMsg(); payload.Transactions.AddRange(txList); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Transaction.Tx, payload); this.p2pComponent.SendCommand(address, port, cmd); } else { this.sendDataNoFoundCommand(address, port, nonce); } } }
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 receivedTransactionMessage(string address, int port, TxsMsg msg) { foreach (var tx in msg.Transactions) { if (this.txsInSynchronizing.ContainsKey(tx.Hash)) { txsInSynchronizing.Remove(tx.Hash); } if (this.newTxInDownloading.Contains(tx.Hash)) { var nodes = this.p2pComponent.GetNodes(); //Broadcast to other node foreach (var node in nodes) { if (node.IsConnected && !node.IsTrackerServer && node.IP != address) { var payload = new NewTxMsg(); payload.Hash = tx.Hash; var cmd = P2PCommand.CreateCommand(CommandNames.Transaction.NewTx, payload); this.p2pComponent.SendCommand(node.IP, node.Port, cmd); } } newTxInDownloading.Remove(tx.Hash); } this.txComponent.AddTransactionToPool(tx); } }
private void receivedGetTransaction(string address, int port, GetTxsMsg msg, int nonce) { var txList = new List <TransactionMsg>(); foreach (var hash in msg.Hashes) { var tx = this.txComponent.GetTransactionMsgFromPool(hash); LogHelper.Info("Get Transaction:" + hash + ":" + tx == null ? "Not found" : "be found"); if (tx != null) { txList.Add(tx); } } if (txList.Count > 0) { var payload = new TxsMsg(); payload.Transactions.AddRange(txList); var cmd = P2PCommand.CreateCommand(CommandNames.Transaction.Tx, payload); this.p2pComponent.SendCommand(address, port, cmd); } else { this.sendDataNoFoundCommand(address, port, nonce); } }
private void sendGetTransaction(string address, int port, List <string> txHashList) { for (int i = txHashList.Count - 1; i >= 0; i--) { var hash = txHashList[i]; if (this.txsInSynchronizing.ContainsKey(hash)) { if (Time.EpochTime - this.txsInSynchronizing[hash] > 60 * 1000) { txsInSynchronizing[hash] = Time.EpochTime; } else { txHashList.RemoveAt(i); } } else { txsInSynchronizing.Add(hash, Time.EpochTime); } } var payload = new GetTxsMsg(); payload.Hashes.AddRange(txHashList); var cmd = P2PCommand.CreateCommand(CommandNames.Transaction.GetTx, payload); p2pComponent.SendCommand(address, port, cmd); }
private void receivedBlocksMessage(string address, int port, BlocksMsg msg) { foreach (var block in msg.Blocks) { this.saveBlockToDB(block); if (this.blocksInSynchronizing.ContainsKey(block.Header.Height)) { blocksInSynchronizing.Remove(block.Header.Height); } if (this.newBlocksInDownloading.Contains(block.Header.Height)) { var nodes = this.p2pComponent.GetNodes(); //Broadcast to other node foreach (var node in nodes) { if (node.IsConnected && !node.IsTrackerServer && node.IP != address) { var cmd = P2PCommand.CreateCommand(CommandNames.Block.NewBlock, msg); this.p2pComponent.SendCommand(node.IP, node.Port, cmd); } } newBlocksInDownloading.Remove(block.Header.Height); } } }
/// <summary> /// 匹配对应的Command命令 /// </summary> /// <param name="tcpClient"></param> /// <param name="packet"></param> /// <returns></returns> public static P2PCommand FindCommand(P2PTcpClient tcpClient, ReceivePacket packet) { P2PCommand command = null; AppCenter appCenter = EasyInject.Get <AppCenter>(); if (appCenter.AllowAnonymous.Contains(packet.CommandType) || tcpClient.IsAuth) { if (appCenter.CommandDict.ContainsKey(packet.CommandType)) { Type type = appCenter.CommandDict[packet.CommandType]; command = Activator.CreateInstance(type, tcpClient, packet.Data.Select(t => t).ToArray()) as P2PCommand; } else { LogUtils.Warning($"{tcpClient.RemoteEndPoint}请求了未知命令{packet.CommandType}"); } } else { tcpClient?.SafeClose(); tcpClient.ToClient?.SafeClose(); LogUtils.Warning($"拦截{tcpClient.RemoteEndPoint}未授权命令"); } return(command); }
public static void ListenTcp <T>(P2PTcpClient tcpClient) where T : ReceivePacket { try { Guid curGuid = Global.CurrentGuid; byte[] buffer = new byte[P2PGlobal.P2PSocketBufferSize]; NetworkStream tcpStream = tcpClient.GetStream(); ReceivePacket msgReceive = Activator.CreateInstance(typeof(T)) as ReceivePacket; while (tcpClient.Connected && curGuid == Global.CurrentGuid) { int curReadLength = tcpStream.ReadSafe(buffer, 0, buffer.Length); if (curReadLength > 0) { byte[] refData = buffer.Take(curReadLength).ToArray(); while (msgReceive.ParseData(ref refData)) { LogUtils.Debug($"命令类型:{msgReceive.CommandType}"); // 执行command using (P2PCommand command = FindCommand(tcpClient, msgReceive)) { command?.Excute(); } //重置msgReceive msgReceive.Reset(); if (refData.Length <= 0) { break; } } } else { break; } } } catch (Exception ex) { LogUtils.Error($"【错误】Global_Func.ListenTcp:{Environment.NewLine}{ex}"); } if (Global.TcpMap.ContainsKey(tcpClient.ClientName)) { if (Global.TcpMap[tcpClient.ClientName].TcpClient == tcpClient) { Global.TcpMap.Remove(tcpClient.ClientName); } } //如果tcp已关闭,需要关闭相关tcp try { tcpClient.ToClient?.Close(); } catch { } LogUtils.Debug($"tcp连接{tcpClient.RemoteEndPoint}已断开"); }
private void sendHeartbeat(string address, int port) { var msg = new HeightMsg(); msg.Height = this.LocalHeight; msg.BlockTime = this.LocalLatestBlockTime; var command = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.P2P.Heartbeat, msg); p2pComponent.SendCommand(address, port, command); }
private void sendGetHeaders(string address, int port, List <long> heightList) { var payload = new GetHeadersMsg(); payload.Heights.AddRange(heightList); var cmd = P2PCommand.CreateCommand(CommandNames.Block.GetHeaders, payload); p2pComponent.SendCommand(address, port, cmd); }
private void sendGetBlocks(string address, int port, List <long> heightList) { if (heightList.Count > 0) { var payload = new GetBlocksMsg(); payload.Heights.AddRange(heightList); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.GetBlocks, payload); p2pComponent.SendCommand(address, port, cmd); } }
private void receivedGetHeaders(string address, int port, GetHeadersMsg msg, int nonce) { var headers = this.blockComponent.GetBlockHeaderMsgByHeights(msg.Heights); var payload = new HeadersMsg(); payload.Headers.AddRange(headers); var cmd = P2PCommand.CreateCommand(CommandNames.Block.Headers, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); }
private void receivedGetTransactionPool(string address, int port, int nonce) { var hashes = this.txComponent.GetAllHashesFromPool(); var payload = new TxPoolMsg(); payload.Hashes.AddRange(hashes); var cmd = P2PCommand.CreateCommand(CommandNames.Transaction.TxPool, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); }
private void receivedGetBlocks(string address, int port, GetBlocksMsg msg, int nonce) { List <BlockMsg> blocks; try { blocks = this.blockComponent.GetBlockMsgByHeights(msg.Heights); } catch (Exception ex) { LogHelper.Error("GetBlocksMsg Message is Empty"); throw; } if (blocks.Count > 0) { int maxLength = 1000 * 1024; //max 100KB; int totalLength = 0; var payload = new BlocksMsg(); foreach (var block in blocks) { totalLength += block.Serialize().Length; if (payload.Blocks.Count == 0 || totalLength <= maxLength) { payload.Blocks.Add(block); } else { break; } } try { var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.Blocks, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } catch (Exception ex) { LogHelper.Error("GetBlocksMsg Result is Empty"); } } else { var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Other.NotFound, nonce, null); this.p2pComponent.SendCommand(address, port, cmd); } }
private void receivedGetHeight(string address, int port, int nonce) { var height = this.blockComponent.GetLatestHeight(); var block = this.blockComponent.GetBlockMsgByHeight(height); if (block != null) { var payload = new HeightMsg(); payload.Height = height; payload.BlockTime = block.Header.Timestamp; var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.Height, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } }
private void receivedNewBlockMessage(string address, int port, NewBlockMsg msg, int nonce) { if (RemoteLatestHeight - LocalHeight <= 10 && msg.Header.Height - LocalHeight <= 10 && !this.tempBlockList.Any(b => b.Header.Height == msg.Header.Height) && !this.blockComponent.CheckBlockExists(msg.Header.Hash)) { if (!this.newBlocksInDownloading.Contains(msg.Header.Height) && !blockedBlockHashList.Contains(msg.Header.Hash)) { this.newBlocksInDownloading.Add(msg.Header.Height); var payload = new GetBlocksMsg(); payload.Heights.Add(msg.Header.Height); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.GetBlocks, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } } }
public void BroadcastNewBlockMessage(BlockHeaderMsg blockHeader) { var nodes = this.p2pComponent.GetNodes(); foreach (var node in nodes) { if (node.IsConnected && !node.IsTrackerServer) { var payload = new NewBlockMsg(); payload.Header = blockHeader; var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.NewBlock, payload); this.p2pComponent.SendCommand(node.IP, node.Port, cmd); } } }
private void receivedNewTransactionMessage(string address, int port, NewTxMsg msg) { if (!this.txComponent.CheckBlackTxExisted(msg.Hash) && !this.txComponent.CheckTxExisted(msg.Hash)) { if (!this.newTxInDownloading.Contains(msg.Hash)) { newTxInDownloading.Add(msg.Hash); var payload = new GetTxsMsg(); payload.Hashes.Add(msg.Hash); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Transaction.GetTx, payload); this.p2pComponent.SendCommand(address, port, cmd); } } }
private void receivedNewBlockMessage(string address, int port, NewBlockMsg msg, int nonce) { if (this.blockComponent.GetBlockMsgByHash(msg.Header.Hash) == null) { if (!this.newBlocksInDownloading.Contains(msg.Header.Height)) { this.newBlocksInDownloading.Add(msg.Header.Height); var payload = new GetBlocksMsg(); payload.Heights.Add(msg.Header.Height); var cmd = P2PCommand.CreateCommand(CommandNames.Block.GetBlocks, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } } }
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; } }
public void BroadcastNewTransactionMessage(string txHash) { var nodes = this.p2pComponent.GetNodes(); //Broadcast to other node foreach (var node in nodes) { if (node.IsConnected && !node.IsTrackerServer) { var payload = new NewTxMsg(); payload.Hash = txHash; var cmd = P2PCommand.CreateCommand(CommandNames.Transaction.NewTx, payload); this.p2pComponent.SendCommand(node.IP, node.Port, cmd); } } }
private void receivedGetHeaders(string address, int port, GetHeadersMsg msg, int nonce) { var headers = this.blockComponent.GetBlockHeaderMsgByHeights(msg.Heights); if (headers.Count > 0) { var payload = new HeadersMsg(); payload.Headers.AddRange(headers); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Block.Headers, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } else { var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Other.NotFound, nonce, null); this.p2pComponent.SendCommand(address, port, cmd); } }
/// <summary> /// 匹配对应的Command命令 /// </summary> /// <param name="tcpClient"></param> /// <param name="packet"></param> /// <returns></returns> public static P2PCommand FindCommand(P2PTcpClient tcpClient, RecievePacket packet) { P2PCommand command = null; if (Global.AllowAnonymous.Contains(packet.CommandType) || tcpClient.IsAuth) { if (Global.CommandDict.ContainsKey(packet.CommandType)) { Type type = Global.CommandDict[packet.CommandType]; command = Activator.CreateInstance(type, tcpClient, packet.GetBytes()) as P2PCommand; } } else { throw new Exception("没有权限"); } return(command); }
private void receivedGetBlocks(string address, int port, GetBlocksMsg msg, int nonce) { var blocks = this.blockComponent.GetBlockMsgByHeights(msg.Heights); if (blocks.Count > 0) { var payload = new BlocksMsg(); payload.Blocks.AddRange(blocks); var cmd = P2PCommand.CreateCommand(CommandNames.Block.Blocks, nonce, payload); this.p2pComponent.SendCommand(address, port, cmd); } else { var cmd = P2PCommand.CreateCommand(CommandNames.Other.NotFound, nonce, null); this.p2pComponent.SendCommand(address, port, cmd); } }
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 sendGetTransaction(string address, int port, List <string> txHashList) { if (RemoteLatestHeight - GlobalParameters.LocalHeight > 10) { return; } for (int i = txHashList.Count - 1; i >= 0; i--) { var hash = txHashList[i]; if (this.txsInSynchronizing.ContainsKey(hash)) { if (Time.EpochTime - this.txsInSynchronizing[hash] > 60 * 1000 && !this.txComponent.CheckBlackTxExisted(hash)) { txsInSynchronizing[hash] = Time.EpochTime; } else { txHashList.RemoveAt(i); } } else { if (!this.txComponent.CheckBlackTxExisted(hash)) { txsInSynchronizing.Add(hash, Time.EpochTime); } else { txHashList.RemoveAt(i); } } } if (txHashList.Count > 0) { var payload = new GetTxsMsg(); payload.Hashes.AddRange(txHashList); var cmd = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.Transaction.GetTx, payload); p2pComponent.SendCommand(address, port, cmd); } }
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 receivedMiningPoolsMessage(MiningPoolMsg msg) { var newMsgs = (new MiningPoolComponent()).UpdateMiningPools(msg.MinerInfos); if (newMsgs == null || !newMsgs.Any()) { return; } var nodes = this.p2pComponent.GetNodes(); nodes.ForEach(peer => { if (!peer.IsTrackerServer) { var command = P2PCommand.CreateCommand(this.Identity.ToString(), CommandNames.MiningPool.MiningPools, msg); this.p2pComponent.SendCommand(peer.IP, peer.Port, command); } }); }