private CTemporaryBlock RequestLastValidBlock() { List <CTemporaryBlock> blocks = new List <CTemporaryBlock>(); CTemporaryBlock ris = null; CBlock block; int ID = 0; foreach (CPeer p in mPeers) { if (p != null) { ID = p.SendRequest(new CMessage(EMessageType.Request, ERequestType.GetLastValid)); block = p.ReceiveBlock(ID, 5000); blocks.Add(new CTemporaryBlock(block, p)); } } if (blocks.Count > 0) { if (blocks[0] != null) { ris = blocks[0]; foreach (CTemporaryBlock b in blocks) { if (ris.Header.BlockNumber < b.Header.BlockNumber) { ris = b; } } } } return(ris); }
public CTemporaryBlock[] DistribuiteDownloadBlocks(ulong initialIndex, ulong finalIndex, CPeer[] Peers = null) { if (finalIndex < initialIndex) { return(new CTemporaryBlock[0]); } if (Peers == null) { Peers = mPeers; } Queue <Thread> threadQueue = new Queue <Thread>(); Queue <CRange> queueRange = new Queue <CRange>(); CTemporaryBlock[] ris; ulong module = 0, rangeDim = 10, totalBlocks = finalIndex - initialIndex; ulong rangeInitialIndex = initialIndex; ris = new CTemporaryBlock[totalBlocks]; foreach (CPeer p in Peers) { if (p != null) { threadQueue.Enqueue(new Thread(new ParameterizedThreadStart(DownloadBlocks))); } } //creazione gruppi di blocchi //1-10 scarica i blocchi dall'1 compreso al 10 non compreso(1-2-3-4-5-6-7-8-9) module = totalBlocks % rangeDim; queueRange.Enqueue(new CRange(finalIndex - module, finalIndex)); finalIndex -= module; while (rangeInitialIndex < finalIndex) { queueRange.Enqueue(new CRange(rangeInitialIndex, rangeInitialIndex += rangeDim)); } //creazione ed avvio thread foreach (CPeer p in Peers) { if (p != null) { threadQueue.Peek().Name = "DownloadBlocks " + p.IP; threadQueue.Peek().Start(new object[] { p, queueRange, ris, initialIndex }); threadQueue.Enqueue(threadQueue.Dequeue()); } } while (threadQueue.Count > 0) { threadQueue.Dequeue().Join(); } return(ris); }
public CBlock(CTemporaryBlock block) : this(block.Header.BlockNumber, block.Header.Hash, block.Header.PreviousBlockHash, block.TxLimit, block.Nonce, block.Timestamp, block.Difficulty, block.Transactions) { }
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; } } } }
public bool AddNewMinedBlock(CTemporaryBlock newBlock) { lock (mSideChain) return(mSideChain.Add(newBlock)); }