unsigned ChooseWinner(const std::vector<bigint_t> &choices, TRng &rng)
	{
		std::vector<std::pair<double,unsigned> > values;
		for(unsigned i=0;i<choices.size();i++){
			values.push_back(std::make_pair(1.0 / wide_as_double(8, choices[i].limbs), i));
		}
		std::sort(values.begin(), values.end());
		double acc=0;
		for(unsigned i=0;i<values.size();i++){
			acc+=sqrt(values[i].first);
			values[i].first=acc;
		}
		
		std::uniform_real_distribution<double> distribution(0.0,acc);
		
		double sel=distribution(rng);
		for(unsigned i=0;i<values.size();i++){
			if(sel<=values[i].first)
				return values[i].second;
		}
		return values.back().second;
	}
		void Run()
		{
			try{
				auto beginConnect = std::make_shared<Packet_ClientBeginConnect>(m_clientId, m_minerId);
				Log(Log_Info, "Connecting with clientId=%s, minerId=%s", m_clientId.begin(), m_minerId.begin());
				SendPacket(beginConnect);

				auto endConnect = RecvPacket<Packet_ServerCompleteConnect>();
				Log(Log_Info, "Connected to exchange=%s, running=%s", endConnect->exchangeId.c_str(), endConnect->serverId.c_str());

				while (1){
					Log(Log_Verbose, "Waiting for round to begin.");
					auto beginRound = RecvPacket<Packet_ServerBeginRound>();
					Log(Log_Info, "Round beginning with %u bytes of chain data.", beginRound->chainData.size());

					Log(Log_Verbose, "Waiting for request for bid.");
					auto requestBid = RecvPacket<Packet_ServerRequestBid>();
					// Get an estimate of the skew between our clock and theirs. If it is positive,
					// then we are ahead of them.
					double tNow = now()*1e-9;
					double skewEstimate = tNow - requestBid->timeStampRequestBids*1e-9;
					// And work out how long they expect it to last, independent of the skew
					double period = requestBid->timeStampReceiveBids*1e-9 - requestBid->timeStampRequestBids*1e-9;

					Log(Log_Info, "Received bid request: serverStart=%lf, ourStart=%lf, skew=%lg. Bid period=%lf", requestBid->timeStampRequestBids*1e-9, tNow, skewEstimate, period);

					std::shared_ptr<Packet_ClientSendBid> bid = std::make_shared<Packet_ClientSendBid>();

					// Making the bid
					MakeBid(beginRound, requestBid, period, skewEstimate, bid->solution, bid->proof);
					bid->timeSent = now();
					Log(Log_Verbose, "Bid ready.");

					SendPacket(bid);
					Log(Log_Verbose, "Bid sent.");

					Log(Log_Verbose, "Waiting for results.");
					auto results = RecvPacket<Packet_ServerCompleteRound>();
					Log(Log_Info, "Got round results.");

					for (unsigned i = 0; i < results->submissions.size(); i++){
						double taken = requestBid->timeStampReceiveBids*1e-9 - results->submissions[i].timeRecv*1e-9;
						bool overDue = requestBid->timeStampReceiveBids < results->submissions[i].timeRecv;
						Log(Log_Info, "  %16s : %.6lg, %lg%s", results->submissions[i].clientId.c_str(),
							wide_as_double(BIGINT_WORDS, results->submissions[i].proof), taken,
							overDue ? " OVERDUE" : ""
							);
						if (m_knownCoins.find(results->submissions[i].clientId) == m_knownCoins.end()){
							m_knownCoins[results->submissions[i].clientId] = 0;
						}
					}

					if (results->winner.clientId == m_clientId){
						Log(Log_Info, "");
						Log(Log_Info, "You won a coin!");
						Log(Log_Info, "");
					}

					m_knownRounds++;
					m_knownCoins[results->winner.clientId]++;

					Log(Log_Info, "  %16s : %6s, %8s\n", "ClientId", "Coins", "Success");
					auto it = m_knownCoins.begin();
					while (it != m_knownCoins.end()){
						Log(Log_Info, "  %16s : %6d, %.6lf", it->first.c_str(), it->second, it->second / (double)m_knownRounds);
						++it;
					}

					Log(Log_Verbose, "");
				}

			}
			catch (std::exception &e){
				Log(Log_Fatal, "Exception : %s.", e.what());
				throw;
			}
		}