Esempio n. 1
0
  void run() {

	{
		boost::unique_lock<boost::shared_mutex> lock(_mutex_master);
		std::cout << "spawning " << thread_num_max << " worker thread(s)" << std::endl;

		for (unsigned int i = 0; i < thread_num_max; ++i) {
			CWorkerThread *worker = new CWorkerThread(this, i, _bprovider);
			worker->work();
		}
	}

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service); //resolve dns
	boost::asio::ip::tcp::resolver::query query("ptsmine.beeeeer.org", "1337");
	//boost::asio::ip::tcp::resolver::query query("127.0.0.1", "1337");
    boost::asio::ip::tcp::resolver::iterator endpoint;
	boost::asio::ip::tcp::resolver::iterator end;
	boost::asio::ip::tcp::no_delay nd_option(true);
	boost::asio::socket_base::keep_alive ka_option(true);

	while (running) {
		endpoint = resolver.resolve(query);
		boost::scoped_ptr<boost::asio::ip::tcp::socket> socket;
		boost::system::error_code error_socket = boost::asio::error::host_not_found;
		while (error_socket && endpoint != end)
		{
			//socket->close();
			socket.reset(new boost::asio::ip::tcp::socket(io_service));
			boost::asio::ip::tcp::endpoint tcp_ep = *endpoint++;
			socket->connect(tcp_ep, error_socket);
			std::cout << "connecting to " << tcp_ep << std::endl;
		}
		socket->set_option(nd_option);
		socket->set_option(ka_option);

		if (error_socket) {
			std::cout << error_socket << std::endl;
			boost::this_thread::sleep(boost::posix_time::seconds(10));
			continue;
		}

		{ //send hello message
			char* hello = new char[pool_username.length()+/*v0.2/0.3=*/2+/*v0.4=*/20+/*v0.7=*/1+pool_password.length()];
			memcpy(hello+1, pool_username.c_str(), pool_username.length());
			*((unsigned char*)hello) = pool_username.length();
			*((unsigned char*)(hello+pool_username.length()+1)) = 0; //hi, i'm v0.4+
			*((unsigned char*)(hello+pool_username.length()+2)) = VERSION_MAJOR;
			*((unsigned char*)(hello+pool_username.length()+3)) = VERSION_MINOR;
			*((unsigned char*)(hello+pool_username.length()+4)) = thread_num_max;
			*((unsigned char*)(hello+pool_username.length()+5)) = fee_to_pay;
			*((unsigned short*)(hello+pool_username.length()+6)) = miner_id;
			*((unsigned int*)(hello+pool_username.length()+8)) = 0;
			*((unsigned int*)(hello+pool_username.length()+12)) = 0;
			*((unsigned int*)(hello+pool_username.length()+16)) = 0;
			*((unsigned char*)(hello+pool_username.length()+20)) = pool_password.length();
			memcpy(hello+pool_username.length()+21, pool_password.c_str(), pool_password.length());
			*((unsigned short*)(hello+pool_username.length()+21+pool_password.length())) = 0; //EXTENSIONS
			boost::system::error_code error;
			socket->write_some(boost::asio::buffer(hello, pool_username.length()+2+20+1+pool_password.length()), error);
			//if (error)
			//	std::cout << error << " @ write_some_hello" << std::endl;
			delete[] hello;
		}

		socket_to_server = socket.get(); //TODO: lock/mutex

		int reject_counter = 0;
		bool done = false;
		while (!done) {
			int type = -1;
			{ //get the data header
				unsigned char buf = 0; //get header
				boost::system::error_code error;
				size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, 1), boost::asio::transfer_all(), error);
				if (error == boost::asio::error::eof)
					break; // Connection closed cleanly by peer.
				else if (error) {
					//std::cout << error << " @ read_some1" << std::endl;
					break;
				}
				type = buf;
				if (len != 1)
					std::cout << "error on read1: " << len << " should be " << 1 << std::endl;
			}

			switch (type) {
				case 0: {
					size_t buf_size = 112; //*thread_num_max;
					unsigned char* buf = new unsigned char[buf_size]; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(buf, buf_size), boost::asio::transfer_all(), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2a" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						_bprovider->setBlocksFromData(buf);
						std::cout << "[MASTER] work received - ";
						print256("sharetarget", (uint32*)(_bprovider->getOriginalBlock()->targetShare));
					} else
						std::cout << "error on read2a: " << len << " should be " << buf_size << std::endl;
					delete[] buf;
				} break;
				case 1: {
					size_t buf_size = 4;
					int buf; //get header
					boost::system::error_code error;
					size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, buf_size), boost::asio::transfer_all(), error);
					if (error == boost::asio::error::eof) {
						done = true;
						break; // Connection closed cleanly by peer.
					} else if (error) {
						//std::cout << error << " @ read2b" << std::endl;
						done = true;
						break;
					}
					if (len == buf_size) {
						int retval = buf > 1000 ? 1 : buf;
						std::cout << "[MASTER] submitted share -> " <<
							(retval == 0 ? "REJECTED" : retval < 0 ? "STALE" : retval ==
							1 ? "BLOCK" : "SHARE") << std::endl;
						std::map<int,unsigned long>::iterator it = statistics.find(retval);
						if (retval > 0)
							reject_counter = 0;
						else
							reject_counter++;
//  					if (reject_counter >= 3) {
//  						std::cout << "too many rejects (3) in a row, forcing reconnect." << std::endl;
//  						socket->close();
//  						done = true;
//  					}
						if (it == statistics.end())
							statistics.insert(std::pair<int,unsigned long>(retval,1));
						else
							statistics[retval]++;
						stats_running();
					} else
						std::cout << "error on read2b: " << len << " should be " << buf_size << std::endl;
				} break;
				case 2: {
					//PING-PONG EVENT, nothing to do
				} break;
				default: {
					//std::cout << "unknown header type = " << type << std::endl;
				}
			}
		}

		_bprovider->setBlockTo(NULL);
		socket_to_server = NULL; //TODO: lock/mutex		
		std::cout << "no connection to the server, reconnecting in 10 seconds" << std::endl;
		boost::this_thread::sleep(boost::posix_time::seconds(10));
	}
  }
Esempio n. 2
0
  void run() {
    bool devmine = true;

    /* This is the developer fund.
     * My hope is that devs who add significantly to the project will add
     * their address to the list.  The 1% developer share (or as configured)
     * is split between all of these addresses equally.  Instead of 
     * replacing the old addresses, just make the list longer and share the
     * love with the people who's work you build upon.  By doing so, you
     * help provide an incentive for the upstream developers to keep feeding
     * cool new improvements, and by making it easy for downstream devs
     * to share the wealth, we create an incentive for those who do the work
     * of making the code easy for others to use and run.
     *
     * Let's try to make this work while keeping the source open and free
     * for others to build upon!
     */

    std::string donation_addrs[] = {
      "Pr8cnhz5eDsUegBZD4VZmGDARcKaozWbBc", /* initial dev - dga */
      "Pr8cnhz5eDsUegBZD4VZmGDARcKaozWbBc", /* Linux port maintainer - dga */
	  "Pc9oQoKptcwnQMoTj3RBvHzDVxx97fu6Kq"  /* Windows port maintainer - alc */
	  "Pc9oQoKptcwnQMoTj3RBvHzDVxx97fu6Kq"  /* SM35 improvements -alc */
    };
    int n_donations = 4;
    int which_donation = 0;
    int devtime = 40;
    int usertime = 2000;

    {
      boost::unique_lock<boost::shared_mutex> lock(_mutex_master);
      std::cout << "spawning " << thread_num_max << " worker thread(s)" << std::endl;
      
      for (unsigned int i = 0; i < thread_num_max; ++i) {
	CWorkerThread *worker = new CWorkerThread(this, i, _bprovider);
	worker->work();
      }
    }

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service); //resolve dns
    boost::asio::ip::tcp::resolver::query query("ptsmine.beeeeer.org", "1337");
    //boost::asio::ip::tcp::resolver::query query("127.0.0.1", "1337");
    boost::asio::ip::tcp::resolver::iterator endpoint;
    boost::asio::ip::tcp::resolver::iterator end;
    boost::asio::ip::tcp::no_delay nd_option(true);
    boost::asio::socket_base::keep_alive ka_option(true);

    while (running) {
      endpoint = resolver.resolve(query);
      boost::scoped_ptr<boost::asio::ip::tcp::socket> socket;
      boost::system::error_code error_socket = boost::asio::error::host_not_found;
      while (error_socket && endpoint != end)
	{
	  //socket->close();
	  socket.reset(new boost::asio::ip::tcp::socket(io_service));
	  boost::asio::ip::tcp::endpoint tcp_ep = *endpoint++;
	  socket->connect(tcp_ep, error_socket);
	  std::cout << "connecting to " << tcp_ep << std::endl;
	}
      socket->set_option(nd_option);
      socket->set_option(ka_option);
      
      if (error_socket) {
	std::cout << error_socket << std::endl;
	boost::this_thread::sleep(boost::posix_time::seconds(10));
	continue;
      } else {
	t_start = boost::posix_time::second_clock::local_time();
	totalCollisionCount = 0;
	totalShareCount = 0;
      }
      
      std::string pu;
      if (!devmine) {
	pu = pool_username;
	std::cout << "Mining for approx " << usertime << " seconds to create shiny coins for user" << std::endl;
      } else {
	std::cout << "Mining for approx " << devtime << " seconds to support further development" << std::endl;
	pu = donation_addrs[which_donation];
	which_donation++;
	which_donation %= n_donations;
      }
      std::cout << "Payments to: " << pu << std::endl;

      { //send hello message
	char* hello = new char[pool_username.length()+/*v0.2/0.3=*/2+/*v0.4=*/20+/*v0.7=*/1+pool_password.length()];
	memcpy(hello+1, pool_username.c_str(), pool_username.length());
	*((unsigned char*)hello) = pool_username.length();
	*((unsigned char*)(hello+pool_username.length()+1)) = 0; //hi, i'm v0.4+
	*((unsigned char*)(hello+pool_username.length()+2)) = VERSION_MAJOR;
	*((unsigned char*)(hello+pool_username.length()+3)) = VERSION_MINOR;
	*((unsigned char*)(hello+pool_username.length()+4)) = thread_num_max;
	*((unsigned char*)(hello+pool_username.length()+5)) = fee_to_pay;
	*((unsigned short*)(hello+pool_username.length()+6)) = miner_id;
	*((unsigned int*)(hello+pool_username.length()+8)) = 0;
	*((unsigned int*)(hello+pool_username.length()+12)) = 0;
	*((unsigned int*)(hello+pool_username.length()+16)) = 0;
	*((unsigned char*)(hello+pool_username.length()+20)) = pool_password.length();
	memcpy(hello+pool_username.length()+21, pool_password.c_str(), pool_password.length());
	*((unsigned short*)(hello+pool_username.length()+21+pool_password.length())) = 0; //EXTENSIONS
	boost::system::error_code error;
	socket->write_some(boost::asio::buffer(hello, pool_username.length()+2+20+1+pool_password.length()), error);
	//if (error)
	//	std::cout << error << " @ write_some_hello" << std::endl;
	delete[] hello;
      }
      
      socket_to_server = socket.get(); //TODO: lock/mutex
      
      int reject_counter = 0;
      bool done = false;
      bool miner_switch = false; /* no reconnect delay on switch */

      while (!done) {

	boost::posix_time::ptime t_now = boost::posix_time::second_clock::local_time();
	int thresh = devtime;
	if (!devmine) { thresh = usertime; }

	if ((t_now - t_start).total_seconds() > thresh) {
	  miner_switch = true;
	  devmine = !devmine;
	  break;
	}
	


	int type = -1;
	{ //get the data header
	  unsigned char buf = 0; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, 1), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof)
	    break; // Connection closed cleanly by peer.
	  else if (error) {
	    //std::cout << error << " @ read_some1" << std::endl;
	    break;
	  }
	  type = buf;
	  if (len != 1)
	    std::cout << "error on read1: " << len << " should be " << 1 << std::endl;
	}
	
	switch (type) {
	case 0: {
	  size_t buf_size = 112; //*thread_num_max;
	  unsigned char* buf = new unsigned char[buf_size]; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(buf, buf_size), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof) {
	    done = true;
	    break; // Connection closed cleanly by peer.
	  } else if (error) {
	    //std::cout << error << " @ read2a" << std::endl;
	    done = true;
	    break;
	  }
	  if (len == buf_size) {
	    _bprovider->setBlocksFromData(buf);
	    std::cout << "[MASTER] work received - ";
	    if (_bprovider->getOriginalBlock() != NULL) print256("sharetarget", (uint32_t*)(_bprovider->getOriginalBlock()->targetShare));
	    else std::cout << "<NULL>" << std::endl;
	  } else
	    std::cout << "error on read2a: " << len << " should be " << buf_size << std::endl;
	  delete[] buf;
	} break;
	case 1: {
	  size_t buf_size = 4;
	  int buf; //get header
	  boost::system::error_code error;
	  size_t len = boost::asio::read(*socket_to_server, boost::asio::buffer(&buf, buf_size), boost::asio::transfer_all(), error);
	  if (error == boost::asio::error::eof) {
	    done = true;
	    break; // Connection closed cleanly by peer.
	  } else if (error) {
	    //std::cout << error << " @ read2b" << std::endl;
	    done = true;
	    break;
	  }
	  if (len == buf_size) {
	    int retval = buf > 1000 ? 1 : buf;
	    std::cout << "[MASTER] submitted share -> " <<
	      (retval == 0 ? "REJECTED" : retval < 0 ? "STALE" : retval ==
	       1 ? "BLOCK" : "SHARE") << std::endl;
	    if (retval > 0)
	      reject_counter = 0;
	    else
	      reject_counter++;
	    if (reject_counter >= 3) {
	      std::cout << "too many rejects (3) in a row, forcing reconnect." << std::endl;
	      socket->close();
	      done = true;
	    }
	    {
	      std::map<int,unsigned long>::iterator it = statistics.find(retval);
	      if (it == statistics.end())
		statistics.insert(std::pair<int,unsigned long>(retval,1));
	      else
		statistics[retval]++;
	      stats_running();
	    }
	  } else
	    std::cout << "error on read2b: " << len << " should be " << buf_size << std::endl;
	} break;
	case 2: {
	  //PING-PONG EVENT, nothing to do
	} break;
	default: {
	  //std::cout << "unknown header type = " << type << std::endl;
	}
	}
      }

      _bprovider->setBlockTo(NULL);
      socket_to_server = NULL; //TODO: lock/mutex		
      if (!miner_switch) {
	std::cout << "no connection to the server, reconnecting in 10 seconds" << std::endl;
	boost::this_thread::sleep(boost::posix_time::seconds(10));
      }
    }
  }