Exemplo n.º 1
0
	Core::CBlock* Miner::DeserializeBlock(std::vector<unsigned char> DATA)
	{
		Core::CBlock* BLOCK = new Core::CBlock();
		BLOCK->SetVersion(bytes2uint(std::vector<unsigned char>(DATA.begin(), DATA.begin() + 4)));
			
		uint1024 prevBlock = BLOCK->GetPrevBlock();
		prevBlock.SetBytes(std::vector<unsigned char>(DATA.begin() + 4, DATA.begin() + 132));
		BLOCK->SetPrevBlock(prevBlock);

		uint512 merkleRoot = BLOCK->GetMerkleRoot();
		merkleRoot.SetBytes(std::vector<unsigned char>(DATA.begin() + 132, DATA.end() - 20));
		BLOCK->SetMerkleRoot(merkleRoot);

		BLOCK->SetChannel(bytes2uint(std::vector<unsigned char>(DATA.end() - 20, DATA.end() - 16)));			
		BLOCK->SetHeight(bytes2uint(std::vector<unsigned char>(DATA.end() - 16, DATA.end() - 12)));
		BLOCK->SetBits(bytes2uint(std::vector<unsigned char>(DATA.end() - 12,  DATA.end() - 8)));
		BLOCK->SetNonce(bytes2uint64(std::vector<unsigned char>(DATA.end() - 8,  DATA.end())));
			
		return BLOCK;
	}
Exemplo n.º 2
0
	/** Main Connection Thread. Handles all the networking to allow
		Mining threads the most performance. **/
	void ServerConnection::ServerThread()
	{
		
		/** Don't begin until all mining threads are Created. **/
		while(THREADS.size() != nThreads)
			Sleep(1);
				
				
		/** Initialize the Server Connection. **/
		CLIENT = new LLP::Miner(IP, PORT);
			
				
		/** Initialize a Timer for the Hash Meter. **/
		METER_TIMER.Start();
		HEIGHT_TIMER.Start();

		loop
		{
			try
			{
				/** Run this thread at 100 Cycles per Second. **/
				Sleep(10);
					
					
				/** Attempt with best efforts to keep the Connection Alive. **/
				if(!CLIENT->Connected() || CLIENT->Errors() || CLIENT->Timeout(nTimeout))
				{
					ResetThreads();
					
					if(!CLIENT->Connect())
						continue;
					else
					{
						CLIENT->SetChannel(1);
						CLIENT->GetHeight();
					}
				}
				
				
				/** Check the Block Height every Second. **/
				if(HEIGHT_TIMER.ElapsedMilliseconds() > 1000)
				{
					HEIGHT_TIMER.Reset();
					CLIENT->GetHeight();
				}
				
				
				/** Show the Meter every 15 Seconds. **/
				if(METER_TIMER.Elapsed() > 15)
				{
					unsigned int SecondsElapsed = (unsigned int)time(0) - nStartTimer;
					unsigned int nElapsed = METER_TIMER.Elapsed();
					double PPS = (double) nPrimes / nElapsed;
					double CPS = (double) nChains / nElapsed;
					double CSD = (double) (nBlocks * 60.0) / (SecondsElapsed / 60.0);
					
					nPrimes = 0;
					nChains = 0;
					
					printf("[METERS] %f PPS | %f CPS | %u Blocks | %f NXS per Hour | Height = %u | Difficulty %f | %02d:%02d:%02d\n", PPS, CPS, nBlocks, CSD, nBestHeight, nDifficulty / 10000000.0, (SecondsElapsed/3600)%60, (SecondsElapsed/60)%60, (SecondsElapsed)%60);
					METER_TIMER.Reset();	
					
					ResetThreads();
				}
				
				
				/** Check if there is work to do for each Miner Thread. **/
				for(int nIndex = 0; nIndex < THREADS.size(); nIndex++)
				{
					/** Attempt to get a new block from the Server if Thread needs One. **/
					if(THREADS[nIndex]->fNewBlock)
					{
						CLIENT->GetBlock();
						THREADS[nIndex]->fBlockWaiting = true;
						THREADS[nIndex]->fNewBlock = false;
					}
				}
					
				CLIENT->ReadPacket();
				if(!CLIENT->PacketComplete())
					continue;
						
				/** Handle the New Packet, and Interpret its Data. **/
				LLP::Packet PACKET = CLIENT->NewPacket();
				CLIENT->ResetPacket();
							
							
				/** Output if a Share is Accepted. **/
				if(PACKET.HEADER == CLIENT->GOOD)
				{
					nBlocks++;
					printf("[MASTER] Nexus : Block ACCEPTED\n");
					
					ResetThreads();
				}
					
					
				/** Output if a Share is Rejected. **/
				else if(PACKET.HEADER == CLIENT->FAIL) 
				{
					printf("[MASTER] Nexus : Block REJECTED\n");
					
					ResetThreads();
				}
					
				/** Reset the Threads if a New Block came in. **/
				else if(PACKET.HEADER == CLIENT->BLOCK_HEIGHT)
				{
					unsigned int nHeight = bytes2uint(PACKET.DATA);
					if(nHeight > nBestHeight)
					{
						nBestHeight = nHeight;
						printf("[MASTER] Nexus : New Block %u.\n", nBestHeight);
							
						ResetThreads();
					}
				}
					
					
				/** Set the Block for the Thread if there is a New Block Packet. **/
				else if(PACKET.HEADER == CLIENT->BLOCK_DATA)
				{
					/** Search for a Thread waiting for a New Block to Supply its need. **/
					for(int nIndex = 0; nIndex < THREADS.size(); nIndex++)
					{
						if(THREADS[nIndex]->fBlockWaiting)
						{
							THREADS[nIndex]->MUTEX.lock();
							THREADS[nIndex]->cBlock.nVersion      = bytes2uint(std::vector<unsigned char>(PACKET.DATA.begin(), PACKET.DATA.begin() + 4));
							
							THREADS[nIndex]->cBlock.hashPrevBlock.SetBytes (std::vector<unsigned char>(PACKET.DATA.begin() + 4, PACKET.DATA.begin() + 132));
							THREADS[nIndex]->cBlock.hashMerkleRoot.SetBytes(std::vector<unsigned char>(PACKET.DATA.begin() + 132, PACKET.DATA.end() - 20));
							
							THREADS[nIndex]->cBlock.nChannel      = bytes2uint(std::vector<unsigned char>(PACKET.DATA.end() - 20, PACKET.DATA.end() - 16));
							THREADS[nIndex]->cBlock.nHeight       = bytes2uint(std::vector<unsigned char>(PACKET.DATA.end() - 16, PACKET.DATA.end() - 12));
							THREADS[nIndex]->cBlock.nBits         = bytes2uint(std::vector<unsigned char>(PACKET.DATA.end() - 12,  PACKET.DATA.end() - 8));
							THREADS[nIndex]->cBlock.nNonce        = bytes2uint64(std::vector<unsigned char>(PACKET.DATA.end() - 8,  PACKET.DATA.end()));
							THREADS[nIndex]->MUTEX.unlock();
							
							if(THREADS[nIndex]->cBlock.nHeight < nBestHeight)
							{
								printf("[MASTER] Received Obsolete Block %u... Requesting New Block.\n", THREADS[nIndex]->cBlock.nHeight);
								CLIENT->GetBlock();
									
								break;
							}
							
							/** Set the Difficulty from most recent Block Received. **/
							nDifficulty = THREADS[nIndex]->cBlock.nBits;
								
							printf("[MASTER] Block %s Height = %u Received on Thread %u\n", THREADS[nIndex]->cBlock.hashMerkleRoot.ToString().substr(0, 20).c_str(), THREADS[nIndex]->cBlock.nHeight, nIndex);
							THREADS[nIndex]->fBlockWaiting = false;
								
							break;
						}
					}
				}
					
			}
			catch(std::exception& e)
			{
				printf("%s\n", e.what()); CLIENT = new LLP::Miner(IP, PORT); 
			}
		}
	}