diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 657fbd888..763b5b1a7 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -97,7 +97,6 @@ void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) { //coin->blocks.ptrs = myrealloc('W',coin->blocks.ptrs,coin->blocks.ptrs==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.ptrs),numitems * sizeof(*coin->blocks.ptrs)); coin->blocks.RO = myrealloc('W',coin->blocks.RO,coin->blocks.RO==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.RO),numitems * sizeof(*coin->blocks.RO)); - coin->utxobits = myrealloc('u',coin->utxobits,coin->utxobits==0?0:coin->blocks.maxbits/8+1,numitems/8+1); printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); coin->blocks.maxbits = numitems; } @@ -396,6 +395,33 @@ void iguana_helper(void *arg) } } +void iguana_coinflush(struct iguana_info *coin) +{ + int32_t hdrsi; struct iguana_bundle *bp; char fname[1024],fname2[1024]; FILE *fp,*fp2=0; + for (hdrsi=0; hdrsibundlescount; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && time(NULL) > bp->dirty+60 && bp->ramchain.H.data != 0 && bp->ramchain.A != 0 && bp->ramchain.Uextras != 0 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); + sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + if ( fwrite(bp->ramchain.A,sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds,fp) == bp->ramchain.H.data->numpkinds ) + { + if ( fwrite(bp->ramchain.Uextras,sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents,fp2) == bp->ramchain.H.data->numunspents ) + { + bp->dirty = 0; + printf("saved (%s) and (%s)\n",fname,fname2); + } + } + fclose(fp), fclose(fp2); + } + else if ( fp != 0 ) + fclose(fp); + } + } +} + void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; @@ -467,10 +493,11 @@ void iguana_coinloop(void *arg) if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); } + iguana_coinflush(coin); } } if ( flag == 0 ) - usleep((coin->polltimeout+1) * 10); + usleep(10000); } } @@ -503,6 +530,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( (coin->MAXBUNDLES= maxbundles) <= 0 ) coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDBUNDLES : IGUANA_MAXPENDBUNDLES * 3; coin->myservices = services; + sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/utxo",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/vouts",symbol), OS_ensure_directory(dirname); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index aed6c55be..c1363fe45 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -417,7 +417,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; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty; 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; @@ -476,7 +476,7 @@ struct iguana_info uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime; 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; uint8_t *utxobits; + void *launched,*started; uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; @@ -713,7 +713,7 @@ void peggy(); int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); struct iguana_info *iguana_coinfind(const char *symbol); struct iguana_info *iguana_coinadd(const char *symbol,cJSON *json); -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delay); diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 5442be433..140d594b3 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -269,7 +269,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) lastbundle = hash2; if ( (block= iguana_blockfind(coin,hash2)) != 0 ) block->mainchain = 1, block->height = height; - if ( iguana_bundleload(coin,&bp->ramchain,bp) != 0 ) + if ( iguana_bundleload(coin,&bp->ramchain,bp,2) != 0 ) { bp->emitfinish = (uint32_t)time(NULL) + 1; //printf("LOADED bundle.%d\n",bp->bundleheight); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index af607e7ac..5722f4fb5 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1287,16 +1287,38 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag return(0); } -void iguana_ramchain_extras(struct iguana_ramchain *ramchain,struct OS_memspace *hashmem) +void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; + RAMCHAIN_DECLARE; char fname[1024]; long filesize; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); - else printf("alloc ramchain->A %ld\n",sizeof(struct iguana_account) * ramchain->H.data->numpkinds); - ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); + if ( extraflag == 0 ) + { + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); + else printf("alloc ramchain->A %ld\n",sizeof(struct iguana_account) * ramchain->H.data->numpkinds); + ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); + ramchain->Uextras = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents,1) : mycalloc('p',ramchain->H.data->numunspents,sizeof(*ramchain->Uextras)); + } + else + { + if ( extraflag == 2 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,ramchain->H.data->height); + ramchain->A = OS_filestr(&filesize,fname); + if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) + printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); + sprintf(fname,"accounts/%s/lastspends.%d",coin->symbol,ramchain->H.data->height); + ramchain->Uextras = OS_filestr(&filesize,fname); + if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) + printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); + } + if ( ramchain->A == 0 ) + ramchain->A = mycalloc('g',sizeof(*ramchain->A),ramchain->H.data->numpkinds); + if ( ramchain->Uextras == 0 ) + ramchain->Uextras = mycalloc('x',sizeof(*ramchain->Uextras),ramchain->H.data->numunspents); + } //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); @@ -1421,7 +1443,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname else if ( ramchain->expanded != 0 ) { if ( allocextras > 0 ) - iguana_ramchain_extras(ramchain,ramchain->hashmem); + iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras); } if ( B != 0 && bp != 0 ) { @@ -1867,7 +1889,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru } else { - iguana_ramchain_extras(&R,0); + iguana_ramchain_extras(coin,&R,0,0); if ( (err= iguana_ramchain_iterate(coin,0,&R,bp)) != 0 ) printf("err.%d iterate ",err); //printf("SUCCESS REMAP\n"); @@ -2076,7 +2098,7 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,1,1)) != 0 ) { iguana_ramchain_link(mapchain,firsthash2,lasthash2,hdrsi,height,0,numblocks,firsti,1); - iguana_ramchain_extras(mapchain,hashmem); + iguana_ramchain_extras(coin,mapchain,hashmem,0); //printf("expSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)mapchain->H.data->Koffset,mapchain->H.scriptoffset,mapchain->H.stacksize,(int32_t)mapchain->H.data->allocsize); if ( (err= iguana_ramchain_iterate(coin,0,mapchain,bp)) != 0 ) printf("err.%d iterate mapped dest\n",err); @@ -2100,13 +2122,13 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru return(retval); } -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) { static bits256 zero; struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; struct iguana_block *block; struct iguana_ramchain *mapchain; memset(ramchain,0,sizeof(*ramchain)); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,0,1)) != 0 ) + if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) { iguana_ramchain_link(mapchain,bp->hashes[0],bp->hashes[bp->n-1],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); @@ -2273,7 +2295,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str dest->expanded = 1; dest->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); + iguana_ramchain_extras(coin,dest,&HASHMEM,0); for (i=0; in; i++) { if ( (block= bp->blocks[i]) != 0 && block == iguana_blockfind(coin,bp->hashes[i]) ) @@ -2348,7 +2370,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str else printf("error removing.(%s)\n",fname); } sprintf(dirname,"%s/%s/%d",GLOBALTMPDIR,coin->symbol,bp->bundleheight), OS_portable_rmdir(dirname,1); - iguana_bundleload(coin,&newchain,bp); + iguana_bundleload(coin,&newchain,bp,1); } iguana_ramchain_free(dest,0); bp->ramchain = newchain; @@ -2408,7 +2430,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st depth++; iguana_ramchain_link(dest,A->H.data->firsthash2,B->H.data->lasthash2,A->H.hdrsi,A->height,0,A->numblocks+B->numblocks,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); + iguana_ramchain_extras(coin,dest,&HASHMEM,0); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = 0; if ( (err= iguana_ramchain_iterate(coin,dest,A,bp)) != 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 061c2a9ce..127b5cebd 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -393,13 +393,14 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) u = &spentU[unspentind]; if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) { - if ( 1 )//(spentbp->ramchain.Uextras[unspentind] & (1 << 31)) == 0 ) + if ( (spentbp->ramchain.Uextras[unspentind] & (1 << 31)) == 0 ) { - /*if ( spentbp->ramchain.Uextras[unspentind] == 0 ) + if ( spentbp->ramchain.Uextras[unspentind] == 0 ) spentbp->ramchain.Uextras[unspentind] |= A2[pkind].lastind; spentbp->ramchain.Uextras[unspentind] |= (1 << 31); A2[pkind].total += u->value; - A2[pkind].lastind = spendind;*/ + A2[pkind].lastind = spendind; + spentbp->dirty = (uint32_t)time(NULL); } else { diff --git a/iguana/main.c b/iguana/main.c index 0f6622b14..bcc637604 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1123,6 +1123,7 @@ void iguana_main(void *arg) } OS_ensure_directory("help"); OS_ensure_directory("confs"); + OS_ensure_directory("accounts"); OS_ensure_directory("DB"), OS_ensure_directory("DB/ECB"); OS_ensure_directory("tmp"); OS_ensure_directory("purgeable");