示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
 public CBlock(CTemporaryBlock block) : this(block.Header.BlockNumber, block.Header.Hash, block.Header.PreviousBlockHash, block.TxLimit, block.Nonce, block.Timestamp, block.Difficulty, block.Transactions)
 {
 }
示例#4
0
        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;
                    }
                }
            }
        }
示例#5
0
 public bool AddNewMinedBlock(CTemporaryBlock newBlock)
 {
     lock (mSideChain)
         return(mSideChain.Add(newBlock));
 }