Beispiel #1
0
uint32_t get_work(uint32_t *midstate, uint32_t *data)
{
	getwork gw;
	uint32_t mtime;
	int h,num=sizeof(hosts)/sizeof(hosts_t);
	static unsigned char host=0;

        gwmut.lock();
	for(h=0;h<num;h++,host++){
		host=host%num;
		GetworkThread* gwt=(GetworkThread*)hosts[host].gwt;
		if(!gwt->getworks.empty()){
			mtime=gwt->getworks.back().mtime;
			memcpy(data,gwt->getworks.back().data,sizeof(gw.data));
			memcpy(midstate,gwt->getworks.back().midstate,sizeof(gw.midstate));
			//add host signature to data
			if(((char*)data)[0]!=0){
				printf("ERROR: got incompatible data header char: %d\n",(int)(((char*)data)[0]));
				gwt->getworks.pop_back();
       				gwmut.unlock();
				return 0;}
			memcpy(data,&host,1);
			gwt->getworks.pop_back();
       			gwmut.unlock();
			hosts[host].got++;
			return mtime;}}
	gwmut.unlock();
	threads_sleep(100); //sleep here rather than in C part
	return 0;
}
Beispiel #2
0
void put_work(uint32_t *data,uint32_t* hash)
{
	//FILE* fd;
	int k;
	unsigned char host;
	for(k=0;k<7;k++){ // Reverse byte order !
		byte_reverse((uint8_t*)(&hash[k]));}
	memcpy(&host,data,1);
	for(k=7;k>0;k--){
		if(hash[k]<hosts[host].target[k]){ // hash meets difficulty
			PutworkThread* pwt;
			putwork pw;
			memset(data,0,1);
			pwt=(PutworkThread*)hosts[host].pwt;
			memcpy(pw.data,data,sizeof(uint32_t)*32);
			pwmut.lock();
			pwt->putworks.push_back(pw);
			pwmut.unlock();
			hosts[host].done++;
			//fd=fopen(".putwork.log", "a");
			//fprintf(fd,"%lu %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x %d good\n",time(NULL),hash[0],hash[1],hash[2],hash[3],hash[4],hash[5],hash[6],hash[7],k);
			//fclose(fd);
			//printf("SENDING: %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x\n",hash[0],hash[1],hash[2],hash[3],hash[4],hash[5],hash[6],hash[7]);
			return;}
		if(hash[k]>hosts[host].target[k]){
			//fd=fopen(".putwork.log", "a");
			//fprintf(fd,"%lu %08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x %d easy\n",time(NULL),hash[0],hash[1],hash[2],hash[3],hash[4],hash[5],hash[6],hash[7],k);
			//fclose(fd);
			return;}}
}
Beispiel #3
0
void PutworkThread::log()
{
        unsigned int i,j;
        char filename[32];
        FILE* fp;
        sprintf(filename,".putwork-%d.log",host);
        fp=fopen(filename, "w");
        gwmut.lock();
	fprintf(fp,"%d\n",putworks.size());
        for(i=0;i<putworks.size();i++){
                for(j=16;j<20;j++){
                        fprintf(fp,"%08x", putworks[i].data[j]);}
                fprintf(fp,"\n");}
        gwmut.unlock();
        fclose(fp);
}
Beispiel #4
0
/* -------------------------------- getwork -----------------------------------*/
void GetworkThread::log()
{	
	unsigned int i,j;
	char filename[32];
	FILE* fp;
	sprintf(filename,".getwork-%d.log",host);
	fp=fopen(filename, "w");
	gwmut.lock();
	for(i=0;i<getworks.size();i++){
		fprintf(fp,"%u ",getworks[i].mtime);
		for(j=0;j<8;j++){
			fprintf(fp,"%08x", getworks[i].midstate[j]);}
		fprintf(fp,"\n");}
	gwmut.unlock();
	fclose(fp);
}
Beispiel #5
0
void PutworkThread::Run() // just send data, don't check anything (again)
{
	for(;;){
		uint32_t data[32];
		char ustr[258];
		unsigned int k;
		//FILE* fd;

		pwmut.lock();
		if(putworks.empty()){
			pwmut.unlock();
			if(testCancel()){
				break;}
			threads_sleep(100);
			continue;}
		memcpy(data,putworks.front().data, sizeof(data));
		putworks.erase(putworks.begin());
		pwmut.unlock();
	        for(k=0;k<32;k++) {
			byte_reverse((uint8_t*)(&data[k]));
			sprintf(&ustr[k*8],"%08x",data[k]);}
		ustr[256] = 0;
		//fd=fopen(".putwork.log", "a");
		//fprintf(fd,"%u %s\n",time(NULL),ustr);
		//fclose(fd);
                Json::Value query;
                query["jsonrpc"] = "2.0";
                query["id"] = 1;
                query["method"] = "getwork";
                query["params"][0] = std::string(ustr);
                Json::Value answ = make_rpc_req(query, false, host); // only one save
		// here we should check if the answer is ok
		hosts[host].sent++;
		//log();
		}
}
Beispiel #6
0
void GetworkThread::Run()
{
	while(!testCancel()) {
		uint32_t midstate[8]={0,0,0,0,0,0,0,0}, data[32];
		unsigned int i;
		getwork gw;
		uint32_t mtime = time(NULL);
		Json::Value query, answ;
		PutworkThread* pwt=(PutworkThread*)hosts[host].pwt;

		gwmut.lock();
		if(!getworks.empty()){
			if(getworks.back().mtime==mtime) {
				gwmut.unlock(); 
				threads_sleep(100);
				continue;}
			for(i=0;i<getworks.size();i++){
				if(getworks[i].mtime>mtime-MAXWORKAGE){
					break;}}
			if(i>0){
				getworks.erase(getworks.begin(),getworks.begin()+i);}}
		gwmut.unlock(); 

		if(pwt==NULL){
			threads_sleep(100);
			continue;}
		if(pwt->putworks.size()>MAXPUTWORK){
			gwmut.lock();
			getworks.clear(); // removes all jobs due to slow queue
			gwmut.unlock(); 
			printf("GETWORK: queue full for host[%d]: %s  \n",host,hosts[host].url);
			threads_sleep(1000);
			continue;}

		query["jsonrpc"] = "2.0";
		query["id"] = 1;
		query["method"] = "getwork";
		answ = make_rpc_req(query, false, host);
		if (answ.type() != Json::objectValue){
			threads_sleep(500);
			continue; }
		if (!parse_ulong(data, answ["data"].asCString(), 32, 0, 1)){
			threads_sleep(500);
			continue; }
		if (!parse_ulong(midstate, answ["midstate"].asCString(), 8, 0, 1)) { 
			const unsigned sha_initial_state[8]={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19};
			SHA256_Full(midstate, data, sha_initial_state); }

		gwmut.lock();
		if(!getworks.empty()){
			if (memcmp( ((btc_block_t*)data)->hashPrevBlock, ((btc_block_t*)getworks.front().data)->hashPrevBlock, 32)) {
				getworks.clear(); // removes all jobs in last block
				gwmut.unlock();
				pwmut.lock();
				if (!parse_ulong(hosts[host].target, answ["target"].asCString(), 8, 0, 1)) {
					bits2bn(hosts[host].target,  ((btc_block_t*)data)->nBits );
				}
				pwmut.unlock();
				gwmut.lock(); 
				} }
		else{
			if(hosts[host].target[7]==0xFFFFFFFF){
				gwmut.unlock();
				pwmut.lock();
				if (!parse_ulong(hosts[host].target, answ["target"].asCString(), 8, 0, 1)) {
					bits2bn(hosts[host].target,  ((btc_block_t*)data)->nBits );
				}
				pwmut.unlock();
				gwmut.lock();
				} }
		gw.mtime=mtime;
		memcpy(gw.data,data,sizeof(data));
		memcpy(gw.midstate,midstate,sizeof(midstate));
		getworks.push_back(gw);
		gwmut.unlock();
		//log();
		}
}
Beispiel #7
0
void GetworkThread::Run()
{
	while(!testCancel()) {
		uint32_t midstate[8]={0,0,0,0,0,0,0,0}, data[32];
		unsigned int i;
		getwork gw;
		uint32_t mtime = time(NULL);
		static uint32_t ltime=0; // last download
		Json::Value query, answ;
		PutworkThread* pwt=(PutworkThread*)hosts[host].pwt;

		if(ltime==mtime){ // limit requests to 1 per second
			threads_sleep(100);
			continue;}

		gwmut.lock();
		if(!getworks.empty()){
                        int h;
                        for(h=0;h<MAXHOSTS;h++){ // check all getwork threads if any has current job
                                GetworkThread* gwt=(GetworkThread*)hosts[h].gwt;
                                if(gwt==NULL || gwt->getworks.empty()){
                                        continue;}
                                if(gwt->getworks.back().mtime==mtime) {
                                        break;}} // this should be a GOTO, I have to start using this
                        if(h<MAXHOSTS){
                                gwmut.unlock();
                                threads_sleep(100);
                                continue;}
			/*if(getworks.back().mtime==mtime) {
				gwmut.unlock(); 
				threads_sleep(100);
				continue;}*/
			for(i=0;i<getworks.size();i++){
				if(getworks[i].mtime>mtime-MAXWORKAGE){
					break;}}
			if(i>0){
				getworks.erase(getworks.begin(),getworks.begin()+i);}}
		gwmut.unlock(); 

		if(pwt==NULL){
			threads_sleep(100);
			continue;}
		if(pwt->putworks.size()>MAXPUTWORK){
			gwmut.lock();
			getworks.clear(); // removes all jobs due to slow queue
			gwmut.unlock(); 
			printf("GETWORK: queue full for host[%d]: %s  \n",host,hosts[host].url);
			threads_sleep(1000);
			continue;}

		query["jsonrpc"] = "2.0";
		query["id"] = 1;
		query["method"] = "getwork";
		answ = make_rpc_req(query, false, host,2);
		if (answ.type() != Json::objectValue){
			threads_sleep(500);
			continue; }
		if (answ["data"].type() != Json::stringValue || !parse_ulong(data, answ["data"].asCString(), 32, 0, 1)){
			threads_sleep(500);
			continue; }
		if (answ["midstate"].type() != Json::stringValue || !parse_ulong(midstate, answ["midstate"].asCString(), 8, 0, 1)) { 
			const unsigned sha_initial_state[8]={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19};
			SHA256_Full(midstate, data, sha_initial_state); }

		gwmut.lock();
		if(!getworks.empty()){
			if (memcmp( ((btc_block_t*)data)->hashPrevBlock, ((btc_block_t*)getworks.front().data)->hashPrevBlock, 32)) { // removes all jobs in last block
				//try clearing all queues
				int h;
				for(h=0;h<MAXHOSTS;h++){
					GetworkThread* gwt=(GetworkThread*)hosts[h].gwt;
                                	if(gwt==NULL){
						continue;}
					gwt->getworks.clear();}
				// clear our again just in case :-)
				getworks.clear();
				gwmut.unlock();
				pwmut.lock();
				if (answ["target"].type() != Json::stringValue || !parse_ulong(hosts[host].target, answ["target"].asCString(), 8, 0, 1)) {
					bits2bn(hosts[host].target,  ((btc_block_t*)data)->nBits );
				}
				pwmut.unlock();
				gwmut.lock(); } }
		else{
			if(hosts[host].target[7]==0xFFFFFFFF){
				gwmut.unlock();
				pwmut.lock();
				if (answ["target"].type() != Json::stringValue || !parse_ulong(hosts[host].target, answ["target"].asCString(), 8, 0, 1)) {
					bits2bn(hosts[host].target,  ((btc_block_t*)data)->nBits );
				}
				pwmut.unlock();
				gwmut.lock(); } }
		gw.mtime=mtime;
		memcpy(gw.data,data,sizeof(data));
		memcpy(gw.midstate,midstate,sizeof(midstate));
		getworks.push_back(gw);
		gwmut.unlock();
		ltime=mtime;
		//log();
		}
}