Browse Source

Merge branch 'master' into win32_old

release/v0.1
Mayur Nagekar 9 years ago
parent
commit
ed3e47efb3
  1. 2
      crypto777/iguana_OS.c
  2. 34
      iguana/iguana777.c
  3. 26
      iguana/iguana777.h
  4. 4
      iguana/iguana_blocks.c
  5. 92
      iguana/iguana_bundles.c
  6. 95
      iguana/iguana_init.c
  7. 10
      iguana/iguana_json.c
  8. 80
      iguana/iguana_ramchain.c
  9. 14
      iguana/iguana_recv.c
  10. 236
      iguana/iguana_unspents.c
  11. 22
      iguana/iguana_wallet.c
  12. 31
      iguana/main.c
  13. 1
      includes/iguana_apideclares.h

2
crypto777/iguana_OS.c

@ -149,6 +149,8 @@ void _myfree(uint8_t type,int32_t origallocsize,void *origptr,int32_t allocsize)
else
{
printf("myfree size error %d vs %d at %p\n",allocsize,origallocsize,origptr);
static int32_t y,z;
printf("div by zero! %d\n",y/z);
getchar();
}
//portable_mutex_unlock(&MEMmutex);

34
iguana/iguana777.c

@ -345,12 +345,14 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m
}
else if ( ptr->type == 'E' )
{
coin->emitbusy++;
if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 )
{
//fprintf(stderr,"emitQ coin.%p bp.[%d]\n",ptr->coin,bp->bundleheight);
bp->emitfinish = (uint32_t)time(NULL) + 1;
coin->numemitted++;
} else bp->emitfinish = 0;
coin->emitbusy--;
}
} else printf("no bundle in helperrequest\n");
} else printf("no coin in helperrequest\n");
@ -379,7 +381,7 @@ void iguana_helper(void *arg)
allcurrent = 1;
if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) )
{
if ( ptr->bp != 0 && (coin= ptr->coin) != 0 )
if ( ptr->bp != 0 && (coin= ptr->coin) != 0 && coin->active != 0 )
{
idle = 0;
coin->helperdepth++;
@ -392,7 +394,7 @@ void iguana_helper(void *arg)
else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 )
{
idle = 0;
if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 )
if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 )
{
coin->numbundlesQ--;
if ( coin->started != 0 && time(NULL) >= bp->nexttime )
@ -400,7 +402,9 @@ void iguana_helper(void *arg)
else iguana_bundleQ(ptr->coin,bp,1000);
if ( coin->current != 0 && coin->current->hdrsi != coin->bundlescount-1 )
allcurrent = 0;
} else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit);
}
else if ( coin->active != 0 )
printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit);
myfree(ptr,ptr->allocsize);
flag++;
}
@ -408,7 +412,7 @@ void iguana_helper(void *arg)
{
if ( (ptr= queue_dequeue(&validateQ,0)) != 0 )
{
if ( ptr->bp != 0 && ptr->coin != 0 )
if ( ptr->bp != 0 && (coin= ptr->coin) != 0 && coin->active != 0 )
flag += iguana_bundlevalidate(ptr->coin,ptr->bp);
else printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp);
myfree(ptr,ptr->allocsize);
@ -433,14 +437,6 @@ void iguana_coinloop(void *arg)
printf("begin coinloop[%d]\n",n);
for (i=0; i<n; i++)
{
if ( (coin= coins[i]) != 0 && coin->started == 0 )
{
iguana_rwiAddrind(coin,0,0,0);
iguana_coinstart(coin,coin->initialheight,coin->mapflags);
printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND);
coin->started = coin;
coin->chain->minconfirms = coin->minconfirms;
}
}
coin = coins[0];
iguana_possible_peer(coin,"127.0.0.1");
@ -455,8 +451,17 @@ void iguana_coinloop(void *arg)
{
if ( (coin= coins[i]) != 0 )
{
if ( coin->started == 0 && coin->active != 0 )
{
iguana_rwiAddrind(coin,0,0,0);
iguana_coinstart(coin,coin->initialheight,coin->mapflags);
printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND);
coin->started = coin;
coin->chain->minconfirms = coin->minconfirms;
}
now = (uint32_t)time(NULL);
if ( coin->active != 0 )
coin->idletime = 0;
if ( coin->started != 0 && coin->active != 0 )
{
if ( coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 )
{
@ -498,6 +503,7 @@ void iguana_coinloop(void *arg)
if ( coin->longestchain+10000 > coin->blocks.maxbits )
iguana_recvalloc(coin,coin->longestchain + 100000);
}
coin->idletime = (uint32_t)time(NULL);
}
}
if ( flag == 0 )
@ -547,6 +553,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,
mult = (strcmp("BTC",coin->symbol) != 0) ? 512 : 1;
maxval = (strcmp("BTC",coin->symbol) != 0) ? 2048 : 64;
coin->MAXMEM = juint(json,"RAM");
if ( (coin->MAXSTUCKTIME= juint(json,"maxstuck")) == 0 )
coin->MAXSTUCKTIME = _IGUANA_MAXSTUCKTIME;
if ( coin->MAXMEM == 0 )
coin->MAXMEM = IGUANA_DEFAULTRAM;
if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM <= 4 )

26
iguana/iguana777.h

@ -23,9 +23,10 @@
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 300
#define IGUANA_MAXCOINS 64
#define IGUANA_MAXDELAY_MILLIS (3600 * 1000)
@ -179,6 +180,8 @@ struct iguana_thread
void *arg;
};
struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; };
struct iguana_chain
{
//const int32_t chain_id;
@ -282,7 +285,7 @@ struct iguana_block
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; bits256 *blockhashes; struct iguana_bundlereq *req;
UT_hash_handle hh; struct iguana_bundlereq *req; //bits256 *blockhashes;
};// __attribute__((packed));
@ -426,10 +429,10 @@ struct iguana_bloominds { uint16_t inds[8]; };
struct iguana_bundle
{
struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp;
struct iguana_bloom16 bloom; uint32_t rawscriptspace;
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;
int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec;
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]; uint32_t issued[IGUANA_MAXBUNDLESIZE];
bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative;
@ -460,9 +463,9 @@ struct iguana_info
struct iguana_peers peers;
uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime;
int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,estsize,activebundles;
int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten,RTheight; bits256 balancehash;
uint32_t lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks,backlog;
int32_t longestchain,badlongestchain,longestchain_strange;
int32_t MAXPEERS,MAXPENDING,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;
struct tai starttime; double startmillis;
struct iguana_chain *chain;
struct iguana_iAddr *iAddrs;
@ -473,12 +476,12 @@ struct iguana_info
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;
portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2];
//portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2];
//struct scriptinfo *scriptstable[2];
struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending;
struct iguana_ramchain RTramchain; struct OS_memspace RTmem,RThashmem;
int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified;
uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis;
uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,idletime,stucktime,stuckmonitor,maxstuck;
double backstopmillis; bits256 backstophash2; int64_t spaceused;
int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes; bits256 reqtxids[64];
void *launched,*started;
@ -818,6 +821,11 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain
void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei);
int32_t iguana_mapchaininit(struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize);
void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp);
void iguana_RTramchainfree(struct iguana_info *coin);
void iguana_coinpurge(struct iguana_info *coin);
int32_t iguana_setmaxbundles(struct iguana_info *coin);
void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp);
uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind);
extern int32_t HDRnet,netBLOCKS;

4
iguana/iguana_blocks.c

@ -66,7 +66,7 @@ struct iguana_block *iguana_blockhashset(struct iguana_info *coin,int32_t height
}
if ( createflag > 0 )
{
block = mycalloc('x',1,sizeof(*block));
block = calloc(1,sizeof(*block));
block->RO.hash2 = hash2;
block->hh.itemind = height, block->height = -1;
HASH_ADD(hh,coin->blocks.hash,RO.hash2,sizeof(hash2),block);
@ -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) )
if ( hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize >= bp->hdrsi+bp->isRT) )
return(0);
if ( (block= iguana_blockfind(coin,newblock->RO.hash2)) != 0 )
{

92
iguana/iguana_bundles.c

@ -365,7 +365,7 @@ struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundl
return(0);
}
void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp)
void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp)
{
static bits256 zero;
char fname[1024]; int32_t hdrsi,m,j; uint32_t ipbits;
@ -663,6 +663,18 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32
return(counter);
}
int32_t iguana_setmaxbundles(struct iguana_info *coin)
{
double completed;
if ( coin->current != 0 && coin->bundlescount != 0 )
{
completed = ((double)coin->current->hdrsi + 1) / coin->bundlescount;
coin->MAXBUNDLES = (double)(coin->endPEND - coin->startPEND)*completed + coin->startPEND;
//printf("MAXBUNDLES %d (%d -> %d) completed %.3f\n",coin->MAXBUNDLES,coin->startPEND,coin->endPEND,completed);
}
return(coin->MAXBUNDLES);
}
int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp)
{
struct iguana_bundle *lastbp;
@ -670,13 +682,14 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp)
coin->current = coin->bundles[bp->hdrsi+1];
if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 )
coin->lastpending = coin->bundles[lastbp->hdrsi + 1];
if ( (rand() % 3) == 0 )
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);
}
@ -704,7 +717,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp)
printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki);
continue;
}
if ( coin->current == bp )
if ( coin->current == bp && (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) )
{
if ( (fp= fopen(fname,"rb")) != 0 )
{
@ -795,7 +808,11 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp)
}
#endif
for (i=0; i<bp->hdrsi; i++)
if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc )
if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc
#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN
|| (i < bp->hdrsi-16 && prevbp->utxofinish <= 1)
#endif
)
break;
if ( i == bp->hdrsi )
{
@ -827,7 +844,7 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp)
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 range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp;
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;
if ( coin->started == 0 )
{
printf("%s not ready yet\n",coin->symbol);
@ -868,7 +885,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
} //else printf("finish incomplete.%d\n",bp->hdrsi);
}
}
else if ( bp->numsaved >= bp->n )
else if ( bp->numsaved >= bp->n )//&& (bp->isRT == 0 || coin->RTheight > bp->bundleheight+bp->n+coin->minconfirms) )
{
if ( iguana_bundleready(coin,bp) == bp->n )
{
@ -885,6 +902,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
iguana_emitQ(coin,bp);
else
{
coin->emitbusy++;
if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 )
{
//fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight);
@ -896,6 +914,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight);
bp->emitfinish = 0;
}
coin->emitbusy--;
}
}
retval = 1;
@ -906,8 +925,40 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
counter = iguana_bundleissue(coin,bp,max,timelimit);
if ( bp == coin->current && coin->isRT == 0 )
bp->nexttime--;
if ( bp->hdrsi == starti && counter > 0 )
printf("ITER now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",(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 ( counter > 0 )
printf("ITER now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",(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 ( coin->stucktime != 0 )
{
lag = time(NULL)-coin->stucktime;
if ( (lag % 60) == 30 )
{
while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 )
myfree(breq,sizeof(*breq));
while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 )
myfree(breq,sizeof(*breq));
for (i=n=0; i<bp->n; i++)
{
if ( (block= bp->blocks[i]) != 0 && (block->RO.recvlen == 0 || block->fpos < 0 || block->fpipbits == 0 || bits256_nonz(block->RO.prev_block) == 0) )
{
printf("[%d:%d] ",bp->hdrsi,i);
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 )
{
if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&block->RO.hash2,1)) > 0 )
{
printf("%s, ",addr->ipaddr);
iguana_send(coin,addr,serialized,len);
}
}
n++;
}
}
printf("issued %d priority requests [%d] to unstick\n",n,bp->hdrsi);
}
}
}
}
iguana_bundleQ(coin,bp,1000);
return(retval);
@ -1002,7 +1053,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
if ( (block= bp->blocks[j]) != 0 && (block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) && time(NULL) > block->issued+3 && (rand() % 10) == 0 )
{
if ( (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 )
iguana_sendblockreqPT(coin,addr,bp,j,block->RO.hash2,0); printf("current stop [%d:%d]\n",bp->hdrsi,j);
iguana_sendblockreqPT(coin,addr,bp,j,block->RO.hash2,0); printf("kick [%d:%d]\n",bp->hdrsi,j);
iguana_blockQ("currentstop",coin,bp,j,block->RO.hash2,1);
block->issued = (uint32_t)time(NULL);
break;
@ -1029,7 +1080,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
done++;
numemit++;
if ( firstgap != 0 && bp->hdrsi > firstgap->hdrsi-3 )
iguana_bundlepurge(coin,bp);
iguana_bundlepurgefiles(coin,bp);
}
else
{
@ -1069,7 +1120,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
free(sortbuf);*/
coin->numremain = n;
coin->blocksrecv = numrecv;
char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now();
uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now();
for (i=0; i<IGUANA_MAXPEERS; i++)
if ( coin->peers.active[i].usock >= 0 )
p++;
@ -1090,11 +1141,23 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
coin->spaceused = spaceused;
coin->numverified = numv;
char str4[65],str5[65];
sprintf(str,"%s.RT%d u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,coin->RTheight,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height/coin->chain->bundlesize,coin->blocks.hwmchain.height%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2));
if ( coin->isRT == 0 && firstgap != 0 && firstgap->hdrsi < coin->bundlescount-1 )
{
if ( coin->stuckmonitor != (firstgap->hdrsi * coin->chain->bundlesize) + firstgap->numsaved )
{
coin->stuckmonitor = (firstgap->hdrsi * coin->chain->bundlesize) + firstgap->numsaved;
coin->stucktime = (uint32_t)time(NULL);
}
}
if ( coin->isRT != 0 || (firstgap != 0 && firstgap->hdrsi == coin->bundlescount-1) )
coin->stucktime = 0;
if ( coin->stucktime != 0 && time(NULL)-coin->stucktime > coin->maxstuck )
coin->maxstuck = (uint32_t)time(NULL) - coin->stucktime;
sprintf(str,"%s.RT%d u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] h.%d r.%d c.%s s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,coin->RTheight,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height/coin->chain->bundlesize,coin->blocks.hwmchain.height%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2));
//sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ));
if ( time(NULL) > coin->lastdisp+3 && strcmp(str,coin->lastdispstr) != 0 )
{
printf("\n%s bQ.%d %d:%02d:%02d %03.3f\n",str,coin->numbundlesQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis);
printf("\n%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,coin->numbundlesQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck);
strcpy(coin->lastdispstr,str);
if ( (rand() % 100) == 0 )
myallocated(0,0);
@ -1102,6 +1165,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str)
if ( firstgap != 0 && firstgap->queued == 0 )
iguana_bundleQ(coin,firstgap,1000);
}
iguana_setmaxbundles(coin);
strcpy(coin->statusstr,str);
coin->estsize = estsize;
}

95
iguana/iguana_init.c

@ -56,8 +56,8 @@ void iguana_initcoin(struct iguana_info *coin,cJSON *argjson)
sprintf(dirname,"tmp/%s",coin->symbol), OS_portable_path(dirname);
portable_mutex_init(&coin->peers_mutex);
portable_mutex_init(&coin->blocks_mutex);
portable_mutex_init(&coin->scripts_mutex[0]);
portable_mutex_init(&coin->scripts_mutex[1]);
//portable_mutex_init(&coin->scripts_mutex[0]);
//portable_mutex_init(&coin->scripts_mutex[1]);
iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,sizeof(coin->blockspace),0);
iguana_initQs(coin);
coin->bindsock = -1;
@ -322,6 +322,90 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp)
}
}
void iguana_ramchainpurge(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain)
{
}
void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp)
{
static bits256 zero;
if ( bp->speculative != 0 )
myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec);
bp->numspec = 0;
bp->speculative = 0;
memset(bp->hashes,0,sizeof(bp->hashes));
memset(bp->issued,0,sizeof(bp->issued));
bp->prevbundlehash2 = bp->nextbundlehash2 = bp->allhash = zero;
iguana_ramchain_free(coin,&bp->ramchain,1);
}
void iguana_blockpurge(struct iguana_info *coin,struct iguana_block *block)
{
if ( block->req != 0 )
{
printf("purge req inside block\n");
myfree(block->req,block->req->allocsize);
}
free(block);
}
void iguana_blockspurge(struct iguana_info *coin)
{
struct iguana_block *block,*tmp;
if ( coin->blocks.hash != 0 )
{
HASH_ITER(hh,coin->blocks.hash,block,tmp)
{
HASH_DEL(coin->blocks.hash,block);
iguana_blockpurge(coin,block);
}
coin->blocks.hash = 0;
}
if ( coin->blocks.RO != 0 )
{
myfree(coin->blocks.RO,coin->blocks.maxbits * sizeof(*coin->blocks.RO));
coin->blocks.RO = 0;
}
coin->blocks.maxbits = coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0;
memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain));
}
void iguana_coinpurge(struct iguana_info *coin)
{
int32_t i; struct iguana_bundle *bp; char *hashstr; struct iguana_bundlereq *req; struct iguana_blockreq *breq;
coin->started = 0; coin->active = 0;
coin->RTgenesis = 0;
while ( (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 )
free_queueitem(hashstr);
while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 )
myfree(breq,sizeof(*breq));
while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 )
myfree(breq,sizeof(*breq));
while ( (req= queue_dequeue(&coin->cacheQ,0)) != 0 )
myfree(req,req->allocsize);
while ( (req= queue_dequeue(&coin->recvQ,0)) != 0 )
{
if ( req->blocks != 0 )
myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0;
if ( req->hashes != 0 )
myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0;
myfree(req,req->allocsize);
}
while ( coin->idletime == 0 && coin->emitbusy > 0 )
{
printf("coinpurge.%s waiting for idle %lu emitbusy.%d\n",coin->symbol,time(NULL),coin->emitbusy);
sleep(1);
}
iguana_RTramchainfree(coin);
coin->bundlescount = 0;
for (i=0; i<coin->bundlescount; i++)
if ( (bp= coin->bundles[i]) != 0 )
iguana_bundlepurge(coin,bp);
coin->current = coin->lastpending = 0;
memset(coin->bundles,0,sizeof(coin->bundles));
iguana_blockspurge(coin);
}
struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags)
{
FILE *fp; char fname[512],*symbol; int32_t iter;
@ -331,8 +415,9 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei
initialheight = coin->chain->bundlesize*10;
iguana_recvalloc(coin,initialheight);
coin->longestchain = 1;
memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain));
coin->blocks.hwmchain.height = 0;
if ( (coin->myservices & NODE_NETWORK) != 0 )
if ( (coin->myservices & NODE_NETWORK) != 0 && coin->peers.acceptloop == 0 )
{
printf("MYSERVICES.%llx\n",(long long)coin->myservices);
coin->peers.acceptloop = malloc(sizeof(pthread_t));
@ -343,7 +428,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei
printf("error launching accept thread for port.%u\n",coin->chain->portp2p);
}
}
coin->firstblock = coin->blocks.parsedblocks + 1;
//coin->firstblock = coin->blocks.parsedblocks + 1;
iguana_genesis(coin,coin->chain);
for (iter=0; iter<2; iter++)
{
@ -360,6 +445,6 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei
#ifndef IGUANA_DEDICATED_THREADS
coin->peers.peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD);
#endif
printf("started.%s\n",coin->symbol);
printf("started.%s %p active.%d\n",coin->symbol,coin->started,coin->active);
return(coin);
}

10
iguana/iguana_json.c

@ -621,6 +621,16 @@ STRING_ARG(iguana,startcoin,activecoin)
} else return(clonestr("{\"error\":\"startcoin needs coin\"}"));
}
STRING_ARG(iguana,stopcoin,activecoin)
{
if ( coin != 0 )
{
coin->active = 0;
iguana_coinpurge(coin);
return(clonestr("{\"result\":\"coin stopped\"}"));
} else return(clonestr("{\"error\":\"stopcoin needs coin\"}"));
}
STRING_ARG(iguana,pausecoin,activecoin)
{
if ( coin != 0 )

80
iguana/iguana_ramchain.c

@ -212,50 +212,6 @@ void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block
block->RO.firstexternalind = ramchain->externalind;
}
struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi)
{
uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind; int32_t i,j;
struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_block *block;
*heightp = -1;
if ( lasthdrsi < 0 )
return(0);
for (i=lasthdrsi; i>=0; i--)
{
if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish > coin->startutc )
{
ramchain = &bp->ramchain;
if ( ramchain->H.data != 0 )
{
TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset);
T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset);
//printf("search bp.%p TXbits.%p T.%p %d %d\n",bp,TXbits,T,(int32_t)ramchain->H.data->TXoffset,(int32_t)ramchain->H.data->Toffset);
if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0)) > 0 )
{
//printf("found txidind.%d\n",txidind);
if ( bits256_cmp(txid,T[txidind].txid) == 0 )
{
for (j=0; j<bp->n; j++)
if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count )
break;
if ( j < bp->n )
{
*heightp = bp->bundleheight + j;
//printf("found height.%d\n",*heightp);
*tx = T[txidind];
return(tx);
}
for (j=0; j<bp->n; j++)
if ( (block= bp->blocks[j]) != 0 )
printf("(%d %d).%d ",block->RO.firsttxidind,block->RO.txn_count,txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count);
printf(" <- firsttxidind txidind.%d not in block range\n",txidind);
} else printf("mismatched sparse entry\n");
}
}
}
}
return(0);
}
int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks)
{
struct iguana_bundle *bp = 0; int32_t bundlei = -2; char str[65];
@ -1650,6 +1606,8 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain
}
for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidind<rdata->numtxids; ramchain->H.txidind++)
{
if ( coin->active == 0 )
return(-1);;
if ( 0 && ramchain->expanded == 0 && dest != 0 )
printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids);
tx = &T[ramchain->H.txidind];
@ -1665,6 +1623,8 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain
}
for (j=0; j<tx->numvouts; j++)
{
if ( coin->active == 0 )
return(-1);
fileid = 0;
scriptpos = 0;
scriptlen = 0;
@ -1744,6 +1704,8 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain
tx = &T[ramchain->H.txidind];
for (j=0; j<tx->numvins; j++)
{
if ( coin->active == 0 )
return(-1);
fileid = 0;
scriptpos = 0;
scriptlen = 0;
@ -1873,7 +1835,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru
{
origtxdata->block.issued = 0;
origtxdata->block.RO.recvlen = 0;
printf("ramchain data: error finding block\n");
char str[65]; printf("ramchain data: error finding block %s\n",bits256_str(str,origtxdata->block.RO.hash2));
return(-1);
}
}
@ -2004,7 +1966,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru
bp->numtxids += ramchain->H.data->numtxids;
bp->numunspents += ramchain->H.data->numunspents;
bp->numspends += ramchain->H.data->numspends;
bp->rawscriptspace += ramchain->H.data->scriptspace;
//bp->rawscriptspace += ramchain->H.data->scriptspace;
}
iguana_ramchain_free(coin,&R,1);
}
@ -2013,7 +1975,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru
bp->numtxids += ramchain->H.data->numtxids;
bp->numunspents += ramchain->H.data->numunspents;
bp->numspends += ramchain->H.data->numspends;
bp->rawscriptspace += ramchain->H.data->scriptspace;
//bp->rawscriptspace += ramchain->H.data->scriptspace;
}
if ( fpos >= 0 )
block->fpos = fpos, block->fpipbits = (uint32_t)addr->ipbits;
@ -2404,6 +2366,11 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
sigspace = pubkeyspace = 0;
for (bundlei=starti,numtxids=numunspents=scriptspace=numspends=0; bundlei<=endi; bundlei++)
{
if ( coin->active == 0 )
{
iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi);
return(-1);
}
if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || block != iguana_blockfind(coin,block->RO.hash2) || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 )
{
printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2));
@ -2460,6 +2427,11 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
iguana_ramchain_extras(coin,dest,&HASHMEM,0);
for (i=starti; i<=endi; i++)
{
if ( coin->active == 0 )
{
iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi);
return(-1);
}
if ( (block= bp->blocks[i]) != 0 && block == iguana_blockfind(coin,bp->hashes[i]) )
{
if ( bits256_nonz(block->RO.prev_block) == 0 && i > 0 )
@ -2482,6 +2454,8 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
dest->H.scriptoffset = 1;
for (bundlei=starti; bundlei<=endi; bundlei++)
{
if ( coin->active == 0 )
break;
if ( (block= bp->blocks[bundlei]) != 0 )
{
iguana_blocksetcounters(coin,block,dest);
@ -2497,7 +2471,8 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
bp->issued[bundlei] = 0;
block->issued = 0;
}
printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei);
if ( coin->active != 0 )
printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei);
break;
}
}
@ -2538,9 +2513,12 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
iguana_bundleload(coin,&newchain,bp,0);
newchain.A = 0;
}
iguana_ramchain_free(coin,dest,0);
bp->ramchain = newchain;
//printf("finished bundlesave.%d\n",bp->bundleheight);
if ( coin->active != 0 )
{
iguana_ramchain_free(coin,dest,0);
bp->ramchain = newchain;
}
//printf("finished bundlesave.%d retval.%d\n",bp->bundleheight,retval);
return(retval);
}

14
iguana/iguana_recv.c

@ -484,8 +484,8 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl
}
prevbp = 0, prevbundlei = -2;
iguana_bundlefind(coin,&prevbp,&prevbundlei,prevhash2);
if ( 0 && block->blockhashes != 0 )
fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei);
//if ( 0 && block->blockhashes != 0 )
// fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei);
if ( prevbp != 0 && prevbundlei >= 0 && (prevblock= iguana_blockfind(coin,prevhash2)) != 0 )
{
if ( prevbundlei < coin->chain->bundlesize )
@ -816,7 +816,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana
if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 )
prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1);
width = sqrt(coin->chain->bundlesize);
while ( prev != 0 && width-- > 0 )
while ( coin->active != 0 && prev != 0 && width-- > 0 )
{
if ( prev->mainchain != 0 )
break;
@ -961,7 +961,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin)
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1);
}*/
lflag = 1;
while ( lflag != 0 )
while ( coin->active != 0 && lflag != 0 )
{
lflag = 0;
hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize;
@ -1085,7 +1085,7 @@ int32_t iguana_processrecvQ(struct iguana_info *coin,int32_t *newhwmp) // single
{
int32_t flag = 0; struct iguana_bundlereq *req;
*newhwmp = 0;
while ( (req= queue_dequeue(&coin->recvQ,0)) != 0 )
while ( coin->active != 0 && (req= queue_dequeue(&coin->recvQ,0)) != 0 )
{
//fprintf(stderr,"%s recvQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n);
if ( req->type == 'B' ) // one block with all txdata
@ -1140,7 +1140,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin)
int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65];
if ( queue_size(&coin->hdrsQ) == 0 )
{
//if ( iguana_needhdrs(coin) > 0 )
if ( coin->active != 0 )
{
for (i=0; i<coin->bundlescount; i++)
{
@ -1177,8 +1177,6 @@ int32_t iguana_reqhdrs(struct iguana_info *coin)
return(n);
}
struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; };
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;

236
iguana/iguana_unspents.c

@ -88,6 +88,41 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t
return(0);
}
int32_t iguana_spentflag(struct iguana_info *coin,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height)
{
uint32_t numunspents; struct iguana_hhutxo *hhutxo; struct iguana_utxo utxo;
uint8_t ubuf[sizeof(uint32_t) + sizeof(int16_t)];
*spentheightp = 0;
numunspents = (ramchain == &coin->RTramchain) ? ramchain->H.unspentind : ramchain->H.data->numunspents;
memset(&utxo,0,sizeof(utxo));
if ( spent_unspentind != 0 && spent_unspentind < numunspents )
{
if ( (hhutxo= iguana_hhutxofind(coin,ubuf,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 )
utxo = hhutxo->u;
else if ( ramchain->Uextras != 0 )
utxo = ramchain->Uextras[spent_unspentind];
else
{
printf("null ramchain->Uextras unspentind.%u vs %u hdrs.%d\n",spent_unspentind,numunspents,spent_hdrsi);
return(-1);
}
}
else
{
printf("illegal unspentind.%u vs %u hdrs.%d\n",spent_unspentind,numunspents,spent_hdrsi);
return(-1);
}
if ( utxo.fromheight == 0 )
{
printf("illegal unspentind.%u vs %u hdrs.%d zero fromheight?\n",spent_unspentind,numunspents,spent_hdrsi);
return(-1);
}
*spentheightp = utxo.fromheight;
if ( height == 0 || utxo.fromheight < height )
return(utxo.spentflag);
else return(0);
}
int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight)
{
struct iguana_account *A2; struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo;
@ -121,59 +156,50 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc
return(-1);
}
struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi)
struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi)
{
uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS;
*balancep = 0;
*ramchainp = 0;
*lastunspentindp = 0;
for (i=firsti; i<coin->bundlescount&&i<=endi; i++)
uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind; int32_t i,j;
struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_block *block;
*heightp = -1;
if ( lasthdrsi < 0 )
return(0);
for (i=lasthdrsi; i>=0; i--)
{
if ( (bp= coin->bundles[i]) != 0 )
if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish > coin->startutc )
{
ramchain = &bp->ramchain;
ramchain = (bp->isRT != 0) ? &coin->RTramchain : &bp->ramchain;
if ( ramchain->H.data != 0 )
{
PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset);
P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset);
ACCTS = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Aoffset);
if ( (pkind= iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,0)) > 0 && pkind < ramchain->H.data->numpkinds )
TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset);
T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset);
//printf("search bp.%p TXbits.%p T.%p %d %d\n",bp,TXbits,T,(int32_t)ramchain->H.data->TXoffset,(int32_t)ramchain->H.data->Toffset);
if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0)) > 0 )
{
*ramchainp = ramchain;
*balancep = ACCTS[pkind].total;
*lastunspentindp = ACCTS[pkind].lastunspentind;
*p = P[pkind];
return(p);
} //else printf("not found pkind.%d vs num.%d\n",pkind,ramchain->H.data->numpkinds);
} else printf("%s.[%d] error null ramchain->H.data\n",coin->symbol,i);
//printf("found txidind.%d\n",txidind);
if ( bits256_cmp(txid,T[txidind].txid) == 0 )
{
for (j=0; j<bp->n; j++)
if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count )
break;
if ( j < bp->n )
{
*heightp = bp->bundleheight + j;
//printf("found height.%d\n",*heightp);
*tx = T[txidind];
return(tx);
}
for (j=0; j<bp->n; j++)
if ( (block= bp->blocks[j]) != 0 )
printf("(%d %d).%d ",block->RO.firsttxidind,block->RO.txn_count,txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count);
printf(" <- firsttxidind txidind.%d not in block range\n",txidind);
} else printf("mismatched sparse entry\n");
}
}
}
}
return(0);
}
char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi)
{
uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; cJSON *retjson; char rmdstr[41];
if ( (bp= coin->bundles[hdrsi]) != 0 )
{
ramchain = &bp->ramchain;
if ( ramchain->H.data != 0 )
{
retjson = cJSON_CreateArray();
PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset);
P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset);
for (pkind=0; pkind<ramchain->H.data->numpkinds; pkind++,P++)
{
init_hexbytes_noT(rmdstr,P->rmd160,20);
jaddistr(retjson,rmdstr);
}
return(jprint(retjson,1));
}
//iguana_bundleQ(coin,bp,bp->n);
return(clonestr("{\"error\":\"no bundle data\"}"));
} return(clonestr("{\"error\":\"no bundle\"}"));
}
struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spend_hdrsi,struct iguana_spend *s)
{
int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65];
@ -249,10 +275,80 @@ cJSON *iguana_unspentjson(struct iguana_info *coin,int32_t hdrsi,uint32_t unspen
return(item);
}
int64_t iguana_pkhashbalance(struct iguana_info *coin,cJSON *array,int64_t *spentp,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi)
struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi)
{
struct iguana_unspent *U; uint32_t unspentind; int64_t balance = 0; struct iguana_txid *T;
uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS;
*balancep = 0;
*ramchainp = 0;
*lastunspentindp = 0;
for (i=firsti; i<coin->bundlescount&&i<=endi; i++)
{
if ( (bp= coin->bundles[i]) != 0 )
{
if ( bp->isRT != 0 && coin->RTramchain_busy != 0 )
{
printf("iguana_pkhashfind: unexpected access when RTramchain_busy\n");
return(0);
}
ramchain = (bp->isRT != 0) ? &bp->ramchain : &coin->RTramchain;
if ( ramchain->H.data != 0 )
{
numpkinds = (bp->isRT != 0) ? ramchain->H.data->numpkinds : ramchain->pkind;
PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset);
P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset);
ACCTS = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Aoffset);
if ( (pkind= iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,0)) > 0 && pkind < numpkinds )
{
*ramchainp = ramchain;
*balancep = ACCTS[pkind].total;
*lastunspentindp = ACCTS[pkind].lastunspentind;
*p = P[pkind];
return(p);
} //else printf("not found pkind.%d vs num.%d\n",pkind,ramchain->H.data->numpkinds);
} else printf("%s.[%d] error null ramchain->H.data\n",coin->symbol,i);
}
}
return(0);
}
char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi)
{
uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; cJSON *retjson; char rmdstr[41];
if ( (bp= coin->bundles[hdrsi]) != 0 )
{
if ( bp->isRT != 0 && coin->RTramchain_busy != 0 )
{
printf("iguana_bundleaddrs: unexpected access when RTramchain_busy\n");
return(0);
}
ramchain = (bp->isRT != 0) ? &bp->ramchain : &coin->RTramchain;
if ( ramchain->H.data != 0 )
{
numpkinds = (bp->isRT != 0) ? ramchain->H.data->numpkinds : ramchain->pkind;
retjson = cJSON_CreateArray();
PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset);
P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset);
for (pkind=0; pkind<numpkinds; pkind++,P++)
{
init_hexbytes_noT(rmdstr,P->rmd160,20);
jaddistr(retjson,rmdstr);
}
return(jprint(retjson,1));
}
//iguana_bundleQ(coin,bp,bp->n);
return(clonestr("{\"error\":\"no bundle data\"}"));
} return(clonestr("{\"error\":\"no bundle\"}"));
}
int64_t iguana_pkhashbalance(struct iguana_info *coin,cJSON *array,int64_t *spentp,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi,int32_t height)
{
struct iguana_unspent *U; int32_t spentheight; uint32_t unspentind; int64_t balance = 0; struct iguana_txid *T;
*spentp = *nump = 0;
if ( ramchain == &coin->RTramchain && coin->RTramchain_busy != 0 )
{
printf("iguana_pkhashbalance: unexpected access when RTramchain_busy\n");
return(0);
}
if ( ramchain->Uextras == 0 )
{
printf("iguana_pkhashbalance: unexpected null spents\n");
@ -265,7 +361,7 @@ int64_t iguana_pkhashbalance(struct iguana_info *coin,cJSON *array,int64_t *spen
{
(*nump)++;
printf("%s u.%d %.8f\n",jprint(iguana_unspentjson(coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33),1),unspentind,dstr(U[unspentind].value));
if ( ramchain->Uextras[unspentind].spentflag == 0 )
if ( iguana_spentflag(coin,&spentheight,ramchain,hdrsi,unspentind,height) == 0 )
{
balance += U[unspentind].value;
if ( array != 0 )
@ -279,11 +375,16 @@ int64_t iguana_pkhashbalance(struct iguana_info *coin,cJSON *array,int64_t *spen
int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33)
{
int32_t i,n,m; int64_t spent,balance,netbalance,total; uint32_t lastunspentind; struct iguana_ramchain *ramchain;
if ( coin->RTramchain_busy != 0 )
{
printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n");
return(-1);
}
for (total=i=n=0; i<max && i<coin->bundlescount; i++)
{
if ( iguana_pkhashfind(coin,&ramchain,&balance,&lastunspentind,&P[n],rmd160,i,i) != 0 )
{
if ( (netbalance= iguana_pkhashbalance(coin,array,&spent,&m,ramchain,&P[n],lastunspentind,rmd160,coinaddr,pubkey33,i)) != balance-spent )
if ( (netbalance= iguana_pkhashbalance(coin,array,&spent,&m,ramchain,&P[n],lastunspentind,rmd160,coinaddr,pubkey33,i,0)) != balance-spent )
{
printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(balance),dstr(spent),dstr(balance)-dstr(spent));
}
@ -304,6 +405,11 @@ int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf
void iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds)
{
int64_t total,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,flag = 0; char coinaddr[64];
if ( coin->RTramchain_busy != 0 )
{
printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n");
return;
}
if ( rmdarray == 0 )
rmdarray = iguana_walletrmds(myinfo,coin,&numrmds), flag++;
addrtypes = &rmdarray[numrmds * 20], pubkeys = &rmdarray[numrmds * 21];
@ -321,27 +427,6 @@ void iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON
free(rmdarray);
}
uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti)
{
int32_t i,n,j=0; char *coinaddr; uint8_t *addrtypes,*rmdarray = 0;
*numrmdsp = 0;
if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
*numrmdsp = n - firsti;
rmdarray = calloc(1,(n-firsti) * 21);
addrtypes = &rmdarray[(n-firsti) * 20];
for (i=firsti; i<n; i++)
{
if ( (coinaddr= jstr(jitem(array,i),0)) != 0 )
{
bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr);
j++;
}
}
}
return(rmdarray);
}
int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp)
{
static uint64_t total,emitted;
@ -907,9 +992,10 @@ int32_t iguana_realtime_update(struct iguana_info *coin)
struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err,n,flag=0;
struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR;
long filesize; void *ptr; char str[65],fname[1024];
if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n )
if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n )//&& coin->blocks.hwmchain.height >= coin->longestchain-1 && coin->RTramchain.H.data->numblocks < bp->n )
{
iguana_RTramchainalloc(coin,bp);
bp->isRT = 1;
while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height)
{
dest = &coin->RTramchain;
@ -978,9 +1064,9 @@ int32_t iguana_realtime_update(struct iguana_info *coin)
}
}
}
if ( dest != 0 && flag != 0 )
n = 0;
if ( dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain )
{
n = 0;
while ( block != 0 )
{
if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 )
@ -998,8 +1084,9 @@ int32_t iguana_realtime_update(struct iguana_info *coin)
printf("RTgenesis verified\n");
coin->RTgenesis = (uint32_t)time(NULL);
}
printf(">>>> RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize);
}
if ( dest != 0 )
printf(">>>> RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize);
return(0);
}
@ -1120,9 +1207,10 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu
printf("error mapping bundle.[%d]\n",hdrsi);
}
char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash));
exit(-1);
coin->balanceswritten = iguana_volatileinit(coin);
iguana_RTramchainfree(coin);
iguana_coinpurge(coin);
//exit(-1);
//coin->balanceswritten = iguana_volatileinit(coin);
//iguana_RTramchainfree(coin);
return(coin->balanceswritten);
}

22
iguana/iguana_wallet.c

@ -15,6 +15,28 @@
#include "iguana777.h"
uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti)
{
int32_t i,n,j=0; char *coinaddr; uint8_t *addrtypes,*rmdarray = 0;
*numrmdsp = 0;
if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
*numrmdsp = n - firsti;
rmdarray = calloc(1,(n-firsti) * 21);
addrtypes = &rmdarray[(n-firsti) * 20];
for (i=firsti; i<n; i++)
{
if ( (coinaddr= jstr(jitem(array,i),0)) != 0 )
{
bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr);
j++;
}
}
}
return(rmdarray);
}
struct iguana_waccount *iguana_waccountcreate(struct iguana_info *coin,char *account)
{
struct iguana_waccount *waddr; int32_t len = (int32_t)strlen(account)+1;

31
iguana/main.c

@ -344,7 +344,7 @@ mksquashfs DB/BTC BTC.squash1M -b 1048576
void mainloop(struct supernet_info *myinfo)
{
int32_t i,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp;
int32_t i,j,flag; struct iguana_info *coin; struct iguana_block *block; struct iguana_helper *ptr; struct iguana_bundle *bp;
sleep(3);
printf("mainloop\n");
while ( 1 )
@ -353,18 +353,43 @@ void mainloop(struct supernet_info *myinfo)
if ( 1 )
{
for (i=0; i<IGUANA_MAXCOINS; i++)
if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 )
if ( (coin= Coins[i]) != 0 && coin->current != 0 )
{
if ( coin->started != 0 )
if ( coin->active != 0 && coin->started != 0 )
{
coin->RTramchain_busy = 1;
iguana_realtime_update(coin);
if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 )
{
flag++;
if ( ptr->coin != 0 && (bp= ptr->bp) != 0 )
{
iguana_balancecalc(ptr->coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1);
if ( coin->active == 0 )
{
printf("detected autopurge after account filecreation. restarting.%s\n",coin->symbol);
coin->active = 1;
}
}
myfree(ptr,ptr->allocsize);
}
if ( (bp= coin->current) != 0 && coin->stucktime != 0 && coin->isRT == 0 && coin->RTheight == 0 && (time(NULL) - coin->stucktime) > coin->MAXSTUCKTIME )
{
if ( bp->emitfinish == 0 && 0 )
{
printf("%s is stuck too long, purging files for %d\n",coin->symbol,bp->hdrsi);
iguana_bundlepurgefiles(coin,bp);
for (j=0; j<bp->n; j++)
if ( (block= bp->blocks[j]) != 0 )
{
block->fpipbits = 0;
block->RO.recvlen = 0;
block->fpos = -1;
}
sleep(5);
}
}
coin->RTramchain_busy = (coin->RTgenesis == 0 || queue_size(&balancesQ) != 0);
}
}
}

1
includes/iguana_apideclares.h

@ -137,6 +137,7 @@ STRING_ARG(iguana,getconnectioncount,activecoin);
STRING_ARG(iguana,addcoin,newcoin);
STRING_ARG(iguana,startcoin,activecoin);
STRING_ARG(iguana,pausecoin,activecoin);
STRING_ARG(iguana,stopcoin,activecoin);
TWO_STRINGS(iguana,addnode,activecoin,ipaddr);
TWO_STRINGS(iguana,persistent,activecoin,ipaddr);
TWO_STRINGS(iguana,removenode,activecoin,ipaddr);

Loading…
Cancel
Save