Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
47d7f6fbe0
  1. 464
      deprecated/obsolete.h
  2. 26
      iguana/iguana777.c
  3. 37
      iguana/iguana777.h
  4. 1
      iguana/iguana_accept.c
  5. 4
      iguana/iguana_blocks.c
  6. 776
      iguana/iguana_bundles.c
  7. 1
      iguana/iguana_init.c
  8. 24
      iguana/iguana_msg.c
  9. 35
      iguana/iguana_peers.c
  10. 64
      iguana/iguana_ramchain.c
  11. 133
      iguana/iguana_recv.c
  12. 2
      iguana/iguana_unspents.c

464
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; j<numpeers; j++)
{
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; i<bp->n&&k<sizeof(hashes)/sizeof(*hashes); i+=numpeers)
{
doneflag = peerid = 0;
if ( bits256_nonz(bp->hashes[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<numpeers; i++)
if ( donecounts[i]+peercounts[i] != 0 )
nonz++;
if ( nonz != 0 && total != 0 )
{
threshold = ((double)total / nonz) - 1.;
for (i=laggard=finished=0; i<numpeers; i++)
{
if ( peercounts[i] > threshold )
laggard++;
if ( peercounts[i] == 0 && donecounts[i] > threshold )
finished++;
}
if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 )
{
for (i=0; i<numpeers; i++)
{
if ( peercounts[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; j<bp->n; 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; i<numpeers; i++)
printf("%d ",peercounts[i]);
printf("peercounts.%d: finished %d, laggards.%d threshold %f\n",bp->hdrsi,finished,laggard,threshold);
}
}
}
for (i=0; i<bp->n; 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; i<bp->n; 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; j<bp->numspec&&j<bp->n; 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; j<bp->n; 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; i<bp->n; 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; i<bp->n; 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; i<bp->numspec&&i<bp->n; 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

26
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);

37
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;

1
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);

4
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);

776
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; i<n&&m<0xff; i++)
{
if ( (addr= coin->peers.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; i<bp->n; i++)
{
for (j=0; j<numpeers; j++)
if ( bp->speculativecache[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; i<bp->n&&k<sizeof(hashes)/sizeof(*hashes); i+=numpeers)
{
doneflag = peerid = 0;
if ( bits256_nonz(bp->hashes[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; i<numpeers; i++)
if ( donecounts[i]+peercounts[i] != 0 )
nonz++;
if ( nonz != 0 && total != 0 )
if ( block->txvalid != 0 )
{
threshold = ((double)total / nonz) - 1.;
for (i=laggard=finished=0; i<numpeers; i++)
{
if ( peercounts[i] > threshold )
laggard++;
if ( peercounts[i] == 0 && donecounts[i] > threshold )
finished++;
}
if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 )
{
for (i=0; i<numpeers; i++)
{
if ( peercounts[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; j<bp->n; 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; i<numpeers; i++)
printf("%d ",peercounts[i]);
printf("peercounts.%d: finished %d, laggards.%d threshold %f\n",bp->hdrsi,finished,laggard,threshold);
}
//printf("[%d:%d].block ",bp->hdrsi,i);
continue;
}
}
for (i=0; i<bp->n; 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; i<bp->n; 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<max; i++)
if ( GETBIT(missings,i) != 0 )
break;
return(i);
}
int32_t iguana_bundlerequests(struct iguana_info *coin,uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1],int32_t *missingp,int32_t *capacityp,struct iguana_bundle *bp,int32_t lag)
{
uint8_t numpeers; int32_t i,j,avail,nonz=0,c,n,m=0,max,capacity,numsent; bits256 hashes[500],hash2;
struct iguana_block *block; struct iguana_peer *peers[256],*addr; uint32_t now = (uint32_t)time(NULL);
max = (int32_t)(sizeof(hashes) / sizeof(*hashes));
*missingp = *capacityp = 0;
if ( (numpeers= iguana_recentpeers(coin,&capacity,peers)) > 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; i<numpeers && avail>0; 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; j<numsent; j++)
{
if ( (nonz= iguana_nextnonz(missings,nonz,bp->n)) < 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; i<bp->n; 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; i<bp->numspec&&i<bp->n; 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; bundlei<bp->n; 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; i<count; i++)
{
if ( (bp= coin->bundles[i]) != 0 )
{
iguana_bundlecalcs(coin,bp,lag);
if ( bp->emitfinish > 1 )
{
for (j=0; j<bp->n; 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; j<bp->n; 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; j<bp->numspec&&j<bp->n; 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; j<bp->n; 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; i<bp->n; 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; i<bp->n; 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;

1
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);

24
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; i<recvlen; i++)

35
iguana/iguana_peers.c

@ -342,7 +342,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port)
return(-1);
}
sleep(13);
continue;
//continue;
}
if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH )
{
@ -964,10 +964,28 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr)
}
#endif
void iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits)
{
char fname[1024];
addr->ipbits = 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));

64
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; i<mapchain->H.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);

133
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; i<coin->bundlescount; i++)
{
if ( (bp= coin->bundles[i]) != 0 && bp->speculative != 0 )
{
for (j=0; j<bp->n&&j<bp->numspec; 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; i<bp->n; 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; i<txdata->space[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; i<sizeof(received)/sizeof(*received); i++)
sum += received[i], sum2 += count[i];
printf("TOTAL BLOCKS.%llu RECEIVED %s ave %.1f\n",(long long)sum2,mbstr(str,sum),(double)sum/(sum2!=0?sum2:1));
printf("TOTAL BLOCKS.%llu RECEIVED %s ave %.1f | duplicates.%d %lld afteremit.%d %lld\n",(long long)sum2,mbstr(str,sum),(double)sum/(sum2!=0?sum2:1),numDuplicates,(long long)sizeDuplicates,numAfteremit,(long long)sizeAfteremit);
}
}
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));
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; i<coin->bundlescount; i++)
for (i=0; i<coin->bundlescount; 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; i<coin->bundlescount; i++)
{
if ( (bp= coin->bundles[i]) != 0 && bp->speculative != 0 )
{
for (j=0; j<bp->n&&j<bp->numspec; 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 )

2
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);
}

Loading…
Cancel
Save