diff --git a/iguana/iguana777.c b/iguana/iguana777.c index be5dce6db..cf026643c 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -418,7 +418,7 @@ void iguana_coinloop(void *arg) now = (uint32_t)time(NULL); if ( coin->active != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+600 && coin->blocksrecv >= coin->longestchain-1 && coin->blocks.hwmchain.height >= coin->longestchain-1 ) + if ( coin->isRT == 0 && now > coin->startutc+600 && coin->blocksrecv >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) { fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); coin->isRT = 1; @@ -489,8 +489,9 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDBUNDLES : IGUANA_MAXPENDBUNDLES * 3; coin->myservices = services; sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); - sprintf(dirname,"vouts/%s",symbol), OS_ensure_directory(dirname); - sprintf(dirname,"vins/%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); + sprintf(dirname,"purgeable/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 77a7dd1cf..c2493b2fe 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -38,8 +38,8 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 #define _IGUANA_MAXPENDING 16 -#define IGUANA_MINPENDBUNDLES 128 -#define IGUANA_MAXPENDBUNDLES 64 +#define IGUANA_MINPENDBUNDLES 64 +#define IGUANA_MAXPENDBUNDLES 128 #define IGUANA_BUNDLELOOP 10000 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) @@ -371,10 +371,10 @@ struct iguana_ramchain_hdr struct iguana_ramchain { struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; - uint32_t numblocks:31,expanded:1,pkind,externalind,height; + uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; struct iguana_kvitem *txids,*pkhashes; - struct OS_memspace *hashmem; long filesize,sigsfilesize; void *fileptr,*sigsfileptr; - struct iguana_account *A,*creditsA; struct iguana_bundleind *spents; + struct OS_memspace *hashmem; long filesize,sigsfilesize; void *fileptr,*sigsfileptr,*Xspendptr; + struct iguana_account *A,*creditsA; struct iguana_bundleind *Xspendinds,*spents; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; }; diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index a486ade12..48599a202 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -954,11 +954,11 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) #endif addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); ipbits = (uint32_t)addr->ipbits; - sprintf(fname,"vouts/%s/%08x.vouts",coin->symbol,ipbits); + sprintf(fname,"DB/%s/vouts/%08x.vouts",coin->symbol,ipbits); if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->voutsfp,0,SEEK_END); else addr->voutsfp = fopen(fname,"wb+"); - sprintf(fname,"vins/%s/%08x.vins",coin->symbol,ipbits); + sprintf(fname,"purgeable/%s/%08x.vins",coin->symbol,ipbits); if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->vinsfp,0,SEEK_END); else addr->vinsfp = fopen(fname,"wb+"); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 2a2fa9149..4d1a076e6 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1242,7 +1242,18 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag if ( ramchain->hashmem != 0 ) iguana_mempurge(ramchain->hashmem), ramchain->hashmem = 0; if ( ramchain->filesize != 0 ) - munmap(ramchain->fileptr,ramchain->filesize), ramchain->fileptr = 0; + { + munmap(ramchain->fileptr,ramchain->filesize); + ramchain->fileptr = 0; + ramchain->filesize = 0; + } + if ( ramchain->Xspendptr != 0 ) + { + munmap(ramchain->Xspendptr,ramchain->filesize); + ramchain->Xspendptr = 0; + ramchain->numXspends = 0; + ramchain->Xspendinds = 0; + } if ( deleteflag != 0 ) memset(ramchain,0,sizeof(*ramchain)); return(0); @@ -1265,6 +1276,31 @@ void iguana_ramchain_extras(struct iguana_ramchain *ramchain,struct OS_memspace } } +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) +{ + int32_t hdrsi; bits256 sha256; char fname[1024]; void *ptr; long filesize; static bits256 zero; + if ( iguana_peerfname(coin,&hdrsi,"DB/utxo",fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + { + if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) + { + ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); + vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); + if ( memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) + { + ramchain->Xspendptr = ptr; + ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); + } + else + { + munmap(ptr,filesize); + ramchain->Xspendinds = 0; + } + } + } + return(ramchain->numXspends); +} + struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) { RAMCHAIN_DECLARE; int32_t valid,i,checki,hdrsi; @@ -1293,6 +1329,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); } + iguana_Xspendmap(coin,ramchain,bp); if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { // verify hashes @@ -1317,7 +1354,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname } ramchain->H.data = (void *)&blocksRO[bp->n];*/ for (valid=0,i=bp->n=1; i>=0; i--) - { + { if ( (block= bp->blocks[i]) != 0 ) { if ( memcmp(block->RO.hash2.bytes,bp->hashes[i].bytes,sizeof(block->RO.hash2)) == 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 4ab9d2722..e19760066 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -468,7 +468,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int char str[64]; queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } - else if ( time(NULL) > bp->lastspeculative+3600 || (bp->hdrsi == starti && time(NULL) > bp->lastspeculative+90) ) + else if ( bp->hdrsi == starti && time(NULL) > bp->lastspeculative+90 ) { for (i=1,counter=0; in && inumspec; i++) { @@ -494,15 +494,13 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int if ( bp->startutxo == 0 ) { bp->startutxo = (uint32_t)time(NULL); - if ( iguana_utxogen(coin,bp) < 0 ) + if ( iguana_utxogen(coin,bp) >= 0 ) { - printf("GENERATE UTXO ERROR ht.%d\n",bp->bundleheight); - exit(-1); - } - printf("GENERATED UTXO for ht.%d duration %d seconds\n",bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); - bp->utxofinish = (uint32_t)time(NULL); + 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 write error\n"); } - if ( bp->balancefinish == 0 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) ) + if ( bp->utxofinish != 0 && bp->balancefinish == 0 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) ) { starttime = (uint32_t)time(NULL); if ( iguana_balancegen(coin,bp) < 0 ) @@ -588,7 +586,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int // 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 ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES ) + if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES && (rand() % 1) == 0 ) coin->MAXBUNDLES--; else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES ) coin->MAXBUNDLES++; @@ -1353,7 +1351,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); flag++; char str[65]; - //if ( 1 && (rand() % 1000) == 0 ) + if ( 1 && (rand() % 1000) == 0 || bp == coin->current ) printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); } else if ( bp != 0 && bundlei < bp->n-1 && bits256_nonz(bp->hashes[bundlei+1]) > 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ead1926ab..e06b175e8 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -120,7 +120,6 @@ int32_t iguana_spentsinit(struct iguana_info *coin,struct iguana_bundleind *spen S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); max = ramchain->H.data->numunspents; n = ramchain->H.data->numspends; - //nextT = &T[1]; for (spendind=1,errs=0; spendindbundleheight); + int32_t spendind,n,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; + FILE *fp; char fname[1024],str[65]; int32_t hdrsi,retval = -1; bits256 zero,sha256; + struct iguana_spend *S,*s; struct iguana_bundleind *ptr; struct iguana_ramchain *ramchain; + ramchain = &bp->ramchain; + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + if ( (n= ramchain->H.data->numspends) < 1 ) + return(0); + if ( ramchain->Xspendinds != 0 ) + { + printf("iguana_utxogen: already have Xspendinds[%d]\n",ramchain->numXspends); + return(0); + } + printf("start UTXOGEN.%d max.%d\n",bp->bundleheight,n); + ptr = malloc(sizeof(*ptr) * n); + for (spendind=ramchain->H.data->firsti; spendindexternal != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_spent(coin,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) + { + ptr->ind = unspentind; + ptr->hdrsi = spentbp->hdrsi; + ptr++; + emit++; + //spentbp->ramchain.spents[unspentind].ind = spendind; + //spentbp->ramchain.spents[unspentind].hdrsi = bp->hdrsi; + if ( spentbp == bp ) + printf("unexpected spendbp: %p bp.[%d] U%d <- S%d.[%d] [%p %p %p]\n",&spentbp->ramchain.spents[unspentind],spentbp->hdrsi,unspentind,spendind,bp->hdrsi,coin->bundles[0],coin->bundles[1],coin->bundles[2]); + } else printf("unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + } + } + if ( emit != 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); + if ( iguana_peerfname(coin,&hdrsi,"DB/utxo",fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + { + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) + printf("error writing hash for %ld -> (%s)\n",sizeof(*ptr) * emit,fname); + else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) + printf("error writing %d of %d -> (%s)\n",emit,n,fname); + else retval = 0; + fclose(fp); + } + } else printf("error getting utxo fname\n"); + } + free(ptr); + printf("processed %d spendinds for bp.[%d] emitted.%d %s of %d\n",spendind,bp->hdrsi,emit,mbstr(str,sizeof(*ptr) * emit),n); return(0); } diff --git a/iguana/main.c b/iguana/main.c index 7b46097ec..c95ea3a31 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1102,9 +1102,8 @@ void iguana_main(void *arg) OS_ensure_directory("confs"); OS_ensure_directory("DB"), OS_ensure_directory("DB/ECB"); OS_ensure_directory("tmp"); + OS_ensure_directory("purgeable"); OS_ensure_directory(GLOBALTMPDIR); - OS_ensure_directory("vins"); - OS_ensure_directory("vouts"); iguana_coinadd("BTC",0); iguana_coinadd("BTCD",0); if ( (tmpstr= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0)) != 0 ) @@ -1131,7 +1130,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":1024,\"newcoin\":\"BTC\",\"active\":1,\"numhelpers\":1,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":1024,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1}"),0)) != 0 ) { free(str); if ( 0 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":1024,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1}"),0)) != 0 )