private static bool ValidateData(CMessage Msg) { if (Msg.RqsType != ERequestType.NULL) { return(false); } switch (Msg.DataType) { case EDataType.PeersList: try { string[] peers = Msg.Data.Split(';'); foreach (string rp in peers) { CPeer.Deserialize(rp); } return(true); } catch { return(false); } case EDataType.Block: try { CBlock.Deserialize(Msg.Data); return(true); } catch { return(false); } case EDataType.ULong: try { Convert.ToUInt64(Msg.Data); return(true); } catch { return(false); } case EDataType.ULongList: try { JsonConvert.DeserializeObject <ulong[]>(Msg.Data); return(true); } catch { return(false); } case EDataType.Header: try { JsonConvert.DeserializeObject <CHeader>(Msg.Data); return(true); } catch { return(false); } case EDataType.BlockList: try { JsonConvert.DeserializeObject <CBlock[]>(Msg.Data); return(true); } catch { return(false); } case EDataType.HeaderList: try { JsonConvert.DeserializeObject <CHeader[]>(Msg.Data); return(true); } catch { return(false); } default: return(false); } }
private static bool ValidateRequest(CMessage Msg) { switch (Msg.RqsType) { case ERequestType.UpdPeers: { if (Msg.DataType == EDataType.NULL && Msg.Data == null) { return(true); } else { return(false); } } case ERequestType.NewBlockMined: { if (Msg.DataType == EDataType.Block && Msg.Data != null) { try { CBlock.Deserialize(Msg.Data); return(true); } catch { return(false); } } else { return(false); } } case ERequestType.ChainLength: { if (Msg.DataType == EDataType.NULL && Msg.Data == null) { return(true); } else { return(false); } } case ERequestType.GetHeader: { if (Msg.DataType == EDataType.ULong) { try { Convert.ToInt64(Msg.Data); } catch { return(false); } return(true); } else { return(false); } } case ERequestType.GetLastHeader: { { if (Msg.DataType == EDataType.NULL && Msg.Data == null) { return(true); } else { return(false); } } } case ERequestType.GetLastValid: { { if (Msg.DataType == EDataType.NULL && Msg.Data == null) { return(true); } else { return(false); } } } case ERequestType.DownloadBlock: { if (Msg.DataType == EDataType.ULong && Msg.Data != null) { try { Convert.ToUInt64(Msg.Data); return(true); } catch { return(false); } } return(false); } case ERequestType.DownloadBlocks: { if (Msg.DataType == EDataType.ULongList && Msg.Data != null) { try { string[] stringToConvert = Msg.Data.Split(';'); if (stringToConvert.Length != 2) { return(false); } foreach (string s in stringToConvert) { Convert.ToUInt64(s); } return(true); } catch { return(false); } } return(false); } case ERequestType.DownloadHeaders: { if (Msg.DataType == EDataType.ULongList && Msg.Data != null) { try { string[] stringToConvert = Msg.Data.Split(';'); if (stringToConvert.Length != 2) { return(false); } foreach (string s in stringToConvert) { Convert.ToUInt64(s); } return(true); } catch { return(false); } } return(false); } case ERequestType.NewTransaction: { if (Msg.DataType == EDataType.Transaction && Msg.Data != null) { try { Transaction t = JsonConvert.DeserializeObject <Transaction>(Msg.Data); if (MemPool.Instance.CheckDouble(t)) { return(false); } if (MemPool.Instance.CheckDoubleSpending(t)) { return(false); } if (CBlockChain.Instance.SideChain.CheckDouble(t)) { return(false); } MemPool.Instance.AddUTX(t); return(true); } catch { return(false); } } return(false); } default: return(false); } }
private void ExecuteRequest() { CMessage rqs; while (mIsConnected) { Thread.Sleep(100); if (RequestQueue.Count > 0) { rqs = RequestQueue.Dequeue(); switch (rqs.RqsType) { case ERequestType.UpdPeers: { if (Program.DEBUG) { CIO.DebugOut("UpdPeers received by " + mIp); } //(!) è meglio farsi ritornare la lista e poi usare json? SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.PeersList, CPeers.Instance.PeersList(), rqs.ID)); break; } case ERequestType.NewBlockMined: { if (CPeers.Instance.CanReceiveBlock) { if (Program.DEBUG) { CIO.DebugOut("NewBlockMined received by " + mIp); } CTemporaryBlock newBlock = new CTemporaryBlock(CBlock.Deserialize(rqs.Data), this); if (!CValidator.ValidateBlock(newBlock) && newBlock.Header.BlockNumber < CBlockChain.Instance.LastValidBlock.Header.BlockNumber) { Disconnect(); break; } //TODO scaricare i blocchi mancanti se ne mancano(sono al blocco 10 e mi arriva il blocco 50) if (!CBlockChain.Instance.AddNewMinedBlock(newBlock)) { Stack <CTemporaryBlock> blocks = new Stack <CTemporaryBlock>(); int ID = 0; blocks.Push(newBlock); for (ulong i = newBlock.Header.BlockNumber - 1; i > CBlockChain.Instance.LastValidBlock.Header.BlockNumber; i--) { ID = SendRequest(new CMessage(EMessageType.Request, ERequestType.DownloadBlock, EDataType.ULong, Convert.ToString(i))); blocks.Push(new CTemporaryBlock(JsonConvert.DeserializeObject <CBlock>(ReceiveData(ID, 5000).Data), this)); if (!CValidator.ValidateBlock(blocks.Peek()) && blocks.Peek().Header.BlockNumber < CBlockChain.Instance.LastValidBlock.Header.BlockNumber) { Disconnect(); break; } if (CBlockChain.Instance.AddNewMinedBlock(blocks.Peek())) { blocks.Pop(); for (int j = blocks.Count; j > 0; j--) { CBlockChain.Instance.AddNewMinedBlock(blocks.Pop()); } } } } } break; } case ERequestType.GetLastHeader: { if (Program.DEBUG) { CIO.DebugOut("GetLastHeader received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Header, JsonConvert.SerializeObject(CBlockChain.Instance.LastValidBlock.Header), rqs.ID)); break; } case ERequestType.ChainLength: { if (Program.DEBUG) { CIO.DebugOut("ChainLength received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.ULong, Convert.ToString(CBlockChain.Instance.LastValidBlock.Header.BlockNumber), rqs.ID)); break; } case ERequestType.GetLastValid: { if (Program.DEBUG) { CIO.DebugOut("GetLastValid received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Block, CBlockChain.Instance.LastValidBlock.Serialize(), rqs.ID)); break; } case ERequestType.DownloadBlock: { if (Program.DEBUG) { CIO.DebugOut("DownloadBlock received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Block, JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlock(Convert.ToUInt64(rqs.Data), true)), rqs.ID)); break; } case ERequestType.DownloadBlocks: { if (Program.DEBUG) { CIO.DebugOut("DownloadBlocks received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.BlockList, JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlocks(Convert.ToUInt64(rqs.Data.Split(';')[0]), Convert.ToUInt64(rqs.Data.Split(';')[1]))), rqs.ID)); break; } case ERequestType.DownloadHeaders: { if (Program.DEBUG) { CIO.DebugOut("DownloadBlocks received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.HeaderList, JsonConvert.SerializeObject(CBlockChain.Instance.RetriveHeaders(Convert.ToUInt64(rqs.Data.Split(';')[0]), Convert.ToUInt64(rqs.Data.Split(';')[1]))), rqs.ID)); break; } case ERequestType.GetHeader: { if (Program.DEBUG) { CIO.DebugOut("GetLastHeader received by " + mIp); } SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Header, JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlock(Convert.ToUInt64(rqs.Data)).Header), rqs.ID)); break; } case ERequestType.NewTransaction: { Transaction t = JsonConvert.DeserializeObject <Transaction>(rqs.Data); if (t.Verify()) { MemPool.Instance.AddUTX(t); } break; } default: if (Program.DEBUG) { CIO.DebugOut("Ricevuto comando sconosciuto: " + rqs.RqsType + " da " + IP); } break; } } } }