diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index bba99e726..5593539e7 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14556,5 +14556,469 @@ len = 0; } }*/ //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); + /*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + continue; + }*/ + if ( 0 && coin->current == bp )//&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) ) + { + //checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + block->RO.recvlen = (uint32_t)ftell(fp); + block->fpipbits = 1; + block->fpos = 0; + //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + fclose(fp); + } + else + { + //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + } + } + int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) + { + int32_t i,j,k,peerid,doneflag,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard=0,flag=0,finished=0,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; + struct iguana_peer *addr; uint32_t now; struct iguana_block *block; + bits256 hashes[50],hash2; uint8_t serialized[sizeof(hashes) + 256]; + if ( bp == 0 ) + return(0); + now = (uint32_t)time(NULL); + memset(peercounts,0,sizeof(peercounts)); + memset(donecounts,0,sizeof(donecounts)); + if ( coin->current != 0 ) + starti = coin->current->hdrsi; + else starti = 0; + priority = (bp->hdrsi < starti + coin->peers.numranked); + if ( strcmp("BTC",coin->symbol) == 0 ) + lag = 10 + (bp->hdrsi - starti); + else lag = 3 + (bp->hdrsi - starti)/10; + if ( coin->current != bp ) + lag *= 3; + if ( (numpeers= coin->peers.numranked) > 3 && 0 )//(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n ) + { + if ( numpeers > 0xff ) + numpeers = 0xff; // fit into 8 bitfield + if ( bp->currentflag == 0 ) + bp->currenttime = now; + if ( bp->numhashes >= 1 ) + { + for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) + { + now = (uint32_t)time(NULL); + for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) + { + hash2 = bp->hashes[i]; + if ( (block= bp->blocks[i]) != 0 ) + { + if ( (peerid= block->peerid) == 0 ) + { + //printf("<%d>.%d ",i,j); + if ( block->fpipbits != 0 || bp->speculativecache[i] != 0 ) + doneflag = 1; + } + } + } + else if ( bp->speculative != 0 && i < bp->numspec && bits256_nonz(bp->speculative[i]) != 0 ) + { + hash2 = bp->speculative[i]; + if ( bp->speculativecache[i] != 0 ) + doneflag = peerid = 1; + } + if ( doneflag == 0 ) + { + hashes[k++] = hash2; + bp->issued[i] = now; + if ( block != 0 ) + { + block->issued = now; + block->peerid = j + 1; + block->numrequests++; + } + } + else + { + doneflag = 1; + if ( block != 0 ) + { + block->peerid = 1; + block->numrequests++; + } + } + if ( bits256_nonz(hash2) != 0 ) + { + if ( peerid > 1 ) + { + total++; + if ( doneflag != 0 ) + { + donecounts[peerid - 1]++; + if ( donecounts[peerid - 1] > doneval ) + doneval = donecounts[peerid - 1]; + } + else + { + peercounts[peerid - 1]++; + if ( peercounts[peerid - 1] > maxval ) + maxval = peercounts[peerid - 1]; + } + } + } + } + if ( k > 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) + { + iguana_send(coin,addr,serialized,len); + counter += k; + coin->numreqsent += k; + addr->pendblocks += k; + addr->pendtime = (uint32_t)time(NULL); + bp->currentflag += k; + } + //printf("a%d/%d ",j,k); + } + } + } + //printf("doneval.%d maxval.%d\n",doneval,maxval); + if ( 0 && priority != 0 ) + { + double threshold; + for (i=nonz=0; i threshold ) + laggard++; + if ( peercounts[i] == 0 && donecounts[i] > threshold ) + finished++; + } + if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) + { + for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) + { + if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) + { + addr->dead = (uint32_t)time(NULL); + addr->rank = 0; + } + for (j=0; jn; j++) + { + if ( ((block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0) || bp->speculativecache[i] == 0 ) + { + if ( bp == coin->current ) + printf("%d ",j); + flag++; + counter++; + if ( block != 0 ) + { + block->issued = now; + block->peerid = 0; + iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); + } else iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); + if ( bp == coin->current ) + bp->issued[i] = now; + } + } + if ( flag != 0 && bp == coin->current ) + printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); + } + } + } + if ( 0 && laggard != 0 ) + { + for (i=0; ihdrsi,finished,laggard,threshold); + } + } + } + for (i=0; in; i++) + { + if ( 0 && (block= bp->blocks[i]) != 0 && iguana_blockstatus(coin,block) == 0 && bp->speculativecache[i] == 0 ) + { + if ( now > block->issued+lag ) + { + counter++; + saved = block->issued; + if ( bp == coin->current ) + forceflag = (now > block->issued + lag); + else forceflag = (now > block->issued + 10*lag); + if ( priority != 0 ) + { + printf("kick.[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,0*forceflag); + if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0*forceflag); + if ( forceflag != 0 ) + bp->issued[i] = block->issued = now; + else bp->issued[i] = block->issued = saved; + flag++; + } //else printf("%d ",now - block->issued); + } + } + if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) + printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + } + if ( bp == coin->current ) + return(counter); + } + for (i=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 ) + { + if ( block->fpipbits == 0 || block->fpos < 0 )// || block->RO.recvlen == 0 ) + { + if ( now > block->issued+lag ) + { + block->numrequests++; + if ( bp == coin->current ) + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,0);//bp == coin->current && now > block->issued+lag); + bp->issued[i] = block->issued = now; + counter++; + if ( --max <= 0 ) + break; + } + } + } + else if ( block != 0 && block->fpipbits == 0 && bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("b[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],0);//bp == coin->current && now > bp->issued[i]+lag*3); + bp->issued[i] = now; + counter++; + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("i[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); + bp->issued[i] = now; + counter++; + } + } + return(counter); + } + /*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 ) + { + char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + if ( block != 0 ) + { + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + } + else if ( now > bp->issued[bundlei]+13 ) + iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); + }*/ + } + /*else + { + char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + bp->issued[bundlei] = 0; + bp->blocks[bundlei] = 0; + memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + OS_removefile(fname,0); + }*/ + /*if ( 0 && bp->numhashes < bp->n && bp->speculative != 0 ) + { + for (j=1; jnumspec&&jn; j++) + { + if ( (block= bp->blocks[j]) == 0 ) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[j]); + else if ( bits256_nonz(bp->speculative[j]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) + block = iguana_blockhashset(coin,-1,bp->speculative[j],1); + } + } + else if ( bits256_nonz(block->RO.prev_block) != 0 && iguana_blockstatus(coin,block) != 0 ) + continue; + prev = bp->blocks[j-1]; + //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); + if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && + { + //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); + if ( iguana_blockstatus(coin,block) == 0 && bp->speculativecache[j] == 0 ) + { + if ( block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + //printf("submit cached [%d:%d]\n",bp->hdrsi,j); + } + else if ( now > block->issued+10 ) + { + block->issued = now; + //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); + } + } + } // else break; + } + }*/ + int32_t checki,hdrsi,havefile,missing,recvlen; char fname[1024]; FILE *fp; + static bits256 zero; + //if ( bp->speculative != 0 ) + { + now = (int32_t)time(NULL); + for (j=havefile=missing=0; jn; j++) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + hash2 = bp->hashes[j]; + else if ( bp->speculative != 0 ) + hash2 = bp->speculative[j]; + if ( bits256_nonz(hash2) == 0 ) + { + missing++; + continue; + } + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,hash2,zero,1,0); + if ( 1 && (fp= fopen(fname,"rb")) != 0 ) + { + havefile++; + fclose(fp); + continue; + } + //if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 ) + // continue; + missing++; + if ( bp->speculativecache[j] != 0 ) + { + block = iguana_blockfind(coin,bp->speculative[j]); + if ( block != 0 ) + block->queued = 1; + if ( bp->speculativecache[j] != 0 && block != 0 ) + xx else if ( bits256_nonz(bp->hashes[j]) != 0 ) + { + iguana_blockQ("currentstop",coin,bp,j,hash2,0); + + } + continue; + } + if ( bp == coin->current && (now > bp->issued[j]+3 || (rand() % 10) == 0) ) + { + fprintf(stderr,"-[%d:%d].%d ",bp->hdrsi,j,now-bp->issued[j]); + struct iguana_peer *addr; int32_t r; + if ( (rand() % 10) == 0 && (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); + else iguana_blockQ("currentstop",coin,bp,j,hash2,1); + //fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j); + bp->issued[j] = now; + } + } + if ( bp == coin->current ) + fprintf(stderr,"[%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d\n",bp->hdrsi,bp->numcached,bp->numhashes,bp->numsaved,havefile,missing); + } + if ( bp->speculative != 0 && missing == 0 ) + { + hash2 = bp->hashes[0]; + for (i=1; in; i++) + { + /*if ( bits256_nonz(bp->speculative[i]) != 0 ) + block = iguana_blockfind(coin,bp->speculative[i]); + else if ( bits256_nonz(bp->hashes[i]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[i]);*/ + if ( (block= bp->blocks[i]) == 0 || bits256_cmp(block->RO.prev_block,hash2) != 0 ) + { + char str[65],str2[65]; + printf("error with speculative prev at i.%d block.%p %s vs %s\n",i,block,bits256_str(str,bp->hashes[i]),bits256_str(str2,hash2)); + if ( block != 0 ) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[i],zero,1,0); + if ( fname[0] != 0 ) + OS_removefile(fname,0); + printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); + //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + block->fpipbits = 0; + block->fpos = -1; + block->queued = 0; + block->RO.recvlen = 0; + } + break; + } + hash2 = block->RO.hash2; + } + if ( i == bp->n && iguana_bundlefinalize(coin,bp,&coin->MEM,coin->MEMB) == 0 ) + { + //free(bp->speculative); + //bp->speculative = 0; + } + } + /*if ( bp->speculative != 0 && missing == 0 ) + { + if ( i == bp->n ) + { + printf("have complete speculative bundle!\n"); + for (i=1; in; i++) + { + if ( bits256_nonz(bp->speculative[i]) != 0 && bits256_nonz(bp->hashes[i]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->speculative[i])) != 0 ) + { + block->bundlei = i; + block->hdrsi = bp->hdrsi; + bp->blocks[i] = block; + printf("bundlehashadd set.%d\n",i); + iguana_bundlehash2add(coin,0,bp,i,bp->speculative[i]); + } + } + } + } + }*/ + //bp->rank = 0; + /*if ( bp->speculative != 0 )//&& bp == coin->current ) + { + now = (uint32_t)time(NULL); + for (i=1; inumspec&&in; i++) + { + if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) + { + if ( (block= bp->blocks[i]) == 0 && bp->speculativecache[i] == 0 && now > bp->issued[i]+60 ) + { + //printf("speculative.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculative",coin,bp,-i,bp->speculative[i],0);//now > bp->issued[i]+60); + bp->issued[i] = now; + continue; + } + } + else if ( 0 && (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 && block->fpipbits == 0 && now > bp->issued[i]+60 ) + { + printf("speculativeB.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculativeB",coin,bp,i,block->RO.hash2,1); + continue; + } + if ( bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+13 ) + { + //printf("speculativeC [%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculativeC",coin,bp,-i,bp->speculative[i],0); + bp->issued[i] = now; + } + } + }*/ #endif diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 5fc20c8fd..b7ed39efe 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -418,7 +418,7 @@ void iguana_helper(void *arg) //printf("[%d] bundleQ size.%d\n",bp->hdrsi,queue_size(&bundlesQ)); coin->numbundlesQ--; if ( coin->started != 0 && time(NULL) >= bp->nexttime && coin->active != 0 ) - flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); + flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit,IGUANA_DEFAULTLAG); else { //printf("skip.%d lag.%ld coin->active.%d\n",bp->hdrsi,time(NULL)-bp->nexttime,coin->active); @@ -540,7 +540,7 @@ void iguana_coinloop(void *arg) { //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers - iguana_bundlestats(coin,str); + iguana_bundlestats(coin,str,IGUANA_DEFAULTLAG); } if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); @@ -554,20 +554,20 @@ void iguana_coinloop(void *arg) } } -void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxpendingp,int32_t *maxbundlesp,cJSON *json) +void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxrequestsp,int32_t *maxbundlesp,cJSON *json) { if ( (*maxrecvcachep= j64bits(json,"maxrecvcache")) != 0 ) *maxrecvcachep *= 1024 * 1024 * 1024L; *minconfirmsp = juint(json,"minconfirms"); *maxpeersp = juint(json,"maxpeers"); - *maxpendingp = juint(json,"maxpending"); + *maxrequestsp = juint(json,"maxrequests"); *maxbundlesp = juint(json,"maxbundles"); if ( (*initialheightp= juint(json,"initialheight")) == 0 ) *initialheightp = (strcmp(symbol,"BTC") == 0) ? 400000 : 100000; *servicesp = j64bits(json,"services"); } -struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxpending,int32_t maxbundles,cJSON *json) +struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512]; cJSON *peers; @@ -578,8 +578,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 128 : 64; if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; - if ( (coin->MAXPENDING= maxpending) <= 0 ) - coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 4*_IGUANA_MAXPENDING; + if ( (coin->MAXPENDINGREQUESTS= maxrequests) <= 0 ) + coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); @@ -646,7 +646,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, int32_t iguana_launchcoin(char *symbol,cJSON *json) { - int32_t maxpeers,maphash,initialheight,minconfirms,maxpending,maxbundles; + int32_t maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; int64_t maxrecvcache; uint64_t services; struct iguana_info **coins,*coin; if ( symbol == 0 ) return(-1); @@ -657,9 +657,9 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json) if ( juint(json,"GBavail") < 8 ) maphash = IGUANA_MAPHASHTABLES; else maphash = 0; - iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxpending,&maxbundles,json); + iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,json); coins = mycalloc('A',1+1,sizeof(*coins)); - if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,json)) != 0 ) + if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,json)) != 0 ) { coins[0] = (void *)((long)1); coins[1] = coin; @@ -680,7 +680,7 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json) void iguana_coins(void *arg) { struct iguana_info **coins,*coin; char *jsonstr,*symbol; cJSON *array,*item,*json; - int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxpending,maxbundles; + int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; int64_t maxrecvcache; uint64_t services; struct vin_info V; memset(&V,0,sizeof(V)); if ( (jsonstr= arg) != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) @@ -710,8 +710,8 @@ void iguana_coins(void *arg) printf("skip strange coin.(%s)\n",symbol); continue; } - iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxpending,&maxbundles,item); - coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,item); + iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,item); + coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,item); } coins[0] = (void *)((long)n); iguana_coinloop(coins); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index f942c61fb..09df3deb6 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -//#define IGUANA_SERIALIZE_SPENDVECTORGEN +#define IGUANA_SERIALIZE_SPENDVECTORGEN //#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS #define _IGUANA_MAXSTUCKTIME 77 @@ -41,7 +41,8 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_HEADPERCENTAGE 0. #define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define _IGUANA_MAXPENDING 3 +#define IGUANA_MAXPENDINGREQUESTS 3 +#define IGUANA_PENDINGREQUESTS 17 #define IGUANA_MINPENDBUNDLES 2 #define IGUANA_MAXPENDBUNDLES 64 #define IGUANA_BUNDLELOOP 77 @@ -62,7 +63,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpos:IGUANA_LOG2PEERFILESIZE,datalen:IGUANA_LOG2PACKETSIZE,isdir:1; }; #define IGUANA_MAXFILEITEMS 8192 - +#define IGUANA_DEFAULTLAG 60 #define IGUANA_RECENTPEER (3600 * 24 * 7) #define IGUANA_PERMTHREAD 0 @@ -284,10 +285,10 @@ struct iguana_block { struct iguana_blockRO RO; double PoW; // NOT consensus safe, for estimation purposes only - int32_t height; uint32_t fpipbits,numrequests,issued; long fpos; - uint16_t hdrsi,bundlei:11,mainchain:1,valid:1,queued:1,txvalid:1,newtx:1,peerid:8; - UT_hash_handle hh; struct iguana_bundlereq *req; //bits256 *blockhashes; -};// __attribute__((packed)); + int32_t height,fpos; uint32_t fpipbits,issued,numrequests:24,peerid:8; + uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; + UT_hash_handle hh; struct iguana_bundlereq *req; +} __attribute__((packed)); #define IGUANA_LHASH_BLOCKS 0 @@ -419,9 +420,9 @@ struct iguana_peer struct iguana_peers { bits256 lastrequest; - struct iguana_peer active[IGUANA_MAXPEERS],*ranked[IGUANA_MAXPEERS],*localaddr; + struct iguana_peer active[IGUANA_MAXPEERS+1],*ranked[IGUANA_MAXPEERS+1],*localaddr; struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop; - double topmetrics[IGUANA_MAXPEERS],avemetric; + double topmetrics[IGUANA_MAXPEERS+1],avemetric; uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected; int32_t numfiles; }; @@ -433,8 +434,8 @@ struct iguana_bundle { struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; struct iguana_bloom16 bloom; //uint32_t rawscriptspace; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch; - int32_t numhashes,numrecv,numsaved,numcached,generrs,checkedtmp,currentflag; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,missingstime; + int32_t numhashes,numrecv,numsaved,numcached,generrs,currentflag,origmissings; int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec,isRT; double avetime,threshold,metric; uint64_t datasize,estsize; struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; @@ -465,10 +466,10 @@ struct scriptinfo { UT_hash_handle hh; uint32_t fpos; uint16_t scriptlen; uint8_ struct iguana_info { char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; - struct iguana_peers peers; + struct iguana_peers peers; struct iguana_peer internaladdr; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,estsize,activebundles; - int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten,RTheight; bits256 balancehash; + int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten,RTheight; bits256 balancehash; uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog; int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters; struct tai starttime; double startmillis; @@ -477,7 +478,7 @@ struct iguana_info struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; - struct OS_memspace TXMEM,HASHMEM,RAWMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; + struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; @@ -605,7 +606,7 @@ void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n); int32_t iguana_updatebundles(struct iguana_info *coin); -void iguana_bundlestats(struct iguana_info *coin,char *str); +void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag); // init struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); @@ -747,7 +748,7 @@ int32_t is_bitcoinrpc(char *method,char *remoteaddr); char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); -int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit); +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag); void ramcoder_test(void *data,int64_t len); void iguana_exit(); int32_t iguana_pendingaccept(struct iguana_info *coin); @@ -813,7 +814,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain); int32_t iguana_realtime_update(struct iguana_info *coin); int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); @@ -834,6 +835,8 @@ uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits2 void iguana_launchpeer(struct iguana_info *coin,char *ipaddr); void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp); int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block); +void iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits); +void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 00b898a6c..9f1a6a1db 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -72,6 +72,7 @@ void iguana_acceptloop(void *args) printf("another daemon running, no need to have iguana accept connections\n"); return; } + return; sleep(5); } printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,coin->bindsock); diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 6daa6373b..35fcd65ed 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -274,7 +274,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl if ( newblock == 0 ) return(0); hwmchain = &coin->blocks.hwmchain; - if ( hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize >= bp->hdrsi+bp->isRT) ) + if ( hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi+0*bp->isRT) ) return(0); if ( (block= iguana_blockfind(coin,newblock->RO.hash2)) != 0 ) { @@ -373,7 +373,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl bp->speculative[block->height % coin->chain->bundlesize] = block->RO.hash2; bp->blocks[block->height % coin->chain->bundlesize] = block;*/ } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 && block->height > coin->longestchain-coin->chain->bundlesize*2 ) + if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == coin->minconfirms && (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 50) == 49) ) { //printf("savehdrs\n"); iguana_savehdrs(coin); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 324275f2e..1c807d3f6 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -286,7 +286,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bundleip,int32_t bundleheight,bits256 bundlehash2,bits256 allhash,int32_t issueflag) { - char str[65],dirname[1024]; struct iguana_bundle *bp = 0; + char str[65],dirname[1024]; struct iguana_bundle *prevbp,*bp = 0; if ( bits256_nonz(bundlehash2) > 0 ) { bits256_str(str,bundlehash2); @@ -312,8 +312,14 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund bp->coin = coin; bp->avetime = coin->avetime * 2.; coin->bundles[bp->hdrsi] = bp; - if ( bp->hdrsi > 0 && coin->bundles[bp->hdrsi-1] != 0 ) - coin->bundles[bp->hdrsi-1]->nextbp = bp; + if ( bp->hdrsi > 0 ) + { + if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 ) + { + prevbp->nextbp = bp; + prevbp->nextbundlehash2 = bundlehash2; + } + } *bundleip = 0; bits256_str(str,bundlehash2); sprintf(dirname,"%s/%s/%d",GLOBALTMPDIR,coin->symbol,bp->bundleheight), OS_ensure_directory(dirname); @@ -321,7 +327,7 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund iguana_bundlehash2add(coin,0,bp,0,bundlehash2); if ( issueflag != 0 ) { - iguana_blockQ("bundlecreate",coin,bp,0,bundlehash2,1); + iguana_blockQ("bundlecreate",coin,bp,0,bundlehash2,0); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } if ( bp->hdrsi >= coin->bundlescount ) @@ -388,247 +394,158 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp) } } -int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) +uint8_t iguana_recentpeers(struct iguana_info *coin,int32_t *capacityp,struct iguana_peer *peers[]) { - int32_t i,j,k,peerid,doneflag,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard=0,flag=0,finished=0,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; - struct iguana_peer *addr; uint32_t now; struct iguana_block *block; - bits256 hashes[50],hash2; uint8_t serialized[sizeof(hashes) + 256]; - if ( bp == 0 ) - return(0); - now = (uint32_t)time(NULL); - memset(peercounts,0,sizeof(peercounts)); - memset(donecounts,0,sizeof(donecounts)); - if ( coin->current != 0 ) - starti = coin->current->hdrsi; - else starti = 0; - priority = (bp->hdrsi < starti + coin->peers.numranked); - if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 10 + (bp->hdrsi - starti); - else lag = 3 + (bp->hdrsi - starti)/10; - if ( coin->current != bp ) - lag *= 3; - if ( (numpeers= coin->peers.numranked) > 3 && 0 )//(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n ) + struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n = coin->peers.numranked; + for (i=m=capacity=0; ipeers.ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 && addr->pendblocks < coin->MAXPENDINGREQUESTS ) + { + if ( peers != 0 ) + peers[m] = addr; + m++; + capacity += (coin->MAXPENDINGREQUESTS - addr->pendblocks); + } + } + *capacityp = capacity; + return(m); +} + +struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i) +{ + struct iguana_block *block = 0; + memset(hash2p,0,sizeof(*hash2p)); + if ( i == bp->n ) + { + if ( bits256_nonz(bp->nextbundlehash2) != 0 ) + block = iguana_blockfind(coin,bp->nextbundlehash2); + else return(0); + } + if ( block != 0 || (block= bp->blocks[i]) != 0 || (bits256_nonz(bp->hashes[i]) != 0 && (block= iguana_blockfind(coin,bp->hashes[i])) != 0) ) { - if ( numpeers > 0xff ) - numpeers = 0xff; // fit into 8 bitfield - if ( bp->currentflag == 0 ) - bp->currenttime = now; - if ( bp->numhashes >= 1 ) + *hash2p = block->RO.hash2; + return(block); + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 ) + { + *hash2p = bp->speculative[i]; + block = iguana_blockfind(coin,bp->speculative[i]); + //char str[65]; printf("[%d:%d] %s\n",bp->hdrsi,i,bits256_str(str,*hash2p)); + } + return(block); +} + +int32_t iguana_blocksmissing(struct iguana_info *coin,int32_t *nonzp,uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1],bits256 hashes[],struct iguana_bundle *bp,int32_t capacity,int32_t lag) +{ + int32_t i,nonz=0,m = 0; bits256 hash2; struct iguana_block *block; uint32_t now = (uint32_t)time(NULL); + memset(missings,0,IGUANA_MAXBUNDLESIZE/8+1); + if ( bp->emitfinish == 0 ) + { + for (i=0; in; i++) { - for (j=0; jspeculativecache[i] != 0 ) { - if ( (addr= coin->peers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) - { - now = (uint32_t)time(NULL); - for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) - { - hash2 = bp->hashes[i]; - if ( (block= bp->blocks[i]) != 0 ) - { - if ( (peerid= block->peerid) == 0 ) - { - //printf("<%d>.%d ",i,j); - if ( block->fpipbits != 0 || bp->speculativecache[i] != 0 ) - doneflag = 1; - } - } - } - else if ( bp->speculative != 0 && i < bp->numspec && bits256_nonz(bp->speculative[i]) != 0 ) - { - hash2 = bp->speculative[i]; - if ( bp->speculativecache[i] != 0 ) - doneflag = peerid = 1; - } - if ( doneflag == 0 ) - { - hashes[k++] = hash2; - bp->issued[i] = now; - if ( block != 0 ) - { - block->issued = now; - block->peerid = j + 1; - block->numrequests++; - } - } - else - { - doneflag = 1; - if ( block != 0 ) - { - block->peerid = 1; - block->numrequests++; - } - } - if ( bits256_nonz(hash2) != 0 ) - { - if ( peerid > 1 ) - { - total++; - if ( doneflag != 0 ) - { - donecounts[peerid - 1]++; - if ( donecounts[peerid - 1] > doneval ) - doneval = donecounts[peerid - 1]; - } - else - { - peercounts[peerid - 1]++; - if ( peercounts[peerid - 1] > maxval ) - maxval = peercounts[peerid - 1]; - } - } - } - } - if ( k > 0 ) - { - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) - { - iguana_send(coin,addr,serialized,len); - counter += k; - coin->numreqsent += k; - addr->pendblocks += k; - addr->pendtime = (uint32_t)time(NULL); - bp->currentflag += k; - } - //printf("a%d/%d ",j,k); - } - } + //printf("[%d:%d].havec ",bp->hdrsi,i); + continue; } - //printf("doneval.%d maxval.%d\n",doneval,maxval); - if ( 0 && priority != 0 ) + if ( (block= iguana_bundleblock(coin,&hash2,bp,i)) != 0 ) { - double threshold; - for (i=nonz=0; itxvalid != 0 ) { - threshold = ((double)total / nonz) - 1.; - for (i=laggard=finished=0; i threshold ) - laggard++; - if ( peercounts[i] == 0 && donecounts[i] > threshold ) - finished++; - } - if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) - { - for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) - { - if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) - { - addr->dead = (uint32_t)time(NULL); - addr->rank = 0; - } - for (j=0; jn; j++) - { - if ( ((block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0) || bp->speculativecache[i] == 0 ) - { - if ( bp == coin->current ) - printf("%d ",j); - flag++; - counter++; - if ( block != 0 ) - { - block->issued = now; - block->peerid = 0; - iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - } else iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - if ( bp == coin->current ) - bp->issued[i] = now; - } - } - if ( flag != 0 && bp == coin->current ) - printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); - } - } - } - if ( 0 && laggard != 0 ) - { - for (i=0; ihdrsi,finished,laggard,threshold); - } + //printf("[%d:%d].block ",bp->hdrsi,i); + continue; } } - for (i=0; in; i++) + if ( bits256_nonz(hash2) != 0 && now > bp->issued[i]+lag ) { - if ( 0 && (block= bp->blocks[i]) != 0 && iguana_blockstatus(coin,block) == 0 && bp->speculativecache[i] == 0 ) - { - if ( now > block->issued+lag ) - { - counter++; - saved = block->issued; - if ( bp == coin->current ) - forceflag = (now > block->issued + lag); - else forceflag = (now > block->issued + 10*lag); - if ( priority != 0 ) - { - printf("kick.[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 ) - bp->issued[i] = block->issued = now; - else bp->issued[i] = block->issued = saved; - flag++; - } //else printf("%d ",now - block->issued); - } + if ( nonz < capacity && hashes != 0 ) + hashes[nonz] = hash2; + nonz++; } - if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) - printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + SETBIT(missings,i); + m++; } - if ( bp == coin->current ) - return(counter); - } - for (i=0; in; i++) + } else printf("[%d] emitfinish.%u\n",bp->hdrsi,bp->emitfinish); + *nonzp = nonz; + //printf("missings.[%d] m.%d nonz.%d spec.%p[%d]\n",bp->hdrsi,m,nonz,bp->speculative,bp->numspec); + return(m); +} + +int32_t iguana_sendhashes(struct iguana_info *coin,struct iguana_peer *addr,int32_t msgtype,bits256 hashes[],int32_t n) +{ + int32_t len; uint8_t serialized[(sizeof(int32_t) + sizeof(*hashes))*IGUANA_PENDINGREQUESTS + 1024]; + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,n)) > 0 ) { - if ( (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 ) + if ( len > sizeof(serialized) ) { - if ( block->fpipbits == 0 || block->fpos < 0 || block->RO.recvlen == 0 ) + printf("iguana_sendhashes: len.%d size.%ld\n",len,sizeof(serialized)); + exit(-1); + } + iguana_send(coin,addr,serialized,len); + coin->numreqsent += n; + addr->pendblocks += n; + addr->pendtime = (uint32_t)time(NULL); + //printf("sendhashes[%d] -> %s\n",n,addr->ipaddr); + } else n = 0; + return(n); +} + +int32_t iguana_nextnonz(uint8_t *missings,int32_t i,int32_t max) +{ + for (; i 0 ) + { + *capacityp = capacity; + if ( (n= iguana_blocksmissing(coin,&avail,missings,hashes,bp,capacity < max ? capacity : max,lag)) > 0 && avail > 0 ) + { + *missingp = n; + //printf("n.%d avail.%d numpeers.%d\n",n,avail,numpeers); + for (i=0; i0; i++) { - if ( now > block->issued+lag ) + if ( (addr= peers[i]) != 0 && (c= (coin->MAXPENDINGREQUESTS - addr->pendblocks)) > 0 ) { - block->numrequests++; - if ( bp == coin->current ) - printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,0);//bp == coin->current && now > block->issued+lag); - bp->issued[i] = block->issued = now; - counter++; - if ( --max <= 0 ) - break; + if ( c+m > max ) + c = max - m; + if ( avail < c ) + c = avail; + //printf("i.%d c.%d avail.%d m.%d max.%d\n",i,c,avail,m,max); + if ( c > 0 && (numsent= iguana_sendhashes(coin,addr,MSG_BLOCK,&hashes[m],c)) > 0 ) + { + for (j=0; jn)) < bp->n ) + { + if ( (block= iguana_bundleblock(coin,&hash2,bp,nonz)) != 0 ) + hash2 = block->RO.hash2; + bp->issued[nonz] = now; + //char str[65]; printf("issue.[%d:%d] %s %u\n",bp->hdrsi,nonz,bits256_str(str,hash2),now); + nonz++; + } else printf("bundlerequests unexpected nonz.%d c.%d m.%d n.%d numsent.%d i.%d\n",nonz,c,m,n,numsent,i); + } + m += numsent; + avail -= numsent; + } } } - } - else if ( block != 0 && block->fpipbits == 0 && bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("b[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],0);//bp == coin->current && now > bp->issued[i]+lag*3); - bp->issued[i] = now; - counter++; - } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); - bp->issued[i] = now; - counter++; - } - } - return(counter); + } //else printf("err avail.%d n.%d\n",avail,n); + } //else printf("numpeers.%d\n",numpeers); + return(m); } int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t i,ready,valid,hdrsi,checki; struct iguana_block *block; char fname[1024]; static bits256 zero; + int32_t i,ready,valid; struct iguana_block *block; for (i=ready=0; in; i++) { if ( (block= bp->blocks[i]) != 0 ) @@ -636,17 +553,9 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); if ( iguana_blockvalidate(coin,&valid,block,1) < 0 || block->fpipbits == 0 || block->fpos < 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) { - fname[0] = 0; - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1,1)) != i ) - printf("checki.%d vs %d mismatch?\n",checki,i); - if ( fname[0] != 0 ) - OS_removefile(fname,0); - printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); + printf(">>>>>>> block contents error at ht.%d [%d:%d]\n",bp->bundleheight+i,bp->hdrsi,i); //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); - block->fpipbits = 0; - block->fpos = -1; - block->queued = 0; - block->RO.recvlen = 0; + iguana_blockunmark(coin,block,bp,i,1); } else ready++; } else @@ -661,7 +570,6 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) { int32_t counter=0; - int32_t i; uint32_t now; struct iguana_block *block; if ( 0 && bp->isRT == 0 && (bp->hdrsi == coin->bundlescount-1 || bp == coin->current) ) printf("hdr ITERATE.%d bundle.%d vs %d: h.%d n.%d r.%d s.%d c.%d finished.%d spec.%p[%d]\n",bp->hdrsi,bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->numcached,bp->emitfinish,bp->speculative,bp->numspec); if ( coin->enableCACHE != 0 && bp->numhashes < bp->n && (bp->speculative == 0 || bp->hdrsi >= coin->longestchain/bp->n) ) @@ -673,39 +581,11 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 { if ( time(NULL) > bp->issued[1]+10 ) { - iguana_blockQ("getnexthdr",coin,bp,-1,bp->speculative[1],1); + printf("request speculative[1] for bp.[%d]\n",bp->hdrsi); + iguana_blockQ("getnexthdr",coin,bp,-1,bp->speculative[1],0); bp->issued[1] = (uint32_t)time(NULL); } } - if ( bp->speculative != 0 )//&& bp == coin->current ) - { - now = (uint32_t)time(NULL); - for (i=1; inumspec&&in; i++) - { - if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) - { - if ( (block= bp->blocks[i]) == 0 && bp->speculativecache[i] == 0 && now > bp->issued[i]+60 ) - { - //printf("speculative.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculative",coin,bp,-i,bp->speculative[i],0);//now > bp->issued[i]+60); - bp->issued[i] = now; - continue; - } - } - else if ( 0 && (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 && block->fpipbits == 0 && now > bp->issued[i]+60 ) - { - printf("speculativeB.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeB",coin,bp,i,block->RO.hash2,1); - continue; - } - if ( bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+13 ) - { - //printf("speculativeC [%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeC",coin,bp,-i,bp->speculative[i],0); - bp->issued[i] = now; - } - } - } return(counter); } @@ -729,105 +609,43 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 ) coin->lastpending = coin->bundles[lastbp->hdrsi + 1]; iguana_setmaxbundles(coin); - /*if ( (rand() % 3) == 0 ) - { - if ( coin->MAXBUNDLES > coin->endPEND ) - coin->MAXBUNDLES--; - else if ( coin->MAXBUNDLES < coin->endPEND ) - coin->MAXBUNDLES++; - }*/ return(coin->MAXBUNDLES); } -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) { - int32_t bundlei,numhashes,numsaved,numcached,numrecv,minrequests; FILE *fp; - int64_t datasize; struct iguana_block *block; uint32_t now; char fname[1024]; + int32_t bundlei,numhashes,avail,numsaved,numrecv,minrequests; uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1]; + int64_t datasize; struct iguana_block *block; if ( bp->emitfinish > coin->startutc ) { bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; return(bp->datasize); } - now = (uint32_t)time(NULL); - datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0; + datasize = numhashes = numsaved = numrecv = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { block = bp->blocks[bundlei]; - if ( bits256_nonz(bp->hashes[bundlei]) > 0 && block != 0 ) + if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) { - //checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) + numhashes++; + if ( block != 0 && bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) { - /*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - continue; - }*/ - if ( 0 && coin->current == bp )//&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - block->RO.recvlen = (uint32_t)ftell(fp); - block->fpipbits = 1; - block->fpos = 0; - //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); - fclose(fp); - } - else - { - //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - } - } - block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) bp->minrequests = block->numrequests; - //if ( (bp->hdrsi == 0 && bundlei == 0) || bits256_nonz(block->RO.prev_block) != 0 ) + if ( block->fpipbits != 0 && block->fpos >= 0 ) + numsaved++; + if ( block->RO.recvlen != 0 ) { - if ( block->fpipbits != 0 && block->fpos >= 0 ) - numsaved++; - if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 ) - { - numrecv++; - datasize += block->RO.recvlen; - } + numrecv++; + datasize += block->RO.recvlen; } - /*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 ) - { - char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); - if ( block != 0 ) - { - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - } - else if ( now > bp->issued[bundlei]+13 ) - iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); - }*/ } - /*else - { - char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - bp->issued[bundlei] = 0; - bp->blocks[bundlei] = 0; - memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); - OS_removefile(fname,0); - }*/ - numhashes++; - bp->checkedtmp++; } - if ( ((block= bp->blocks[bundlei]) != 0 && block->fpipbits != 0 && block->fpos >= 0) || bp->speculativecache[bundlei] != 0 ) - numcached++; } + bp->numcached = bp->n - iguana_blocksmissing(coin,&avail,missings,0,bp,0,lag); bp->datasize = datasize; bp->numhashes = numhashes; bp->numsaved = numsaved; - bp->numcached = numcached; bp->numrecv = numrecv; bp->minrequests = minrequests; bp->estsize = ((int64_t)bp->datasize * bp->n) / (bp->numrecv+1); @@ -897,9 +715,9 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp, return(1); } -int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit) +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag) { - int32_t range,starti,lasti,i,n,len,retval=0,max,counter = 0; struct iguana_block *block; struct iguana_bundle *currentbp,*lastbp; uint8_t serialized[512]; struct iguana_peer *addr; long lag; struct iguana_blockreq *breq; + int32_t range,starti,lasti,i,n,len,retval=0,max,counter = 0; struct iguana_block *block; struct iguana_bundle *currentbp,*lastbp; uint8_t serialized[512]; struct iguana_peer *addr; struct iguana_blockreq *breq; if ( coin->started == 0 || coin->active == 0 ) { printf("%s not ready yet\n",coin->symbol); @@ -914,15 +732,9 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; - if ( bp != coin->current || bp->dirty != 0 ) - { - iguana_bundlecalcs(coin,bp); - bp->dirty = 0; - } + iguana_bundlecalcs(coin,bp,lag); if ( bp->hdrsi == coin->bundlescount-1 ) - { iguana_autoextend(coin,bp); - } //printf("ITER utxo.%u now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->utxofinish,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); bp->nexttime = (uint32_t)(time(NULL) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) @@ -957,16 +769,16 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru else if ( bp->hdrsi == starti || (bp->hdrsi >= starti && bp->hdrsi <= starti+range) ) //bits256_nonz(bp->allhash) != 0 && { max = bp->n; - counter = iguana_bundleissue(coin,bp,max,timelimit); - //if ( bp == coin->current && coin->isRT == 0 ) - // bp->nexttime--; + counter = 0;//iguana_bundleissue(coin,bp,max,timelimit); + if ( bp == coin->current && coin->isRT == 0 ) + bp->nexttime--; if ( bp->isRT == 0 && bp == coin->current && counter > 0 ) printf("ITER.rt%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->isRT,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); if ( bp->hdrsi == starti && bp->isRT == 0 ) { if ( coin->stucktime != 0 ) { - lag = time(NULL)-coin->stucktime; + lag = (int32_t)time(NULL)-coin->stucktime; if ( ((lag/coin->MAXSTUCKTIME)>>1) > coin->stuckiters ) { coin->stuckiters = (int32_t)lag/60; @@ -986,7 +798,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru } if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 && bp->speculativecache[i] == 0 ) { - printf("[%d:%d] ",bp->hdrsi,i); + printf("s.[%d:%d] ",bp->hdrsi,i); iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,0); iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,1); if ( coin->peers.numranked > 8 && (addr= coin->peers.ranked[n % 8]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack != 0 ) @@ -1002,7 +814,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru } } if ( n > 0 ) - printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%ld\n",n,bp->hdrsi,coin->stuckiters,lag); + printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag); } } } @@ -1031,19 +843,69 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) return(0); }*/ -void iguana_bundlestats(struct iguana_info *coin,char *str) +int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) +{ + int32_t recvlen; struct iguana_msghdr H; uint8_t *data; struct iguana_block *block; + if ( (data= bp->speculativecache[bundlei]) != 0 && bp->speculative != 0 && (block= iguana_blockfind(coin,bp->speculative[bundlei])) != 0 ) + { + iguana_bundlehash2add(coin,0,bp,bundlei,bp->speculative[bundlei]); + recvlen = *(int32_t *)data; + memset(&H,0,sizeof(H)); + iguana_sethdr(&H,coin->chain->netmagic,"block",&data[sizeof(recvlen)],recvlen); + if ( coin->internaladdr.RAWMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.RAWMEM,"cache",0,IGUANA_MAXPACKETSIZE + 65536*3,0); + if ( coin->TXMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); + if ( coin->internaladdr.HASHMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.HASHMEM,"HASHPTRS",0,256,0); + if ( iguana_msgparser(coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen) < 0 ) + printf("error parsing speculativecache.[%d:%d]\n",bp->hdrsi,bundlei); + else block->processed = 1; + //char str[65]; printf("iguana_cacheprocess [%d:%d] %s fp.%x len.%d:%d\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),block->fpipbits,block->RO.recvlen,recvlen); + //myfree(data,recvlen + sizeof(recvlen)); + //bp->speculativecache[bundlei] = 0; + return(recvlen); + } + return(-1); +} + +int32_t iguana_bundlemissings(struct iguana_info *coin,struct iguana_bundle *bp,int32_t capacity,int32_t lag) +{ + uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1]; int32_t tmp,missing,avail,n; + if ( bp == coin->current ) + lag = 10; + missing = iguana_blocksmissing(coin,&avail,missings,0,bp,0,lag); + if ( bp->missingstime == 0 || (bp == coin->current && missing < (bp->origmissings >> 1)) || missing < (bp->origmissings>>3) || time(NULL) > bp->missingstime+lag ) + { + if ( (n= iguana_bundlerequests(coin,missings,&bp->origmissings,&tmp,bp,lag)) > 0 ) + { + printf("bundle.[%d] missings.%d n.%d capacity %d -> %d\n",bp->hdrsi,bp->origmissings,n,capacity,capacity-n); + capacity -= n; + bp->missingstime = (uint32_t)time(NULL); + } + } + return(capacity); +} + +void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) { - int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; bits256 hash2; + int32_t i,n,m,j,numv,count,starti,lasti,pending,capacity,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; struct iguana_block *block; bits256 hash2; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *currentbp,*lastbp,*bp,*lastpending = 0,*firstgap = 0;uint32_t now; now = (uint32_t)time(NULL); dispflag = 1;//(rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; count = coin->bundlescount; - //sortbuf = calloc(count,sizeof(*sortbuf)*2); + currentbp = coin->current; + lastbp = coin->lastpending; + starti = currentbp == 0 ? 0 : currentbp->hdrsi; + lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; + iguana_recentpeers(coin,&capacity,0); + //sortbuf = calloc(count,sizeof(*sortbuf)*2); for (i=n=m=numv=pending=0; ibundles[i]) != 0 ) { + iguana_bundlecalcs(coin,bp,lag); if ( bp->emitfinish > 1 ) { for (j=0; jn; j++) @@ -1054,186 +916,19 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } else { + if ( bp->hdrsi >= starti && bp->hdrsi < lasti ) + capacity = iguana_bundlemissings(coin,bp,capacity,lag); for (j=0; jn; j++) { if ( bp->speculativecache[j] != 0 ) { - iguana_blockhashset(coin,-1,bp->speculative[j],1); - numcached++; - } - } - } - if ( 0 && bp->numhashes < bp->n && bp->speculative != 0 ) - { - for (j=1; jnumspec&&jn; j++) - { - if ( (block= bp->blocks[j]) == 0 ) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[j]); - else if ( bits256_nonz(bp->speculative[j]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) - block = iguana_blockhashset(coin,-1,bp->speculative[j],1); - } - } - else if ( bits256_nonz(block->RO.prev_block) != 0 && iguana_blockstatus(coin,block) != 0 ) - continue; - prev = bp->blocks[j-1]; - //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); - if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && - { - //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); - if ( iguana_blockstatus(coin,block) == 0 && bp->speculativecache[j] == 0 ) - { - if ( block->req != 0 ) - { - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); - block->req = 0; - //printf("submit cached [%d:%d]\n",bp->hdrsi,j); - } - else if ( now > block->issued+10 ) - { - block->issued = now; - //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); - iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); - } - } - } // else break; - } - } - int32_t checki,hdrsi,havefile,missing,recvlen; char fname[1024]; FILE *fp; struct iguana_msghdr H; static bits256 zero; - //if ( bp->speculative != 0 ) - { - now = (int32_t)time(NULL); - for (j=havefile=missing=0; jn; j++) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - hash2 = bp->hashes[j]; - else if ( bp->speculative != 0 ) - hash2 = bp->speculative[j]; - if ( bits256_nonz(hash2) == 0 ) - { - missing++; - continue; - } - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,hash2,zero,1,0); - if ( 1 && (fp= fopen(fname,"rb")) != 0 ) - { - havefile++; - fclose(fp); - continue; - } - //if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 ) - // continue; - missing++; - if ( bp->speculativecache[j] != 0 ) - { - block = iguana_blockfind(coin,bp->speculative[j]); - if ( block != 0 ) - block->queued = 1; - if ( bp->speculativecache[j] != 0 && block != 0 ) - { - block->bundlei = j; - block->hdrsi = bp->hdrsi; - bp->blocks[j] = block; - //printf("bundlehashadd set.%d recvlen.%d\n",j,recvlen); - iguana_bundlehash2add(coin,0,bp,j,bp->speculative[j]); - recvlen = *(int32_t *)bp->speculativecache[j]; - memset(&H,0,sizeof(H)); - iguana_sethdr(&H,coin->chain->netmagic,"block",&bp->speculativecache[j][sizeof(recvlen)],recvlen); - if ( coin->RAWMEM.ptr == 0 ) - iguana_meminit(&coin->RAWMEM,"cache",0,IGUANA_MAXPACKETSIZE + 65536*3,0); - if ( coin->TXMEM.ptr == 0 ) - iguana_meminit(&coin->TXMEM,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); - if ( coin->HASHMEM.ptr == 0 ) - iguana_meminit(&coin->HASHMEM,"HASHPTRS",0,256,0); - if ( iguana_msgparser(coin,0,&coin->RAWMEM,&coin->TXMEM,&coin->HASHMEM,&H,&bp->speculativecache[j][sizeof(recvlen)],recvlen) < 0 ) - printf("error parsing speculativecache.[%d:%d]\n",bp->hdrsi,j); - myfree(bp->speculativecache[j],recvlen + sizeof(recvlen)); - bp->speculativecache[j] = 0; - } - else if ( bits256_nonz(bp->hashes[j]) != 0 ) - { - iguana_blockQ("currentstop",coin,bp,j,hash2,0); - - } - continue; - } - if ( bp == coin->current && (now > bp->issued[j]+3 || (rand() % 10) == 0) ) - { - fprintf(stderr,"-[%d:%d].%d ",bp->hdrsi,j,now-bp->issued[j]); - struct iguana_peer *addr; int32_t r; - if ( (rand() % 10) == 0 && (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) - iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); - else iguana_blockQ("currentstop",coin,bp,j,hash2,1); - //fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j); - bp->issued[j] = now; + if ( (block= iguana_blockhashset(coin,-1,bp->speculative[j],1)) != 0 && block->processed == 0 ) + iguana_cacheprocess(coin,bp,j); + numcached++; } } - if ( bp == coin->current ) - fprintf(stderr,"[%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d\n",bp->hdrsi,bp->numcached,bp->numhashes,bp->numsaved,havefile,missing); } - if ( bp->speculative != 0 && missing == 0 ) - { - hash2 = bp->hashes[0]; - for (i=1; in; i++) - { - /*if ( bits256_nonz(bp->speculative[i]) != 0 ) - block = iguana_blockfind(coin,bp->speculative[i]); - else if ( bits256_nonz(bp->hashes[i]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[i]);*/ - if ( (block= bp->blocks[i]) == 0 || bits256_cmp(block->RO.prev_block,hash2) != 0 ) - { - char str[65],str2[65]; - printf("error with speculative prev at i.%d block.%p %s vs %s\n",i,block,bits256_str(str,bp->hashes[i]),bits256_str(str2,hash2)); - if ( block != 0 ) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[i],zero,1,0); - if ( fname[0] != 0 ) - OS_removefile(fname,0); - printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); - //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); - block->fpipbits = 0; - block->fpos = -1; - block->queued = 0; - block->RO.recvlen = 0; - } - break; - } - hash2 = block->RO.hash2; - } - if ( i == bp->n && iguana_bundlefinalize(coin,bp,&coin->MEM,coin->MEMB) == 0 ) - { - //free(bp->speculative); - //bp->speculative = 0; - } - } - /*if ( bp->speculative != 0 && missing == 0 ) - { - if ( i == bp->n ) - { - printf("have complete speculative bundle!\n"); - for (i=1; in; i++) - { - if ( bits256_nonz(bp->speculative[i]) != 0 && bits256_nonz(bp->hashes[i]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[i])) != 0 ) - { - block->bundlei = i; - block->hdrsi = bp->hdrsi; - bp->blocks[i] = block; - printf("bundlehashadd set.%d\n",i); - iguana_bundlehash2add(coin,0,bp,i,bp->speculative[i]); - } - } - } - } - }*/ - //bp->rank = 0; - estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); - //bp->metric = bp->numhashes; + estsize += bp->estsize; bp->metric = coin->bundlescount - bp->hdrsi; if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE ) bp->metric *= 1000; @@ -1312,7 +1007,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->numsaved = numsaved; coin->spaceused = spaceused; coin->numverified = numv; - char str4[65],str5[65]; + char str5[65]; if ( coin->isRT == 0 && firstgap != 0 && firstgap->hdrsi < coin->bundlescount-1 ) { if ( coin->stuckmonitor != (firstgap->hdrsi * coin->chain->bundlesize * 10) + firstgap->numsaved + firstgap->numhashes + firstgap->numcached ) @@ -1336,8 +1031,21 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) myallocated(0,0); coin->lastdisp = (uint32_t)time(NULL); } - if ( (bp= coin->current) != 0 && bp->queued == 0 ) - iguana_bundleQ(coin,firstgap,1000); + if ( (bp= coin->current) != 0 ) + { + if ( coin->blocks.hwmchain.height >= bp->bundleheight && coin->blocks.hwmchain.height < bp->bundleheight+bp->n ) + { + for (i=coin->blocks.hwmchain.height-bp->bundleheight+1; i<=bp->n; i++) + { + if ( (block= iguana_bundleblock(coin,&hash2,bp,i)) == 0 && bits256_nonz(hash2) != 0 ) + block = iguana_blockfind(coin,hash2); + if ( block == 0 || _iguana_chainlink(coin,block) == 0 ) + break; + } + } + if ( bp->queued == 0 ) + iguana_bundleQ(coin,firstgap,1000); + } iguana_setmaxbundles(coin); strcpy(coin->statusstr,str); coin->estsize = estsize; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index f0834cd38..8ba34e47a 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -427,6 +427,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei FILE *fp; char fname[512],*symbol; int32_t iter; coin->sleeptime = 10000; symbol = coin->symbol; + iguana_peerslotinit(coin,&coin->internaladdr,IGUANA_MAXPEERS,calc_ipbits("127.0.0.1:7777")); if ( initialheight < coin->chain->bundlesize*10 ) initialheight = coin->chain->bundlesize*10; iguana_recvalloc(coin,initialheight); diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index ba4ac77e5..f3ef963e2 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -484,7 +484,18 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } retval = 0; //printf("iguana_msgparser %s parse.(%s)\n",addr->ipaddr,H->command); - if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) + if ( strcmp(H->command,"block") == 0 ) + { + struct iguana_txblock txdata; + if ( addr != 0 ) + addr->msgcounts.block++; + iguana_memreset(rawmem), iguana_memreset(txmem); + memset(&txdata,0,sizeof(txdata)); + if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) + iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); + else printf("parse error block txn_count.%d, len.%d vs recvlen.%d\n",txdata.block.RO.txn_count,len,recvlen); + } + else if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) { addr->supernet = 1; addr->msgcounts.verack++; @@ -595,17 +606,6 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc printf("tx recvlen.%d vs len.%d\n",recvlen,len); addr->msgcounts.tx++; } - else if ( strcmp(H->command,"block") == 0 ) - { - struct iguana_txblock txdata; - if ( addr != 0 ) - addr->msgcounts.block++; - iguana_memreset(rawmem), iguana_memreset(txmem); - memset(&txdata,0,sizeof(txdata)); - if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) - iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); - else printf("parse error block txn_count.%d, len.%d vs recvlen.%d\n",txdata.block.RO.txn_count,len,recvlen); - } else if ( strcmp(H->command,"reject") == 0 ) { for (i=0; iipbits = ipbits; + addr->addrind = slotid; + sprintf(fname,"DB/%s/vouts/%04d.vouts",coin->symbol,addr->addrind); + if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->voutsfp,0,SEEK_END); + else addr->voutsfp = fopen(fname,"wb+"); + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + sprintf(fname,"purgeable/%s/%04d.vins",coin->symbol,addr->addrind); + if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->vinsfp,0,SEEK_END); + else addr->vinsfp = fopen(fname,"wb+"); + } +} + void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf; uint32_t ipbits; + struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf; uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; @@ -983,18 +1001,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) iguana_memreset(mem[i]); } #endif - addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); - sprintf(fname,"DB/%s/vouts/%04d.vouts",coin->symbol,addr->addrind); - if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) - fseek(addr->voutsfp,0,SEEK_END); - else addr->voutsfp = fopen(fname,"wb+"); - if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) - { - sprintf(fname,"purgeable/%s/%04d.vins",coin->symbol,addr->addrind); - if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) - fseek(addr->vinsfp,0,SEEK_END); - else addr->vinsfp = fopen(fname,"wb+"); - } + iguana_peerslotinit(coin,addr,(int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)),calc_ipbits(addr->ipaddr)); //addr->pubkey = GENESIS_PUBKEY; ipbits = (uint32_t)addr->ipbits; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d93bccccf..51413c365 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1718,7 +1718,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru if ( time(NULL) > lastdisp+30 ) { lastdisp = (uint32_t)time(NULL); - printf("ramchaindata have %d:%d at %ld | %d blocks %s redundant xfers total %s %.2f%% wasted\n",bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); + printf("ramchaindata have %d:%d at %d | %d blocks %s redundant xfers total %s %.2f%% wasted\n",bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); } return(block->fpos); } @@ -1877,6 +1877,33 @@ void iguana_ramchain_disp(struct iguana_ramchain *ramchain) } } +void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile) +{ + void *ptr; int32_t recvlen,hdrsi,checki; char fname[1024]; static bits256 zero; + block->queued = 0; + block->fpipbits = 0; + block->fpos = -1; + block->txvalid = 0; + block->issued = 0; + if ( bp != 0 && i >= 0 && i < bp->n ) + { + bp->issued[i] = 0; + if ( (ptr= bp->speculativecache[i]) != 0 ) + { + memcpy(&recvlen,ptr,sizeof(recvlen)); + myfree(ptr,recvlen + sizeof(recvlen)); + bp->speculativecache[i] = 0; + } + } + if ( deletefile != 0 ) + { + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1,1)) != i ) + printf("checki.%d vs %d mismatch?\n",checki,i); + if ( fname[0] != 0 ) + OS_removefile(fname,0); + } +} + int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp) { static bits256 zero; @@ -1887,10 +1914,7 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p fpipbits = block->fpipbits; else { - block->queued = 0; - block->fpipbits = 0; - block->issued = 0; - bp->issued[bundlei] = 0; + iguana_blockunmark(coin,block,bp,bundlei,0); return(0); } if ( num > 0 ) @@ -1910,9 +1934,7 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) { printf("error mapping bundlei.%d (%s)\n",bundlei,fname); - block->queued = 0; - block->fpipbits = 0; - bp->issued[bundlei] = 0; + iguana_blockunmark(coin,block,bp,bundlei,1); return(0); } //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); @@ -2103,7 +2125,7 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana } //printf("mapped bundle.%d\n",bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; - iguana_bundlecalcs(coin,bp); + iguana_bundlecalcs(coin,bp,60); /*for (i=1; iH.data->numtxids; i++) {break; @@ -2180,7 +2202,7 @@ int32_t iguana_mapchaininit(struct iguana_info *coin,struct iguana_ramchain *map mapchain->H.ROflag = 1; if ( block->fpos > filesize ) { - printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",block->fpos,filesize,bp->hdrsi,bundlei); + printf("fpos error %d > %ld mapping hdrsi.%d bundlei.%d\n",block->fpos,filesize,bp->hdrsi,bundlei); return(-1); } _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); @@ -2258,15 +2280,9 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str //printf("mem.%p mapchain txid tables, scriptspace.%u sigspace.%u pubkeyspace.%u bundlei.%d/%d\n",mem,scriptspace,sigspace,pubkeyspace,bundlei,bp->n); if ( bundlei != endi+1 ) { - if ( (block= bp->blocks[bundlei]) != 0 ) - { - block->fpipbits = 0; - block->queued = 0; - block->issued = 0; - block->RO.recvlen = 0; - bp->issued[bundlei] = 0; - } iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + if ( (block= bp->blocks[bundlei]) != 0 ) + iguana_blockunmark(coin,block,bp,bundlei,1); printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } @@ -2302,11 +2318,8 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str if ( (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) { char str[65]; printf("null prevblock error at ht.%d patch.(%s)\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); - block->queued = 0; - block->fpipbits = 0; - bp->issued[i] = 0; - block->issued = 0; iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,block,bp,i,1); return(-1); } destB[i] = block->RO; @@ -2329,10 +2342,9 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { if ( (block= bp->blocks[bundlei]) != 0 ) { - block->queued = 0; - block->fpipbits = 0; - bp->issued[bundlei] = 0; - block->issued = 0; + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,block,bp,bundlei,1); + return(-1); } if ( coin->active != 0 ) printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index f3b805183..7b42ae7fe 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -17,6 +17,9 @@ // peer context, ie massively multithreaded -> bundlesQ +static int32_t numDuplicates,numAfteremit; +static int64_t sizeDuplicates,sizeAfteremit; + struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) { struct iguana_bundlereq *req; int32_t allocsize; @@ -30,10 +33,33 @@ struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana return(req); } +int32_t iguana_speculativesearch(struct iguana_info *coin,struct iguana_block **blockptrp,bits256 hash2) +{ + int32_t i,j; struct iguana_bundle *bp; + if ( blockptrp != 0 ) + *blockptrp = 0; + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->speculative != 0 ) + { + for (j=0; jn&&jnumspec; j++) + if ( bits256_cmp(hash2,bp->speculative[j]) == 0 ) + { + if ( blockptrp != 0 ) + *blockptrp = bp->blocks[j]; + if ( bp->speculativecache[j] != 0 ) + return(1); + else return(-1); + } + } + } + return(0); +} + int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe) { static bits256 lastreq,lastreq2; - int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; + int32_t len,j; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { @@ -41,6 +67,20 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, // if ( (rand() % 10 ) != 0 ) return(0); } + if ( (checkbp= iguana_bundlefind(coin,&checkbp,&j,hash2)) != 0 && j >= 0 && j < checkbp->n ) + { + if ( checkbp->emitfinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0) ) + { + //printf("found valid [%d:%d] in blockreqPT\n",checkbp->hdrsi,j); + return(0); + } + } + if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) + { + //printf("found valid [%d:%d] in blockreqPT\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1); + return(0); + } + if ( addr->msgcounts.verack == 0 ) { //printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); @@ -159,7 +199,7 @@ struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundl int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_block *block,uint8_t *data,int32_t recvlen) { - int32_t i,j,numcached; uint8_t *tmp; char str[65]; + int32_t i,j,numcached; uint8_t *tmp; //char str[65]; for (i=1; in; i++) { if ( bits256_cmp(bp->speculative[i],block->RO.hash2) == 0 ) @@ -168,7 +208,7 @@ int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp { if ( memcmp(&recvlen,tmp,sizeof(recvlen)) != 0 || memcmp(&tmp[sizeof(recvlen)],data,recvlen) != 0 ) printf("ERROR "); - printf("[%d:%d] already has recvlen.%d for %s\n",bp->hdrsi,i,recvlen,bits256_str(str,block->RO.hash2)); + //printf("[%d:%d] already has recvlen.%d for %s\n",bp->hdrsi,i,recvlen,bits256_str(str,block->RO.hash2)); return(0); } bp->speculativecache[i] = mycalloc('p',1,recvlen + sizeof(recvlen)); @@ -202,8 +242,7 @@ int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block) void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { - struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag; struct iguana_block *block; - struct iguana_bundle *bp; + struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag; struct iguana_block *block; struct iguana_bundle *bp; char str[65]; if ( 0 ) { for (i=0; ispace[0]; i++) @@ -229,8 +268,15 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } - char str[65]; - if ( addr != 0 ) + if ( iguana_blockvalidate(coin,&valid,&origtxdata->block,1) < 0 ) + { + printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); + return; + } + else if ( 0 && coin->enableCACHE != 0 ) + printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); + origtxdata->block.txvalid = 1; + if ( addr != 0 && addr != &coin->internaladdr ) { static uint64_t received[IGUANA_MAXPEERS],count[IGUANA_MAXPEERS]; received[addr->addrind] += recvlen; @@ -240,16 +286,9 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i uint64_t sum2 = 0,sum = 0; for (i=0; iblock,1) < 0 ) - { - printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); - return; - } - else if ( 0 && coin->enableCACHE != 0 ) - printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); copyflag = 0;//(coin->enableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); @@ -257,6 +296,8 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { if ( bp->emitfinish != 0 ) { + numAfteremit++; + sizeAfteremit += recvlen; //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); return; } @@ -265,13 +306,17 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { if ( iguana_blockstatus(coin,block) != 0 && block->txvalid != 0 ) { + numDuplicates++; + sizeDuplicates += recvlen; + //printf("duplicate [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); if ( bits256_cmp(origtxdata->block.RO.hash2,block->RO.hash2) == 0 ) return; else printf("mismatched tx received? mainchain.%d\n",block->mainchain); if ( block->mainchain != 0 ) return; - } + } //else printf("recv [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); block->RO = origtxdata->block.RO; + block->txvalid = 1; //printf("update prev for [%d:%d]\n",bp->hdrsi,bundlei); } } @@ -279,7 +324,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { if ( (bp= coin->current) != 0 && bp->speculative != 0 ) { - for (i=bp->hdrsi; ibundlescount; i++) + for (i=0; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->speculative != 0 && bp->numhashes < bp->n ) { @@ -534,7 +579,7 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in // main context, ie single threaded struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) { - struct iguana_block *block,*prevblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t prevbundlei,bundlei = -2; + struct iguana_block *block,*prevblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t hdrsi,checki,prevbundlei,bundlei = -2; char fname[1024]; FILE *fp; *bundleip = -2; *blockp = 0; if ( origblock == 0 ) return(0); @@ -557,6 +602,21 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl block->bundlei = bundlei; block->hdrsi = bp->hdrsi; bp->blocks[bundlei] = block; + if ( bits256_nonz(bp->hashes[bundlei]) == 0 && bp->emitfinish == 0 ) + { + block->fpos = -1; + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1,0); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + block->RO.recvlen = (uint32_t)ftell(fp); + block->fpipbits = 1; + block->txvalid = 1; + block->fpos = 0; + printf("initialize with fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + fclose(fp); + } + } //printf("bundlehashadd set.%d\n",bundlei); iguana_bundlehash2add(coin,0,bp,bundlei,hash2); if ( bundlei > 0 ) @@ -714,7 +774,7 @@ void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) { if ( newbp->speculative == 0 ) queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - //printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); + //char str[65],str2[65]; printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); if ( newbp->queued == 0 ) iguana_bundleQ(coin,newbp,1000); } @@ -767,6 +827,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //printf("speculate new issue [%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculate",coin,bp,-i,blockhashes[i],0); } + bp->speculative[0] = bp->hashes[0]; bp->numspec = num <= bp->n+1 ? num : bp->n+1; //iguana_blockQ(coin,0,-1,blockhashes[2],1); } @@ -1112,7 +1173,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( bits256_nonz(hash2) > 0 ) { coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,0,-1,hash2,lag > threshold); + iguana_blockQ("mainchain",coin,0,-1,hash2,0);//lag > threshold); flag++; char str[65]; if ( 1 && (rand() % 10000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) @@ -1245,25 +1306,6 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) return(n); } -int32_t iguana_speculativesearch(struct iguana_info *coin,bits256 hash2) -{ - int32_t i,j; struct iguana_bundle *bp; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 && bp->speculative != 0 ) - { - for (j=0; jn&&jnumspec; j++) - if ( bits256_cmp(hash2,bp->speculative[j]) == 0 ) - { - if ( bp->speculativecache[j] != 0 ) - return(1); - else return(-1); - } - } - } - return(0); -} - int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) { queue_t *Q; char *str; int32_t n,height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; @@ -1273,8 +1315,11 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle //getchar(); return(-1); } - if ( coin->enableCACHE != 0 || iguana_speculativesearch(coin,hash2) > 0 ) + if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) + { + //printf("found valid [%d:%d] in blockQ\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1); return(0); + } block = iguana_blockfind(coin,hash2); if ( priority != 0 || block == 0 || iguana_blockstatus(coin,block) == 0 ) { @@ -1312,7 +1357,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle } return(0); } - if ( block->queued != 0 ) + if ( block->queued != 0 || block->txvalid != 0 ) return(0); height = block->height; } @@ -1405,8 +1450,8 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } //if ( netBLOCKS > coin->MAXPEERS*coin->MAXPENDING ) // usleep(netBLOCKS); - if ( (limit= addr->recvblocks) > coin->MAXPENDING ) - limit = coin->MAXPENDING; + if ( (limit= addr->recvblocks) > coin->MAXPENDINGREQUESTS ) + limit = coin->MAXPENDINGREQUESTS; if ( limit < 1 ) limit = 1; if ( addr->pendblocks >= limit ) @@ -1424,7 +1469,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( (ptr= coin->peers.ranked[i]) != 0 && ptr->msgcounts.verack > 0 ) pend += ptr->pendblocks, m++; } - if ( pend < coin->MAXPENDING*m ) + if ( pend < coin->MAXPENDINGREQUESTS*m ) req = queue_dequeue(&coin->blocksQ,0); } if ( req != 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index afa9800e1..f690b805d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1178,7 +1178,7 @@ int32_t iguana_volatileinit(struct iguana_info *coin) } } coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; - iguana_bundlestats(coin,buf); + iguana_bundlestats(coin,buf,IGUANA_DEFAULTLAG); return(coin->balanceswritten); }