Browse Source

merkle

release/v0.1
jl777 9 years ago
parent
commit
42fe0d4b63
  1. 21
      deprecated/obsolete.h
  2. 7
      iguana/iguana777.h
  3. 198
      iguana/iguana_bundles.c
  4. 2
      iguana/iguana_peers.c
  5. 48
      iguana/iguana_ramchain.c
  6. 268
      iguana/iguana_recv.c
  7. 3
      iguana/main.c

21
deprecated/obsolete.h

@ -14252,5 +14252,26 @@ len = 0;
printf("processed %d spendinds for bp.[%d] -> errs.%d\n",spendind,bp->hdrsi,errs);
return(-errs);
}
if ( bp != currentbp )
{
//printf("initial requests for hdrs.%d\n",bp->hdrsi);
pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ);
for (i=0; i<IGUANA_MAXPEERS; i++)
pend += coin->peers.active[i].pendblocks;
if ( 0 && pend >= IGUANA_BUNDLELOOP )
{
//for (i=better=0; i<coin->bundlescount; i++)
// if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved )
// better++;
//if ( better > coin->peers.numranked )
{
//usleep(10000);
//printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit);
iguana_bundleQ(coin,bp,1000);
return(0);
}
}
counter = iguana_bundlekick(coin,bp,starti,max);
}
#endif

7
iguana/iguana777.h

@ -278,7 +278,7 @@ struct iguana_block
{
struct iguana_blockRO RO;
double PoW; // NOT consensus safe, for estimation purposes only
int32_t height,fpos; uint32_t fpipbits,numrequests,issued;
int32_t height; uint32_t fpipbits,numrequests,issued; long fpos;
uint16_t hdrsi,bundlei:12,mainchain:1,valid:1,queued:1,tbd:1,extra:8;
UT_hash_handle hh; bits256 *blockhashes;
};// __attribute__((packed));
@ -418,7 +418,7 @@ 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;
uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime;
int32_t numhashes,numrecv,numsaved,numcached,rank,generrs,checkedtmp;
int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec;
double avetime,threshold,metric; uint64_t datasize,estsize;
@ -795,8 +795,9 @@ struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_b
int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp);
void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp);
void iguana_coinflush(struct iguana_info *coin,int32_t forceflag);
int32_t iguana_bundlekick(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max);
int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max);
void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp);
extern int32_t HDRnet,netBLOCKS;
extern queue_t bundlesQ,validateQ,emitQ,balancesQ;
extern char GLOBALTMPDIR[];

198
iguana/iguana_bundles.c

@ -364,7 +364,126 @@ void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp)
}
}
int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t done)
int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit)
{
int32_t i,counter = 0; uint32_t now; struct iguana_block *block;
if ( bp == 0 )
return(0);
now = (uint32_t)time(NULL);
if ( bp == coin->current )
{
if ( time(NULL) > bp->lastspeculative+60 )
{
for (i=1,counter=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) == 0 || block->RO.recvlen == 0 )
{
if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 && i < bp->numspec )
iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++;
else if ( bits256_nonz(bp->hashes[i]) != 0 )
iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++;
}
}
if ( counter != 0 )
printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi);
bp->lastspeculative = (uint32_t)time(NULL);
}
}
for (i=counter=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 )
{
if ( block->fpipbits == 0 || block->RO.recvlen == 0 )
{
if ( block->issued == 0 || now > block->issued+60 )
{
block->numrequests++;
iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0);
bp->issued[i] = block->issued = now;
counter++;
if ( --max <= 0 )
break;
}
//else if ( block->fpipbits != 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) != 0) )
// n++;
}
} //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i);
}
return(counter);
}
int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp)
{
int32_t i,ready,valid; struct iguana_block *block;
for (i=ready=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 )
{
//printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]);
if ( block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 )
{
char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block));
iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1);
} else ready++;
} else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i]));
}
return(ready);
}
int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti)
{
int32_t counter=0;
//if ( bp->speculative != 0 )
// printf("hdr ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative);
if ( strcmp(coin->symbol,"BTC") != 0 && bp->speculative == 0 && bp->numhashes < bp->n )
{
char str[64];
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1);
}
return(counter);
}
int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp)
{
struct iguana_bundle *prevbp;
if ( bp->hdrsi == 0 || ((prevbp= coin->bundles[bp->hdrsi-1]) != 0 && coin->current != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > coin->startutc && time(NULL) > prevbp->emitfinish+3) )
{
//printf("postfinish.%d startutxo.%u prevbp.%p current.%p\n",bp->hdrsi,bp->startutxo,coin->bundles[bp->hdrsi-1],coin->current);
if ( bp->startutxo == 0 )
{
bp->startutxo = (uint32_t)time(NULL);
if ( iguana_utxogen(coin,bp) >= 0 )
{
printf("GENERATED UTXO for ht.%d duration %d seconds\n",bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo);
bp->utxofinish = (uint32_t)time(NULL);
}
else printf("UTXO gen.[%d] error\n",bp->hdrsi);
}
if ( bp->utxofinish != 0 && bp->balancefinish == 0 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) )
{
iguana_balancesQ(coin,bp);
return(-1);
}
}
return(0);
}
int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp)
{
struct iguana_bundle *lastbp;
if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 )
coin->lastpending = coin->bundles[lastbp->hdrsi + 1];
if ( (rand() % 2) == 0 )
{
if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES )
coin->MAXBUNDLES--;
else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES )
coin->MAXBUNDLES++;
}
return(coin->MAXBUNDLES);
}
int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp)
{
FILE *fp; int32_t bundlei,checki,hdrsi; struct iguana_block *block; char fname[1024]; static bits256 zero;
if ( bp->emitfinish > coin->startutc )
@ -398,14 +517,24 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int
bp->blocks[bundlei] = block;
if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) )
bp->minrequests = block->numrequests;
if ( block->fpipbits != 0 )
bp->numsaved++;
if ( block->RO.recvlen != 0 )
if ( bits256_nonz(block->RO.prev_block) > 0 )
{
bp->numrecv++;
bp->datasize += block->RO.recvlen;
if ( block->queued != 0 )
bp->numcached++;
if ( block->fpipbits != 0 )
bp->numsaved++;
if ( block->RO.recvlen != 0 )
{
bp->numrecv++;
bp->datasize += block->RO.recvlen;
if ( block->queued != 0 )
bp->numcached++;
}
}
else
{
block->RO.recvlen = 0;
block->fpipbits = 0;
block->fpos = -1;
block->issued = bp->issued[bundlei] = 0;
}
}
else if ( 0 )
@ -420,13 +549,52 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int
}
}
bp->estsize = ((int64_t)bp->datasize * bp->n) / (bp->numrecv+1);
//bp->metric = bp->numhashes;
bp->metric = coin->bundlescount - bp->hdrsi;//1000 + sqrt(sqrt(bp->n * (1 + bp->numsaved + bp->numrecv)) * (10 + coin->bundlescount - bp->hdrsi));
if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE )
bp->metric *= 1000;
return(bp->estsize);
}
int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit)
{
int32_t range,starti,lasti,retval=0,max,counter = 0; double endmillis; struct iguana_bundle *currentbp,*lastbp;
if ( (range= coin->peers.numranked) > coin->MAXBUNDLES )
range = coin->MAXBUNDLES;
currentbp = coin->current;
lastbp = coin->lastpending;
starti = currentbp == 0 ? 0 : currentbp->hdrsi;
lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi;
coin->numbundlesQ--;
iguana_bundlecalcs(coin,bp);
if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize )
iguana_bundlehdr(coin,bp,starti);
else if ( bp->emitfinish > coin->startutc && (retval= iguana_bundlefinish(coin,bp)) < 0 )
return(0);
else if ( bp->emitfinish != 0 && bp->numsaved >= bp->n )
{
if ( iguana_bundleready(coin,bp) == bp->n )
{
printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",bp->bundleheight,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS);
bp->emitfinish = 1;
iguana_bundletweak(coin,bp);
sleep(1); // just in case data isnt totally sync'ed to HDD
iguana_emitQ(coin,bp);
}
retval = 1;
}
else if ( bp->hdrsi <= starti+range )
{
max = sqrt(bp->n) - (bp->n/coin->MAXBUNDLES)*(bp->hdrsi - starti);
if ( max > 100 )
max = 100;
else if ( max < 10 )
max = 10;
counter = iguana_bundleissue(coin,bp,max,timelimit);
if ( 0 && bp->hdrsi == starti )
printf("ITERATE.%d max.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d %f counter.%d\n",bp->rank,max,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,endmillis-OS_milliseconds(),counter);
}
bp->nexttime = (uint32_t)time(NULL) + 1;
iguana_bundleQ(coin,bp,1000);
return(retval);
}
static int _decreasing_double(const void *a,const void *b)
{
#define double_a (*(double *)a)
@ -460,7 +628,11 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
if ( (bp= coin->bundles[i]) != 0 )
{
bp->rank = 0;
estsize += iguana_bundlecalcs(coin,bp,done);
estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done);
//bp->metric = bp->numhashes;
bp->metric = coin->bundlescount - bp->hdrsi;
if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE )
bp->metric *= 1000;
numhashes += bp->numhashes;
numcached += bp->numcached;
numrecv += bp->numrecv;

2
iguana/iguana_peers.c

@ -987,7 +987,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr)
{
if ( req->datalen != 0 )
{
//char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2));
char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2));
iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen);
} else printf("CACHE error no datalen\n");
coin->cachefreed++;

48
iguana/iguana_ramchain.c

@ -1755,16 +1755,56 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain
return(0);
}
bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,struct iguana_msgtx *txarray,int32_t txn_count)
{
int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2];
if ( txn_count == 1 )
return(txarray[0].txid);
for (i=0; i<txn_count; i++)
tree[i] = txarray[i].txid;
prev = 0;
while ( txn_count > 1 )
{
if ( (txn_count & 1) != 0 )
tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++;
n += txn_count;
for (i=0; i<txn_count; i+=2)
{
//printf("prev.%d n.%d txn_count.%d dest.%d src2.%d\n",prev,n,txn_count,n+(i>>1),prev+i);
iguana_rwbignum(1,serialized,sizeof(*tree),tree[prev + i].bytes);
iguana_rwbignum(1,&serialized[sizeof(*tree)],sizeof(*tree),tree[prev + i + 1].bytes);
tree[n + (i >> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized));
}
prev = n;
txn_count >>= 1;
}
return(tree[n]);
}
long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen)
{
int32_t verifyflag = 0; static uint64_t totalrecv;
RAMCHAIN_DECLARE; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain;
struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; long fsize; void *ptr;
int32_t i,j,fpos,pubkeysize,sigsize,firsti=1,err,flag,bundlei = -2;
int32_t i,j,fpos,pubkeysize,msize,sigsize,firsti=1,err,flag,bundlei = -2; bits256 merkle_root;
struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace;
totalrecv += recvlen;
for (i=0; i<sizeof(addr->dirty)/sizeof(*addr->dirty); i++)
addr->dirty[i] = 0;
msize = (int32_t)sizeof(bits256) * (txn_count+1) * 2;
if ( msize <= addr->TXDATA.totalsize )
{
iguana_memreset(&addr->TXDATA);
merkle_root = iguana_merkle(coin,addr->TXDATA.ptr,txarray,txn_count);
if ( bits256_cmp(merkle_root,origtxdata->block.RO.merkle_root) != 0 )
{
char str[65],str2[65];
printf(">>>>>>>>>> merkle mismatch.[%d] calc.(%s) vs (%s)\n",txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->block.RO.merkle_root));
origtxdata->block.RO.recvlen = 0;
origtxdata->block.issued = 0;
return(-1);
} //else printf("matched merkle.%d\n",txn_count);
} else printf("not enough memory for merkle verify %ld vs %lu\n",sizeof(bits256)*(txn_count+1),(long)addr->TXDATA.totalsize);
if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2) == 0 )
{
if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.prev_block) == 0 )
@ -1798,7 +1838,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 %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);
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);
}
//return(block->fpos);
}
@ -2192,7 +2232,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE;
void **ptrs,*ptr; long *filesizes,filesize; uint32_t *ipbits; char fname[1024];
struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits;
int32_t i,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,fpos; struct iguana_block *block;
int32_t i,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos;
struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1;
//if ( bp->bundleheight == 166000 || bp->bundleheight == 316000 || bp->bundleheight == 142000 || bp->bundleheight == 306000 || bp->bundleheight == 128000 || bp->bundleheight == 254000 || bp->bundleheight == 190000 || bp->bundleheight == 118000 || bp->bundleheight == 62000 || bp->bundleheight == 148000 )
//return(0);
@ -2237,7 +2277,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
if ( fpos > filesize )
{
iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,bp->n);
printf("fpos error %d > %ld mapping hdrsi.%d bundlei.%d\n",fpos,filesize,bp->hdrsi,bundlei);
printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",fpos,filesize,bp->hdrsi,bundlei);
break;
}
if ( fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize )

268
iguana/iguana_recv.c

@ -155,7 +155,6 @@ struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundl
}
#endif
static int32_t netBLOCKS;
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,i,j,bundlei,copyflag; char fname[1024];
@ -258,7 +257,6 @@ void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256
queue_enqueue("recvQ",&coin->recvQ,&req->DL,0);
}
static int32_t HDRnet;
void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n)
{
struct iguana_bundlereq *req;
@ -413,234 +411,6 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in
} //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1);
}
int32_t iguana_bundlekick(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max)
{
int32_t i,n,issued,counter = 0; uint32_t now; struct iguana_block *block;
if ( bp == 0 )
return(0);
now = (uint32_t)time(NULL);
if ( bp == coin->current )
{
}
for (i=n=counter=issued=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 )
{
if ( block->fpipbits == 0 || block->RO.recvlen == 0 )
{
if ( block->issued == 0 || now > block->issued+60 )//|| (rand() % 100) == 0) )
{
block->numrequests++;
//printf("bundleQ issue %d %x %d [%d:%d] numsaved.%d\n",block->RO.recvlen,block->fpipbits,block->fpos,bp->hdrsi,i,bp->numsaved);
/*if ( bp->hdrsi == starti )
{
//if ( coin->peers.ranked[0] != 0 )
// iguana_sendblockreqPT(coin,coin->peers.ranked[0],bp,i,block->RO.hash2,0);
iguana_blockQ(coin,bp,i,block->RO.hash2,1);
} else*/
iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0);
bp->issued[i] = block->issued = now;
counter++;
if ( --max <= 0 )
break;
}
else if ( block->fpipbits != 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) != 0) )
n++, issued++;
else if ( bp->issued[i] != 0 )
issued++;
} else n++, issued++;
} //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i);
}
return(counter);
}
int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit)
{
int32_t i,range,starti,pend,lasti,numhashes,issued,valid,max,counter = 0; struct iguana_block *block; double endmillis,width; struct iguana_bundle *prevbp,*currentbp,*lastbp;
if ( (range= coin->peers.numranked) > coin->MAXBUNDLES )
range = coin->MAXBUNDLES;
currentbp = coin->current;
lastbp = coin->lastpending;
starti = currentbp == 0 ? 0 : currentbp->hdrsi;
lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi;
coin->numbundlesQ--;
for (i=numhashes=0; i<bp->n; i++)
numhashes += bits256_nonz(bp->hashes[i]);
if ( numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize )
{
//if ( bp->speculative != 0 )
// printf("hdr ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative);
if ( strcmp(coin->symbol,"BTC") != 0 && bp->speculative == 0 && bp->numhashes < 3 )
{
char str[64];
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1);
}
else if ( bp->hdrsi == starti && time(NULL) > bp->lastspeculative+90 )
{
for (i=1,counter=0; i<bp->n && i<bp->numspec; i++)
{
if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 )
iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++;
else if ( bits256_nonz(bp->hashes[i]) != 0 )
iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++;
}
if ( counter != 0 )
printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi);
bp->lastspeculative = (uint32_t)time(NULL);
}
if ( bp->hdrsi != starti )
{
iguana_bundleQ(coin,bp,bp->n*5);
return(0);
}
}
if ( bp->emitfinish > coin->startutc )
{
if ( bp->hdrsi == 0 || ((prevbp= coin->bundles[bp->hdrsi-1]) != 0 && coin->current != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > coin->startutc && time(NULL) > prevbp->emitfinish+3) )
{
//printf("postfinish.%d startutxo.%u prevbp.%p current.%p\n",bp->hdrsi,bp->startutxo,coin->bundles[bp->hdrsi-1],coin->current);
if ( bp->startutxo == 0 )
{
bp->startutxo = (uint32_t)time(NULL);
if ( iguana_utxogen(coin,bp) >= 0 )
{
printf("GENERATED UTXO for ht.%d duration %d seconds\n",bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo);
bp->utxofinish = (uint32_t)time(NULL);
}
else
{
printf("UTXO gen error\n");
sleep(3);
if ( iguana_utxogen(coin,bp) >= 0 )
{
printf("GENERATED UTXO for ht.%d duration %d seconds\n",bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo);
bp->utxofinish = (uint32_t)time(NULL);
}
else
{
printf("UTXO gen second error\n");
iguana_bundleQ(coin,bp,1000);
return(0);
}
}
}
if ( bp->utxofinish != 0 && bp->balancefinish == 0 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) )
{
iguana_balancesQ(coin,bp);
return(0);
}
}
iguana_bundleQ(coin,bp,1000);
return(0);
}
else if ( bp->emitfinish != 0 )
{
iguana_bundleQ(coin,bp,1000);
return(0);
}
//printf("BUNDLEITERS.%d\n",bp->hdrsi);
if ( bp->hdrsi <= starti+range && coin->lastpending != 0 )
{
for (i=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 && block->numrequests == 0 )//&& block->mainchain != 0 )
{
block->numrequests++;
iguana_blockQ("iters",coin,bp,i,block->RO.hash2,1);
//printf("%d ",i);
}
}
}
else
{
iguana_bundleQ(coin,bp,1000);
return(0);
}
max = sqrt(bp->n) - (bp->n/coin->MAXBUNDLES)*(bp->hdrsi - starti);
if ( max > 100 )
max = 100;
else if ( max < 10 )
max = 10;
if ( bp != currentbp )
{
//printf("initial requests for hdrs.%d\n",bp->hdrsi);
pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ);
for (i=0; i<IGUANA_MAXPEERS; i++)
pend += coin->peers.active[i].pendblocks;
if ( 0 && pend >= IGUANA_BUNDLELOOP )
{
//for (i=better=0; i<coin->bundlescount; i++)
// if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved )
// better++;
//if ( better > coin->peers.numranked )
{
//usleep(10000);
//printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit);
iguana_bundleQ(coin,bp,1000);
return(0);
}
}
counter = iguana_bundlekick(coin,bp,starti,max);
}
issued = 0;
/*if ( coin->numsaved > coin->longestchain*.99 )
{
printf("last percent via hdrsi.%d\n",bp->hdrsi);
for (r=starti; r<coin->bundlescount; r++)
iguana_bundlekick(coin,coin->bundles[r],r,coin->bundles[r]->n);
}*/
endmillis = OS_milliseconds() + timelimit + (rand() % 1000);
//if ( bp->numsaved < bp->n )
width = 100;// + max*100;//sqrt(sqrt(bp->n * (1+bp->numsaved+issued)) * (10+coin->bundlescount-bp->hdrsi));
if ( 0 && bp->hdrsi == starti )
printf("ITERATE.%d max.%d bundle.%d h.%d n.%d r.%d s.%d F.%d I.%d T.%d %f %u next %f counter.%d\n",bp->rank,max,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,issued,timelimit,endmillis-OS_milliseconds(),(uint32_t)time(NULL),width,counter);
if ( bp->emitfinish == 0 )
{
if ( bp->numsaved >= bp->n )
{
for (i=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 )
{
//printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]);
if ( block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 )
{
char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block));
block->queued = 0;
block->fpipbits = 0;
block->issued = 0;
bp->issued[i] = 0;
iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,0);
iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2);
return(0);
}
} else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i]));
}
// merkle
printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",bp->bundleheight,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS);
bp->emitfinish = 1;
if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 )
coin->lastpending = coin->bundles[lastbp->hdrsi + 1];
if ( (rand() % 2) == 0 )
{
if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES )
coin->MAXBUNDLES--;
else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES )
coin->MAXBUNDLES++;
}
sleep(1);
iguana_emitQ(coin,bp);
iguana_bundleQ(coin,bp,width);
if ( bp == currentbp && bp->hdrsi < coin->bundlescount-1 && (bp= coin->bundles[currentbp->hdrsi+1]) != 0 )
iguana_bundlekick(coin,bp,bp->hdrsi,bp->n);
return(1);
}
}
iguana_bundleQ(coin,bp,width);
return(0);
}
// 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)
@ -811,7 +581,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct
return(req);
//printf("done allhashes\n");
}
if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 )
if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 )
{
printf("FOUND speculative.%p BLOCKHASHES[%d] ht.%d\n",bp->speculative,num,bp->bundleheight);
if ( bp->speculative != 0 )
@ -859,16 +629,8 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana
{
struct iguana_bundle *bp=0; int32_t bundlei = -2; struct iguana_block *block;
bp = iguana_bundleset(coin,&block,&bundlei,origblock);
/*if ( bp != 0 && bundlei > 0 && bits256_nonz(origblock->RO.prev_block) > 0 && bits256_cmp(origblock->RO.prev_block,bp->hashes[bundlei-1]) != 0 )
{
printf("backfill [%d:%d]\n",bp->hdrsi,bundlei-1);
bp->hashes[bundlei-1] = origblock->RO.prev_block;
struct iguana_bloominds bit = iguana_calcbloom(origblock->RO.prev_block);
if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 )
iguana_bloomset(coin,&bp->bloom,0,bit);
}*/
char str[65];
if ( 0 && bp == coin->current )
if ( 1 && bp == coin->current )
fprintf(stderr,"blockRECV.%d %s [%d:%d] block.%08x | h.%d\n",req->numtx,bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,bp!=0?bp->numhashes:-1);
if ( bundlei == 1 && bp != 0 && bp->numhashes < bp->n )
{
@ -878,39 +640,15 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana
if ( block != 0 )
{
block->RO.txn_count = req->numtx;
if ( 0 && bp != 0 && bundlei > 0 && bits256_nonz(block->RO.prev_block) > 0 && bits256_cmp(block->RO.prev_block,bp->hashes[bundlei-1]) != 0 )
{
if ( bundlei > 0 )
{
printf("backfill [%d:%d]\n",bp->hdrsi,bundlei-1);
bp->hashes[bundlei-1] = block->RO.prev_block;
}
/*else if ( bp->hdrsi > 0 && coin->bundles[bp->hdrsi-1] != 0 )
{
printf("prev backfill [%d:%d]\n",bp->hdrsi-1,coin->chain->bundlesize-1);
iguana_blockQ(coin,coin->bundles[bp->hdrsi-1],coin->chain->bundlesize-1,block->RO.prev_block,0);
}*/
//iguana_blockQ(coin,bundlei > 0 ? bp : 0,bundlei-1,block->RO.prev_block,0);
//printf("recv autoreq prev [%d:%d]\n",bp!=0?bp->hdrsi:-1,bundlei);
}
//block->RO.recvlen = recvlen;
if ( req->copyflag != 0 && block->queued == 0 && bp != 0 )
{
//char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen);
char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen);
coin->numcached++;
block->queued = 1;
//iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen);
queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0);
return(0);
}
/*while ( block != 0 && memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 )
{
if ( _iguana_chainlink(coin,block) != 0 )
{
printf("chainlink.%d -> next.%p\n",block->height,block->hh.next);
block = block->hh.next;
} else break;
}*/
//printf("datalen.%d ipbits.%x\n",datalen,req->ipbits);
} else printf("cant create origblock.%p block.%p bp.%p bundlei.%d\n",origblock,block,bp,bundlei);
return(req);

3
iguana/main.c

@ -41,6 +41,7 @@ uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100;
queue_t helperQ,jsonQ,finishedQ,bundlesQ,validateQ,emitQ,balancesQ;
struct supernet_info MYINFO,**MYINFOS;
static int32_t initflag;
int32_t HDRnet,netBLOCKS;
cJSON *API_json;
#ifdef __linux__
int32_t IGUANA_NUMHELPERS = 8;
@ -331,7 +332,7 @@ void mainloop(struct supernet_info *myinfo)
for (i=0; i<IGUANA_MAXCOINS; i++)
if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 )
{
iguana_bundlekick(coin,bp,bp->hdrsi,100);
iguana_bundleissue(coin,bp,bp->hdrsi,100);
if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 )
{
if ( ptr->bp != 0 && ptr->coin != 0 )

Loading…
Cancel
Save