From ee026c8b70f37ea85769f359997788cd8ae08f2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 13:09:19 -0300 Subject: [PATCH 001/333] fix merge --- crypto777/bitcoind_RPC.c | 7 +++++-- crypto777/cJSON.c | 6 +++--- crypto777/inet.c | 6 ++---- iguana/iguana_bundles.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d1c878e13..2de139073 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -14,10 +14,13 @@ ******************************************************************************/ #include "OS_portable.h" -//#include "../includes/cJSON.h" - +#ifdef _WIN32 #include #include +#else +#include +#include +#endif // return data from the server #define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 0978af460..c7ce836c0 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -26,10 +26,10 @@ #include #include "../includes/cJSON.h" -//#define DEFINES_ONLY -//#include "../common/system777.c" -//#undef DEFINES_ONLY + +#ifndef DBL_EPSILON #define DBL_EPSILON 2.2204460492503131E-16 +#endif static const char *ep; diff --git a/crypto777/inet.c b/crypto777/inet.c index 2057f90d3..757389a49 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -19,12 +19,8 @@ #ifndef crypto777_inet_h #define crypto777_inet_h #include "OS_portable.h" -//#include #ifdef _WIN32 -//#include -//#include -//#include #define in6_addr sockaddr #define in_addr_t struct sockaddr_storage #define EAFNOSUPPORT WSAEAFNOSUPPORT @@ -37,7 +33,9 @@ struct sockaddr_in6 { u_long sin6_scope_id; }; #endif +#ifndef AF_INET6 #define AF_INET6 23 +#endif static int inet_ntop4(unsigned char *src, char *dst, size_t size); static int inet_ntop6(unsigned char *src, char *dst, size_t size); static int inet_pton4(char *src, unsigned char *dst); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 512df107e..b64b8183d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -622,7 +622,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 ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + if ( 0 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) { fseek(fp,0,SEEK_END); if ( block->RO.recvlen == 0 ) From 5c93c75a9b52be26068b620ffa3ded3f6485a540 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 13:09:48 -0300 Subject: [PATCH 002/333] test --- iguana/iguana777.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 692ccc81c..91cf49ae3 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 3 -#define IGUANA_MINPENDBUNDLES 4 -#define IGUANA_MAXPENDBUNDLES 16 +#define IGUANA_MINPENDBUNDLES 1 +#define IGUANA_MAXPENDBUNDLES 64 #define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) From 75d3d42eb05545cd0ff18189ddb4a3992bbac450 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 13:42:29 -0300 Subject: [PATCH 003/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b64b8183d..bbd21399f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -515,7 +515,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { //if ( (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) // iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); + iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag*10); printf("[%d:%d] ",bp->hdrsi,i); } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); flag++; From 36640c7452fdc75e395fce28926f288ec4ae51f1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 13:42:40 -0300 Subject: [PATCH 004/333] test --- iguana/iguana777.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 91cf49ae3..703319fa4 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -39,7 +39,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_MAXPENDHDRS 1 #define _IGUANA_MAXPENDING 3 #define IGUANA_MINPENDBUNDLES 1 -#define IGUANA_MAXPENDBUNDLES 64 +#define IGUANA_MAXPENDBUNDLES 1 #define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) From 8d6a7bfa7524e33bcb7201d7e8c7e4f6453b0bb5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 14:42:55 -0300 Subject: [PATCH 005/333] test --- iguana/iguana777.c | 12 ++++++++++-- iguana/iguana777.h | 4 ++-- iguana/iguana_bundles.c | 12 ++++++------ iguana/iguana_init.c | 1 - iguana/iguana_recv.c | 36 ++++++++++++++++++++++++++++++++---- iguana/main.c | 2 +- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 2e23b1e28..c64b2a51b 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -583,8 +583,6 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; if ( (coin->MAXPENDING= maxpending) <= 0 ) coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 64*_IGUANA_MAXPENDING; - if ( (coin->MAXBUNDLES= maxbundles) <= 0 ) - coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDBUNDLES : IGUANA_MAXPENDBUNDLES * 64; coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); @@ -596,6 +594,16 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; + if ( (coin->startPEND= juint(json,"startpend")) == 0 ) + coin->startPEND = IGUANA_MAXPENDBUNDLES; + else if ( coin->startPEND > 128 ) + coin->startPEND = 128; + coin->MAXBUNDLES = coin->startPEND; + if ( (coin->endPEND= juint(json,"endpend")) == 0 ) + coin->endPEND = IGUANA_MINPENDBUNDLES; + else if ( coin->endPEND > 128 ) + coin->endPEND = 128; + coin->enableCACHE = juint(json,"cache"); coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 703319fa4..5d25536e3 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -280,7 +280,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:12,mainchain:1,valid:1,queued:1,txvalid:1,peerid:8; - UT_hash_handle hh; bits256 *blockhashes; + UT_hash_handle hh; bits256 *blockhashes; struct iguana_bundlereq *req; };// __attribute__((packed)); @@ -451,7 +451,7 @@ 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; + int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE; uint32_t longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; struct tai starttime; double startmillis; struct iguana_chain *chain; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index bbd21399f..c3b747359 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -378,7 +378,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( coin->current != 0 ) starti = coin->current->hdrsi; else starti = 0; - priority = (bp->hdrsi < starti+8); + priority = 1;//(bp->hdrsi < starti+8); lag = (bp->hdrsi - starti); lag *= lag; if ( (i= sqrt(bp->hdrsi)) < 2 ) @@ -516,14 +516,14 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int //if ( (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) // iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag*10); - printf("[%d:%d] ",bp->hdrsi,i); + //printf("[%d:%d] ",bp->hdrsi,i); } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); flag++; } //else printf("%d ",now - block->issued); } } if ( flag != 0 && priority != 0 && laggard != 0 ) - printf("currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + printf("reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } } if ( bp == coin->current ) @@ -591,11 +591,11 @@ 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() % 2) == 0 ) + if ( (rand() % 3) == 0 ) { - if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES ) + if ( coin->MAXBUNDLES > coin->endPEND ) coin->MAXBUNDLES--; - else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES ) + else if ( coin->MAXBUNDLES < coin->endPEND ) coin->MAXBUNDLES++; } return(coin->MAXBUNDLES); diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 9cb31693f..f09122c07 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -359,7 +359,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 - coin->MAXBUNDLES = IGUANA_MAXPENDBUNDLES; printf("started.%s\n",coin->symbol); return(coin); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index b84613fb7..3fcf53a51 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -189,8 +189,10 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; - } //else printf("validated prev.%s\n",bits256_str(str,origtxdata->block.RO.prev_block)); - copyflag = 1 * (strcmp(coin->symbol,"BTC") != 0); + } + else if ( coin->enableCACHE != 0 ) + printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); + copyflag = coin->enableCACHE * (strcmp(coin->symbol,"BTC") != 0); bp = 0, bundlei = -2; if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { @@ -691,7 +693,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv); } - if ( bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp(coin->symbol,"BTC") != 0 ) + if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp(coin->symbol,"BTC") != 0 ) { printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); @@ -708,6 +710,23 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); return(0); } + else + { + if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) + { + if ( block != origblock ) + { + iguana_blockcopy(coin,block,origblock); + coin->numcached++; + if ( block->req == 0 ) + { + block->req = req; + req = 0; + } else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); + //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); + } else printf("got origblock.%s to cache\n",bits256_str(str,origblock->RO.hash2)); + } + } //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); @@ -1027,8 +1046,17 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle } if ( block != 0 ) { - if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && block->fpipbits != 0 && block->fpos >= 0 ) + if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && (block->fpipbits != 0 || block->req != 0 || block->queued != 0) ) + { + if ( block->fpipbits == 0 && block->queued == 0 && block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); + } return(0); + } height = block->height; } if ( bp != 0 && bp->emitfinish != 0 ) diff --git a/iguana/main.c b/iguana/main.c index 7e1c479cc..df3a52f1a 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTCD\",\"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\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":1024,\"endpend\":1024,\"cache\":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 ) From 2146ab850e3361d3eccf38d081d706f86db56e53 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 14:47:28 -0300 Subject: [PATCH 006/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index c64b2a51b..88924912b 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -486,7 +486,7 @@ void iguana_coinloop(void *arg) if ( (coin= coins[i]) != 0 && coin->started == 0 ) { iguana_coinstart(coin,coin->initialheight,coin->mapflags); - printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout); + 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; } From 3456cf730505e3731d135f34cbe5550b6e585cd2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 14:47:51 -0300 Subject: [PATCH 007/333] test --- iguana/iguana777.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 5d25536e3..a6eb0ae17 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 3 -#define IGUANA_MINPENDBUNDLES 1 -#define IGUANA_MAXPENDBUNDLES 1 +#define IGUANA_MINPENDBUNDLES 2 +#define IGUANA_MAXPENDBUNDLES 2 #define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) From 74f9ccc57c47e8e6d73aa34d9eec510b9169a50b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 14:59:39 -0300 Subject: [PATCH 008/333] test --- iguana/iguana777.c | 12 ++++++++---- iguana/iguana777.h | 2 +- iguana/main.c | 9 ++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 88924912b..63e14e332 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -596,13 +596,17 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->mapflags = mapflags; if ( (coin->startPEND= juint(json,"startpend")) == 0 ) coin->startPEND = IGUANA_MAXPENDBUNDLES; - else if ( coin->startPEND > 128 ) - coin->startPEND = 128; + else if ( coin->startPEND > 1024 ) + coin->startPEND = 1024; + else if ( coin->startPEND < 2 ) + coin->startPEND = 2; coin->MAXBUNDLES = coin->startPEND; if ( (coin->endPEND= juint(json,"endpend")) == 0 ) coin->endPEND = IGUANA_MINPENDBUNDLES; - else if ( coin->endPEND > 128 ) - coin->endPEND = 128; + else if ( coin->endPEND > 1024 ) + coin->endPEND = 1024; + else if ( coin->endPEND < 2 ) + coin->endPEND = 2; coin->enableCACHE = juint(json,"cache"); coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index a6eb0ae17..729c2758f 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -37,7 +37,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_HEADPERCENTAGE 0. #define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define _IGUANA_MAXPENDING 3 +#define _IGUANA_MAXPENDING 64 #define IGUANA_MINPENDBUNDLES 2 #define IGUANA_MAXPENDBUNDLES 2 #define IGUANA_BUNDLELOOP 77 diff --git a/iguana/main.c b/iguana/main.c index df3a52f1a..7e19f49fd 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1162,7 +1162,14 @@ void iguana_main(void *arg) } #endif if ( arg != 0 ) - SuperNET_JSON(&MYINFO,cJSON_Parse(arg),0); + { + cJSON *argjson; + if ( (argjson= cJSON_Parse(arg)) != 0 ) + { + SuperNET_JSON(&MYINFO,argjson,0); + free_json(argjson); + } + } mainloop(&MYINFO); } From eff641b4bea23b75f384c40119c3c3e4bdcba519 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 15:19:20 -0300 Subject: [PATCH 009/333] test --- iguana/iguana_recv.c | 41 ++++++++++++++++++++++------------------- iguana/main.c | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 3fcf53a51..a3ba8ab0c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -702,29 +702,32 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { block->RO.txn_count = req->numtx; //block->RO.recvlen = recvlen; - if ( req->copyflag != 0 && block->queued == 0 && bp != 0 ) + if ( req->copyflag != 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); - coin->numcached++; - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); - return(0); - } - else - { - if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) + if ( block->queued == 0 && bp != 0 ) { - if ( block != origblock ) + 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; + queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); + return(0); + } + else + { + if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) { - iguana_blockcopy(coin,block,origblock); - coin->numcached++; - if ( block->req == 0 ) + if ( block != origblock ) { - block->req = req; - req = 0; - } else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); - //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); - } else printf("got origblock.%s to cache\n",bits256_str(str,origblock->RO.hash2)); + iguana_blockcopy(coin,block,origblock); + coin->numcached++; + if ( block->req == 0 ) + { + block->req = req; + req = 0; + } else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); + //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); + } else printf("got origblock.%s to cache\n",bits256_str(str,origblock->RO.hash2)); + } } } //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); diff --git a/iguana/main.c b/iguana/main.c index 7e19f49fd..5db5cb16b 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":1024,\"endpend\":1024,\"cache\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2,\"cache\":0}"),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 ) From 78c2a293c8b59b51e503f6a97a6af8b704a5f2f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 15:22:04 -0300 Subject: [PATCH 010/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 5db5cb16b..0918f449c 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1168,7 +1168,7 @@ void iguana_main(void *arg) { SuperNET_JSON(&MYINFO,argjson,0); free_json(argjson); - } + } else printf("error parsing.(%s)\n",arg); } mainloop(&MYINFO); } From 876473e32318edb02a2e294084c58e01d4433caa Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 15:23:57 -0300 Subject: [PATCH 011/333] test --- iguana/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 0918f449c..266f0d0c4 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1166,9 +1166,10 @@ void iguana_main(void *arg) cJSON *argjson; if ( (argjson= cJSON_Parse(arg)) != 0 ) { + printf("call argv JSON\n"); SuperNET_JSON(&MYINFO,argjson,0); free_json(argjson); - } else printf("error parsing.(%s)\n",arg); + } else printf("error parsing.(%s)\n",(char *)arg); } mainloop(&MYINFO); } From 2b52416deb900e4597afbce4dd3a85fedc9f5c6d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 16:02:40 -0300 Subject: [PATCH 012/333] test --- iguana/iguana_bundles.c | 9 +++- iguana/iguana_recv.c | 107 ++++++++++++++++++++-------------------- iguana/main.c | 4 +- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c3b747359..98b8587e9 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -576,11 +576,18 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 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 ) + int32_t i; struct iguana_block *block; + if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } + else if ( bp->speculative != 0 ) + { + for (i=0; inumspec; i++) + if ( bits256_nonz(bp->speculative[i]) != 0 && ((block= iguana_blockfind(coin,bp->speculative[i])) == 0 || block->req == 0) ) + iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); + } return(counter); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index a3ba8ab0c..aa4c124db 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -192,7 +192,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } else if ( coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); - copyflag = coin->enableCACHE * (strcmp(coin->symbol,"BTC") != 0); + copyflag = coin->enableCACHE * (coin->enableCACHE != 0); bp = 0, bundlei = -2; if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { @@ -414,7 +414,7 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in if ( bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) { char str[65]; bits256_str(str,bp->hashes[0]); - //fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); + fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } /*else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) @@ -464,7 +464,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl } else if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,prevhash2); - if ( strcmp(coin->symbol,"BTC") != 0 ) + if ( coin->enableCACHE != 0 ) iguana_bundlespeculate(coin,bp,bundlei,hash2,1); } prevbp = 0, prevbundlei = -2; @@ -487,7 +487,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl //printf("bundlehash2add next %d\n",prevbundlei); iguana_bundlehash2add(coin,0,prevbp,prevbundlei+1,hash2); } - if ( strcmp(coin->symbol,"BTC") != 0 ) + if ( coin->enableCACHE != 0 ) iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); } } @@ -679,7 +679,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana break; } } - printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); + //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } if ( 0 && bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { @@ -693,7 +693,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv); } - if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp(coin->symbol,"BTC") != 0 ) + if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); @@ -847,7 +847,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) { if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) - next = block->hh.next, block->mainchain = 1; + next = block->hh.next; //, next/block->mainchain = 1; } if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) { @@ -879,55 +879,54 @@ int32_t iguana_reqblocks(struct iguana_info *coin) lflag++, flag++; //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); } - if ( strcmp(coin->symbol,"BTC") != 0 && queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + } + if ( 1 )//queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + { + /*double threshold,lag = OS_milliseconds() - coin->backstopmillis; + threshold = (10 + coin->longestchain - coin->blocksrecv); + if ( threshold < 1 ) + threshold = 1.; + if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) + threshold = (bp->avetime + coin->avetime) * .5; + else threshold = coin->avetime; + threshold *= 100. * sqrt(threshold) * .000777;*/ + double threshold,lag = OS_milliseconds() - coin->backstopmillis; + threshold = 1000; + if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) { - double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777; - if ( strcmp(coin->symbol,"BTC") != 0 ) - threshold = 1000; - else threshold = 10000; - if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) + coin->backstop = coin->blocks.hwmchain.height+1; + hash2 = iguana_blockhash(coin,coin->backstop); + bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( bp != 0 && bits256_nonz(hash2) == 0 ) { - coin->backstop = coin->blocks.hwmchain.height+1; - hash2 = iguana_blockhash(coin,coin->backstop); - bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( bp != 0 && bits256_nonz(hash2) == 0 ) - { - hash2 = bp->hashes[bundlei]; - if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) - hash2 = bp->speculative[bundlei]; - } - if ( bits256_nonz(hash2) > 0 ) - { - if ( bp != 0 && bits256_nonz(hash2) > 0 ) - { - coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,bp,bundlei,hash2,0); - flag++; - char str[65]; - if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) - 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 ) - { - printf("MAINCHAIN skip issue %d\n",bundlei+1); - iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); - } - else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) + hash2 = bp->hashes[bundlei]; + if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + hash2 = bp->speculative[bundlei]; + } + if ( bits256_nonz(hash2) > 0 ) + { + if ( bp != 0 && bits256_nonz(hash2) > 0 ) { + coin->backstopmillis = OS_milliseconds(); + iguana_blockQ("mainchain",coin,bp,bundlei,hash2,0); + flag++; char str[65]; - printf("MAINCHAIN gethdr %d\n",bp->bundleheight); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - bp->hdrtime = (uint32_t)time(NULL); - }*/ + if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + 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 ) + { + printf("MAINCHAIN skip issue %d\n",bundlei+1); + iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + } + else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) + { + char str[65]; + printf("MAINCHAIN gethdr %d\n",bp->bundleheight); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); } } } @@ -1000,7 +999,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) ) { - lag = 60; + lag = 10; if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) { //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); @@ -1180,7 +1179,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) char str[65]; if ( block != 0 ) block->numrequests++; - if ( 0 && priority != 0 ) + if ( 1 && priority != 0 ) printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); } diff --git a/iguana/main.c b/iguana/main.c index 266f0d0c4..96536b784 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTC\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2,\"cache\":0}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2,\"cache\":0}"),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 ) @@ -1166,7 +1166,7 @@ void iguana_main(void *arg) cJSON *argjson; if ( (argjson= cJSON_Parse(arg)) != 0 ) { - printf("call argv JSON\n"); + printf("call argv JSON.(%s)\n",(char *)arg); SuperNET_JSON(&MYINFO,argjson,0); free_json(argjson); } else printf("error parsing.(%s)\n",(char *)arg); From 64656f1887a3defbde4161b610f316541d139a30 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 16:32:21 -0300 Subject: [PATCH 013/333] test --- iguana/iguana777.c | 11 ++++++----- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 8 ++++++-- iguana/iguana_recv.c | 4 ++-- iguana/main.c | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 63e14e332..d3057f241 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -573,7 +573,7 @@ void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,i struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxpending,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mapflags; char dirname[512]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,mapflags; char dirname[512]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; coin = iguana_coinadd(symbol,json); coin->launched = launched; @@ -594,16 +594,17 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; + mult = (strcmp("BTC",coin->symbol) != 0) ? 64 : 1; if ( (coin->startPEND= juint(json,"startpend")) == 0 ) - coin->startPEND = IGUANA_MAXPENDBUNDLES; - else if ( coin->startPEND > 1024 ) + coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; + if ( coin->startPEND > 1024 ) coin->startPEND = 1024; else if ( coin->startPEND < 2 ) coin->startPEND = 2; coin->MAXBUNDLES = coin->startPEND; if ( (coin->endPEND= juint(json,"endpend")) == 0 ) - coin->endPEND = IGUANA_MINPENDBUNDLES; - else if ( coin->endPEND > 1024 ) + coin->endPEND = IGUANA_MINPENDBUNDLES * mult; + if ( coin->endPEND > 1024 ) coin->endPEND = 1024; else if ( coin->endPEND < 2 ) coin->endPEND = 2; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 729c2758f..a6eb0ae17 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -37,7 +37,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_HEADPERCENTAGE 0. #define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define _IGUANA_MAXPENDING 64 +#define _IGUANA_MAXPENDING 3 #define IGUANA_MINPENDBUNDLES 2 #define IGUANA_MAXPENDBUNDLES 2 #define IGUANA_BUNDLELOOP 77 diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 98b8587e9..d6f8210f0 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -576,7 +576,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 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); - int32_t i; struct iguana_block *block; + int32_t i; struct iguana_block *block; uint32_t now; if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; @@ -584,9 +584,13 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 } else if ( bp->speculative != 0 ) { + now = (uint32_t)time(NULL); for (i=0; inumspec; i++) - if ( bits256_nonz(bp->speculative[i]) != 0 && ((block= iguana_blockfind(coin,bp->speculative[i])) == 0 || block->req == 0) ) + if ( bits256_nonz(bp->speculative[i]) != 0 && bp->issued[i] > now+10 && ((block= iguana_blockfind(coin,bp->speculative[i])) == 0 || block->req == 0) ) + { + bp->issued[i] = now; iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); + } } return(counter); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index aa4c124db..f83589fdf 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -891,7 +891,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else threshold = coin->avetime; threshold *= 100. * sqrt(threshold) * .000777;*/ double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = 1000; + threshold = 300; if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) { coin->backstop = coin->blocks.hwmchain.height+1; @@ -909,7 +909,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( bp != 0 && bits256_nonz(hash2) > 0 ) { coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,bp,bundlei,hash2,0); + iguana_blockQ("mainchain",coin,0,-1,hash2,lag > 100 * threshold); flag++; char str[65]; if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) diff --git a/iguana/main.c b/iguana/main.c index 96536b784..a0feff418 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -44,7 +44,7 @@ static int32_t initflag; int32_t HDRnet,netBLOCKS; cJSON *API_json; #ifdef __linux__ -int32_t IGUANA_NUMHELPERS = 8; +int32_t IGUANA_NUMHELPERS = 16; #else int32_t IGUANA_NUMHELPERS = 4; #endif From 461fdabfbcbb760d46fcbf5ad5112118c62085f0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 16:37:26 -0300 Subject: [PATCH 014/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index f83589fdf..0f9a5a37b 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -190,7 +190,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else if ( coin->enableCACHE != 0 ) + else if ( 0 && coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE * (coin->enableCACHE != 0); bp = 0, bundlei = -2; From 2e63b2e3e4be460b1ec354de1299a043cf75be71 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 16:41:54 -0300 Subject: [PATCH 015/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d6f8210f0..c6e388d7b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -734,7 +734,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - //printf("ITERATE.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + printf("ITERATE.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 0f9a5a37b..753364f7d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -997,7 +997,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) ) + if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) && (bp->speculative == 0 || bp->numspec < bp->n) ) { lag = 10; if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) @@ -1179,7 +1179,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) char str[65]; if ( block != 0 ) block->numrequests++; - if ( 1 && priority != 0 ) + if ( 0 && priority != 0 ) printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); } From bb15d057461408af907d7f3cbb157ec6131e54bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:21:56 -0300 Subject: [PATCH 016/333] test --- iguana/iguana777.c | 21 ++++++---- iguana/iguana_bundles.c | 87 ++++++++++++++++++++++++++++++++-------- iguana/iguana_peers.c | 2 +- iguana/iguana_ramchain.c | 7 ++++ iguana/iguana_recv.c | 54 +++++++++++++++++++------ iguana/main.c | 2 +- 6 files changed, 135 insertions(+), 38 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index d3057f241..8f9fadbb4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -323,8 +323,6 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m { if ( (bp= ptr->bp) != 0 ) { - if ( time(NULL) > bp->nexttime ) - return(0); if ( 0 && ptr->type == 'M' ) { if ( (nextbp= ptr->nextbp) != 0 ) @@ -369,7 +367,7 @@ void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) void iguana_helper(void *arg) { FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t type,flag,idle=0; - struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; + struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) helpername = jstr(argjson,"name"); if ( helpername == 0 ) @@ -404,10 +402,15 @@ void iguana_helper(void *arg) else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { idle = 0; - if ( ptr->bp != 0 && ptr->coin != 0 ) - flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,ptr->bp,ptr->timelimit); - else printf("helper missing param? %p %p %u\n",ptr->coin,ptr->bp,ptr->timelimit); - myfree(ptr,ptr->allocsize); + if ( (bp= ptr->bp) != 0 && ptr->coin != 0 ) + { + if ( time(NULL) >= bp->nexttime ) + { + //printf("t.%lu vs next.%u\n",time(NULL),bp->nexttime); + flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); + myfree(ptr,ptr->allocsize); + } else queue_enqueue("requeue",&bundlesQ,&ptr->DL,0); + } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); flag++; } else @@ -608,7 +611,9 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->endPEND = 1024; else if ( coin->endPEND < 2 ) coin->endPEND = 2; - coin->enableCACHE = juint(json,"cache"); + if ( jobj(json,"cache") != 0 ) + coin->enableCACHE = juint(json,"cache"); + else coin->enableCACHE = mult != 0; coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c6e388d7b..3df80dc13 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -153,7 +153,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu bit = iguana_calcbloom(newhash2); if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) { - //printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); + // printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); iguana_bloomset(coin,&bp->bloom,0,bit); if ( 0 ) { @@ -220,6 +220,8 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo block->hdrsi = bp->hdrsi; block->bundlei = bundlei; bp->hashes[bundlei] = block->RO.hash2; + if ( bp->speculative != 0 && bundlei < bp->numspec ) + bp->speculative[bundlei] = bp->hashes[bundlei]; bp->blocks[bundlei] = block; otherbp = 0; if ( (otherbp= iguana_bundlefind(coin,&otherbp,&otherbundlei,hash2)) != 0 || (bundlei % (bundlesize-1)) == 0) @@ -566,7 +568,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) 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])); + } else printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); } return(ready); } @@ -576,21 +578,30 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 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); - int32_t i; struct iguana_block *block; uint32_t now; + int32_t i; uint32_t now; if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } - else if ( bp->speculative != 0 ) + if ( bp->speculative != 0 ) { now = (uint32_t)time(NULL); for (i=0; inumspec; i++) - if ( bits256_nonz(bp->speculative[i]) != 0 && bp->issued[i] > now+10 && ((block= iguana_blockfind(coin,bp->speculative[i])) == 0 || block->req == 0) ) + { + if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) { - bp->issued[i] = now; - iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); + if ( now > bp->issued[i]+10 ) + { + bp->issued[i] = now; + //printf("speculative.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); + } + break; } + else if ( bp->blocks[i] == 0 ) + break; + } } return(counter); } @@ -626,7 +637,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) { - if ( block == iguana_blockfind(coin,bp->hashes[bundlei]) ) + //if ( block == iguana_blockfind(coin,bp->hashes[bundlei]) ) { if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { @@ -670,13 +681,13 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) //block->issued = bp->issued[bundlei] = 0; }*/ } - else if ( 0 ) + /*else if ( 0 ) { bp->blocks[bundlei] = iguana_blockfind(coin,bp->hashes[bundlei]); bp->hashes[bundlei] = bp->blocks[bundlei]->RO.hash2; if ( (block= bp->blocks[bundlei]) != 0 ) block->fpipbits = block->queued = 0; - } + }*/ numhashes++; bp->checkedtmp++; } @@ -718,9 +729,9 @@ 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; - bp->nexttime = (uint32_t)time(NULL) + 1; if ( coin->started == 0 ) { + bp->nexttime = (uint32_t)time(NULL) + 1; iguana_bundleQ(coin,bp,1000); return(retval); } @@ -734,11 +745,13 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - printf("ITERATE.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + printf("ITERATE.%-4d now.%u numspec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d counter.%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + bp->nexttime = (uint32_t)(time(NULL) + (bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) { + //bp->nexttime -= 60; if ( bp->emitfinish > 1 ) { if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) @@ -809,8 +822,9 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) void iguana_bundlestats(struct iguana_info *coin,char *str) { static uint32_t lastdisp; - int32_t i,n,m,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; double *sortbuf; struct iguana_peer *addr; + int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; double *sortbuf; struct iguana_peer *addr; struct iguana_block *block,*prev; uint32_t now; + now = (uint32_t)time(NULL); dispflag = (rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; count = coin->bundlescount; @@ -819,6 +833,47 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) { if ( (bp= coin->bundles[i]) != 0 ) { + //if ( iguana_blockfind(coin,bp->hashes[0]) == 0 ) + // printf("UNEXPECTED null block for bundlehash.%d\n",bp->hdrsi); + if ( bp->numhashes < bp->n && bp->speculative != 0 ) + { + for (j=1; jnumspec&&jn; j++) + iguana_blockhashset(coin,-1,bp->speculative[j],1); + //char str[65],str2[65]; + for (j=1; jnumspec&&jn; j++) + { + if ( (block= bp->blocks[j]) == 0 ) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[j]); + else if ( bits256_nonz(bp->speculative[j]) != 0 ) + block = iguana_blockfind(coin,bp->speculative[j]); + } + else if ( bits256_nonz(block->RO.prev_block) != 0 && block->fpipbits != 0 ) + continue; + prev = bp->blocks[j-1]; + //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); + if ( block != 0 && prev != 0 && bp->blocks[j] == 0 ) + { + //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); + if ( block->fpipbits == 0 && block->queued == 0 ) + { + if ( block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + printf("submit cached [%d:%d]\n",bp->hdrsi,j); + } + else if ( now > block->issued+10 ) + { + block->issued = now; + iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); + } + } + } // else break; + } + } bp->rank = 0; estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); //bp->metric = bp->numhashes; @@ -902,8 +957,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) if ( (rand() % 100) == 0 ) myallocated(0,0); lastdisp = (uint32_t)time(NULL); - //if ( firstgap != 0 && firstgap->queued == 0 ) - // iguana_bundleQ(coin,firstgap,1000); + if ( firstgap != 0 && firstgap->queued == 0 ) + iguana_bundleQ(coin,firstgap,1000); } strcpy(coin->statusstr,str); coin->estsize = estsize; diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 4de289c0b..dcd510e01 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -992,7 +992,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++; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 7deaf1675..94328c7ca 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -253,8 +253,15 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, // printf("illegal ipbits.%d\n",ipbits), getchar(); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) { + int32_t i; + if ( (bp= coin->bundles[0]) != 0 && bp->speculative != 0 ) + for (i=0; i<100; i++) + printf("(%d %d %d).%d ",bits256_nonz(bp->hashes[i]),bits256_nonz(bp->speculative[i]),bits256_cmp(bp->hashes[i],bp->speculative[i]),bits256_cmp(hash2,bp->hashes[i])); + printf("iguana_peerfname error finding.(%s)\n",bits256_str(str,hash2)); if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) + { return(-2); + } else bundlei++; } hash2 = bp->hashes[0], *hdrsip = bp->hdrsi; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 753364f7d..eed374012 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -192,11 +192,12 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } else if ( 0 && coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); - copyflag = coin->enableCACHE * (coin->enableCACHE != 0); + copyflag = coin->enableCACHE; bp = 0, bundlei = -2; if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); + req->copyflag = 1; //printf("copy %p serialized[%d]\n",req,req->recvlen); memcpy(req->serialized,data,recvlen); } @@ -564,7 +565,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i,len; struct iguana_bundle *bp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; + int32_t bundlei,i,len; struct iguana_bundle *bp,*newbp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; if ( num < 2 ) @@ -588,13 +589,13 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct { init_hexbytes_noT(hashstr,blockhashes[coin->chain->bundlesize].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - bp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,blockhashes[coin->chain->bundlesize],zero,1); - if ( bp != 0 ) + newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,blockhashes[coin->chain->bundlesize],zero,1); + if ( newbp != 0 ) { char str2[65]; - printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,bp->hashes[0]),bits256_str(str2,blockhashes[coin->chain->bundlesize]),bp->bundleheight); - if ( bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); + printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,blockhashes[coin->chain->bundlesize]),newbp->bundleheight); + if ( newbp->queued == 0 ) + iguana_bundleQ(coin,newbp,1000); } } else if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) @@ -603,7 +604,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } 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); + printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); if ( bp->speculative != 0 ) myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); bp->speculative = blockhashes; @@ -660,6 +661,24 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock; char str[65]; if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) == 0 ) { + if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,origblock->RO.hash2)) != 0 ) + { + printf("got block [%d:%d]\n",bp->hdrsi,bundlei); + /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) + { + bundlei++; + iguana_bundlehash2add(coin,&tmpblock,bp,bundlei,block->RO.hash2); + if ( tmpblock == block ) + { + printf("[%d:%d] speculative block.%p\n",bp->hdrsi,bundlei,block); + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + block->mainchain = prev->mainchain; + } else printf("error adding speculative prev [%d:%d]\n",bp->hdrsi,bundlei); + }*/ + } for (i=coin->bundlescount-1; i>=0; i--) { //if ( coin->bundles[i] != 0 ) @@ -681,7 +700,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } - if ( 0 && bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; numrecv++; @@ -691,7 +710,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) numsaved++; } - fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv); + //fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); } if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { @@ -706,7 +725,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { if ( 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; queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); @@ -901,8 +920,19 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( bp != 0 && bits256_nonz(hash2) == 0 ) { hash2 = bp->hashes[bundlei]; - if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + /*if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + { hash2 = bp->speculative[bundlei]; + if ( bits256_nonz(hash2) > 0 ) + { + if ( (block= iguana_blockfind(coin,hash2)) != 0 && bits256_cmp(block->RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) + { + printf("speculative is next at %d\n",coin->backstop); + if ( _iguana_chainlink(coin,block) != 0 ) + lflag++, flag++, printf("NEWHWM.%d\n",coin->backstop); + } + } + }*/ } if ( bits256_nonz(hash2) > 0 ) { diff --git a/iguana/main.c b/iguana/main.c index a0feff418..e67ebfd36 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2,\"cache\":0}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2}"),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 ) From a10f343477148ebcbf52d1b1f2161f005877ff80 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:23:48 -0300 Subject: [PATCH 017/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 3df80dc13..d2de2ecf5 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -746,7 +746,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); printf("ITERATE.%-4d now.%u numspec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d counter.%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); - bp->nexttime = (uint32_t)(time(NULL) + (bp->hdrsi - starti) + 1); + bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) From e4fe2b064f65ff9d4ea71aab4db192d37f0d27e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:34:32 -0300 Subject: [PATCH 018/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 3 ++- iguana/main.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d2de2ecf5..49f4130e7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -745,7 +745,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - printf("ITERATE.%-4d now.%u numspec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d counter.%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES); bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index eed374012..ff49d86de 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -949,7 +949,8 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else if ( bp != 0 && bundlei < bp->n-1 && bits256_nonz(bp->hashes[bundlei+1]) > 0 ) { printf("MAINCHAIN skip issue %d\n",bundlei+1); - iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + if ( time(NULL) > bp->issued[bundlei+1]+10 ) + iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); } else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) { diff --git a/iguana/main.c b/iguana/main.c index e67ebfd36..b916fe074 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1,\"startpend\":2,\"endpend\":2}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"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 ) From 0a731d8437dbaaeab135f2207eb0e7d248083de5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:39:50 -0300 Subject: [PATCH 019/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 49f4130e7..4820c8ef9 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -745,7 +745,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES); + printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); From 14683fcbe63ed35e53e56608ca3bcf4bd2a429ea Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:41:45 -0300 Subject: [PATCH 020/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 4820c8ef9..1a9f5601b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -745,7 +745,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); + //printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); @@ -793,8 +793,8 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 0 && counter > 0 ) - printf("ITERATE.%d max.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,max,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + if ( 1 && counter > 0 ) + printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); } iguana_bundleQ(coin,bp,1000); return(retval); From df8f14772b926ef2a60dafa0743215c7ddcb7bae Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:49:31 -0300 Subject: [PATCH 021/333] test --- iguana/iguana_bundles.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 1a9f5601b..3c7c7d55f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -731,13 +731,14 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; if ( coin->started == 0 ) { - bp->nexttime = (uint32_t)time(NULL) + 1; + printf("%s not ready yet\n",coin->symbol); + bp->nexttime = (uint32_t)time(NULL) + 3; iguana_bundleQ(coin,bp,1000); return(retval); } if ( coin->current == 0 ) coin->current = coin->bundles[0]; - if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) + //if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) range = coin->MAXBUNDLES; currentbp = coin->current; lastbp = coin->lastpending; @@ -793,7 +794,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 1 && counter > 0 ) + if ( 0 && counter > 0 ) printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); } iguana_bundleQ(coin,bp,1000); From 69bb35ff3ff2aa018c134df7202a76c1160fdf99 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:53:10 -0300 Subject: [PATCH 022/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 3c7c7d55f..aeb3df35f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -380,7 +380,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( coin->current != 0 ) starti = coin->current->hdrsi; else starti = 0; - priority = 1;//(bp->hdrsi < starti+8); + priority = (bp->hdrsi < starti + coin->peers.numranked); lag = (bp->hdrsi - starti); lag *= lag; if ( (i= sqrt(bp->hdrsi)) < 2 ) @@ -746,7 +746,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - //printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); + printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); From bb38b2515ec7168f15461a928944c35f7e9730d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 21:59:46 -0300 Subject: [PATCH 023/333] test --- iguana/iguana777.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 8f9fadbb4..ded613295 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -405,12 +405,10 @@ void iguana_helper(void *arg) if ( (bp= ptr->bp) != 0 && ptr->coin != 0 ) { if ( time(NULL) >= bp->nexttime ) - { - //printf("t.%lu vs next.%u\n",time(NULL),bp->nexttime); flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); - myfree(ptr,ptr->allocsize); - } else queue_enqueue("requeue",&bundlesQ,&ptr->DL,0); + else iguana_bundleQ(ptr->coin,bp,1000); } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); + myfree(ptr,ptr->allocsize); flag++; } else From 11e3ff56f4ed23de0f8b1ca56c1ef4cb52e3d622 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:07:49 -0300 Subject: [PATCH 024/333] test --- iguana/iguana777.c | 2 +- iguana/iguana777.h | 5 +++-- iguana/iguana_bundles.c | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index ded613295..e5c9bcb20 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -399,7 +399,7 @@ void iguana_helper(void *arg) } myfree(ptr,ptr->allocsize); } - else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { idle = 0; if ( (bp= ptr->bp) != 0 && ptr->coin != 0 ) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index a6eb0ae17..ea8d62af5 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -395,7 +395,8 @@ struct iguana_peer struct OS_memspace RAWMEM,TXDATA,HASHMEM; struct iguana_ramchain ramchain; struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; - struct iguana_bundle *bp; FILE *voutsfp,*vinsfp; + //struct iguana_bundle *bp; + FILE *voutsfp,*vinsfp; #ifdef IGUANA_PEERALLOC struct OS_memspace *SEROUT[128]; #endif @@ -419,7 +420,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,nexttime,currenttime; - int32_t numhashes,numrecv,numsaved,numcached,rank,generrs,checkedtmp,currentflag; + int32_t numhashes,numrecv,numsaved,numcached,generrs,checkedtmp,currentflag; int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec; double avetime,threshold,metric; uint64_t datasize,estsize; struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; uint32_t issued[IGUANA_MAXBUNDLESIZE]; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index aeb3df35f..41cf00ab4 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -746,7 +746,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); + 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); bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); @@ -795,13 +795,13 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); if ( 0 && counter > 0 ) - printf("ITER.%-4d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->rank,(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); + 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); } iguana_bundleQ(coin,bp,1000); return(retval); } -static int _decreasing_double(const void *a,const void *b) +/*static int _decreasing_double(const void *a,const void *b) { #define double_a (*(double *)a) #define double_b (*(double *)b) @@ -818,18 +818,18 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) { qsort(buf,num,size,_decreasing_double); return(0); -} +}*/ void iguana_bundlestats(struct iguana_info *coin,char *str) { static uint32_t lastdisp; int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; double *sortbuf; struct iguana_peer *addr; struct iguana_block *block,*prev; uint32_t now; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; now = (uint32_t)time(NULL); dispflag = (rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; count = coin->bundlescount; - sortbuf = calloc(count,sizeof(*sortbuf)*2); + //sortbuf = calloc(count,sizeof(*sortbuf)*2); for (i=n=m=numv=pending=0; ibundles[i]) != 0 ) @@ -875,7 +875,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } // else break; } } - bp->rank = 0; + //bp->rank = 0; estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); //bp->metric = bp->numhashes; bp->metric = coin->bundlescount - bp->hdrsi; @@ -909,14 +909,14 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) if ( bp->emitfinish == 0 ) { spaceused += bp->estsize; - sortbuf[m*2] = bp->metric; - sortbuf[m*2 + 1] = i; + //sortbuf[m*2] = bp->metric; + //sortbuf[m*2 + 1] = i; m++; } } } } - if ( m > 0 ) + /*if ( m > 0 ) { revsortds(sortbuf,m,sizeof(*sortbuf)*2); for (i=0; inumremain = n; coin->blocksrecv = numrecv; char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); From d70b31e1c0585f0aa6d9b21b4541460e1eafb24e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:16:24 -0300 Subject: [PATCH 025/333] test --- iguana/iguana777.c | 4 ++-- iguana/main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index e5c9bcb20..2e91592f4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -402,9 +402,9 @@ void iguana_helper(void *arg) if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { idle = 0; - if ( (bp= ptr->bp) != 0 && ptr->coin != 0 ) + if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) { - if ( time(NULL) >= bp->nexttime ) + if ( coin->started != 0 && time(NULL) >= bp->nexttime ) flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); else iguana_bundleQ(ptr->coin,bp,1000); } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); diff --git a/iguana/main.c b/iguana/main.c index b916fe074..57d697dec 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,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\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":1024,\"endpend\":1024,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"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 ) From 9cdf08c8d9100c3a36e41712b74ce4c7ba715354 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:23:23 -0300 Subject: [PATCH 026/333] test --- iguana/iguana777.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 2e91592f4..0a2c55877 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -404,9 +404,9 @@ void iguana_helper(void *arg) idle = 0; if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) { - if ( coin->started != 0 && time(NULL) >= bp->nexttime ) + //if ( coin->started != 0 && time(NULL) >= bp->nexttime ) flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); - else iguana_bundleQ(ptr->coin,bp,1000); + //else iguana_bundleQ(ptr->coin,bp,1000); } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); myfree(ptr,ptr->allocsize); flag++; From 092962ec4e301f6c7c0987aa57a8b9776bd6ea87 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:25:21 -0300 Subject: [PATCH 027/333] test --- iguana/iguana777.c | 4 ++-- iguana/iguana_bundles.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 0a2c55877..2e91592f4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -404,9 +404,9 @@ void iguana_helper(void *arg) idle = 0; if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) { - //if ( coin->started != 0 && time(NULL) >= bp->nexttime ) + if ( coin->started != 0 && time(NULL) >= bp->nexttime ) flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); - //else iguana_bundleQ(ptr->coin,bp,1000); + else iguana_bundleQ(ptr->coin,bp,1000); } else printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); myfree(ptr,ptr->allocsize); flag++; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 41cf00ab4..75376d838 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -738,7 +738,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru } if ( coin->current == 0 ) coin->current = coin->bundles[0]; - //if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) + if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) range = coin->MAXBUNDLES; currentbp = coin->current; lastbp = coin->lastpending; From d6a8e3b1b2c1fcdaf8ac0e4d7f613e4555c8df78 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:28:35 -0300 Subject: [PATCH 028/333] test --- crypto777/iguana_OS.c | 1 + iguana/iguana_bundles.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index e2ec357d2..63d41127c 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -234,6 +234,7 @@ void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t printf("FATAL type error: queueing empty value\n");//, getchar(); return; } + fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); lock_queue(queue); item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); DL_APPEND(queue->list,item); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 75376d838..41cf00ab4 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -738,7 +738,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru } if ( coin->current == 0 ) coin->current = coin->bundles[0]; - if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) + //if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) range = coin->MAXBUNDLES; currentbp = coin->current; lastbp = coin->lastpending; From eae9b60aec254b017cd1d728ffed08ba8174726d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:36:41 -0300 Subject: [PATCH 029/333] test --- crypto777/iguana_OS.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 63d41127c..bf9048c59 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -234,7 +234,7 @@ void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t printf("FATAL type error: queueing empty value\n");//, getchar(); return; } - fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); + //fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); lock_queue(queue); item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); DL_APPEND(queue->list,item); From 3a811672fc97f5d469dc862db2684d42e5e32531 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 22:51:16 -0300 Subject: [PATCH 030/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 41cf00ab4..1f45a523b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -746,8 +746,8 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - 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); - bp->nexttime = (uint32_t)(time(NULL) + 3);//(bp->hdrsi - starti) + 1); + //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); + bp->nexttime = (uint32_t)(time(NULL) + 1*0);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) From aae9849104f851cac6ba954c6975563cf4107fb6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 23:24:06 -0300 Subject: [PATCH 031/333] test --- iguana/iguana_bundles.c | 11 ++++++----- iguana/iguana_recv.c | 4 ++-- iguana/main.c | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 1f45a523b..206d5b4e9 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -381,14 +381,15 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int starti = coin->current->hdrsi; else starti = 0; priority = (bp->hdrsi < starti + coin->peers.numranked); - lag = (bp->hdrsi - starti); + /*lag = (bp->hdrsi - starti); lag *= lag; if ( (i= sqrt(bp->hdrsi)) < 2 ) i = 2; if ( lag < i ) lag = i; else if ( lag > 10*i ) - lag = 10*i; + lag = 10*i;*/ + lag = 10; if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) { if ( bp->currentflag == 0 ) @@ -525,7 +526,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } } if ( flag != 0 && priority != 0 && laggard != 0 ) - printf("reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } } if ( bp == coin->current ) @@ -747,7 +748,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); //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); - bp->nexttime = (uint32_t)(time(NULL) + 1*0);//(bp->hdrsi - starti) + 1); + bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) @@ -794,7 +795,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 0 && counter > 0 ) + if ( 1 && 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); } iguana_bundleQ(coin,bp,1000); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index ff49d86de..300ceb342 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -743,7 +743,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { block->req = req; req = 0; - } else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); + } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); } else printf("got origblock.%s to cache\n",bits256_str(str,origblock->RO.hash2)); } @@ -1158,7 +1158,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( bp == 0 || z != 0 ) { - //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); + printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; diff --git a/iguana/main.c b/iguana/main.c index 57d697dec..f036d26c0 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":1024,\"endpend\":1024,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":1024,\"endpend\":1024,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"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 ) From 1c425c594b8a87c0be031818f494f55d0f3d00e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 20 Mar 2016 23:56:12 -0300 Subject: [PATCH 032/333] test --- iguana/iguana_blocks.c | 2 +- iguana/iguana_recv.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 4c00ce9e3..762e7b7df 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -359,7 +359,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; bp->blocks[block->height % coin->chain->bundlesize] = block; } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 ) + if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 && block->height > coin->longestchain-coin->chain->bundlesize*2 ) { //printf("savehdrs\n"); iguana_savehdrs(coin); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 300ceb342..12d3409bc 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1030,7 +1030,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) && (bp->speculative == 0 || bp->numspec < bp->n) ) { - lag = 10; + lag = 30; if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) { //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); @@ -1158,7 +1158,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( bp == 0 || z != 0 ) { - printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); + //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; From 9f6d0ea19588861efa69b1eb7cbc75395762455a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 00:07:51 -0300 Subject: [PATCH 033/333] test --- iguana/iguana_recv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 12d3409bc..681d1dceb 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -948,9 +948,11 @@ int32_t iguana_reqblocks(struct iguana_info *coin) } else if ( bp != 0 && bundlei < bp->n-1 && bits256_nonz(bp->hashes[bundlei+1]) > 0 ) { - printf("MAINCHAIN skip issue %d\n",bundlei+1); if ( time(NULL) > bp->issued[bundlei+1]+10 ) + { + printf("MAINCHAIN skip issue %d\n",bundlei+1); iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + } } else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) { From a6f07612b93f34f985d63e59a504c0cb77d76839 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 00:32:58 -0300 Subject: [PATCH 034/333] test --- iguana/iguana_init.c | 2 +- iguana/iguana_recv.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index f09122c07..1792cf3fa 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -43,7 +43,7 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t memset(addr,0,sizeof(*addr)); addr->ipbits = ipbits; addr->usock = -1; - expand_ipbits(addr->ipaddr,addr->ipbits); + expand_ipbits(addr->ipaddr,(uint32_t)addr->ipbits); //addr->pending = (uint32_t)time(NULL); strcpy(addr->symbol,coin->symbol); strcpy(addr->coinstr,coin->name); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 681d1dceb..559da8e05 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -415,7 +415,7 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in if ( bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) { char str[65]; bits256_str(str,bp->hashes[0]); - fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); + //fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } /*else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) @@ -574,7 +574,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - if ( num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) + if ( 0 && num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { @@ -649,7 +649,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhashes[1],1)) > 0 ) { iguana_send(coin,addr,serialized,len); - char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); + //char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); } } } else iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],0); // should be RT block @@ -700,7 +700,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } - if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; numrecv++; @@ -714,7 +714,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { - printf("reissue hdrs request for [%d]\n",bp->hdrsi); + //printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } if ( block != 0 ) From 0ddc4f7c5bf00f1b8ad1c7ec8d837050862062aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:14:45 -0300 Subject: [PATCH 035/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_recv.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 2e91592f4..53cc01efa 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -221,7 +221,7 @@ uint32_t iguana_updatemetrics(struct iguana_info *coin) { for (j=0; jpeers.numranked; j++) { - if ( i != 0 && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) + if ( i != j && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) break; } if ( j == coin->peers.numranked ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 559da8e05..f53541741 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -950,6 +950,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) { if ( time(NULL) > bp->issued[bundlei+1]+10 ) { + bp->issued[bundlei+1] = (uint32_t)time(NULL); printf("MAINCHAIN skip issue %d\n",bundlei+1); iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); } @@ -1040,7 +1041,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) { iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],0); @@ -1088,7 +1089,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle block->queued = 1; queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); block->req = 0; - char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); + //char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); } return(0); } From ef58e29c6e1edaa1910e6f6a571504fe54e3d49a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:16:14 -0300 Subject: [PATCH 036/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 206d5b4e9..e10b3b61b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -645,7 +645,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 ( 0 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + if ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) { fseek(fp,0,SEEK_END); if ( block->RO.recvlen == 0 ) From d3eae5cc3001490c4bc35493b01f1659cbe134b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:17:41 -0300 Subject: [PATCH 037/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index e10b3b61b..a747aeaba 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -645,7 +645,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 ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + /*if ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) { fseek(fp,0,SEEK_END); if ( block->RO.recvlen == 0 ) @@ -656,7 +656,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) //printf("[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); } fclose(fp); - } + }*/ bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) From be77c271c3faf368e98953673292e6b9e1a35ca6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:29:10 -0300 Subject: [PATCH 038/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a747aeaba..38fdd1e27 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -795,7 +795,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 1 && counter > 0 ) + if ( 1 && counter > 0 && bp->hdrsi == starti ) 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); } iguana_bundleQ(coin,bp,1000); From 7005e711a96724c0a5887e5c763c47ad80860d51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:41:28 -0300 Subject: [PATCH 039/333] test --- confs/BTCD_hdrs.txt | 255 ++++++++++++++++++++++++++++++++++++++++++- confs/BTCD_peers.txt | 45 -------- 2 files changed, 252 insertions(+), 48 deletions(-) mode change 100755 => 100644 confs/BTCD_hdrs.txt diff --git a/confs/BTCD_hdrs.txt b/confs/BTCD_hdrs.txt old mode 100755 new mode 100644 index f6fd2a2f9..482b1333d --- a/confs/BTCD_hdrs.txt +++ b/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -889011 +1013511 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 @@ -1776,5 +1776,254 @@ 887000 51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554 b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda 887500 576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f 888000 a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f 87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d -888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0167b781dbd255ab898ff8c21f10f5ae14b6c6182728eaf64570cb64026ccbe3 -889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 c2d745d450a820d6d8e4aa241606ecf0b855dff32f8ebc3e2435dafb51f81f73 +888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc +889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84 +889500 49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919 b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53 +890000 761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6 81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810 +890500 6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19 b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364 +891000 945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c +891500 118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b 90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d +892000 80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76 ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed +892500 887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4 46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949 +893000 8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5 5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e +893500 961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071 49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207 +894000 cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b 9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6 +894500 25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5 +895000 50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8 c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb +895500 944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d 21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c +896000 8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f +896500 c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287 36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2 +897000 6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c 387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f +897500 323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98 b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00 +898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 +898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a +899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 c2e16965e43b94444853f16cb48de52c406448aa65a2ccbad61163a18f2529f0 +900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 +900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 +901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 +901500 5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f 6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8 +902000 433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73 6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6 +902500 4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef 06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9 +903000 3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856 ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32 +903500 38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179 cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e +904000 56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467 +904500 62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6 004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21 +905000 02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023 0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341 +905500 013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122 +906000 3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448 bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474 +906500 0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2 79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7 +907000 6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da 9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f +907500 7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2 06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7 +908000 1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17 0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca +908500 c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320 b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4 +909000 340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4 50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc +909500 bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827 69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028 +910000 355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24 6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab +910500 cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e 6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04 +911000 0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6 649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46 +911500 6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435 b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119 +912000 c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48 ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc +912500 4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694 6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222 +913000 fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8 bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb +913500 928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76 49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7 +914000 7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e 6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715 +914500 8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869 5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd +915000 33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7 8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3 +915500 afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f 06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552 +916000 fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361 41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79 +916500 2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1 324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269 +917000 b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2 96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f +917500 624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081 +918000 eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8 121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6 +918500 e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148 3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca +919000 4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640 +919500 fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33 +920000 94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31 985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5 +920500 7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869 3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8 +921000 3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f +921500 fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6 +922000 7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a 9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a +922500 c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8 01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5 +923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 +923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 +924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 1a9d440004523707f292fd87bf077df59c59e3d39e7f799604765343197f722b +925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 +925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 +926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 +926500 eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1 13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12 +927000 6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28 3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c +927500 5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f 044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625 +928000 3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840 +928500 c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045 +929000 73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68 9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f +929500 90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d 43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5 +930000 993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029 5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7 +930500 53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5 b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5 +931000 310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648 e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba +931500 8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968 +932000 975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66 38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1 +932500 438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22 aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393 +933000 07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654 de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a +933500 bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319 ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188 +934000 f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e 74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b +934500 d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46 c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2 +935000 00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a 85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c +935500 bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192 99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f +936000 03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5 7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a +936500 36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b 53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1 +937000 665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c 801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015 +937500 89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930 +938000 69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36 1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda +938500 031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe 2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344 +939000 342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00 e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd +939500 250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520 b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344 +940000 1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44 +940500 37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834 257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7 +941000 6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3 8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3 +941500 e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c 7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43 +942000 08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09 94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90 +942500 e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4 0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1 +943000 dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb 66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e +943500 efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195 da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7 +944000 2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861 +944500 c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644 e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586 +945000 5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5 a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1 +945500 160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e 1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9 +946000 baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f 3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1 +946500 3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3 +947000 1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce 45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb +947500 b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2 17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51 +948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c +948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 +949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 989e6b9308da79b0b768c6216474a6d1700eb89a59771bec804e8caa61089dac +950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 +950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 +951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 +951500 3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb 9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772 +952000 f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5 336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e +952500 09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9 a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf +953000 613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd 5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600 +953500 f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f 3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd +954000 01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1 b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be +954500 c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683 e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f +955000 2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c 3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2 +955500 9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7 c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec +956000 769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3 69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945 +956500 ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee 727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473 +957000 1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd 3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea +957500 0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8 b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d +958000 05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b +958500 a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625 7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a +959000 ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e +959500 c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b 9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420 +960000 bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400 5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4 +960500 c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4 9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3 +961000 9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251 13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9 +961500 7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658 d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1 +962000 92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca 79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9 +962500 4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834 2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9 +963000 e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431 +963500 64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae 3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d +964000 59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f +964500 6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79 186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97 +965000 6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6 9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1 +965500 07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b 8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de +966000 46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f 4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c +966500 5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157 4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59 +967000 ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07 f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408 +967500 fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7 c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb +968000 9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47 3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381 +968500 0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4 75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6 +969000 f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11 caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2 +969500 b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6 003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15 +970000 391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812 9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27 +970500 caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad 293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101 +971000 ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c 718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5 +971500 dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e 6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916 +972000 099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a 2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018 +972500 eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626 b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d +973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d +973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 +974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d 67c8b4a9a90a48fbf8bd43f41d290fb38c4318f00d177b76472d176fa4960836 +975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 +975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 +976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 +976500 82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec 147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55 +977000 92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796 9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d +977500 bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1 8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e +978000 b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee +978500 6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca 6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f +979000 8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39 e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11 +979500 4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e 1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6 +980000 d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0 cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11 +980500 a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a 50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9 +981000 e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07 3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833 +981500 f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41 ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895 +982000 4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea 790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a +982500 77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670 2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e +983000 fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851 9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646 +983500 4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6 62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0 +984000 15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f 46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce +984500 bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2 +985000 215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95 f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494 +985500 aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2 0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a +986000 f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f 289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687 +986500 bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7 +987000 eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60 a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7 +987500 d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91 95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce +988000 8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71 +988500 7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5 +989000 464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab 3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05 +989500 29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae 6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe +990000 7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f 77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994 +990500 2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967 19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b +991000 13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71 +991500 d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf 7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92 +992000 86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16 b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282 +992500 e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46 4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d +993000 88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6 fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081 +993500 c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba 796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e +994000 d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5 4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e +994500 b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a +995000 e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4 86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179 +995500 a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749 +996000 f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9 b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b +996500 b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb +997000 caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641 670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389 +997500 8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26 302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c +998000 4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af 3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d +998500 9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9 d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df +999000 ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271 ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082 +999500 6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06 125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9 +1000000 0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37 acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074 +1000500 d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82 6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820 +1001000 895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26 688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab +1001500 5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57 5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070 +1002000 19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025 658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1 +1002500 6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1 4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d +1003000 e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33 f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11 +1003500 da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241 0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367 +1004000 764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39 2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5 +1004500 bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1 49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822 +1005000 98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18 a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d +1005500 0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314 37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c +1006000 db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee 2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8 +1006500 7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2 1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9 +1007000 98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650 a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c +1007500 037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54 f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22 +1008000 0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1 7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40 +1008500 903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4 be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51 +1009000 0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8 577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386 +1009500 e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955 5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195 +1010000 8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184 d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780 +1010500 f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021 015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5 +1011000 e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2 59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f +1011500 624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5 b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91 +1012000 1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981 308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237 +1012500 1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746 bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e +1013000 332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461 +1013500 0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b 90a3e76d69a0556ecfab5ab4ece1960353fe0040732065d2900167415b007ebe diff --git a/confs/BTCD_peers.txt b/confs/BTCD_peers.txt index 69592171a..380bfffc4 100755 --- a/confs/BTCD_peers.txt +++ b/confs/BTCD_peers.txt @@ -10,48 +10,3 @@ 67.212.70.88 94.102.50.69 50.179.58.158 -194.135.94.30 -109.236.85.42 -104.236.127.154 -68.45.147.145 -37.59.14.7 -78.47.115.250 -188.40.138.8 -62.75.143.120 -82.241.71.230 -217.23.6.2 -73.28.172.128 -45.55.149.34 -192.0.242.54 -81.181.155.53 -91.66.185.97 -85.25.217.233 -144.76.239.66 -95.80.9.112 -80.162.193.118 -173.65.129.85 -2.26.173.58 -78.14.250.69 -188.226.253.77 -58.107.67.39 -124.191.37.212 -176.226.137.238 -69.145.25.85 -24.168.14.28 -73.201.180.47 -76.188.171.53 -63.247.147.166 -121.108.241.247 -36.74.36.125 -106.186.119.171 -188.166.91.37 -223.134.228.208 -89.248.160.244 -178.33.209.212 -71.53.156.38 -88.198.10.165 -24.117.221.0 -74.14.104.57 -158.69.27.82 -110.174.129.213 -75.130.163.51 From 0eb042a88da1cf79ef1e3ee364ed767106599cce Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 01:58:28 -0300 Subject: [PATCH 040/333] test --- iguana/confs/BTCD_hdrs.txt | 255 ++++++++++++++++++++++++++++++++++++- iguana/iguana_recv.c | 2 +- iguana/main.c | 2 +- 3 files changed, 254 insertions(+), 5 deletions(-) mode change 100755 => 100644 iguana/confs/BTCD_hdrs.txt diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt old mode 100755 new mode 100644 index f6fd2a2f9..482b1333d --- a/iguana/confs/BTCD_hdrs.txt +++ b/iguana/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -889011 +1013511 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 @@ -1776,5 +1776,254 @@ 887000 51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554 b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda 887500 576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f 888000 a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f 87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d -888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0167b781dbd255ab898ff8c21f10f5ae14b6c6182728eaf64570cb64026ccbe3 -889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 c2d745d450a820d6d8e4aa241606ecf0b855dff32f8ebc3e2435dafb51f81f73 +888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc +889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84 +889500 49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919 b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53 +890000 761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6 81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810 +890500 6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19 b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364 +891000 945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c +891500 118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b 90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d +892000 80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76 ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed +892500 887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4 46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949 +893000 8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5 5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e +893500 961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071 49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207 +894000 cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b 9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6 +894500 25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5 +895000 50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8 c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb +895500 944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d 21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c +896000 8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f +896500 c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287 36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2 +897000 6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c 387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f +897500 323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98 b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00 +898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 +898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a +899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 c2e16965e43b94444853f16cb48de52c406448aa65a2ccbad61163a18f2529f0 +900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 +900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 +901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 +901500 5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f 6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8 +902000 433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73 6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6 +902500 4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef 06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9 +903000 3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856 ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32 +903500 38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179 cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e +904000 56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467 +904500 62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6 004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21 +905000 02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023 0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341 +905500 013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122 +906000 3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448 bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474 +906500 0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2 79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7 +907000 6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da 9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f +907500 7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2 06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7 +908000 1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17 0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca +908500 c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320 b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4 +909000 340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4 50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc +909500 bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827 69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028 +910000 355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24 6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab +910500 cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e 6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04 +911000 0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6 649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46 +911500 6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435 b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119 +912000 c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48 ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc +912500 4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694 6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222 +913000 fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8 bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb +913500 928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76 49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7 +914000 7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e 6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715 +914500 8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869 5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd +915000 33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7 8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3 +915500 afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f 06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552 +916000 fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361 41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79 +916500 2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1 324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269 +917000 b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2 96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f +917500 624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081 +918000 eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8 121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6 +918500 e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148 3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca +919000 4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640 +919500 fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33 +920000 94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31 985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5 +920500 7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869 3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8 +921000 3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f +921500 fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6 +922000 7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a 9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a +922500 c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8 01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5 +923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 +923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 +924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 1a9d440004523707f292fd87bf077df59c59e3d39e7f799604765343197f722b +925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 +925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 +926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 +926500 eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1 13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12 +927000 6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28 3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c +927500 5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f 044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625 +928000 3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840 +928500 c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045 +929000 73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68 9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f +929500 90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d 43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5 +930000 993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029 5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7 +930500 53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5 b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5 +931000 310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648 e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba +931500 8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968 +932000 975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66 38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1 +932500 438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22 aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393 +933000 07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654 de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a +933500 bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319 ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188 +934000 f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e 74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b +934500 d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46 c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2 +935000 00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a 85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c +935500 bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192 99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f +936000 03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5 7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a +936500 36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b 53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1 +937000 665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c 801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015 +937500 89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930 +938000 69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36 1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda +938500 031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe 2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344 +939000 342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00 e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd +939500 250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520 b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344 +940000 1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44 +940500 37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834 257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7 +941000 6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3 8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3 +941500 e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c 7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43 +942000 08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09 94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90 +942500 e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4 0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1 +943000 dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb 66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e +943500 efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195 da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7 +944000 2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861 +944500 c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644 e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586 +945000 5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5 a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1 +945500 160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e 1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9 +946000 baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f 3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1 +946500 3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3 +947000 1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce 45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb +947500 b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2 17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51 +948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c +948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 +949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 989e6b9308da79b0b768c6216474a6d1700eb89a59771bec804e8caa61089dac +950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 +950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 +951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 +951500 3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb 9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772 +952000 f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5 336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e +952500 09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9 a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf +953000 613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd 5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600 +953500 f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f 3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd +954000 01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1 b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be +954500 c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683 e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f +955000 2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c 3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2 +955500 9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7 c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec +956000 769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3 69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945 +956500 ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee 727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473 +957000 1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd 3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea +957500 0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8 b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d +958000 05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b +958500 a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625 7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a +959000 ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e +959500 c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b 9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420 +960000 bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400 5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4 +960500 c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4 9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3 +961000 9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251 13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9 +961500 7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658 d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1 +962000 92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca 79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9 +962500 4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834 2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9 +963000 e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431 +963500 64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae 3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d +964000 59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f +964500 6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79 186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97 +965000 6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6 9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1 +965500 07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b 8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de +966000 46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f 4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c +966500 5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157 4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59 +967000 ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07 f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408 +967500 fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7 c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb +968000 9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47 3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381 +968500 0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4 75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6 +969000 f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11 caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2 +969500 b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6 003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15 +970000 391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812 9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27 +970500 caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad 293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101 +971000 ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c 718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5 +971500 dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e 6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916 +972000 099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a 2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018 +972500 eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626 b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d +973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d +973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 +974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d 67c8b4a9a90a48fbf8bd43f41d290fb38c4318f00d177b76472d176fa4960836 +975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 +975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 +976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 +976500 82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec 147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55 +977000 92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796 9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d +977500 bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1 8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e +978000 b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee +978500 6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca 6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f +979000 8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39 e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11 +979500 4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e 1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6 +980000 d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0 cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11 +980500 a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a 50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9 +981000 e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07 3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833 +981500 f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41 ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895 +982000 4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea 790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a +982500 77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670 2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e +983000 fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851 9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646 +983500 4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6 62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0 +984000 15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f 46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce +984500 bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2 +985000 215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95 f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494 +985500 aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2 0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a +986000 f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f 289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687 +986500 bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7 +987000 eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60 a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7 +987500 d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91 95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce +988000 8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71 +988500 7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5 +989000 464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab 3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05 +989500 29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae 6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe +990000 7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f 77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994 +990500 2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967 19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b +991000 13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71 +991500 d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf 7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92 +992000 86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16 b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282 +992500 e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46 4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d +993000 88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6 fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081 +993500 c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba 796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e +994000 d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5 4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e +994500 b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a +995000 e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4 86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179 +995500 a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749 +996000 f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9 b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b +996500 b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb +997000 caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641 670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389 +997500 8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26 302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c +998000 4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af 3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d +998500 9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9 d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df +999000 ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271 ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082 +999500 6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06 125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9 +1000000 0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37 acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074 +1000500 d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82 6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820 +1001000 895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26 688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab +1001500 5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57 5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070 +1002000 19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025 658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1 +1002500 6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1 4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d +1003000 e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33 f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11 +1003500 da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241 0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367 +1004000 764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39 2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5 +1004500 bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1 49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822 +1005000 98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18 a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d +1005500 0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314 37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c +1006000 db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee 2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8 +1006500 7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2 1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9 +1007000 98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650 a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c +1007500 037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54 f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22 +1008000 0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1 7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40 +1008500 903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4 be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51 +1009000 0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8 577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386 +1009500 e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955 5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195 +1010000 8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184 d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780 +1010500 f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021 015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5 +1011000 e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2 59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f +1011500 624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5 b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91 +1012000 1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981 308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237 +1012500 1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746 bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e +1013000 332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461 +1013500 0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b 90a3e76d69a0556ecfab5ab4ece1960353fe0040732065d2900167415b007ebe diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index f53541741..8b3696b80 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -631,7 +631,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],0); iguana_blockQ("recvhash3",coin,bp,0,blockhashes[0],0); iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); - printf("matched bundle.%d\n",bp->bundleheight); + //printf("matched bundle.%d\n",bp->bundleheight); return(req); } else printf("unexpected mismatch??\n"); } diff --git a/iguana/main.c b/iguana/main.c index f036d26c0..21e13d08c 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":1024,\"endpend\":1024,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"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 ) From 6c984b615c25b880a703229bff05fcdfc9ddfd7e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 02:29:21 -0300 Subject: [PATCH 041/333] test --- iguana/iguana_bundles.c | 16 ++++++++++------ iguana/main.c | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 38fdd1e27..a1bfc9fec 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -389,7 +389,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int lag = i; else if ( lag > 10*i ) lag = 10*i;*/ - lag = 10; + if ( strcmp("BTC",coin->symbol) == 0 ) + lag = 10; + else lag = 3; if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) { if ( bp->currentflag == 0 ) @@ -516,10 +518,12 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int counter++; if ( priority != 0 ) { - //if ( (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - // iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag*10); - //printf("[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); + if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + { + printf("[%d:%d] ",bp->hdrsi,i); + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + } } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); flag++; } //else printf("%d ",now - block->issued); @@ -626,7 +630,7 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { - FILE *fp; int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; + int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; //FILE *fp; int64_t datasize; struct iguana_block *block; char fname[1024]; static bits256 zero; if ( bp->emitfinish > coin->startutc ) { diff --git a/iguana/main.c b/iguana/main.c index 21e13d08c..07f2443f0 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1117,7 +1117,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"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 ) From 7e7117508ca44042c504fc8c1cb554a2cc928bc5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 02:31:41 -0300 Subject: [PATCH 042/333] test --- crypto777/inet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crypto777/inet.c b/crypto777/inet.c index 757389a49..d9f216a9b 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -33,7 +33,10 @@ struct sockaddr_in6 { u_long sin6_scope_id; }; #endif -#ifndef AF_INET6 +#ifdef _WIN32 +#ifdef AF_INET6 +#undef AF_INET6 +#endif #define AF_INET6 23 #endif static int inet_ntop4(unsigned char *src, char *dst, size_t size); From 04efcd204b1ff54a3614e6f70e88badbdf717b95 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 15:27:31 -0300 Subject: [PATCH 043/333] test --- iguana/iguana_unspents.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 5fa71c192..cb4512f13 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -370,6 +370,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) u = 0; unspentind = 0; hdrsi = -1; + spentbp = 0; if ( s->external != 0 && s->prevout >= 0 ) { if ( emit >= ramchain->numXspends ) @@ -414,7 +415,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) } else continue; now = (uint32_t)time(NULL); - if ( unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { if ( spentbp->ramchain.Uextras == 0 ) { @@ -462,7 +463,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) else { errs++; - printf("iguana_balancegen: error with unspentind.%d vs max.%d\n",unspentind,spentbp->ramchain.H.data->numunspents); + printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); } } if ( numtxid != bp->ramchain.H.data->numtxids ) From 285ef2a6d9e76133338b0bb762d39caf441407bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 16:30:49 -0300 Subject: [PATCH 044/333] test --- iguana/iguana_bundles.c | 14 +++++++------- iguana/iguana_ramchain.c | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a1bfc9fec..c476612fd 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -532,9 +532,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( flag != 0 && priority != 0 && laggard != 0 ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } + if ( bp == coin->current ) + return(counter); } - if ( bp == coin->current ) - return(counter); for (i=0; in; i++) { if ( (block= bp->blocks[i]) != 0 ) @@ -604,8 +604,8 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 } break; } - else if ( bp->blocks[i] == 0 ) - break; + // else if ( bp->blocks[i] == 0 ) + // break; } } return(counter); @@ -642,7 +642,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) { - //if ( block == iguana_blockfind(coin,bp->hashes[bundlei]) ) + if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) { if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { @@ -661,7 +661,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } fclose(fp); }*/ - bp->blocks[bundlei] = block; + //bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) bp->minrequests = block->numrequests; @@ -685,7 +685,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) //block->fpos = -1; //block->issued = bp->issued[bundlei] = 0; }*/ - } + } else printf("bundlecalc: mismatched block vs hash [%d:%d]\n",bp->hdrsi,bundlei); /*else if ( 0 ) { bp->blocks[bundlei] = iguana_blockfind(coin,bp->hashes[bundlei]); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 94328c7ca..de5bc1b6a 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -249,6 +249,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, { struct iguana_bundle *bp = 0; int32_t bundlei = -2; char str[65]; *hdrsip = -1; ipbits = 0; + fname[0] = 0; //if ( ipbits == 0 ) // printf("illegal ipbits.%d\n",ipbits), getchar(); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) From 828bdfe41fb0a3f89985d4bb40481bf57b946e4e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 17:02:49 -0300 Subject: [PATCH 045/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_bundles.c | 13 ++++++++++++- iguana/iguana_recv.c | 12 ++++++------ iguana/main.c | 1 - 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 53cc01efa..cc0cc63b6 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -385,7 +385,7 @@ void iguana_helper(void *arg) MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) { - //iguana_jsonQ(); + //iguana_jsonQ(); cant do this here flag = 0; if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) { diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c476612fd..480648a1f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -180,7 +180,18 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu retval = 0; } else retval = (bundlei >= 0 && bundlei < coin->chain->bundlesize) ? 0 : 1; //printf("set [%d] <- %s\n",bundlei,bits256_str(str,newhash2)); - *orighash2p = newhash2; + if ( bits256_cmp(*orighash2p,newhash2) != 0 ) + { + *orighash2p = newhash2; + if ( bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) + { + printf("changing [%d:%d] -> %d < hwmheight %d\n",bp->hdrsi,bundlei,bp->bundleheight+bundlei,coin->blocks.hwmchain.height); + if ( bp->bundleheight+bundlei > 0 ) + { + printf("REORG %d blocks\n",coin->blocks.hwmchain.height - (bp->bundleheight+bundlei)); + } + } + } return(retval); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 8b3696b80..bf2ccae46 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -574,7 +574,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - if ( 0 && num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) + //if ( 0 && num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { @@ -663,7 +663,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,origblock->RO.hash2)) != 0 ) { - printf("got block [%d:%d]\n",bp->hdrsi,bundlei); + printf("iguana_recvblock got block [%d:%d]\n",bp->hdrsi,bundlei); /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) { bundlei++; @@ -688,7 +688,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana bp = coin->bundles[i]; bundlei = 1; iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); - printf("[%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); + printf("iguana_recvblock [%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); if ( block != 0 ) { bp->blocks[bundlei] = block; @@ -700,7 +700,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } - if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; numrecv++; @@ -710,7 +710,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) numsaved++; } - //fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); + fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); } if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { @@ -1213,7 +1213,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) char str[65]; if ( block != 0 ) block->numrequests++; - if ( 0 && priority != 0 ) + //if ( 0 && priority != 0 ) printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); } diff --git a/iguana/main.c b/iguana/main.c index 07f2443f0..63c30ddda 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -337,7 +337,6 @@ void mainloop(struct supernet_info *myinfo) if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 && coin->started != 0 ) { flag++; - //iguana_bundleissue(coin,bp,bp->n,100); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) From 236daf7577de745240bef72d8f9aa432f00d4cf8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 17:20:27 -0300 Subject: [PATCH 046/333] test --- iguana/iguana_bundles.c | 12 ++++++++---- iguana/iguana_recv.c | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 480648a1f..33ad67b47 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -557,7 +557,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int block->numrequests++; if ( bp == coin->current ) printf("[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); bp->issued[i] = block->issued = now; counter++; if ( --max <= 0 ) @@ -854,8 +854,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) // printf("UNEXPECTED null block for bundlehash.%d\n",bp->hdrsi); if ( bp->numhashes < bp->n && bp->speculative != 0 ) { - for (j=1; jnumspec&&jn; j++) - iguana_blockhashset(coin,-1,bp->speculative[j],1); + //for (j=1; jnumspec&&jn; j++) + // iguana_blockhashset(coin,-1,bp->speculative[j],1); //char str[65],str2[65]; for (j=1; jnumspec&&jn; j++) { @@ -864,7 +864,10 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) if ( bits256_nonz(bp->hashes[j]) != 0 ) block = iguana_blockfind(coin,bp->hashes[j]); else if ( bits256_nonz(bp->speculative[j]) != 0 ) - block = iguana_blockfind(coin,bp->speculative[j]); + { + if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) + block = iguana_blockhashset(coin,-1,bp->speculative[j],1); + } } else if ( bits256_nonz(block->RO.prev_block) != 0 && block->fpipbits != 0 ) continue; @@ -885,6 +888,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( now > block->issued+10 ) { block->issued = now; + printf("submit speculative [%d:%d]\n",bp->hdrsi,j); iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); } } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index bf2ccae46..722515fad 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -958,7 +958,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) { char str[65]; - printf("MAINCHAIN gethdr %d\n",bp->bundleheight); + printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); bp->hdrtime = (uint32_t)time(NULL); } @@ -1161,7 +1161,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( bp == 0 || z != 0 ) { - //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); + printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; From 29d510c09c6f4ca2fb9570074769e199be7838b6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 17:44:45 -0300 Subject: [PATCH 047/333] test --- iguana/iguana_recv.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 722515fad..d02c13eac 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -53,7 +53,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - if ( 0 && coin->current == bp ) + //if ( 0 && coin->current == bp ) printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); @@ -1202,20 +1202,19 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { hash2 = req->hash2; height = req->height; - block = 0; - if ( priority == 0 && (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && (block= bp->blocks[req->bundlei]) != 0 && (block->fpipbits != 0 || block->queued != 0) ) + if ( (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n ) + block = bp->blocks[req->bundlei]; + else block = 0; + if ( priority == 0 && bp != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && block != 0 && (block->fpipbits != 0 || block->queued != 0) ) { - if ( 1 && priority != 0 ) + //if ( 1 && priority != 0 ) printf("SKIP %p[%d] %d\n",bp,bp!=0?bp->bundleheight:-1,req->bundlei); } else { - char str[65]; if ( block != 0 ) block->numrequests++; - //if ( 0 && priority != 0 ) - printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); - iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); + iguana_sendblockreqPT(coin,addr,bp,req->bundlei,hash2,0); } flag++; myfree(req,sizeof(*req)); From 114f71f972fdca9858404efdefc739e847a02706 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 19:01:14 -0300 Subject: [PATCH 048/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 6 ++-- iguana/iguana_init.c | 3 +- iguana/iguana_ramchain.c | 2 +- iguana/iguana_recv.c | 71 +++++++++++++++++++++++++--------------- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index ea8d62af5..d62c273d5 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -279,7 +279,7 @@ struct iguana_block struct iguana_blockRO RO; double PoW; // NOT consensus safe, for estimation purposes only int32_t height; uint32_t fpipbits,numrequests,issued; long fpos; - uint16_t hdrsi,bundlei:12,mainchain:1,valid:1,queued:1,txvalid:1,peerid:8; + 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; };// __attribute__((packed)); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 33ad67b47..eb2fb5abc 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -405,6 +405,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int else lag = 3; if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) { + if ( numpeers > 0xff ) + numpeers = 0xff; // fit into 8 bitfield if ( bp->currentflag == 0 ) bp->currenttime = now; if ( bp->numhashes >= bp->n ) @@ -550,13 +552,13 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 || block->RO.recvlen == 0 ) + if ( block->fpipbits == 0 )//|| block->RO.recvlen == 0 ) { if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; if ( bp == coin->current ) - printf("[%d:%d] ",bp->hdrsi,i); + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); bp->issued[i] = block->issued = now; counter++; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 1792cf3fa..f7d5f6662 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -279,7 +279,8 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //printf("LOADED bundle.%d %p current %p\n",bp->bundleheight,bp,coin->current); //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) { - //bp->startutxo = (uint32_t)time(NULL); + if ( 1 ) + bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); iguana_bundleQ(coin,bp,1000); } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index de5bc1b6a..d872cf07b 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -258,9 +258,9 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, if ( (bp= coin->bundles[0]) != 0 && bp->speculative != 0 ) for (i=0; i<100; i++) printf("(%d %d %d).%d ",bits256_nonz(bp->hashes[i]),bits256_nonz(bp->speculative[i]),bits256_cmp(bp->hashes[i],bp->speculative[i]),bits256_cmp(hash2,bp->hashes[i])); - printf("iguana_peerfname error finding.(%s)\n",bits256_str(str,hash2)); if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) { + printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); } else bundlei++; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index d02c13eac..7328f3b0d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -238,7 +238,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i if ( iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) >= 0 ) { txdata->block.fpipbits = (uint32_t)addr->ipbits; - txdata->block.fpipbits = recvlen; + txdata->block.RO.recvlen = recvlen; txdata->block.fpos = 0; req->datalen = txdata->datalen; req->ipbits = txdata->block.fpipbits; @@ -256,7 +256,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } req->block = txdata->block; - //printf("recvlen.%d prev.(%s)\n",req->recvlen,bits256_str(str,txdata->block.RO.prev_block)); + printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); @@ -302,7 +302,9 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi } req = iguana_bundlereq(coin,addr,'S',0); req->hashes = blockhashes, req->n = n; - //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); + char str[65]; + if ( n > 1 ) + printf("bundlesQ blockhashes.%s [%d]\n",bits256_str(str,blockhashes[1]),n); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } @@ -565,7 +567,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i,len; struct iguana_bundle *bp,*newbp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; + int32_t bundlei,i,len; struct iguana_bundle *bp,*newbp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; struct iguana_block *block; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; if ( num < 2 ) @@ -574,7 +576,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - //if ( 0 && num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) + if ( num > 2 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { @@ -652,13 +654,25 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); } } - } else iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],0); // should be RT block + } + else + { + if ( (block= iguana_blockfind(coin,blockhashes[1])) == 0 ) + { + iguana_blockhashset(coin,-1,blockhashes[1],1); + if ( (block= iguana_blockfind(coin,blockhashes[1])) != 0 ) + { + block->newtx = 1; + iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],1); // should be RT block + } + } + } return(req); } struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) { - struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock; char str[65]; + struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock,*prev; char str[65]; if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) == 0 ) { if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,origblock->RO.hash2)) != 0 ) @@ -700,6 +714,9 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } + else + { + } if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; @@ -717,10 +734,21 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana //printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } - if ( block != 0 ) + if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) { - block->RO.txn_count = req->numtx; - //block->RO.recvlen = recvlen; + if ( block != origblock ) + iguana_blockcopy(coin,block,origblock); + if ( block->newtx != 0 ) + { + if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) + prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); + if ( prev != 0 && (bits256_nonz(prev->RO.prev_block) == 0 || prev->fpipbits == 0) ) + { + printf("auto prev newtx %s\n",bits256_str(str,prev->RO.prev_block)); + prev->newtx = 1; + iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); + } + } if ( req->copyflag != 0 ) { if ( block->queued == 0 && bp != 0 ) @@ -731,23 +759,11 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); return(0); } - else + else if ( block->req == 0 ) { - if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) - { - if ( block != origblock ) - { - iguana_blockcopy(coin,block,origblock); - coin->numcached++; - if ( block->req == 0 ) - { - block->req = req; - req = 0; - } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); - //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); - } else printf("got origblock.%s to cache\n",bits256_str(str,origblock->RO.hash2)); - } - } + block->req = req; + req = 0; + } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); } //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); @@ -756,6 +772,9 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) { + char str[65]; + if ( n > 0 ) + printf("got txids[%d] %s\n",n,bits256_str(str,txids[0])); return(req); } From d4cdbcdaec7526228e5f013efe68e5319b827343 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 19:21:23 -0300 Subject: [PATCH 049/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index eb2fb5abc..b19ad5491 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -875,7 +875,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) continue; prev = bp->blocks[j-1]; //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); - if ( block != 0 && prev != 0 && bp->blocks[j] == 0 ) + if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && { //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); if ( block->fpipbits == 0 && block->queued == 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 7328f3b0d..0f1642f81 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -607,11 +607,11 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); - if ( bp->speculative != 0 ) - myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); - bp->speculative = blockhashes; - bp->numspec = num; - req->hashes = 0; + if ( bp->speculative == 0 ) + bp->speculative = mycalloc('s',bp->n+1,sizeof(*bp->speculative)); + for (i=bp->numspec; in; i++) + bp->speculative[i] = blockhashes[i]; + bp->numspec = num <= bp->n+1 ? num : bp->n+1; //iguana_blockQ(coin,0,-1,blockhashes[2],1); } } @@ -714,8 +714,13 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); } - else + else if ( bp == coin->current && bp != 0 && block != 0 && bundlei >= 0 ) { + if ( bp->speculative != 0 && bp->numspec <= bundlei ) + { + bp->speculative[bundlei] = block->RO.hash2; + bp->numspec = bundlei+1; + } } if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { @@ -744,7 +749,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); if ( prev != 0 && (bits256_nonz(prev->RO.prev_block) == 0 || prev->fpipbits == 0) ) { - printf("auto prev newtx %s\n",bits256_str(str,prev->RO.prev_block)); + printf("auto prev newtx %s\n",bits256_str(str,prev->RO.hash2)); prev->newtx = 1; iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); } From 10392fe9c618f586283f8b27eef72be7c357d5fa Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 19:32:06 -0300 Subject: [PATCH 050/333] test --- iguana/iguana_blocks.c | 7 +++++-- iguana/iguana_recv.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 762e7b7df..d423a433e 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -356,8 +356,11 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl printf("ERROR: need to fix up bundle for height.%d\n",block->height); //getchar(); } - bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; - bp->blocks[block->height % coin->chain->bundlesize] = block; + iguana_bundlehash2add(coin,0,bp,block->height % coin->chain->bundlesize,block->RO.hash2); + /* bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; + if ( bp->speculative != 0 ) + bp->speculative[block->height % coin->chain->bundlesize] = block->RO.hash2; + bp->blocks[block->height % coin->chain->bundlesize] = block;*/ } if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 && block->height > coin->longestchain-coin->chain->bundlesize*2 ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 0f1642f81..88e425c2c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -303,7 +303,7 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi req = iguana_bundlereq(coin,addr,'S',0); req->hashes = blockhashes, req->n = n; char str[65]; - if ( n > 1 ) + if ( n > 2 ) printf("bundlesQ blockhashes.%s [%d]\n",bits256_str(str,blockhashes[1]),n); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } From 000ce16c6f1481422ff26747e59630a8bbd0d6ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 19:54:01 -0300 Subject: [PATCH 051/333] test --- iguana/iguana_bundles.c | 10 +++++----- iguana/iguana_ramchain.c | 8 ++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b19ad5491..47bbfc7ba 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -182,8 +182,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu //printf("set [%d] <- %s\n",bundlei,bits256_str(str,newhash2)); if ( bits256_cmp(*orighash2p,newhash2) != 0 ) { - *orighash2p = newhash2; - if ( bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) + if ( bits256_nonz(*orighash2p) != 0 && bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) { printf("changing [%d:%d] -> %d < hwmheight %d\n",bp->hdrsi,bundlei,bp->bundleheight+bundlei,coin->blocks.hwmchain.height); if ( bp->bundleheight+bundlei > 0 ) @@ -191,6 +190,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu printf("REORG %d blocks\n",coin->blocks.hwmchain.height - (bp->bundleheight+bundlei)); } } + *orighash2p = newhash2; } return(retval); } @@ -643,7 +643,7 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; //FILE *fp; + int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; FILE *fp; int64_t datasize; struct iguana_block *block; char fname[1024]; static bits256 zero; if ( bp->emitfinish > coin->startutc ) { @@ -662,7 +662,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 ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + if ( coin->current == bp && (fp= fopen(fname,"rb")) != 0 ) { fseek(fp,0,SEEK_END); if ( block->RO.recvlen == 0 ) @@ -673,7 +673,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) //printf("[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); } fclose(fp); - }*/ + } //bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d872cf07b..e883a224f 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -254,10 +254,6 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, // printf("illegal ipbits.%d\n",ipbits), getchar(); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) { - int32_t i; - if ( (bp= coin->bundles[0]) != 0 && bp->speculative != 0 ) - for (i=0; i<100; i++) - printf("(%d %d %d).%d ",bits256_nonz(bp->hashes[i]),bits256_nonz(bp->speculative[i]),bits256_cmp(bp->hashes[i],bp->speculative[i]),bits256_cmp(hash2,bp->hashes[i])); if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) { printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); @@ -269,7 +265,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, if ( numblocks == 1 ) { if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) - sprintf(fname,"%s/%s/%d/%s_%u.%d",dirname,coin->symbol,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits!=0?ipbits:*hdrsip,bundlei); + sprintf(fname,"%s/%s/%d/%s_%u.%d",dirname,coin->symbol,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits>1?ipbits:*hdrsip,bundlei); else { printf("no hash for [%d:%d]\n",bp->hdrsi,bundlei); @@ -277,7 +273,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, } } else if ( strcmp("DB",dirname) == 0 ) - sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits!=0?ipbits:*hdrsip); + sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); return(bundlei); From e88193ffcad71b8ef4f9af1705a6188865c078f9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 20:20:14 -0300 Subject: [PATCH 052/333] test --- iguana/iguana_bundles.c | 16 +++++++++++----- iguana/iguana_recv.c | 8 ++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 47bbfc7ba..c4afc0116 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -662,17 +662,23 @@ 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 && (fp= fopen(fname,"rb")) != 0 ) + if ( coin->current == bp ) { - fseek(fp,0,SEEK_END); - if ( block->RO.recvlen == 0 ) + if ( (fp= fopen(fname,"rb")) != 0 ) { + fseek(fp,0,SEEK_END); block->RO.recvlen = (uint32_t)ftell(fp); block->fpipbits = 1; block->fpos = 0; - //printf("[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + fclose(fp); + } + else + { + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = 0; } - fclose(fp); } //bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 88e425c2c..f2a2bba26 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -53,7 +53,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - //if ( 0 && coin->current == bp ) + if ( 0 && coin->current == bp ) printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); @@ -256,7 +256,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } req->block = txdata->block; - printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); + //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); @@ -982,7 +982,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) { char str[65]; - printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); + //printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); bp->hdrtime = (uint32_t)time(NULL); } @@ -1185,7 +1185,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( bp == 0 || z != 0 ) { - printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); + //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; From 5fd1b27d79e0c963803475d77599377183b6c262 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 20:39:11 -0300 Subject: [PATCH 053/333] test --- iguana/iguana_bundles.c | 4 ++-- iguana/iguana_init.c | 6 ++++-- iguana/iguana_ramchain.c | 2 +- iguana/iguana_recv.c | 4 ++-- iguana/main.c | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c4afc0116..5f2315767 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -891,12 +891,12 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) block->queued = 1; queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); block->req = 0; - printf("submit cached [%d:%d]\n",bp->hdrsi,j); + //printf("submit cached [%d:%d]\n",bp->hdrsi,j); } else if ( now > block->issued+10 ) { block->issued = now; - printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); } } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index f7d5f6662..32d6e7df9 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -313,9 +313,11 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( coin->bundles[i] == 0 ) break; printf("INIT bundles i.%d\n",i); - if ( i > 0 ) + if ( i == coin->bundlescount && i > 1 ) { - //iguana_spentsfile(coin,i); + bp = coin->bundles[coin->bundlescount - 2]; + bp->emitfinish = bp->startutxo = bp->utxofinish = bp->balancefinish = 0; + iguana_bundleQ(coin,bp,1000); } char buf[1024]; iguana_bundlestats(coin,buf); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index e883a224f..5927973e2 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2432,7 +2432,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { char dirname[1024]; //printf("delete %d files hdrs.%d retval.%d\n",num,bp->hdrsi,retval); - if ( bp_n == bp->n && bp->n == coin->chain->bundlesize ) + if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) { for (j=starti; j<=endi; j++) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index f2a2bba26..2ebe7d4e0 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -722,7 +722,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana bp->numspec = bundlei+1; } } - if ( 1 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; numrecv++; @@ -749,7 +749,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); if ( prev != 0 && (bits256_nonz(prev->RO.prev_block) == 0 || prev->fpipbits == 0) ) { - printf("auto prev newtx %s\n",bits256_str(str,prev->RO.hash2)); + //printf("auto prev newtx %s\n",bits256_str(str,prev->RO.hash2)); prev->newtx = 1; iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); } diff --git a/iguana/main.c b/iguana/main.c index 63c30ddda..9dfa09d63 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -353,7 +353,8 @@ void mainloop(struct supernet_info *myinfo) coin->pendbalances--; iguana_balancesQ(coin,bp); } - //iguana_coinflush(ptr->coin,0); + if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_coinflush(ptr->coin,1); } myfree(ptr,ptr->allocsize); } From aedc3a5ab0d0ba76986b6ed998896f78dedb4a16 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 20:41:05 -0300 Subject: [PATCH 054/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 2ebe7d4e0..fe59033b9 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -850,7 +850,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) _iguana_chainlink(coin,next); else if ( next->queued == 0 && next->fpipbits == 0 && (rand() % 100) == 0 ) { - printf("HWM next %d\n",coin->blocks.hwmchain.height+1); + //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); iguana_blockQ("reqblocks",coin,bp,bundlei,next->RO.hash2,0); } } From bfcb8aab04bb1fbedc9637bb1f034bb8af9382b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 21:21:34 -0300 Subject: [PATCH 055/333] test --- iguana/iguana_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 32d6e7df9..069bfe1b2 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -313,13 +313,13 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( coin->bundles[i] == 0 ) break; printf("INIT bundles i.%d\n",i); - if ( i == coin->bundlescount && i > 1 ) + if ( 0 && i == coin->bundlescount && i > 1 ) { bp = coin->bundles[coin->bundlescount - 2]; bp->emitfinish = bp->startutxo = bp->utxofinish = bp->balancefinish = 0; iguana_bundleQ(coin,bp,1000); } - char buf[1024]; + char buf[2048]; iguana_bundlestats(coin,buf); } } From 2029fba831c9fa661ef40c3c8b405522cb2d170b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 21:41:04 -0300 Subject: [PATCH 056/333] test --- iguana/iguana_bundles.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 5f2315767..925e21383 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -675,9 +675,10 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else { + printf("missing.(%s)\n",fname); block->RO.recvlen = 0; block->fpipbits = 0; - block->fpos = 0; + block->fpos = -1; } } //bp->blocks[bundlei] = block; From 618079aa1b0b643c1a8bc5f5a49a0dab69438520 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 22:16:28 -0300 Subject: [PATCH 057/333] test --- iguana/iguana_bundles.c | 41 ++++++++++++++++++++--------------------- iguana/iguana_recv.c | 2 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 925e21383..f1840a452 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -675,10 +675,11 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else { - printf("missing.(%s)\n",fname); + char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); block->RO.recvlen = 0; block->fpipbits = 0; block->fpos = -1; + iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); } } //bp->blocks[bundlei] = block; @@ -697,25 +698,20 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) numcached++; } } - /*else //if ( 0 ) - { - printf("cleared block?\n"); - //block->RO.recvlen = 0; - //block->fpipbits = 0; - //block->fpos = -1; - //block->issued = bp->issued[bundlei] = 0; - }*/ - } else printf("bundlecalc: mismatched block vs hash [%d:%d]\n",bp->hdrsi,bundlei); - /*else if ( 0 ) + } + else if ( bp == coin->current && time(NULL) > bp->issued[bundlei]+10 ) { - bp->blocks[bundlei] = iguana_blockfind(coin,bp->hashes[bundlei]); - bp->hashes[bundlei] = bp->blocks[bundlei]->RO.hash2; - if ( (block= bp->blocks[bundlei]) != 0 ) - block->fpipbits = block->queued = 0; - }*/ + iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],1); + bp->issued[bundlei] = (uint32_t)time(NULL); + } numhashes++; bp->checkedtmp++; } + else if ( bp == coin->current && bits256_nonz(bp->hashes[bundlei]) != 0 && time(NULL) > bp->issued[bundlei]+30 ) + { + iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); + } } bp->datasize = datasize; bp->numhashes = numhashes; @@ -763,8 +759,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru } if ( coin->current == 0 ) coin->current = coin->bundles[0]; - //if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) - range = coin->MAXBUNDLES; + range = coin->MAXBUNDLES; currentbp = coin->current; lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; @@ -821,6 +816,10 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); if ( 1 && counter > 0 && bp->hdrsi == starti ) 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 == coin->current ) + { + + } } iguana_bundleQ(coin,bp,1000); return(retval); @@ -933,7 +932,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) lastpending = bp; //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); } - if ( firstgap == 0 ) + if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) firstgap = bp; if ( bp->emitfinish == 0 ) { @@ -978,8 +977,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->numsaved = numsaved; coin->spaceused = spaceused; coin->numverified = numv; - char str4[65]; - sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:0,firstgap!=0?firstgap->hdrsi:0,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); + char str4[65],str5[65]; + sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:0,firstgap!=0?firstgap->hdrsi:0,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,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) > lastdisp+10 ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index fe59033b9..53d7e5b7b 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -256,7 +256,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } req->block = txdata->block; - //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); + printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); From 7e43f29b64f27b9eba2508598940f7d06acb0958 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 22:31:21 -0300 Subject: [PATCH 058/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index f1840a452..5ebbce4ff 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -814,7 +814,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( 1 && counter > 0 && bp->hdrsi == starti ) + if ( bp->hdrsi == starti ) 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 == coin->current ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 53d7e5b7b..33eb56cf6 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -37,12 +37,12 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { - //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); + printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); return(0); } if ( addr->msgcounts.verack == 0 ) { - //printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); + printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); return(-1); } lastreq2 = lastreq; @@ -53,7 +53,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - if ( 0 && coin->current == bp ) + //if ( 0 && coin->current == bp ) printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); @@ -641,9 +641,9 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } //printf("no match to allhashes issue block1\n"); struct iguana_block *block; - if ( num == coin->chain->bundlesize+1 && (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) + if ( (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) { - block->blockhashes = blockhashes, req->hashes = 0; + //block->blockhashes = blockhashes, req->hashes = 0; //printf("set block->blockhashes[%d]\n",num); } if ( (addr= coin->peers.ranked[0]) != 0 ) @@ -653,7 +653,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_send(coin,addr,serialized,len); //char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); } - } + } else iguana_blockQ("hdr1",coin,0,-1,blockhashes[1],1); } else { From be119a3edf4107459177db6fa16158c1b005b9b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 22:38:08 -0300 Subject: [PATCH 059/333] test --- iguana/iguana_recv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 33eb56cf6..bb1c01b6c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -666,6 +666,11 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],1); // should be RT block } } + else + { + block->newtx = 1; + iguana_blockQ("recvhash6",coin,0,-7,blockhashes[1],0); // should be RT block + } } return(req); } From 2d81ece98cbb09656f75cb85803c24e8baa7e35b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 22:44:11 -0300 Subject: [PATCH 060/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 5ebbce4ff..1a93cc75a 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -403,13 +403,13 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( strcmp("BTC",coin->symbol) == 0 ) lag = 10; else lag = 3; - if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) + if ( (numpeers= coin->peers.numranked) > 3 )//&& bp->currentflag < bp->n ) { if ( numpeers > 0xff ) numpeers = 0xff; // fit into 8 bitfield if ( bp->currentflag == 0 ) bp->currenttime = now; - if ( bp->numhashes >= bp->n ) + if ( bp->numhashes >= 1 ) { for (j=0; jissued); } } - if ( flag != 0 && priority != 0 && laggard != 0 ) + //if ( flag != 0 && priority != 0 && laggard != 0 ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } if ( bp == coin->current ) From 52b6bfdef711da6dfd1728d77527252a3e5aaf53 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:05:12 -0300 Subject: [PATCH 061/333] test --- iguana/iguana_recv.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index bb1c01b6c..5b3de967e 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -38,7 +38,8 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); - return(0); + if ( (rand() % 10 ) != 0 ) + return(0); } if ( addr->msgcounts.verack == 0 ) { @@ -256,7 +257,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } req->block = txdata->block; - printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); + //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); @@ -677,7 +678,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) { - struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock,*prev; char str[65]; + struct iguana_bundle *bp=0; int32_t i,width,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock,*prev; char str[65]; if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) == 0 ) { if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,origblock->RO.hash2)) != 0 ) @@ -752,11 +753,21 @@ 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); - if ( prev != 0 && (bits256_nonz(prev->RO.prev_block) == 0 || prev->fpipbits == 0) ) + width = coin->chain->bundlesize; + while ( prev != 0 && width-- > 0 ) { - //printf("auto prev newtx %s\n",bits256_str(str,prev->RO.hash2)); - prev->newtx = 1; - iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); + if ( prev->fpipbits == 0 ) + { + printf("width.%d auto prev newtx %s\n",width,bits256_str(str,prev->RO.hash2)); + prev->newtx = 1; + iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); + } + if ( bits256_nonz(prev->RO.prev_block) != 0 ) + { + if ( (prev= iguana_blockfind(coin,prev->RO.prev_block)) == 0 ) + prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1); + prev->newtx = 1; + } } } if ( req->copyflag != 0 ) @@ -1056,7 +1067,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 ( iguana_needhdrs(coin) > 0 ) { for (i=0; ibundlescount; i++) { @@ -1070,7 +1081,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) { iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],0); From 748dddf0a8215c7cc35519eb05363efedeb218a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:07:55 -0300 Subject: [PATCH 062/333] test --- iguana/iguana_recv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 5b3de967e..7e50373fd 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -756,6 +756,8 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana width = coin->chain->bundlesize; while ( prev != 0 && width-- > 0 ) { + if ( prev->mainchain != 0 ) + break; if ( prev->fpipbits == 0 ) { printf("width.%d auto prev newtx %s\n",width,bits256_str(str,prev->RO.hash2)); @@ -767,7 +769,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( (prev= iguana_blockfind(coin,prev->RO.prev_block)) == 0 ) prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1); prev->newtx = 1; - } + } else prev = 0; } } if ( req->copyflag != 0 ) From 4934d75eabd49b1b4bb7c6e3a539432e07298f54 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:18:50 -0300 Subject: [PATCH 063/333] test --- iguana/iguana_recv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 7e50373fd..12892fc0c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -37,7 +37,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { - printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); + //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); if ( (rand() % 10 ) != 0 ) return(0); } @@ -727,6 +727,14 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana bp->speculative[bundlei] = block->RO.hash2; bp->numspec = bundlei+1; } + if ( block != 0 && bundlei > 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) + { + if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) + { + printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); + iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,1); + } + } } if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { From f258b8a97f1d751f6d45bfe094d098867f8b10aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:35:54 -0300 Subject: [PATCH 064/333] test --- iguana/iguana_bundles.c | 4 +--- iguana/iguana_recv.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 1a93cc75a..7072b3f14 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -531,12 +531,10 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int counter++; if ( priority != 0 ) { + printf("[%d:%d] ",bp->hdrsi,i); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - { - printf("[%d:%d] ",bp->hdrsi,i); iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); flag++; } //else printf("%d ",now - block->issued); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 12892fc0c..a35cca059 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -732,7 +732,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) { printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); - iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,1); + iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); } } } From 9d58346700c0344727fe133994020999697318a2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:40:26 -0300 Subject: [PATCH 065/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 7072b3f14..6b01b9fc0 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -764,7 +764,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - //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); + 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); bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); From 2e74a3c56a05f28befa4065b4052e12154dcd3d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:42:58 -0300 Subject: [PATCH 066/333] test --- iguana/iguana_bundles.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 6b01b9fc0..593aaf83d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -741,6 +741,11 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) return(1); } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); } + else if ( bp->utxofinish != 0 ) + { + iguana_balancesQ(coin,bp); + return(1); + } } // else printf("%u notready postfinish.%d startutxo.%u prevbp.%d %u current.%d\n",(uint32_t)time(NULL),bp->hdrsi,bp->startutxo,prevbp!=0?prevbp->hdrsi:-1,prevbp!=0?prevbp->emitfinish:0,coin->current!=0?coin->current->hdrsi:-1); return(0); } From ec0ea521601834d745570860251107dfc63e2cef Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:49:13 -0300 Subject: [PATCH 067/333] test --- iguana/iguana777.c | 6 ++++++ iguana/iguana_init.c | 2 +- iguana/iguana_unspents.c | 7 +++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index cc0cc63b6..05fb6ba72 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -353,6 +353,12 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) { uint32_t starttime; + if ( bp->balancefinish > 1 ) + { + printf("make sure DB files have this bp.%d\n",bp->hdrsi); + iguana_validateQ(coin,bp); + return; + } starttime = (uint32_t)time(NULL); if ( iguana_balancegen(coin,bp) < 0 ) { diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 069bfe1b2..6349a60a2 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -280,7 +280,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) { if ( 1 ) - bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); + bp->validated = bp->balancefinish = bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); iguana_bundleQ(coin,bp,1000); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index cb4512f13..b1ce4cc08 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -484,7 +484,10 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp) { - bp->validated = (uint32_t)time(NULL); - printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + if ( bp->validated <= 1 ) + { + bp->validated = (uint32_t)time(NULL); + printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + } return(0); } \ No newline at end of file From c596706988edee36d93cec3284f48718c5045f90 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:53:14 -0300 Subject: [PATCH 068/333] test --- iguana/iguana_bundles.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 593aaf83d..06b186bd2 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -699,16 +699,18 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else if ( bp == coin->current && time(NULL) > bp->issued[bundlei]+10 ) { - iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],1); - bp->issued[bundlei] = (uint32_t)time(NULL); + printf(" missing [%d:%d]\n",bp->hdrsi,bundlei); + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + //bp->issued[bundlei] = (uint32_t)time(NULL); } numhashes++; bp->checkedtmp++; } else if ( bp == coin->current && bits256_nonz(bp->hashes[bundlei]) != 0 && time(NULL) > bp->issued[bundlei]+30 ) { - iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],0); - bp->issued[bundlei] = (uint32_t)time(NULL); + printf(" missing [%d:%d]\n",bp->hdrsi,bundlei); + //iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],0); + //bp->issued[bundlei] = (uint32_t)time(NULL); } } bp->datasize = datasize; From 6fd29d1803455a2d87b4fa63932dfa79cdedba14 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 21 Mar 2016 23:55:46 -0300 Subject: [PATCH 069/333] test --- iguana/iguana777.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 05fb6ba72..41251614a 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -309,7 +309,8 @@ void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->type = 'B'; ptr->starttime = (uint32_t)time(NULL); ptr->timelimit = 0; - bp->balancefinish = 1; + if ( bp->balancefinish == 0 ) + bp->balancefinish = 1; coin->pendbalances++; //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); From 92920982d838aa3c206dd4a963f25eb7c9303491 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:02:10 -0300 Subject: [PATCH 070/333] test --- iguana/iguana_bundles.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 06b186bd2..3218ef758 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -550,7 +550,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 )//|| block->RO.recvlen == 0 ) + if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 ) { if ( block->issued == 0 || now > block->issued+lag ) { @@ -566,7 +566,19 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int //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); + } + else if ( bits256_nonz(bp->hashes[i]) > 0 && now > bp->issued[i]+lag ) + { + iguana_blockQ("kick",coin,bp,i,bp->hashes[i],bp == coin->current); + bp->issued[i] = now; + counter++; + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) > 0 && now > bp->issued[i]+lag ) + { + iguana_blockQ("kick",coin,bp,i,bp->speculative[i],0); + bp->issued[i] = now; + counter++; + } } return(counter); } From 14a66e339dc85a1bb0b253d1bc1b56cc852a3c00 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:08:05 -0300 Subject: [PATCH 071/333] test --- iguana/iguana_bundles.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 3218ef758..2e3c0486c 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -550,7 +550,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 ) + if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || bits256_nonz(block->RO.prev_block) == 0 ) { if ( block->issued == 0 || now > block->issued+lag ) { @@ -569,12 +569,16 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } else if ( bits256_nonz(bp->hashes[i]) > 0 && now > bp->issued[i]+lag ) { + if ( bp == coin->current ) + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->hashes[i],bp == coin->current); bp->issued[i] = now; counter++; } else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) > 0 && now > bp->issued[i]+lag ) { + if ( bp == coin->current ) + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->speculative[i],0); bp->issued[i] = now; counter++; From 26a4a2b7b934e3fc7b84a34a30a9b76c72e15b65 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:12:36 -0300 Subject: [PATCH 072/333] test --- iguana/iguana_bundles.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2e3c0486c..45f028398 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -713,18 +713,20 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } } } - else if ( bp == coin->current && time(NULL) > bp->issued[bundlei]+10 ) + else { - printf(" missing [%d:%d]\n",bp->hdrsi,bundlei); + printf(" mismatched [%d:%d]\n",bp->hdrsi,bundlei); //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - //bp->issued[bundlei] = (uint32_t)time(NULL); + bp->issued[bundlei] = 0; + bp->blocks[bundlei] = 0; + memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); } numhashes++; bp->checkedtmp++; } else if ( bp == coin->current && bits256_nonz(bp->hashes[bundlei]) != 0 && time(NULL) > bp->issued[bundlei]+30 ) { - printf(" missing [%d:%d]\n",bp->hdrsi,bundlei); + printf(" missingB [%d:%d]\n",bp->hdrsi,bundlei); //iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],0); //bp->issued[bundlei] = (uint32_t)time(NULL); } From af20b6e733e7c8c5b4409f899d52f631c334a2ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:17:38 -0300 Subject: [PATCH 073/333] test --- iguana/iguana_bundles.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 45f028398..5dfa804f7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -669,9 +669,10 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); continue; @@ -696,7 +697,6 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); } } - //bp->blocks[bundlei] = block; block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) bp->minrequests = block->numrequests; @@ -715,11 +715,12 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else { - printf(" mismatched [%d:%d]\n",bp->hdrsi,bundlei); + char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); bp->issued[bundlei] = 0; bp->blocks[bundlei] = 0; memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + OS_removefile(fname,0); } numhashes++; bp->checkedtmp++; From 3cf59b245adc0255b5df5e95f6391502bb24a803 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:23:36 -0300 Subject: [PATCH 074/333] test --- iguana/iguana_bundles.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 5dfa804f7..3a29895ce 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -667,7 +667,8 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) + block = bp->blocks[bundlei]; + if ( bits256_nonz(bp->hashes[bundlei]) > 0 && block != 0 ) { checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) @@ -725,11 +726,14 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) numhashes++; bp->checkedtmp++; } - else if ( bp == coin->current && bits256_nonz(bp->hashes[bundlei]) != 0 && time(NULL) > bp->issued[bundlei]+30 ) + else if ( bp == coin->current ) { - printf(" missingB [%d:%d]\n",bp->hdrsi,bundlei); - //iguana_blockQ("missing",coin,0,-1,bp->hashes[bundlei],0); - //bp->issued[bundlei] = (uint32_t)time(NULL); + if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+10 ) + { + char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),block); + iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); + //bp->issued[bundlei] = (uint32_t)time(NULL); + } } } bp->datasize = datasize; From c9bb9e8826b12fad787df2e156ffc36781ba5fe1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:27:29 -0300 Subject: [PATCH 075/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 3a29895ce..b8d317f1d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -550,9 +550,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || bits256_nonz(block->RO.prev_block) == 0 ) + if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || (bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) > 0 ) { - if ( block->issued == 0 || now > block->issued+lag ) + //if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; if ( bp == coin->current ) @@ -730,7 +730,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+10 ) { - char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),block); + char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); //bp->issued[bundlei] = (uint32_t)time(NULL); } From 1e560e048f1e1dc19a7ec1ee19561b6abed7b4d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:33:22 -0300 Subject: [PATCH 076/333] test --- iguana/iguana_bundles.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b8d317f1d..a2deaeec6 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -552,7 +552,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || (bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) > 0 ) { - //if ( block->issued == 0 || now > block->issued+lag ) + if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; if ( bp == coin->current ) @@ -658,12 +658,13 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; FILE *fp; - int64_t datasize; struct iguana_block *block; char fname[1024]; static bits256 zero; + int64_t datasize; struct iguana_block *block; uint32_t now; char fname[1024]; static bits256 zero; if ( bp->emitfinish > coin->startutc ) { bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; return(bp->datasize); } + now = (uint32_t)time(NULL); datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { @@ -703,15 +704,21 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) bp->minrequests = block->numrequests; if ( (bp->hdrsi == 0 && bundlei == 0) || bits256_nonz(block->RO.prev_block) > 0 ) { - if ( block->fpipbits != 0 ) //block->fpos >= 0 && + if ( block->queued != 0 ) + numcached++; + if ( block->fpipbits != 0 && block->fpos >= 0 ) numsaved++; - if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 )//|| block->queued != 0 ) + if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 ) { numrecv++; datasize += block->RO.recvlen; - if ( block->queued != 0 ) - numcached++; - } + } + } + else if ( bp == coin->current ) + { + printf("missing [%d:%d]\n",bp->hdrsi,bundlei); + if ( now > bp->issued[bundlei]+10 ) + iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],0); } } else From 57b1c167bf95b693f629610922031d8ee972fc8d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:36:07 -0300 Subject: [PATCH 077/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a2deaeec6..a8a5ca97f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -716,7 +716,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else if ( bp == coin->current ) { - printf("missing [%d:%d]\n",bp->hdrsi,bundlei); + char str[65]; printf("missing [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); if ( now > bp->issued[bundlei]+10 ) iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],0); } From 0204d974f7e1a977de4bfd82a30567d7a6dc8a4f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:38:50 -0300 Subject: [PATCH 078/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a8a5ca97f..abc14cac5 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -540,7 +540,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } //else printf("%d ",now - block->issued); } } - //if ( flag != 0 && priority != 0 && laggard != 0 ) + if ( flag != 0 && priority != 0 && laggard != 0 ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } if ( bp == coin->current ) @@ -801,7 +801,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); - 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); + //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); bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); From f338f46d92b19b96b6dba318e23ac4dd38864aac Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:41:10 -0300 Subject: [PATCH 079/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index abc14cac5..9524c992f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -849,7 +849,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; counter = iguana_bundleissue(coin,bp,max,timelimit); - if ( bp->hdrsi == starti ) + 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 == coin->current ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index a35cca059..8a03ccdfc 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -54,7 +54,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - //if ( 0 && coin->current == bp ) + if ( 0 && coin->current == bp ) printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); From 690a59cb75d2d05f8c81e2435f56d2ae5d843f3e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:46:06 -0300 Subject: [PATCH 080/333] test --- iguana/iguana_bundles.c | 9 ++++++--- iguana/iguana_recv.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 9524c992f..45a45065c 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -721,7 +721,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],0); } } - else + /*else { char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); @@ -729,7 +729,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) bp->blocks[bundlei] = 0; memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); OS_removefile(fname,0); - } + }*/ numhashes++; bp->checkedtmp++; } @@ -853,7 +853,10 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru 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 == coin->current ) { - + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + + } } } iguana_bundleQ(coin,bp,1000); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 8a03ccdfc..3805e12b0 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -304,7 +304,7 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi req = iguana_bundlereq(coin,addr,'S',0); req->hashes = blockhashes, req->n = n; char str[65]; - if ( n > 2 ) + if ( 0 && n > 2 ) printf("bundlesQ blockhashes.%s [%d]\n",bits256_str(str,blockhashes[1]),n); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } From ffc816a9ae26623945189497301312f827981b7f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 00:57:38 -0300 Subject: [PATCH 081/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_ramchain.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 45a45065c..82018954a 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -851,7 +851,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); 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 == coin->current ) + if ( bp == coin->current && (bp->ramchain.H->data == 0 || bp->ramchain.H.data->numblocks != numblocks) ) { if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) { diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 5927973e2..5f17b5380 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2062,12 +2062,12 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - return(0); + return(bp == coin->current ? num : 0); } if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) { printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); - return(0); + return(bp == coin->current ? num : 0); } //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); num++; @@ -2257,7 +2257,6 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; memset(&HASHMEM,0,sizeof(HASHMEM)); starti = 0, endi = bp->n - 1; - bp_n = (endi - starti + 1); B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); @@ -2269,6 +2268,9 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str printf("iguana_bundlesaveHT: no bundlefiles error\n"); return(-1); } + if ( bp == coin->current ) + endi = num-1; + bp_n = (endi - starti + 1); scriptspace = 1; sigspace = pubkeyspace = 0; for (bundlei=starti,numtxids=numunspents=numspends=scriptspace=0; bundlei<=endi; bundlei++) From 534c3e2feaced510272b5980d492a66909c9b23f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 01:01:19 -0300 Subject: [PATCH 082/333] test --- iguana/iguana_bundles.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 82018954a..8d2e79ba1 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -784,7 +784,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,checki,retval=0,max,bundlei,hdrsi,counter = 0; char fname[1024]; struct iguana_bundle *currentbp,*lastbp; FILE *fp; static bits256 zero; if ( coin->started == 0 ) { printf("%s not ready yet\n",coin->symbol); @@ -851,7 +851,17 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); 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 == coin->current && (bp->ramchain.H->data == 0 || bp->ramchain.H.data->numblocks != numblocks) ) + for (bundlei=0; bundlein; bundlei++) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( checki == bundlei ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + fclose(fp); + else break; + } + } + if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) { if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) { From d6f82e30edb50fc58ebf30432ea48abb40ae13ce Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 01:43:38 -0300 Subject: [PATCH 083/333] test --- iguana/iguana_recv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 3805e12b0..7a38be960 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -927,7 +927,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) next = 0; } } - else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) + /*else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) { if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) { @@ -938,7 +938,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); } } - } + }*/ if ( next != 0 ) { //printf("have next %d\n",coin->blocks.hwmchain.height); @@ -996,13 +996,16 @@ int32_t iguana_reqblocks(struct iguana_info *coin) 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 ) + else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { if ( time(NULL) > bp->issued[bundlei+1]+10 ) { bp->issued[bundlei+1] = (uint32_t)time(NULL); printf("MAINCHAIN skip issue %d\n",bundlei+1); - iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + if ( bits256_nonz(bp->hashes[bundlei+1]) != 0 ) + iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + else if ( bp->speculative != 0 && bundlei+1 < bp->numspec ) + iguana_blockQ("mainskip",coin,bp,bundlei,bp->speculative[bundlei+1],0); } } else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) @@ -1119,6 +1122,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle if ( bits256_nonz(hash2) == 0 ) { printf("cant queue zerohash bundlei.%d\n",bundlei); + //getchar(); return(-1); } block = iguana_blockfind(coin,hash2); From fe96af5c911c8de70c2db52ba25d0199f95a840a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 01:49:41 -0300 Subject: [PATCH 084/333] test --- iguana/iguana_bundles.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 8d2e79ba1..d2eaa2a20 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -851,21 +851,25 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); 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); - for (bundlei=0; bundlein; bundlei++) + if ( coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( checki == bundlei ) + for (bundlei=0; bundlein; bundlei++) { - if ( (fp= fopen(fname,"rb")) != 0 ) - fclose(fp); - else break; + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( checki == bundlei ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + fclose(fp); + else break; + } } - } - if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) - { - if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) { - + printf("RT bundls\n"); + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + + } } } } From d7637802f6f9fbb85bde5d5483e0e71b020fa6d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 01:56:46 -0300 Subject: [PATCH 085/333] test --- iguana/iguana_blocks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index d423a433e..e4b85d431 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -303,6 +303,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl else { char str[65]; printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); + memset(&block->RO.prev_block.bytes,0,sizeof(block->RO.prev_block)); //getchar(); return(0); } From 5326a68ab05639d079d41f23175aa588e0e18a65 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 02:41:06 -0300 Subject: [PATCH 086/333] test --- iguana/iguana_bundles.c | 10 ++++++++-- iguana/iguana_recv.c | 10 +++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d2eaa2a20..2269bc8a7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -985,7 +985,10 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); } if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) + { + printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); firstgap = bp; + } if ( bp->emitfinish == 0 ) { spaceused += bp->estsize; @@ -1022,7 +1025,10 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); if ( (coin->current= firstgap) == 0 ) - coin->current = coin->bundlescount > 0 ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + { + firstgap = coin->current = (coin->bundlescount > 0) ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + //printf("bundlescount.%d %p[%d]\n",coin->bundlescount,coin->current,coin->current->hdrsi); + } if ( lastpending != 0 ) coin->lastpending = lastpending; else coin->lastpending = coin->bundles[coin->bundlescount - 1]; @@ -1030,7 +1036,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:0,firstgap!=0?firstgap->hdrsi:0,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); + sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,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) > lastdisp+10 ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 7a38be960..9ed684944 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -768,7 +768,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana break; if ( prev->fpipbits == 0 ) { - printf("width.%d auto prev newtx %s\n",width,bits256_str(str,prev->RO.hash2)); + //printf("width.%d auto prev newtx %s\n",width,bits256_str(str,prev->RO.hash2)); prev->newtx = 1; iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); } @@ -1084,10 +1084,10 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) && (bp->speculative == 0 || bp->numspec < bp->n) ) + if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { lag = 30; - if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) + if ( bp->bundleheight < coin->longestchain && time(NULL) > bp->issuetime+lag ) { //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) @@ -1213,7 +1213,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) else if ( bp->numhashes < bp->n ) z = 1; } - if ( bp == 0 || z != 0 ) + if ( bp == 0 || z != 0 || bp == coin->current ) { //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); @@ -1261,7 +1261,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) else block = 0; if ( priority == 0 && bp != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && block != 0 && (block->fpipbits != 0 || block->queued != 0) ) { - //if ( 1 && priority != 0 ) + if ( 1 && priority != 0 ) printf("SKIP %p[%d] %d\n",bp,bp!=0?bp->bundleheight:-1,req->bundlei); } else From 38d857c5adfdf4b9b15ee506c263486eb6a74455 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 02:50:44 -0300 Subject: [PATCH 087/333] test --- iguana/iguana777.c | 6 +++--- iguana/iguana_bundles.c | 6 +++--- iguana/main.c | 5 ++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 41251614a..cda54840c 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -526,9 +526,9 @@ void iguana_coinloop(void *arg) } if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) { - static int32_t saved; - if ( saved++ == 0 ) - iguana_coinflush(coin,1); + //static int32_t saved; + //if ( saved++ == 0 ) + // iguana_coinflush(coin,1); } if ( coin->bindsock >= 0 ) { diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2269bc8a7..2ba1d6e08 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -737,8 +737,8 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+10 ) { - char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); - iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); + //char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); + //iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); //bp->issued[bundlei] = (uint32_t)time(NULL); } } @@ -986,7 +986,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) { - printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); + //printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); firstgap = bp; } if ( bp->emitfinish == 0 ) diff --git a/iguana/main.c b/iguana/main.c index 9dfa09d63..0e791f229 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -353,8 +353,11 @@ void mainloop(struct supernet_info *myinfo) coin->pendbalances--; iguana_balancesQ(coin,bp); } - if ( bp->hdrsi == coin->bundlescount-1 ) + if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) + { iguana_coinflush(ptr->coin,1); + printf("flushed bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + } } myfree(ptr,ptr->allocsize); } From 46c980698bbcb5db622148792324c0e7725479b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 02:53:40 -0300 Subject: [PATCH 088/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2ba1d6e08..1ef610aaa 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -738,8 +738,8 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+10 ) { //char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); - //iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); - //bp->issued[bundlei] = (uint32_t)time(NULL); + iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); } } } From 4275c1a91d59adf47f04f29b9574d1e1bc1ca976 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:00:16 -0300 Subject: [PATCH 089/333] test --- iguana/iguana_recv.c | 4 ++-- iguana/main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 9ed684944..e49d4cf32 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -970,7 +970,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( bp != 0 && bits256_nonz(hash2) == 0 ) { hash2 = bp->hashes[bundlei]; - /*if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) { hash2 = bp->speculative[bundlei]; if ( bits256_nonz(hash2) > 0 ) @@ -982,7 +982,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) lflag++, flag++, printf("NEWHWM.%d\n",coin->backstop); } } - }*/ + } } if ( bits256_nonz(hash2) > 0 ) { diff --git a/iguana/main.c b/iguana/main.c index 0e791f229..cc698d1a8 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -355,7 +355,7 @@ void mainloop(struct supernet_info *myinfo) } if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) { - iguana_coinflush(ptr->coin,1); + //iguana_coinflush(ptr->coin,1); printf("flushed bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); } } From be1ce55bb7acf1f9b29e524b6a058820ec815c8a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:01:58 -0300 Subject: [PATCH 090/333] test --- iguana/iguana_recv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index e49d4cf32..58575fcc5 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -960,7 +960,9 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else threshold = coin->avetime; threshold *= 100. * sqrt(threshold) * .000777;*/ double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = 300; + if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) + threshold = 10000; + else threshold = 300; if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) { coin->backstop = coin->blocks.hwmchain.height+1; From a80b2730324fa81769081885a6ff3a52036a7915 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:06:08 -0300 Subject: [PATCH 091/333] test --- iguana/iguana_recv.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 58575fcc5..105a45663 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -988,22 +988,19 @@ int32_t iguana_reqblocks(struct iguana_info *coin) } if ( bits256_nonz(hash2) > 0 ) { - if ( bp != 0 && bits256_nonz(hash2) > 0 ) - { - coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,0,-1,hash2,lag > 100 * threshold); - flag++; - char str[65]; - if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) - printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); - } + coin->backstopmillis = OS_milliseconds(); + iguana_blockQ("mainchain",coin,0,-1,hash2,lag > 100 * threshold); + flag++; + char str[65]; + if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + 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 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { if ( time(NULL) > bp->issued[bundlei+1]+10 ) { bp->issued[bundlei+1] = (uint32_t)time(NULL); - printf("MAINCHAIN skip issue %d\n",bundlei+1); + printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1); if ( bits256_nonz(bp->hashes[bundlei+1]) != 0 ) iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); else if ( bp->speculative != 0 && bundlei+1 < bp->numspec ) From a4d3ef4a9e4691611f437ca4f013983575f3d53f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:10:00 -0300 Subject: [PATCH 092/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 1ef610aaa..eec16333d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -629,7 +629,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 //printf("speculative.[%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); } - break; + //break; } // else if ( bp->blocks[i] == 0 ) // break; From 3d534658bca4794ad92f705a6930053e8c2b3476 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:13:54 -0300 Subject: [PATCH 093/333] test --- iguana/iguana_recv.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 105a45663..e5fb3deac 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -997,14 +997,18 @@ int32_t iguana_reqblocks(struct iguana_info *coin) } else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { - if ( time(NULL) > bp->issued[bundlei+1]+10 ) + int32_t j; + for (j=0; j<5&&bundlei+j+1n; j++) { - bp->issued[bundlei+1] = (uint32_t)time(NULL); - printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1); - if ( bits256_nonz(bp->hashes[bundlei+1]) != 0 ) - iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); - else if ( bp->speculative != 0 && bundlei+1 < bp->numspec ) - iguana_blockQ("mainskip",coin,bp,bundlei,bp->speculative[bundlei+1],0); + if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) + { + bp->issued[bundlei+1+j] = (uint32_t)time(NULL); + printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1+j); + if ( bits256_nonz(bp->hashes[bundlei+1+j]) != 0 ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->hashes[bundlei+1+j],0); + else if ( bp->speculative != 0 && bundlei+1+j < bp->numspec ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->speculative[bundlei+1+j],0); + } } } else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) From 622c3c358747177b5351e062b3fde03dd38da376 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:16:22 -0300 Subject: [PATCH 094/333] test --- iguana/iguana_recv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index e5fb3deac..25bc68175 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -998,6 +998,8 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { int32_t j; + memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + bp->blocks[bundlei] = 0; for (j=0; j<5&&bundlei+j+1n; j++) { if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) From 6e6822fe871cbe1afe317b0869dbd53094d74c4c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:16:39 -0300 Subject: [PATCH 095/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 25bc68175..da81ddb56 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1000,7 +1000,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) int32_t j; memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); bp->blocks[bundlei] = 0; - for (j=0; j<5&&bundlei+j+1n; j++) + for (j=0; j<1&&bundlei+j+1n; j++) { if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) { From 547701ec91072df25bad8f28f6d8524c6c6c9b5b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:28:42 -0300 Subject: [PATCH 096/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index da81ddb56..bbe6c6212 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -748,7 +748,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); } - if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) + if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { //printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); From 66b0f8913b761e4f40baa2ac308b9b827ca3782f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:39:28 -0300 Subject: [PATCH 097/333] test --- iguana/iguana_bundles.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index eec16333d..6152e7b69 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -598,7 +598,13 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) 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); + block->fpipbits = 0; + block->fpos = -1; + block->queued = 0; + block->RO.recvlen = 0; + memset(bp->hashes[i].bytes,0,sizeof(bp->hashes[i])); + bp->blocks[i] = 0; + //iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1); } else ready++; } else printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); } From 6c54613d3dafcd625dad5288858e91b822ccaef4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 03:53:39 -0300 Subject: [PATCH 098/333] test --- iguana/iguana_recv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index bbe6c6212..e558de785 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -603,6 +603,11 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } else if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) return(req); + else if ( bp == coin->current ) + { + for (i=0; in; i++) + iguana_blockQ("reissue",coin,bp,i,bp->hashes[i],0); + } //printf("done allhashes\n"); } if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) From 926837d01adeae39d49fa963fd1e350b735efef5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:01:38 -0300 Subject: [PATCH 099/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 6152e7b69..fcc16d838 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -635,10 +635,10 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 //printf("speculative.[%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); } - //break; + break; } - // else if ( bp->blocks[i] == 0 ) - // break; + else if ( bp->blocks[i] == 0 ) + break; } } return(counter); From ad9f82a458a34342edb60e49dd87b2deb0e3eb48 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:11:25 -0300 Subject: [PATCH 100/333] test --- iguana/iguana_bundles.c | 16 ++++++++-------- iguana/iguana_recv.c | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index fcc16d838..a2bf071fb 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -529,9 +529,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( now > block->issued+lag ) { counter++; + printf("[%d:%d] ",bp->hdrsi,i); if ( priority != 0 ) { - printf("[%d:%d] ",bp->hdrsi,i); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); @@ -555,7 +555,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; - if ( bp == coin->current ) + //if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); bp->issued[i] = block->issued = now; @@ -567,17 +567,17 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int // n++; } } - else if ( bits256_nonz(bp->hashes[i]) > 0 && now > bp->issued[i]+lag ) + else if ( bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) { - if ( bp == coin->current ) + //if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->hashes[i],bp == coin->current); bp->issued[i] = now; counter++; } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) > 0 && now > bp->issued[i]+lag ) + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) { - if ( bp == coin->current ) + //if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->speculative[i],0); bp->issued[i] = now; @@ -632,7 +632,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 if ( now > bp->issued[i]+10 ) { bp->issued[i] = now; - //printf("speculative.[%d:%d]\n",bp->hdrsi,i); + printf("speculative.[%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); } break; @@ -954,7 +954,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( now > block->issued+10 ) { block->issued = now; - //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + printf("submit speculative [%d:%d]\n",bp->hdrsi,j); iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); } } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index e558de785..4595d90b9 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -605,8 +605,8 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct return(req); else if ( bp == coin->current ) { - for (i=0; in; i++) - iguana_blockQ("reissue",coin,bp,i,bp->hashes[i],0); + //for (i=0; in; i++) + // iguana_blockQ("reissue",coin,bp,i,bp->hashes[i],0); } //printf("done allhashes\n"); } @@ -762,7 +762,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { if ( block != origblock ) iguana_blockcopy(coin,block,origblock); - if ( block->newtx != 0 ) + if ( block->newtx != 0 && 0 ) { if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); From 16cd020da95bc31983915a016e13f84327c773ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:27:56 -0300 Subject: [PATCH 101/333] test --- iguana/iguana_bundles.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a2bf071fb..1e33d31a4 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -529,9 +529,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( now > block->issued+lag ) { counter++; - printf("[%d:%d] ",bp->hdrsi,i); if ( priority != 0 ) { + printf("[%d:%d] ",bp->hdrsi,i); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); @@ -555,7 +555,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( block->issued == 0 || now > block->issued+lag ) { block->numrequests++; - //if ( bp == coin->current ) + if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); bp->issued[i] = block->issued = now; @@ -569,7 +569,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } else if ( bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) { - //if ( bp == coin->current ) + if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->hashes[i],bp == coin->current); bp->issued[i] = now; @@ -577,7 +577,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) { - //if ( bp == coin->current ) + if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); iguana_blockQ("kick",coin,bp,i,bp->speculative[i],0); bp->issued[i] = now; From 834d6238562e7ec347a4fe68c5b7c1e553225899 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:28:27 -0300 Subject: [PATCH 102/333] test --- iguana/iguana_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 6349a60a2..0b80469de 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -279,7 +279,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //printf("LOADED bundle.%d %p current %p\n",bp->bundleheight,bp,coin->current); //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) { - if ( 1 ) + if ( 0 ) bp->validated = bp->balancefinish = bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); iguana_bundleQ(coin,bp,1000); From d0f60dde55c1209b4f396eab72357907b6e790c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:32:54 -0300 Subject: [PATCH 103/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 1e33d31a4..2ae69b53d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -143,10 +143,10 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { char str2[65],str3[65]; bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("WARNING iguana_hash2set REFUSE overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); - //*orighash2p = newhash2; + printf("WARNING iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); + *orighash2p = newhash2; // getchar(); - return(-1); + // return(-1); } if ( isinside != 0 ) { From ad9bd2a35598d155baa088cb055d6a899cea5152 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:43:42 -0300 Subject: [PATCH 104/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2ae69b53d..d9b516eb8 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -635,10 +635,10 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 printf("speculative.[%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); } - break; + //break; } - else if ( bp->blocks[i] == 0 ) - break; + //else if ( bp->blocks[i] == 0 ) + // break; } } return(counter); From bd573262a079be5248459c418a1fa58c8aa8fe80 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 04:45:36 -0300 Subject: [PATCH 105/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d9b516eb8..c18fb3f58 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -857,7 +857,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); 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 ( coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) + if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) { for (bundlei=0; bundlein; bundlei++) { From 298087a7679e4d07cea9d454972af6b2b8989253 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:06:17 -0300 Subject: [PATCH 106/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c18fb3f58..aaa24be30 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -764,7 +764,7 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) struct iguana_bundle *prevbp; int32_t prevdone = 0; if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) prevdone = 1; - else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+3 ) + else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+13 ) prevdone = 1; if ( bp->hdrsi == 0 || prevdone != 0 ) { From e45d02c8b78937a0c799889cdca6933b4af7a02f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:09:59 -0300 Subject: [PATCH 107/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 4595d90b9..d1a377524 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -762,7 +762,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { if ( block != origblock ) iguana_blockcopy(coin,block,origblock); - if ( block->newtx != 0 && 0 ) + if ( block->newtx != 0 ) { if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); From 00540570fc5b4fd7fcf08cdd9f04440d132b1d50 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:38:47 -0300 Subject: [PATCH 108/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index aaa24be30..fe73efcf7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -698,11 +698,11 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else { - char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); + //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); block->RO.recvlen = 0; block->fpipbits = 0; block->fpos = -1; - iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); } } block->hdrsi = bp->hdrsi, block->bundlei = bundlei; From b03ff776cedcb52185aaa3bbde885441fc3694a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:42:37 -0300 Subject: [PATCH 109/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index cc698d1a8..686a7defc 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -341,7 +341,7 @@ void mainloop(struct supernet_info *myinfo) { if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { - if ( bp->utxofinish != 0 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish != 0)) ) + if ( bp->utxofinish != 0 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish > 1 && time(NULL) > prevbp->utxofinish+13)) ) { //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); iguana_balancecalc(ptr->coin,bp); From 1269ff11a2b935bdc6c4399ffc046a5e3f113aae Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:46:04 -0300 Subject: [PATCH 110/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index fe73efcf7..b8c3036b8 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -531,7 +531,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int counter++; if ( priority != 0 ) { - printf("[%d:%d] ",bp->hdrsi,i); + //printf("[%d:%d] ",bp->hdrsi,i); iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); @@ -632,7 +632,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 if ( now > bp->issued[i]+10 ) { bp->issued[i] = now; - printf("speculative.[%d:%d]\n",bp->hdrsi,i); + //printf("speculative.[%d:%d]\n",bp->hdrsi,i); iguana_blockQ("speculative",coin,0,-1,bp->speculative[i],0); } //break; From 50a8c24d5d16475b4859a16425fe781217f8dc9f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:47:04 -0300 Subject: [PATCH 111/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b8c3036b8..75eed979e 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -494,7 +494,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag ) + if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { if ( numpeers > 64 || addr->laggard++ > 3 ) addr->dead = (uint32_t)time(NULL); From 20d8881cf15e00114018450e7019b9b7ad07cb80 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:49:23 -0300 Subject: [PATCH 112/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 75eed979e..7e1a270fe 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -540,7 +540,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } //else printf("%d ",now - block->issued); } } - if ( flag != 0 && priority != 0 && laggard != 0 ) + if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } if ( bp == coin->current ) From 2dc6adfcbf153a5ff76d6212c08dbe7462c26e22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:49:48 -0300 Subject: [PATCH 113/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 7e1a270fe..4424ccf63 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1042,7 +1042,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); + sprintf(str,"%s u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",coin->symbol,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,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) > lastdisp+10 ) { From a4508ee5ee106c42a1e4b0f9384cc02ae721df5d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 05:56:27 -0300 Subject: [PATCH 114/333] test --- iguana/iguana777.c | 3 ++- iguana/iguana_bundles.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index cda54840c..bca79028a 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -581,7 +581,7 @@ void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,i struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxpending,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mult,mapflags; char dirname[512]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; coin = iguana_coinadd(symbol,json); coin->launched = launched; @@ -603,6 +603,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->initialheight = initialheight; coin->mapflags = mapflags; mult = (strcmp("BTC",coin->symbol) != 0) ? 64 : 1; + maxval = (strcmp("BTC",coin->symbol) != 0) ? 2048 : 64; if ( (coin->startPEND= juint(json,"startpend")) == 0 ) coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; if ( coin->startPEND > 1024 ) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 4424ccf63..a047b3cd9 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -401,7 +401,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int else if ( lag > 10*i ) lag = 10*i;*/ if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 10; + lag = 30; else lag = 3; if ( (numpeers= coin->peers.numranked) > 3 )//&& bp->currentflag < bp->n ) { @@ -629,7 +629,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 { if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) { - if ( now > bp->issued[i]+10 ) + if ( now > bp->issued[i]+60 ) { bp->issued[i] = now; //printf("speculative.[%d:%d]\n",bp->hdrsi,i); From 354ddd84339746932a0185ff5ecca52f0e0780cf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 13:48:09 -0300 Subject: [PATCH 115/333] test --- iguana/iguana_recv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index d1a377524..0bfde50e7 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -551,7 +551,9 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig if ( i != n-1 ) fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); } - } else printf("blockhash[%d] cant be found\n",i); + } + else if ( bp != firstbp ) + printf("blockhash[%d] cant be found\n",i); } //char str[65]; printf("blockhdrs.%s hdrsi.%d\n",bits256_str(str,blocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) From 411e2c22f82bfd8eb5a2ca6b3eeb4d54509b874c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:15:26 -0300 Subject: [PATCH 116/333] test --- iguana/iguana_recv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 0bfde50e7..93ff71680 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -195,7 +195,13 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; - if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) + bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); + if ( bp != 0 && bp->emitfinish != 0 ) + { + printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + return; + } + if ( copyflag != 0 && recvlen != 0 && (bp == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); req->copyflag = 1; From 26433939553a789c590e72c3a3744e95b703a368 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:24:22 -0300 Subject: [PATCH 117/333] test --- iguana/iguana_bundles.c | 5 +++-- iguana/iguana_unspents.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a047b3cd9..98db40b05 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -981,7 +981,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) { done++; numemit++; - iguana_bundlepurge(coin,bp); + if ( firstgap != 0 && bp->hdrsi > firstgap->hdrsi-3 ) + iguana_bundlepurge(coin,bp); } else { @@ -990,7 +991,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) lastpending = bp; //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); } - if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) + if ( firstgap == 0 )//&& (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) { //printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); firstgap = bp; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index b1ce4cc08..4a623e69d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -297,6 +297,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { errs++; printf("utxogen: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; } } } From cddfebb82e9bda6f8a0b3ccb8e4ba090392d7c6a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:26:21 -0300 Subject: [PATCH 118/333] test --- iguana/iguana_recv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 93ff71680..2f4839a1d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1275,8 +1275,14 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) hash2 = req->hash2; height = req->height; if ( (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n ) + { + if ( bp->emitfinish != 0 ) + { + printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); + return(0); + } block = bp->blocks[req->bundlei]; - else block = 0; + } else block = 0; if ( priority == 0 && bp != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && block != 0 && (block->fpipbits != 0 || block->queued != 0) ) { if ( 1 && priority != 0 ) From 00d3088b9e17615614e0570c32f92a188b427bf8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:28:58 -0300 Subject: [PATCH 119/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 2f4839a1d..27ba2d61a 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -198,7 +198,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); if ( bp != 0 && bp->emitfinish != 0 ) { - printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); return; } if ( copyflag != 0 && recvlen != 0 && (bp == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) From 2e62665aa924a8e1706ec69dc6f887b57b7c9bc6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:30:07 -0300 Subject: [PATCH 120/333] test --- iguana/iguana_unspents.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 4a623e69d..06aad65cf 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -337,6 +337,8 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d | ",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + if ( errs != 0 ) + exit(-1); return(-errs); } From 1393743622bd70ff9c9e5d1a102782df49d38409 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 14:37:16 -0300 Subject: [PATCH 121/333] test --- iguana/iguana_bundles.c | 13 ++++++++----- iguana/iguana_recv.c | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 98db40b05..c58e80f86 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -761,12 +761,15 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { - struct iguana_bundle *prevbp; int32_t prevdone = 0; - if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) + struct iguana_bundle *prevbp; int32_t i;//prevdone = 0; + /*if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) prevdone = 1; else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+13 ) - prevdone = 1; - if ( bp->hdrsi == 0 || prevdone != 0 ) + prevdone = 1;*/ + for (i=0; ihdrsi; i++) + if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) + break; + if ( i == bp->hdrsi ) { if ( bp->startutxo == 0 ) { @@ -991,7 +994,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) lastpending = bp; //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); } - if ( firstgap == 0 )//&& (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) + if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) { //printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); firstgap = bp; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 27ba2d61a..885974fc2 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1102,7 +1102,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) + if ( (bp= coin->bundles[i]) != 0 && (bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { lag = 30; if ( bp->bundleheight < coin->longestchain && time(NULL) > bp->issuetime+lag ) From 5070f0a2e3e75a9146bfe1a1893e8e572a669eae Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 16:36:22 -0300 Subject: [PATCH 122/333] test --- iguana/iguana777.c | 2 ++ iguana/iguana_bundles.c | 10 ++++------ iguana/iguana_ramchain.c | 13 +++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index bca79028a..689395e80 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -635,6 +635,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, printf("cant initialize chain.(%s)\n",jstr(json,0)); return(0); } else iguana_chainparms(coin->chain,json); + //coin->RELAY = juint(json,"RELAY"); + //coin->VALIDATE = juint(json,"VALIDATE"); if ( (peers= jarray(&m,json,"peers")) != 0 ) { for (j=0; jbundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) - prevdone = 1; - else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+13 ) - prevdone = 1;*/ + struct iguana_bundle *prevbp; int32_t i; + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) + return(0); for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; @@ -816,7 +814,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish != 0 ) { - //bp->nexttime -= 60; + bp->nexttime += 10; if ( bp->emitfinish > 1 ) { if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 5f17b5380..873d328aa 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2246,6 +2246,19 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana return(mapchain); } + +/*{ + RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; + if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) == 0 ) + { + iguana_ramchain_link(dest,bp->hashes[starti],bp->hashes[endi],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); + dest->expanded = 1; + dest->H.scriptoffset = 1; + _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); + iguana_ramchain_extras(coin,dest,&HASHMEM,0); + } +}*/ + // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { From 7048dd7c269b7b5607e8230238f1e151b76d91de Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 16:41:52 -0300 Subject: [PATCH 123/333] test --- iguana/iguana777.c | 4 ++-- iguana/iguana777.h | 2 +- iguana/iguana_peers.c | 11 +++++++---- iguana/iguana_ramchain.c | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 689395e80..fb9436135 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -635,8 +635,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, printf("cant initialize chain.(%s)\n",jstr(json,0)); return(0); } else iguana_chainparms(coin->chain,json); - //coin->RELAY = juint(json,"RELAY"); - //coin->VALIDATE = juint(json,"VALIDATE"); + coin->RELAYNODE = juint(json,"RELAY"); + coin->VALIDATENODE = juint(json,"VALIDATE"); if ( (peers= jarray(&m,json,"peers")) != 0 ) { for (j=0; jvoutsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->voutsfp,0,SEEK_END); else addr->voutsfp = fopen(fname,"wb+"); - 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+"); + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + 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+"); + } //addr->pubkey = GENESIS_PUBKEY; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 873d328aa..d6df9d021 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1919,7 +1919,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru origtxdata->datalen = (int32_t)ramchain->H.data->allocsize; ramchain->H.ROflag = 0; flag = 1; - if ( 1 ) + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) { if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) fflush(addr->voutsfp); From f3fa5ed82357d224d00e7156798f15065a0ece92 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 16:53:14 -0300 Subject: [PATCH 124/333] test --- iguana/iguana777.c | 1 + iguana/iguana_init.c | 6 +++--- iguana/main.c | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index fb9436135..c6a10fb7f 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -74,6 +74,7 @@ struct iguana_info *iguana_coinadd(const char *symbol,cJSON *argjson) coin->chain = iguana_chainfind((char *)symbol,argjson,1); strcpy(coin->symbol,symbol); iguana_initcoin(coin,argjson); + printf("coin.%s initialized\n",symbol); } return(coin); } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 0b80469de..9d00881e0 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -52,9 +52,9 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) { - int32_t i; - //sprintf(dirname,"%s/%s",GLOBALTMPDIR,coin->symbol), OS_portable_path(dirname); - //OS_portable_rmdir(dirname,0); + int32_t i; char dirname[1024]; + sprintf(dirname,"%s/%s",GLOBALTMPDIR,coin->symbol), OS_portable_path(dirname); + 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]); diff --git a/iguana/main.c b/iguana/main.c index 686a7defc..29e3f12d6 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1022,7 +1022,7 @@ int maingen(int argc, char** argv) void iguana_main(void *arg) { - cJSON *argjson; int32_t usessl = 0, ismainnet = 1; int32_t i; + cJSON *argjson; int32_t usessl = 0, ismainnet = 1; int32_t i; struct iguana_info *btc,*btcd; struct supernet_info *myinfo; char *tmpstr,*helperargs,*coinargs,helperstr[512]; mycalloc(0,0,0); myinfo = SuperNET_MYINFO(0); @@ -1094,8 +1094,13 @@ void iguana_main(void *arg) OS_ensure_directory("tmp"); OS_ensure_directory("purgeable"); OS_ensure_directory(GLOBALTMPDIR); - iguana_coinadd("BTC",0); - iguana_coinadd("BTCD",0); + btc = iguana_coinadd("BTC",0); + btcd = iguana_coinadd("BTCD",0); + if ( btc == 0 || btcd == 0 ) + { + printf("error adding BTC.%p or BTCD.%p\n",btc,btcd); + exit(-1); + } if ( (tmpstr= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0)) != 0 ) { if ( (API_json= cJSON_Parse(tmpstr)) != 0 && (API_json= jobj(API_json,"result")) != 0 ) @@ -1108,12 +1113,13 @@ void iguana_main(void *arg) { sprintf(helperstr,"{\"name\":\"%d\"}",i); helperargs = clonestr(helperstr); - iguana_launch(iguana_coinadd("BTCD",0),"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD); + iguana_launch(btcd,"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD); + free(helperstr); } - iguana_launch(iguana_coinadd("BTCD",0),"rpcloop",iguana_rpcloop,SuperNET_MYINFO(0),IGUANA_PERMTHREAD); + iguana_launch(btcd,"rpcloop",iguana_rpcloop,SuperNET_MYINFO(0),IGUANA_PERMTHREAD); category_init(&MYINFO); if ( (coinargs= SuperNET_keysinit(&MYINFO,arg)) != 0 ) - iguana_launch(iguana_coinadd("BTCD",0),"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD); + iguana_launch(btcd,"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD); #ifdef __APPLE__ else if ( 1 ) { From b30767192df30419e3df7ed491fd0fd4386df265 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 17:01:24 -0300 Subject: [PATCH 125/333] test --- crypto777/iguana_utils.c | 8 ++++---- iguana/iguana777.c | 16 ++++++---------- iguana/main.c | 4 +++- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index d69a4e981..40f2b7ff8 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -190,8 +190,8 @@ double dxblend(double *destp,double val,double decay) return(slope); } -/*queue_t TerminateQ; int32_t TerminateQ_queued; -void iguana_terminator(void *arg) +queue_t TerminateQ; int32_t TerminateQ_queued; +/*void iguana_terminator(void *arg) { struct iguana_thread *t; uint32_t lastdisp = 0; int32_t terminated = 0; printf("iguana_terminator\n"); @@ -229,7 +229,7 @@ void iguana_launcher(void *ptr) coin = t->coin; t->funcp(t->arg); coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; - queue_enqueue("TerminateQ",&coin->TerminateQ,&t->DL,0); + queue_enqueue("TerminateQ",&TerminateQ,&t->DL,0); } void iguana_terminate(struct iguana_info *coin,struct iguana_thread *t) @@ -254,7 +254,7 @@ struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_f retval = OS_thread_create(&t->handle,NULL,(void *)iguana_launcher,(void *)t); if ( retval != 0 ) printf("error launching %s\n",t->name); - while ( (t= queue_dequeue(&coin->TerminateQ,0)) != 0 ) + while ( (t= queue_dequeue(&TerminateQ,0)) != 0 ) { if ( (rand() % 100000) == 0 ) printf("terminated.%d launched.%d terminate.%p\n",coin->Terminated[t->type],coin->Launched[t->type],t); diff --git a/iguana/iguana777.c b/iguana/iguana777.c index c6a10fb7f..5d663e8e1 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -374,21 +374,17 @@ void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) void iguana_helper(void *arg) { - FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t type,flag,idle=0; + FILE *fp = 0; cJSON *argjson=0; int32_t type,helperid=rand(),flag,idle=0; struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) - helpername = jstr(argjson,"name"); - if ( helpername == 0 ) - { - sprintf(name,"%d",rand()); - helpername = name; - } - type = (name[0] % 2); - sprintf(fname,"%s/%s",GLOBALTMPDIR,helpername); + helperid = juint(argjson,"helperid"); + type = (helperid % 2); + /*sprintf(fname,"%s/%s",GLOBALTMPDIR,helpername); OS_compatible_path(fname); - fp = fopen(fname,"wb"); + fp = fopen(fname,"wb");*/ if ( argjson != 0 ) free_json(argjson); + printf("HELPER.%d started\n",helperid); memset(&MEM,0,sizeof(MEM)); MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) diff --git a/iguana/main.c b/iguana/main.c index 29e3f12d6..54b1f4f00 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1107,12 +1107,14 @@ void iguana_main(void *arg) API_json = jobj(API_json,"API"); free(tmpstr); } + printf("generated API_json\n"); if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; for (i=0; i Date: Tue, 22 Mar 2016 17:03:23 -0300 Subject: [PATCH 126/333] test --- iguana/main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 54b1f4f00..92d1a5489 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1108,6 +1108,16 @@ void iguana_main(void *arg) free(tmpstr); } printf("generated API_json\n"); + if ( arg != 0 ) + { + cJSON *argjson; + if ( (argjson= cJSON_Parse(arg)) != 0 ) + { + printf("call argv JSON.(%s)\n",(char *)arg); + SuperNET_JSON(&MYINFO,argjson,0); + free_json(argjson); + } else printf("error parsing.(%s)\n",(char *)arg); + } if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; for (i=0; i Date: Tue, 22 Mar 2016 17:13:49 -0300 Subject: [PATCH 127/333] test --- iguana/main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 92d1a5489..6668f4f60 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1120,14 +1120,6 @@ void iguana_main(void *arg) } if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; - for (i=0; i Date: Tue, 22 Mar 2016 17:18:15 -0300 Subject: [PATCH 128/333] test --- iguana/iguana777.h | 11 ++--------- iguana/iguana_init.c | 1 - iguana/main.c | 1 + 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index ba9559be6..5aea81199 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -457,18 +457,11 @@ struct iguana_info struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; - //struct iguanakv *txids,*spends,*unspents,*pkhashes; - //struct iguana_txid *T; - //struct iguana_unspent *U; struct iguana_Uextra *Uextras; - //struct iguana_spend *S; struct iguana_Sextra *Sextras; - //struct iguana_pkhash *P; struct iguana_account *accounts; struct iguana_pkextra *pkextras; - //struct iguana_counts latest; - //struct iguana_ledger LEDGER,loadedLEDGER; struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; struct OS_memspace TXMEM; - queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ,recvQ; + 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]; @@ -804,7 +797,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); extern int32_t HDRnet,netBLOCKS; -extern queue_t bundlesQ,validateQ,emitQ,balancesQ; +extern queue_t bundlesQ,validateQ,emitQ,balancesQ,TerminateQ; extern char GLOBALTMPDIR[]; #include "../includes/iguana_api.h" diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 9d00881e0..cf5b83dd3 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -32,7 +32,6 @@ void iguana_initQs(struct iguana_info *coin) iguana_initQ(&coin->priorityQ,"priorityQ"); iguana_initQ(&coin->possibleQ,"possibleQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); - iguana_initQ(&coin->TerminateQ,"TerminateQ"); iguana_initQ(&coin->recvQ,"recvQ"); for (i=0; ipeers.active[i].sendQ,"addrsendQ"); diff --git a/iguana/main.c b/iguana/main.c index 6668f4f60..9a9de2580 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1120,6 +1120,7 @@ void iguana_main(void *arg) } if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; + iguana_initQ(&TerminateQ,"TerminateQ"); iguana_launch(btcd,"rpcloop",iguana_rpcloop,SuperNET_MYINFO(0),IGUANA_PERMTHREAD); category_init(&MYINFO); if ( (coinargs= SuperNET_keysinit(&MYINFO,arg)) != 0 ) From 4030eab558a45c0e955ef16652b84766f3037c66 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 17:23:16 -0300 Subject: [PATCH 129/333] test --- iguana/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 9a9de2580..bbef3214d 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -38,7 +38,7 @@ struct iguana_info *Coins[IGUANA_MAXCOINS]; char Userhome[512],GLOBALTMPDIR[512] = "tmp"; int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel; uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100; -queue_t helperQ,jsonQ,finishedQ,bundlesQ,validateQ,emitQ,balancesQ; +queue_t helperQ,jsonQ,finishedQ,bundlesQ,validateQ,emitQ,balancesQ,TerminateQ; struct supernet_info MYINFO,**MYINFOS; static int32_t initflag; int32_t HDRnet,netBLOCKS; @@ -1181,7 +1181,6 @@ void iguana_main(void *arg) helperargs = clonestr(helperstr); printf("launch[%d] of %d (%s)\n",i,IGUANA_NUMHELPERS,helperstr); iguana_launch(btcd,"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD); - free(helperstr); } mainloop(&MYINFO); } From 3eb24104251850134f30561cbfe2a2bf71f4235c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 17:28:32 -0300 Subject: [PATCH 130/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index bbef3214d..e0513bef1 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1121,7 +1121,6 @@ void iguana_main(void *arg) if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; iguana_initQ(&TerminateQ,"TerminateQ"); - iguana_launch(btcd,"rpcloop",iguana_rpcloop,SuperNET_MYINFO(0),IGUANA_PERMTHREAD); category_init(&MYINFO); if ( (coinargs= SuperNET_keysinit(&MYINFO,arg)) != 0 ) iguana_launch(btcd,"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD); @@ -1182,6 +1181,7 @@ void iguana_main(void *arg) printf("launch[%d] of %d (%s)\n",i,IGUANA_NUMHELPERS,helperstr); iguana_launch(btcd,"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD); } + iguana_launch(btcd,"rpcloop",iguana_rpcloop,SuperNET_MYINFO(0),IGUANA_PERMTHREAD); mainloop(&MYINFO); } From e50fff501e44d10592c3fe0e28176effce1b09c4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 18:03:02 -0300 Subject: [PATCH 131/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 7 +++---- iguana/iguana_recv.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 5aea81199..ae805025a 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -468,7 +468,7 @@ struct iguana_info //struct scriptinfo *scriptstable[2]; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified; - uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp; 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; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index e64f2608e..b50ce88a0 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -905,7 +905,6 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) void iguana_bundlestats(struct iguana_info *coin,char *str) { - static uint32_t lastdisp; int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; now = (uint32_t)time(NULL); @@ -955,7 +954,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( now > block->issued+10 ) { block->issued = now; - printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); } } @@ -1046,12 +1045,12 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) char str4[65],str5[65]; sprintf(str,"%s u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",coin->symbol,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,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) > lastdisp+10 ) + if ( time(NULL) > coin->lastdisp+10 ) { printf("%s\n",str); if ( (rand() % 100) == 0 ) myallocated(0,0); - lastdisp = (uint32_t)time(NULL); + coin->lastdisp = (uint32_t)time(NULL); if ( firstgap != 0 && firstgap->queued == 0 ) iguana_bundleQ(coin,firstgap,1000); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 885974fc2..6330e7af6 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1278,7 +1278,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { if ( bp->emitfinish != 0 ) { - printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); + //printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); return(0); } block = bp->blocks[req->bundlei]; From 98c75304d26d0fbc045d6ea719967811eabbb517 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 19:04:28 -0300 Subject: [PATCH 132/333] test --- iguana/iguana777.c | 48 +---------------------------- iguana/iguana777.h | 4 +-- iguana/iguana_bundles.c | 14 ++++----- iguana/iguana_peers.c | 2 +- iguana/iguana_ramchain.c | 4 +-- iguana/iguana_recv.c | 14 ++++----- iguana/iguana_unspents.c | 4 +-- iguana/main.c | 65 +++++++++++++++++++++++++++++++++++----- 8 files changed, 80 insertions(+), 75 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 5d663e8e1..e0207054a 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -252,7 +252,7 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->bp = bp, ptr->hdrsi = bp->hdrsi; ptr->type = 'E'; ptr->starttime = (uint32_t)time(NULL); - printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); queue_enqueue("emitQ",&emitQ,&ptr->DL,0); } @@ -432,52 +432,6 @@ void iguana_helper(void *arg) } } -void iguana_coinflush(struct iguana_info *coin,int32_t forceflag) -{ - int32_t hdrsi,blen; struct iguana_bundle *bp; char fname[1024],fname2[1024]; FILE *fp,*fp2=0; - memset(coin->bundlebits,0,sizeof(coin->bundlebits)); - for (hdrsi=0; hdrsibundlescount; hdrsi++) - if ( (bp= coin->bundles[hdrsi]) != 0 && bp->validated != 0 ) - SETBIT(coin->bundlebits,hdrsi); - blen = (int32_t)hconv_bitlen(coin->bundlescount); - for (hdrsi=0; hdrsibundlescount; hdrsi++) - { - if ( (bp= coin->bundles[hdrsi]) != 0 && (forceflag != 0 || (bp->dirty != 0 && time(NULL) > bp->dirty+60)) && bp->ramchain.H.data != 0 && bp->ramchain.A != 0 && bp->ramchain.Uextras != 0 ) - { - if ( forceflag == 0 ) - { - sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); - sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); - } - else - { - sprintf(fname,"DB/%s/accounts/debits_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - sprintf(fname2,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - } - //printf("save (%s) and (%s) %p %p\n",fname,fname2,bp,bp->ramchain.H.data);//,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numunspents); - if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) - { - if ( fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp) == sizeof(coin->bundlescount) && fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp2) == sizeof(coin->bundlescount) && fwrite(coin->bundlebits,1,blen,fp) == blen && fwrite(coin->bundlebits,1,blen,fp2) == blen ) - { - 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); - if ( bp->dirty != 0 ) - printf("error writing %s\n",fname); - } - else if ( fp != 0 ) - fclose(fp); - } - } -} - void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index ae805025a..f725d6f82 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -452,7 +452,7 @@ 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; + int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten; uint32_t longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; struct tai starttime; double startmillis; struct iguana_chain *chain; @@ -788,7 +788,7 @@ int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,i struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); 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_balanceflush(struct iguana_info *coin,int32_t refhdrsi); 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); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b50ce88a0..23bef3a86 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -496,7 +496,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { - if ( numpeers > 64 || addr->laggard++ > 3 ) + if ( numpeers > 64 || addr->laggard++ > 777 ) addr->dead = (uint32_t)time(NULL); for (j=0; jn; j++) { @@ -532,10 +532,10 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( priority != 0 ) { //printf("[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); + iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); flag++; } //else printf("%d ",now - block->issued); } @@ -557,7 +557,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int block->numrequests++; if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current); bp->issued[i] = block->issued = now; counter++; if ( --max <= 0 ) @@ -571,7 +571,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kick",coin,bp,i,bp->hashes[i],bp == coin->current); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current); bp->issued[i] = now; counter++; } @@ -579,7 +579,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kick",coin,bp,i,bp->speculative[i],0); + iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); bp->issued[i] = now; counter++; } @@ -741,7 +741,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else if ( bp == coin->current ) { - if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+10 ) + if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) { //char str[65]; printf(" mismatched [%d:%d] %s block.%p\n",bp->hdrsi,bundlei,bits256_str(str,bp->speculative[bundlei]),block); iguana_blockQ("missing",coin,0,-1,bp->speculative[bundlei],0); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 13aff469b..7ec17a4cb 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -622,7 +622,7 @@ void iguana_startconnection(void *arg) n++; iguana_iAconnected(coin,addr); coin->peers.numconnected++; - printf("PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); + printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) coin->peers.localaddr = addr; else if ( coin->peers.numranked == 0 ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d6df9d021..567c5496c 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2119,7 +2119,7 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru if ( (long)destoffset > (long)srcoffset ) printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); } - printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); + //printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); scriptspace = ramchain->H.data->scriptspace; scriptoffset = ramchain->H.scriptoffset; stacksize = ramchain->H.stacksize; @@ -2181,7 +2181,7 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru } int32_t i; for (i=0; iH.data->lhashes[i].uints[0]); - printf("%llx ht.%d bundlehashes\n",(long long)mapchain->H.data->sha256.txid,mapchain->height); + printf("%llx ht.%d bundlehashes.%s\n",(long long)mapchain->H.data->sha256.txid,mapchain->height,coin->symbol); iguana_ramchain_free(mapchain,cmpflag); } iguana_mempurge(hashmem); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 6330e7af6..8fcf3bb48 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -407,7 +407,7 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit prev = block; } coin->allhashes++; - // if ( bp->hdrsi == 0 ) + if ( bp->hdrsi == 0 ) printf("ALLHASHES FOUND! %d allhashes.%d\n",bp->bundleheight,coin->allhashes); if ( bp->queued == 0 ) iguana_bundleQ(coin,bp,bp->n*5 + (rand() % 500)); @@ -585,7 +585,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - if ( num > 2 ) + if ( 0 && num > 2 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { @@ -744,7 +744,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana { if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) { - printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); + //printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); } } @@ -774,7 +774,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 = coin->chain->bundlesize; + width = sqrt(coin->chain->bundlesize); while ( prev != 0 && width-- > 0 ) { if ( prev->mainchain != 0 ) @@ -1112,7 +1112,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) { iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],0); @@ -1184,8 +1184,8 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle req->height = height; req->bundlei = bundlei; char str2[65]; - if ( 0 && (bundlei % 250) == 0 ) - printf("%s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + //if ( 0 && (bundlei % 250) == 0 ) + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); if ( block != 0 ) { block->numrequests++; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 06aad65cf..76b3f34db 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -480,8 +480,8 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) errs++; } printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); - if ( errs == 0 ) - bp->validated = (uint32_t)time(NULL); + //if ( errs == 0 ) + // bp->validated = (uint32_t)time(NULL); return(-errs); } diff --git a/iguana/main.c b/iguana/main.c index e0513bef1..9ec16854c 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -323,9 +323,60 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) +{ + int32_t hdrsi,numpkinds; struct iguana_bundle *bp; char fname[1024],fname2[1024]; struct iguana_utxo *Uptr; struct iguana_account *Aptr; + memset(coin->bundlebits,0,sizeof(coin->bundlebits)); + for (hdrsi=0; hdrsibundlescount; hdrsi++) + if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) + break; + if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) + return(0); + refhdrsi = hdrsi; + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + if ( 1 )//forceflag == 0 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); + sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); + } + else + { + sprintf(fname,"DB/%s/accounts/debits_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); + sprintf(fname2,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); + } + //printf("save (%s) and (%s) %p %p\n",fname,fname2,bp,bp->ramchain.H.data);//,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numunspents); + /* if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + if ( fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp) == sizeof(coin->bundlescount) && fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp2) == sizeof(coin->bundlescount) && fwrite(coin->bundlebits,1,blen,fp) == blen && fwrite(coin->bundlebits,1,blen,fp2) == blen ) + { + 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); + if ( bp->dirty != 0 ) + printf("error writing %s\n",fname); + } + else if ( fp != 0 ) + fclose(fp);*/ + } + else return(-1); + } + coin->balanceswritten = refhdrsi + 1; + return(coin->balanceswritten); +} + void mainloop(struct supernet_info *myinfo) { - int32_t i,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; + int32_t i,j,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; sleep(3); printf("mainloop\n"); while ( 1 ) @@ -341,11 +392,16 @@ void mainloop(struct supernet_info *myinfo) { if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { - if ( bp->utxofinish != 0 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || (prevbp != 0 && prevbp->utxofinish > 1 && time(NULL) > prevbp->utxofinish+13)) ) + for (j=0; jhdrsi; j++) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->emitfinish <= 1 ) + break; + if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); iguana_balancecalc(ptr->coin,bp); bp->queued = 0; + iguana_balanceflush(ptr->coin,bp->hdrsi); + printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); } else { @@ -353,11 +409,6 @@ void mainloop(struct supernet_info *myinfo) coin->pendbalances--; iguana_balancesQ(coin,bp); } - if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) - { - //iguana_coinflush(ptr->coin,1); - printf("flushed bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); - } } myfree(ptr,ptr->allocsize); } From e73d24af925fc5776d0403220269f1c4059ac1cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 19:08:08 -0300 Subject: [PATCH 133/333] test --- iguana/iguana_recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 8fcf3bb48..1be3b0d7d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -974,9 +974,9 @@ int32_t iguana_reqblocks(struct iguana_info *coin) threshold *= 100. * sqrt(threshold) * .000777;*/ double threshold,lag = OS_milliseconds() - coin->backstopmillis; if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) - threshold = 10000; + threshold = 1000; else threshold = 300; - if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) + if ( coin->blocks.hwmchain.height < coin->longestchain && ((strcmp(coin->symbol,"BTC") != 0 && coin->backstop != coin->blocks.hwmchain.height+1) || lag > threshold) ) { coin->backstop = coin->blocks.hwmchain.height+1; hash2 = iguana_blockhash(coin,coin->backstop); From ba55665597040d60b3c7db98fb5a4daf547c77d4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 19:09:25 -0300 Subject: [PATCH 134/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 1be3b0d7d..41c70ed4c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1184,7 +1184,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle req->height = height; req->bundlei = bundlei; char str2[65]; - //if ( 0 && (bundlei % 250) == 0 ) + if ( 0 && (bundlei % 250) == 0 ) printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); if ( block != 0 ) { From 1b3a623c4206e3548184128d85df81ace4bf7c0f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 19:59:33 -0300 Subject: [PATCH 135/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 8 ++-- iguana/iguana_peers.c | 2 +- iguana/iguana_recv.c | 4 +- iguana/main.c | 92 ++++++++++++++++++++++++++++------------- 5 files changed, 72 insertions(+), 36 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index f725d6f82..a678f2397 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -788,7 +788,7 @@ int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,i struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); 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); -int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi); +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist); 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); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 23bef3a86..06d5f759f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -496,7 +496,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { - if ( numpeers > 64 || addr->laggard++ > 777 ) + if ( numpeers > 64 || addr->laggard++ > 13 ) addr->dead = (uint32_t)time(NULL); for (j=0; jn; j++) { @@ -762,8 +762,8 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i; - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) - return(0); + //if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) + // return(0); for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; @@ -829,7 +829,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { 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); + printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT.%s bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",coin->symbol,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 diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 7ec17a4cb..64a63ead0 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1085,7 +1085,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) addr->dead = 1; } } - printf(">>>>>>>>>>>>>> finish dedicatedloop.%s\n",addr->ipaddr); + printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); if ( addr->vinsfp != 0 ) fclose(addr->vinsfp); if ( addr->voutsfp != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 41c70ed4c..ebe5a7754 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -620,7 +620,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { - printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); + //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); if ( bp->speculative == 0 ) bp->speculative = mycalloc('s',bp->n+1,sizeof(*bp->speculative)); for (i=bp->numspec; in; i++) @@ -1006,7 +1006,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) flag++; char str[65]; if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) - printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); + printf("%s %s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",coin->symbol,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 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { diff --git a/iguana/main.c b/iguana/main.c index 9ec16854c..73dcdb2a5 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -323,54 +323,90 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif -int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { - int32_t hdrsi,numpkinds; struct iguana_bundle *bp; char fname[1024],fname2[1024]; struct iguana_utxo *Uptr; struct iguana_account *Aptr; + int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; + char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; + struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; + vupdate_sha256(balancehash.bytes,&vstate,0,0); memset(coin->bundlebits,0,sizeof(coin->bundlebits)); for (hdrsi=0; hdrsibundlescount; hdrsi++) if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) break; if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) return(0); - refhdrsi = hdrsi; - for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); - } - else - { - sprintf(fname,"DB/%s/accounts/debits_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - sprintf(fname2,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); - } - //printf("save (%s) and (%s) %p %p\n",fname,fname2,bp,bp->ramchain.H.data);//,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numunspents); - /* if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) - { - if ( fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp) == sizeof(coin->bundlescount) && fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp2) == sizeof(coin->bundlescount) && fwrite(coin->bundlebits,1,blen,fp) == blen && fwrite(coin->bundlebits,1,blen,fp2) == blen ) + if ( iter == 0 ) { - if ( fwrite(bp->ramchain.A,sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds,fp) == bp->ramchain.H.data->numpkinds ) + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + else if ( iter == 1 ) + { + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) { - if ( fwrite(bp->ramchain.Uextras,sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents,fp2) == bp->ramchain.H.data->numunspents ) + err = -1; + if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) ) { - bp->dirty = 0; - printf("saved (%s) and (%s)\n",fname,fname2); + if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) + { + if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) + { + bp->dirty = 0; + err = 0; + //printf("saved (%s) and (%s)\n",fname,fname2); + } + } } + if ( err != 0 ) + { + printf("balanceflush.%s error iter.%d hdrsi.%d\n",coin->symbol,iter,hdrsi); + fclose(fp); + fclose(fp2); + return(-1); + } + fclose(fp), fclose(fp2); + } + else if ( fp != 0 ) + fclose(fp); + } + else if ( iter == 2 ) + { + sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi,bp->bundleheight); + if ( OS_copyfile(fname,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname,destfname); + return(-1); + } + sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi,bp->bundleheight); + if ( OS_copyfile(fname2,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname2,destfname); + return(-1); + } + if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) + { + sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); + sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); } + continue; } - fclose(fp), fclose(fp2); - if ( bp->dirty != 0 ) - printf("error writing %s\n",fname); } - else if ( fp != 0 ) - fclose(fp);*/ } - else return(-1); } - coin->balanceswritten = refhdrsi + 1; + coin->balanceswritten = numhdrsi; + printf("BALANCES WRITTEN for %d bundles\n",coin->balanceswritten); return(coin->balanceswritten); } @@ -400,7 +436,7 @@ void mainloop(struct supernet_info *myinfo) //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); iguana_balancecalc(ptr->coin,bp); bp->queued = 0; - iguana_balanceflush(ptr->coin,bp->hdrsi); + iguana_balanceflush(ptr->coin,bp->hdrsi,3); printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); } else From ac2cddf38cd6e24e9d01763a28fd85193d03e71d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:15:53 -0300 Subject: [PATCH 136/333] test --- iguana/iguana_bundles.c | 6 ++++++ iguana/iguana_recv.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 06d5f759f..f86d5bc93 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -916,6 +916,12 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) { if ( (bp= coin->bundles[i]) != 0 ) { + if ( bp->emitfinish > 1 ) + { + for (j=0; jn; j++) + if ( bp->blocks[j] == 0 ) + bp->blocks[j] = iguana_blockfind(coin,bp->hashes[j]); + } //if ( iguana_blockfind(coin,bp->hashes[0]) == 0 ) // printf("UNEXPECTED null block for bundlehash.%d\n",bp->hdrsi); if ( bp->numhashes < bp->n && bp->speculative != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index ebe5a7754..167fbfa7e 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -992,9 +992,9 @@ int32_t iguana_reqblocks(struct iguana_info *coin) { if ( (block= iguana_blockfind(coin,hash2)) != 0 && bits256_cmp(block->RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) { - printf("speculative is next at %d\n",coin->backstop); + //printf("speculative is next at %d\n",coin->backstop); if ( _iguana_chainlink(coin,block) != 0 ) - lflag++, flag++, printf("NEWHWM.%d\n",coin->backstop); + lflag++, flag++;//, printf("NEWHWM.%d\n",coin->backstop); } } } From d8f3f7a121330c0cd04de3aea015e0921e0fceca Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:32:18 -0300 Subject: [PATCH 137/333] test --- iguana/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 73dcdb2a5..b88d683c6 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -429,15 +429,18 @@ void mainloop(struct supernet_info *myinfo) if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { for (j=0; jhdrsi; j++) - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->emitfinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->balancefinish <= 1 ) break; if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); iguana_balancecalc(ptr->coin,bp); bp->queued = 0; - iguana_balanceflush(ptr->coin,bp->hdrsi,3); - printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-20 ) + { + iguana_balanceflush(ptr->coin,bp->hdrsi,3); + printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + } } else { From c41604a53633aa2bfd038ebda472285e44a99fcf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:33:23 -0300 Subject: [PATCH 138/333] test --- iguana/iguana_ramchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 567c5496c..1af768449 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2275,7 +2275,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); ipbits = mycalloc('w',bp->n,sizeof(*ipbits)); filesizes = mycalloc('f',bp->n,sizeof(*filesizes)); - if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) == 0 ) + if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) != bp->n ) { iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("iguana_bundlesaveHT: no bundlefiles error\n"); From 8a0ea0bb84858f6a4af7c8f4bebdc5c715b4ade8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:40:33 -0300 Subject: [PATCH 139/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index f86d5bc93..df3ea7ee8 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -762,8 +762,8 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i; - //if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) - // return(0); + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) + return(0); for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; From 4f0bad6ba9400b11e0a75e1fc810a307bbe21aa1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:42:53 -0300 Subject: [PATCH 140/333] test --- iguana/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index b88d683c6..0d07119dc 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -44,9 +44,9 @@ static int32_t initflag; int32_t HDRnet,netBLOCKS; cJSON *API_json; #ifdef __linux__ -int32_t IGUANA_NUMHELPERS = 16; +int32_t IGUANA_NUMHELPERS = 3; #else -int32_t IGUANA_NUMHELPERS = 4; +int32_t IGUANA_NUMHELPERS = 3; #endif struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char **retjsonstrp; char remoteaddr[64]; char jsonstr[]; }; From c814cda0a4dc353f4f50353eff8f540b3dc00e36 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 20:45:19 -0300 Subject: [PATCH 141/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 0d07119dc..47c312a79 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -436,7 +436,7 @@ void mainloop(struct supernet_info *myinfo) //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); iguana_balancecalc(ptr->coin,bp); bp->queued = 0; - if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-20 ) + if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-3 ) { iguana_balanceflush(ptr->coin,bp->hdrsi,3); printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); From bba00a456c3cbadb7105e1a7ad10debc53eb1818 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 21:03:30 -0300 Subject: [PATCH 142/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index e0207054a..be73b47b2 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -467,7 +467,7 @@ void iguana_coinloop(void *arg) now = (uint32_t)time(NULL); if ( coin->active != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+600 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) + if ( coin->isRT == 0 && now > coin->startutc+200 && coin->numsaved >= (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; From cd3ac9c24df7ef61618c218c89177d4ee5ff43bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 21:43:09 -0300 Subject: [PATCH 143/333] test --- deprecated/obsolete.h | 17 ++++++++ iguana/iguana777.h | 6 ++- iguana/iguana_ramchain.c | 84 ++++++++++++++++++++++++++-------------- iguana/main.c | 8 ++-- 4 files changed, 80 insertions(+), 35 deletions(-) diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 043561e08..3aca5b870 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14395,5 +14395,22 @@ len = 0; printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); bp->lastspeculative = (uint32_t)time(NULL); }*/ + //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,"DB/%s/accounts/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 = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //if ( ramchain->Uextras == 0 ) + ramchain->Uextras = myaligned_alloc(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)); + //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); + //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); + //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index a678f2397..b705b4e67 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -374,8 +374,10 @@ struct iguana_ramchain struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; 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,*Xspendptr; - struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; struct iguana_utxo *Uextras; + struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; + void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; + struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; + struct iguana_utxo *Uextras; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; }; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 1af768449..562b675bb 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1286,14 +1286,26 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag ramchain->numXspends = 0; ramchain->Xspendinds = 0; } + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } if ( deleteflag != 0 ) memset(ramchain,0,sizeof(*ramchain)); return(0); } -void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) +int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; char fname[1024]; //long filesize; + RAMCHAIN_DECLARE; int32_t err=0,numhdrsi; char fname[1024]; //long filesize; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); @@ -1307,37 +1319,48 @@ void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ram } else { - if ( 1 && extraflag == 2 ) + err = -1; + sprintf(fname,"DB/%s/accounts/debits.%d",coin->symbol,ramchain->H.data->height); + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { - 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 = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + numhdrsi = *(int32_t *)ramchain->debitsfileptr; + if ( coin->balanceswritten == 0 && numhdrsi > 0 && numhdrsi <= coin->bundlescount ) + coin->balanceswritten = numhdrsi; + else if ( numhdrsi == coin->balanceswritten ) + { + ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + { + numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; + if ( numhdrsi == coin->balanceswritten ) + { + ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + err = 0; + } + } + } else printf("ramchain map error balanceswritten %d vs %d\n",coin->balanceswritten,numhdrsi); } - else + if ( err != 0 ) { - //if ( ramchain->A == 0 ) - ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); - } - //printf("ALLOC RAMCHAIN A.%p Uextras.%p | extraflag.%d hashmem.%p\n",ramchain->A,ramchain->Uextras,extraflag,ramchain->hashmem); + ramchain->A = 0; + ramchain->Uextras = 0; + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } + } } - //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)); - //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); - //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); } + return(err); } int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) @@ -1455,7 +1478,10 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname else if ( ramchain->expanded != 0 ) { if ( allocextras > 0 ) - iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras); + { + if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) + bp->balancefinish = (uint32_t)time(NULL); + } } if ( B != 0 && bp != 0 ) { diff --git a/iguana/main.c b/iguana/main.c index 47c312a79..7484d1686 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -381,25 +381,25 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } else if ( iter == 2 ) { - sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi,bp->bundleheight); + sprintf(destfname,"DB/%s/accounts/debits.%d",coin->symbol,bp->bundleheight); if ( OS_copyfile(fname,destfname,1) < 0 ) { printf("balances error copying (%s) -> (%s)\n",fname,destfname); return(-1); } - sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi,bp->bundleheight); + sprintf(destfname,"DB/%s/accounts/lastspends.%d",coin->symbol,bp->bundleheight); if ( OS_copyfile(fname2,destfname,1) < 0 ) { printf("balances error copying (%s) -> (%s)\n",fname2,destfname); return(-1); } - if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) + /*if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) { sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); OS_removefile(destfname,0); sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); OS_removefile(destfname,0); - } + }*/ continue; } } From befbe7eda14c209688963f7e5f16b4ea61a26f79 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 22:20:50 -0300 Subject: [PATCH 144/333] test --- iguana/iguana777.h | 5 ++- iguana/iguana_bundles.c | 15 +++++--- iguana/iguana_init.c | 80 ++++++++++++++++++++++++++++++++-------- iguana/iguana_ramchain.c | 18 ++++++--- iguana/main.c | 1 - 5 files changed, 90 insertions(+), 29 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index b705b4e67..17b975d7c 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -454,7 +454,7 @@ 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; + int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,balanceswritten; bits256 balancehash; uint32_t longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; struct tai starttime; double startmillis; struct iguana_chain *chain; @@ -474,7 +474,8 @@ struct iguana_info 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; - uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192],bundlebits[IGUANA_MAXBUNDLES/8+1]; struct OS_memspace blockMEM; + 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; }; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index df3ea7ee8..999942e7b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -761,7 +761,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { - struct iguana_bundle *prevbp; int32_t i; + struct iguana_bundle *prevbp; int32_t i,retval; if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) return(0); for (i=0; ihdrsi; i++) @@ -772,11 +772,16 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->startutxo == 0 ) { bp->startutxo = (uint32_t)time(NULL); - if ( iguana_utxogen(coin,bp) >= 0 ) + if ( (retval= iguana_utxogen(coin,bp)) >= 0 ) { - printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); - bp->utxofinish = (uint32_t)time(NULL); - iguana_balancesQ(coin,bp); + if ( retval > 0 ) + { + printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); + bp->utxofinish = (uint32_t)time(NULL); + bp->balancefinish = 0; + } + if ( bp->balancefinish <= 1 ) + iguana_balancesQ(coin,bp); return(1); } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index cf5b83dd3..41f398557 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -184,6 +184,34 @@ int32_t iguana_savehdrs(struct iguana_info *coin) return(retval); } +void iguana_truncatebalances(struct iguana_info *coin) +{ + int32_t i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + bp->balancefinish = 0; + ramchain = &bp->ramchain; + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + ramchain->A = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + ramchain->Uextras = 0; + } + } + } + coin->balanceswritten = 0; +} + void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { int32_t i,j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; @@ -275,14 +303,6 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) bp->emitfinish = (uint32_t)time(NULL) + 1; if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) coin->current = bp; - //printf("LOADED bundle.%d %p current %p\n",bp->bundleheight,bp,coin->current); - //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) - { - if ( 0 ) - bp->validated = bp->balancefinish = bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); - //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); - iguana_bundleQ(coin,bp,1000); - } } else { @@ -308,18 +328,46 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } if ( iter == 1 ) { - for (i=0; ibundlescount; i++) - if ( coin->bundles[i] == 0 ) - break; - printf("INIT bundles i.%d\n",i); - if ( 0 && i == coin->bundlescount && i > 1 ) + if ( coin->balanceswritten > 0 ) { - bp = coin->bundles[coin->bundlescount - 2]; - bp->emitfinish = bp->startutxo = bp->utxofinish = bp->balancefinish = 0; - iguana_bundleQ(coin,bp,1000); + for (i=0; ibalanceswritten; i++) + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) + break; + if ( i != coin->balanceswritten ) + { + printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); + iguana_truncatebalances(coin); + } + else + { + bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; int32_t numpkinds,numunspents; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + } + char str[65],str2[65]; printf("balancehash.(%s) vs (%s)\n",bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) + { + printf("balancehash mismatch\n"); + iguana_truncatebalances(coin); + } else printf("MATCHED balancehash numhdrsi.%d\n",coin->balanceswritten); + } } char buf[2048]; iguana_bundlestats(coin,buf); + if ( coin->balanceswritten < coin->bundlescount ) + { + for (i=coin->balanceswritten; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } + } } } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 562b675bb..9d9e148d2 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1305,7 +1305,7 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; int32_t err=0,numhdrsi; char fname[1024]; //long filesize; + RAMCHAIN_DECLARE; int32_t err=0,numhdrsi; char fname[1024]; bits256 balancehash; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); @@ -1324,22 +1324,27 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { numhdrsi = *(int32_t *)ramchain->debitsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); if ( coin->balanceswritten == 0 && numhdrsi > 0 && numhdrsi <= coin->bundlescount ) + { coin->balanceswritten = numhdrsi; - else if ( numhdrsi == coin->balanceswritten ) + coin->balancehash = balancehash; + } + else if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) { ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) { numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; - if ( numhdrsi == coin->balanceswritten ) + memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) { ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); err = 0; - } + } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); } - } else printf("ramchain map error balanceswritten %d vs %d\n",coin->balanceswritten,numhdrsi); + } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); } if ( err != 0 ) { @@ -1480,7 +1485,10 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname if ( allocextras > 0 ) { if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) + { bp->balancefinish = (uint32_t)time(NULL); + printf("found balances for %d\n",bp->hdrsi); + } } } if ( B != 0 && bp != 0 ) diff --git a/iguana/main.c b/iguana/main.c index 7484d1686..3693fffe4 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -329,7 +329,6 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; vupdate_sha256(balancehash.bytes,&vstate,0,0); - memset(coin->bundlebits,0,sizeof(coin->bundlebits)); for (hdrsi=0; hdrsibundlescount; hdrsi++) if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) break; From 42585cf8245a06746a611bbd69ba6e03098e4d56 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 22:34:14 -0300 Subject: [PATCH 145/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 9d9e148d2..764c35523 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1325,7 +1325,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * { numhdrsi = *(int32_t *)ramchain->debitsfileptr; memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); - if ( coin->balanceswritten == 0 && numhdrsi > 0 && numhdrsi <= coin->bundlescount ) + if ( coin->balanceswritten == 0 ) { coin->balanceswritten = numhdrsi; coin->balancehash = balancehash; diff --git a/iguana/main.c b/iguana/main.c index 3693fffe4..20d3f3546 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -323,6 +323,8 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif +// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 +// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; From 626dc8c9cca31367eea53c1b5f0e99f83dd0175d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 22:38:53 -0300 Subject: [PATCH 146/333] test --- iguana/iguana_ramchain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 764c35523..9b4d569e2 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1380,6 +1380,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); if ( memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) { + bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); ramchain->Xspendptr = ptr; ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); //int32_t i; for (i=0; inumXspends; i++) From 34d244cf91fc4808899e8b8499d5760a32357c30 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 22:58:11 -0300 Subject: [PATCH 147/333] test --- iguana/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 20d3f3546..fb3595c22 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -327,7 +327,7 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func // mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { - int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; + int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; vupdate_sha256(balancehash.bytes,&vstate,0,0); @@ -342,6 +342,10 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); @@ -403,11 +407,12 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu }*/ continue; } - } + } else printf("error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",hdrsi,Aptr,Uptr,numpkinds,numunspents); } } + coin->balancehash = balancehash; coin->balanceswritten = numhdrsi; - printf("BALANCES WRITTEN for %d bundles\n",coin->balanceswritten); + char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash)); return(coin->balanceswritten); } From 872f3b5523466897280254594798b6caaf67f477 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 23:27:38 -0300 Subject: [PATCH 148/333] test --- iguana/iguana_bundles.c | 30 +++++---- iguana/iguana_init.c | 4 ++ iguana/iguana_ramchain.c | 127 ++++++++++++++++++++++----------------- iguana/main.c | 12 ++-- 4 files changed, 100 insertions(+), 73 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 999942e7b..29fe97d51 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -336,22 +336,26 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind) { static bits256 zero; - int32_t hdrsi; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata; - iguana_peerfname(coin,&hdrsi,"DB",fname,0,bp->hashes[0],zero,bp->n); - if ( (fp= fopen(fname,"rb")) != 0 ) + int32_t hdrsi,iter; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata; + for (iter=0; iter<2; iter++) { - fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); - if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) + iguana_peerfname(coin,&hdrsi,iter==0?"DB/ro":"DB",fname,0,bp->hashes[0],zero,bp->n); + if ( (fp= fopen(fname,"rb")) != 0 ) { - fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); - if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) + fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); + if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) { - fclose(fp); - return(tx); - } else printf("bundletx read error\n"); - } else printf("bundletx Toffset read error\n"); - fclose(fp); - } else printf("bundletx couldnt open.(%s)\n",fname); + fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); + if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) + { + fclose(fp); + return(tx); + } else printf("bundletx read error\n"); + } else printf("bundletx Toffset read error\n"); + fclose(fp); + } + } + printf("bundletx couldnt open.(%s)\n",fname); return(0); } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 41f398557..eb780f551 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -365,8 +365,12 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) for (i=coin->balanceswritten; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) + { + printf("%d ",i); iguana_bundleQ(coin,bp,1000); + } } + printf("BALANCESQ\n"); } } } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 9b4d569e2..82cd218fd 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1305,7 +1305,7 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; int32_t err=0,numhdrsi; char fname[1024]; bits256 balancehash; + RAMCHAIN_DECLARE; int32_t iter,err=0,numhdrsi; char fname[1024]; bits256 balancehash; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); @@ -1320,31 +1320,36 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * else { err = -1; - sprintf(fname,"DB/%s/accounts/debits.%d",coin->symbol,ramchain->H.data->height); - if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) + for (iter=0; iter<2; iter++) { - numhdrsi = *(int32_t *)ramchain->debitsfileptr; - memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); - if ( coin->balanceswritten == 0 ) + sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { - coin->balanceswritten = numhdrsi; - coin->balancehash = balancehash; - } - else if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) - { - ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); - sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); - if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + numhdrsi = *(int32_t *)ramchain->debitsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( coin->balanceswritten == 0 ) { - numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; - memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); - if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) - { - ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); - err = 0; - } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + coin->balanceswritten = numhdrsi; + coin->balancehash = balancehash; } - } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + else if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + { + numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + err = 0; + } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } + } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } + if ( err == 0 ) + break; } if ( err != 0 ) { @@ -1370,39 +1375,43 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { - int32_t hdrsi; bits256 sha256; char fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; - sprintf(dirname,"DB/%s/spends",coin->symbol); - if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + int32_t hdrsi,iter; bits256 sha256; char fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; + for (iter=0; iter<2; iter++) { - if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) + sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); + if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 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 ) - { - bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); - ramchain->Xspendptr = ptr; - ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); - //int32_t i; for (i=0; inumXspends; i++) - // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); - //printf("filesize %ld Xspendptr.%p %p num.%d\n",ftell(fp),ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); - //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); - } - else + if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) { - char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); - munmap(ptr,filesize); - ramchain->Xspendinds = 0; - } - } //else printf("no Xspendfile\n"); - } else printf("couldnt open.(%s)\n",fname); + 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 ) + { + bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); + ramchain->Xspendptr = ptr; + ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + return(ramchain->numXspends); + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",ftell(fp),ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); + } + else + { + char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); + munmap(ptr,filesize); + ramchain->Xspendinds = 0; + } + } //else printf("no Xspendfile\n"); + } else printf("couldnt open.(%s)\n",fname); + } 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; - char str[65],str2[65]; long filesize; void *ptr; struct iguana_block *block; + RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; + char str[65],str2[65],*dirstr; long filesize; void *ptr; struct iguana_block *block; /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) { sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); @@ -1414,18 +1423,24 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname }*/ if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + for (iter=0; iter<2; iter++) { - printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); - return(0); + dirstr = (iter == 0) ? "DB/ro" : "DB"; + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?dirstr:GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); + continue; + } + memset(ramchain,0,sizeof(*ramchain)); + if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + continue; + ramchain->fileptr = ptr; + ramchain->filesize = (long)filesize; + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); } - memset(ramchain,0,sizeof(*ramchain)); - if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + if ( ramchain->fileptr == 0 ) return(0); - ramchain->fileptr = ptr; - ramchain->filesize = (long)filesize; - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); } if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { diff --git a/iguana/main.c b/iguana/main.c index fb3595c22..333231bfe 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -368,7 +368,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { bp->dirty = 0; err = 0; - //printf("saved (%s) and (%s)\n",fname,fname2); + printf("saved (%s) and (%s)\n",fname,fname2); } } } @@ -381,8 +381,12 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } fclose(fp), fclose(fp2); } - else if ( fp != 0 ) - fclose(fp); + else + { + printf("error opening %s or %s %p\n",fname,fname2,fp); + if ( fp != 0 ) + fclose(fp); + } } else if ( iter == 2 ) { @@ -398,6 +402,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu printf("balances error copying (%s) -> (%s)\n",fname2,destfname); return(-1); } + printf("%s %s\n",fname,destfname); /*if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) { sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); @@ -405,7 +410,6 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); OS_removefile(destfname,0); }*/ - continue; } } else printf("error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",hdrsi,Aptr,Uptr,numpkinds,numunspents); } From 6b45e35c4b4ac3ea8cea73da0816a838ef8d8917 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 23:44:20 -0300 Subject: [PATCH 149/333] test --- iguana/iguana_unspents.c | 14 +++----------- iguana/main.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 76b3f34db..7028aee34 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -347,7 +347,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t spendind,n,errs=0,emit=0; uint32_t unspentind,pkind,txidind; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; int32_t hdrsi; - uint32_t numtxid,now,h,refheight; struct iguana_utxo *utxo; + uint32_t numtxid,now,h,refheight; struct iguana_utxo *utxo,*Uextras; ramchain = &bp->ramchain; //printf("BALANCEGEN.%d\n",bp->bundleheight); if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) @@ -420,15 +420,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->ramchain.Uextras == 0 ) - { - spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); - } - if ( spentbp->ramchain.A == 0 ) - { - spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); - } - if ( spentbp->ramchain.Uextras == 0 || (A2= spentbp->ramchain.A) == 0 ) + if ( (Uextras= spentbp->ramchain.Uextras) == 0 || (A2= spentbp->ramchain.A) == 0 ) { printf("null ptrs %p %p\n",spentbp->ramchain.Uextras,spentbp->ramchain.A); errs++; @@ -439,7 +431,7 @@ 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 ) { - utxo = &spentbp->ramchain.Uextras[unspentind]; + utxo = &Uextras[unspentind]; if ( utxo->spentflag == 0 ) { utxo->prevspendind = A2[pkind].lastind; diff --git a/iguana/main.c b/iguana/main.c index 333231bfe..8b0137dc7 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -342,6 +342,19 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { for (hdrsi=0; hdrsibundles[hdrsi]) == 0 || bp->ramchain.H.data == 0 ) + { + printf("balance flush null bp[%d]??\n",hdrsi); + exit(-1); + } + if ( bp->ramchain.Uextras == 0 ) + { + bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); + } + if ( bp->ramchain.A == 0 ) + { + bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); + } Aptr = 0; Uptr = 0; numunspents = 0; @@ -368,7 +381,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { bp->dirty = 0; err = 0; - printf("saved (%s) and (%s)\n",fname,fname2); + printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); } } } From 8fdb38f98729720f2b2cd39408dfb9a7d2a2cec3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 22 Mar 2016 23:52:02 -0300 Subject: [PATCH 150/333] test --- iguana/iguana_unspents.c | 10 +++++++++- iguana/main.c | 19 ++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 7028aee34..40d422724 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -420,9 +420,17 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { + if ( spentbp->ramchain.Uextras == 0 ) + { + spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); + } + if ( spentbp->ramchain.A == 0 ) + { + spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); + } if ( (Uextras= spentbp->ramchain.Uextras) == 0 || (A2= spentbp->ramchain.A) == 0 ) { - printf("null ptrs %p %p\n",spentbp->ramchain.Uextras,spentbp->ramchain.A); + printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); errs++; } else diff --git a/iguana/main.c b/iguana/main.c index 8b0137dc7..27c5b8dcd 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -342,19 +342,6 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { for (hdrsi=0; hdrsibundles[hdrsi]) == 0 || bp->ramchain.H.data == 0 ) - { - printf("balance flush null bp[%d]??\n",hdrsi); - exit(-1); - } - if ( bp->ramchain.Uextras == 0 ) - { - bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); - } - if ( bp->ramchain.A == 0 ) - { - bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); - } Aptr = 0; Uptr = 0; numunspents = 0; @@ -452,11 +439,17 @@ void mainloop(struct supernet_info *myinfo) if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { for (j=0; jhdrsi; j++) + { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->balancefinish <= 1 ) break; + prevbp->ramchain.A = 0; + prevbp->ramchain.Uextras = 0; + } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); + bp->ramchain.A = 0; + bp->ramchain.Uextras = 0; iguana_balancecalc(ptr->coin,bp); bp->queued = 0; if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-3 ) From 640056ab83a94436225e66cebd145379bbfdaa44 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:07:29 -0300 Subject: [PATCH 151/333] test --- iguana/iguana777.c | 4 +- iguana/iguana777.h | 10 +++- iguana/iguana_unspents.c | 125 ++++++++++++++++++++++++++++++--------- iguana/main.c | 3 +- 4 files changed, 109 insertions(+), 33 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index be73b47b2..8de74e774 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -352,7 +352,7 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m return(0); } -void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) +void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental) { uint32_t starttime; if ( bp->balancefinish > 1 ) @@ -362,7 +362,7 @@ void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) return; } starttime = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,bp) < 0 ) + if ( iguana_balancegen(coin,bp,incremental) < 0 ) { printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); exit(-1); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 17b975d7c..c513112ac 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -338,7 +338,9 @@ struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((pack // dynamic struct iguana_account { int64_t total; uint32_t lastind; } __attribute__((packed)); -struct iguana_utxo { uint32_t prevspendind,height:31,spentflag:1; } __attribute__((packed)); +struct iguana_utxo { uint32_t prevunspentind,height:31,spentflag:1; } __attribute__((packed)); +struct iguana_hhaccount { UT_hash_handle hh; uint8_t buf[6]; struct iguana_account a; } __attribute__((packed)); +struct iguana_hhutxo { UT_hash_handle hh; uint8_t buf[6]; struct iguana_utxo u; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) struct iguana_spendvector { uint32_t ind,height; uint16_t hdrsi; } __attribute__((packed)); // unspentind @@ -478,6 +480,7 @@ struct iguana_info uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; + struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; @@ -783,7 +786,7 @@ int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint3 void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp); -int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental); int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); struct iguana_bloominds iguana_calcbloom(bits256 hash2); @@ -793,10 +796,11 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist); 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); +void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 40d422724..69e1e3287 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -16,6 +16,32 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" +int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdris,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) +{ + struct iguana_hhutxo *hhutxo; struct iguana_hhaccount *hhacct; + uint8_t buf[sizeof(spent_hdris) + sizeof(uint32_t)]; + memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdris,sizeof(spent_hdris)); + memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); + HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); + if ( hhutxo != 0 && hhutxo->u.spentflag != 0 ) + return(-1); + hhutxo = calloc(1,sizeof(*hhutxo)); + HASH_ADD(hh,coin->utxotable,buf,sizeof(buf),hhutxo); + memcpy(buf,(void *)&spent_pkind,sizeof(spent_pkind)); + HASH_FIND(hh,coin->accountstable,buf,sizeof(buf),hhacct); + if ( hhacct == 0 ) + { + hhacct = calloc(1,sizeof(*hhacct)); + HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); + } + hhutxo->u.spentflag = 1; + hhutxo->u.height = height; + hhutxo->u.prevunspentind = hhacct->a.lastind; + hhacct->a.lastind = spent_unspentind; + hhacct->a.total += spent_value; + return(0); +} + 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) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; @@ -196,6 +222,26 @@ int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf return(n); } +void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + struct iguana_pkhash *P,p; struct iguana_unspent *U,u; struct iguana_txid *T,txid; uint32_t i,numpkinds,numtxids,numunspents; + if ( ramchain->H.data != 0 ) + { + U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); + T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + numpkinds = ramchain->H.data->numpkinds; + numunspents = ramchain->H.data->numunspents; + numtxids = ramchain->H.data->numtxids; + for (i=1; iramchain; + Uextras = 0; + A2 = 0; //printf("BALANCEGEN.%d\n",bp->bundleheight); if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); @@ -420,39 +468,64 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->ramchain.Uextras == 0 ) + if ( spentbp->dirty == 0 ) + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + if ( incremental == 0 ) { - spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); - } - if ( spentbp->ramchain.A == 0 ) - { - spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); - } - if ( (Uextras= spentbp->ramchain.Uextras) == 0 || (A2= spentbp->ramchain.A) == 0 ) - { - printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); - errs++; + if ( spentbp->ramchain.Uextras == 0 ) + { + spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); + } + if ( spentbp->ramchain.A == 0 ) + { + spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); + } } - else + Uextras = spentbp->ramchain.Uextras; + A2 = spentbp->ramchain.A; + if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) { spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); u = &spentU[unspentind]; if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) + spentbp->dirty = now; + flag = -1; + if ( incremental == 0 ) { - utxo->prevspendind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = h; - A2[pkind].total += u->value; - A2[pkind].lastind = spendind; - spentbp->dirty = now; + if ( Uextras == 0 || A2 == 0 ) + { + printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); + errs++; + } + else + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevunspentind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = h; + A2[pkind].total += u->value; + A2[pkind].lastind = unspentind;//spendind; + flag = 0; + } + } } else + { + if ( bp != spentbp ) + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); + } + else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); + } + if ( flag != 0 ) { errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevspendind,utxo->spentflag,utxo->height); + printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); getchar(); } } @@ -480,8 +553,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) errs++; } printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); - //if ( errs == 0 ) - // bp->validated = (uint32_t)time(NULL); return(-errs); } diff --git a/iguana/main.c b/iguana/main.c index 27c5b8dcd..2342439f7 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -323,6 +323,7 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif +// mksquashfs DB/BTC BTC.squash -b 1048576 // mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 // mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) @@ -450,7 +451,7 @@ void mainloop(struct supernet_info *myinfo) //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); bp->ramchain.A = 0; bp->ramchain.Uextras = 0; - iguana_balancecalc(ptr->coin,bp); + iguana_balancecalc(ptr->coin,bp,bp == coin->current); bp->queued = 0; if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-3 ) { From 2860ce437ae2f3f6aa5415ae31a655c4e57e614b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:10:03 -0300 Subject: [PATCH 152/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 2342439f7..ba42c0129 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -441,7 +441,7 @@ void mainloop(struct supernet_info *myinfo) { for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->balancefinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 )//prevbp->balancefinish <= 1 ) break; prevbp->ramchain.A = 0; prevbp->ramchain.Uextras = 0; From 8251da8efb83b0e8ee972ec60c1035a8a6a7d895 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:15:50 -0300 Subject: [PATCH 153/333] test --- iguana/iguana_unspents.c | 4 +++- iguana/main.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 69e1e3287..d59a87f98 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -469,7 +469,10 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { if ( spentbp->dirty == 0 ) + { + spentbp->dirty = now; iguana_ramchain_prefetch(coin,&spentbp->ramchain); + } if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) @@ -489,7 +492,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 u = &spentU[unspentind]; if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) { - spentbp->dirty = now; flag = -1; if ( incremental == 0 ) { diff --git a/iguana/main.c b/iguana/main.c index ba42c0129..cf62f18e9 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -367,7 +367,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) { - bp->dirty = 0; + //bp->dirty = 0; err = 0; printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); } From 8e9977654a036e5cde3801efee159611b3e7430f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:20:57 -0300 Subject: [PATCH 154/333] test --- iguana/iguana_unspents.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d59a87f98..70ecb5f32 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -20,6 +20,8 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdris,uint32_t { struct iguana_hhutxo *hhutxo; struct iguana_hhaccount *hhacct; uint8_t buf[sizeof(spent_hdris) + sizeof(uint32_t)]; + printf("unexpected utxoupdate\n"); + exit(-1); memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdris,sizeof(spent_hdris)); memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); From 10e896303870b066bf5cc2250c52dfcd9a532457 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:23:55 -0300 Subject: [PATCH 155/333] test --- iguana/iguana_unspents.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 70ecb5f32..c1b88b491 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -473,16 +473,19 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 if ( spentbp->dirty == 0 ) { spentbp->dirty = now; + printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); } if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) { + printf("alloc Uextras.[%d]\n",spentbp->hdrsi); spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); } if ( spentbp->ramchain.A == 0 ) { + printf("alloc A2.[%d]\n",spentbp->hdrsi); spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); } } From 4d0a19a08400022d7308da1be8942124ba84a669 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:28:13 -0300 Subject: [PATCH 156/333] test --- iguana/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index cf62f18e9..3c6f4dec1 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -449,8 +449,8 @@ void mainloop(struct supernet_info *myinfo) if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); - bp->ramchain.A = 0; - bp->ramchain.Uextras = 0; + //bp->ramchain.A = 0; + //bp->ramchain.Uextras = 0; iguana_balancecalc(ptr->coin,bp,bp == coin->current); bp->queued = 0; if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-3 ) From 3a0006599ba2ef262013e75a848db3cf394b73ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:33:22 -0300 Subject: [PATCH 157/333] test --- iguana/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 3c6f4dec1..3071fab3b 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -443,8 +443,8 @@ void mainloop(struct supernet_info *myinfo) { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 )//prevbp->balancefinish <= 1 ) break; - prevbp->ramchain.A = 0; - prevbp->ramchain.Uextras = 0; + //prevbp->ramchain.A = 0; + //prevbp->ramchain.Uextras = 0; } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { From 36c0d5245f2daf926a0b2140bb3b40e8f5d107f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:41:51 -0300 Subject: [PATCH 158/333] test --- iguana/iguana_unspents.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c1b88b491..ddb923ecf 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -470,22 +470,21 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->dirty == 0 ) + if ( spentbp->dirty++ > 100 ) { - spentbp->dirty = now; printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); } - if ( incremental == 0 ) + //if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) { - printf("alloc Uextras.[%d]\n",spentbp->hdrsi); + //printf("alloc Uextras.[%d]\n",spentbp->hdrsi); spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); } if ( spentbp->ramchain.A == 0 ) { - printf("alloc A2.[%d]\n",spentbp->hdrsi); + //printf("alloc A2.[%d]\n",spentbp->hdrsi); spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); } } From 3ac0e1425cc82f0b7c631810861f4f85195ee0fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:43:46 -0300 Subject: [PATCH 159/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ddb923ecf..e475d7c1d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -470,7 +470,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->dirty++ > 100 ) + if ( spentbp->dirty++ == 100 ) { printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 1c8dd79107b64aeb5ee77267fbead9b6cfff107c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 01:59:31 -0300 Subject: [PATCH 160/333] test --- iguana/main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 3071fab3b..273052647 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -439,9 +439,19 @@ void mainloop(struct supernet_info *myinfo) { if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { + if ( bp->ramchain.Uextras == 0 ) + { + printf("alloc Uextras.[%d]\n",bp->hdrsi); + bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); + } + if ( bp->ramchain.A == 0 ) + { + printf("alloc A2.[%d]\n",bp->hdrsi); + bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); + } for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 )//prevbp->balancefinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ||prevbp->balancefinish <= 1 ) break; //prevbp->ramchain.A = 0; //prevbp->ramchain.Uextras = 0; @@ -453,7 +463,7 @@ void mainloop(struct supernet_info *myinfo) //bp->ramchain.Uextras = 0; iguana_balancecalc(ptr->coin,bp,bp == coin->current); bp->queued = 0; - if ( bp->hdrsi > coin->longestchain/coin->chain->bundlesize-3 ) + if ( bp->hdrsi >= coin->longestchain/coin->chain->bundlesize-1 ) { iguana_balanceflush(ptr->coin,bp->hdrsi,3); printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); From 2f75411bb28cb51a91f74183b1aeadac250afe84 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 02:11:08 -0300 Subject: [PATCH 161/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 273052647..d9328ff72 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -463,7 +463,7 @@ void mainloop(struct supernet_info *myinfo) //bp->ramchain.Uextras = 0; iguana_balancecalc(ptr->coin,bp,bp == coin->current); bp->queued = 0; - if ( bp->hdrsi >= coin->longestchain/coin->chain->bundlesize-1 ) + if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) { iguana_balanceflush(ptr->coin,bp->hdrsi,3); printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); From 02da91fbf94c896ca6b9c4f54fdbfa111c141aac Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 02:51:52 -0300 Subject: [PATCH 162/333] test --- iguana/iguana_init.c | 2 +- iguana/main.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index eb780f551..33a90321a 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -333,7 +333,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) for (i=0; ibalanceswritten; i++) if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) break; - if ( i != coin->balanceswritten ) + if ( i != coin->balanceswritten-1 ) { printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); iguana_truncatebalances(coin); diff --git a/iguana/main.c b/iguana/main.c index d9328ff72..18f4f7bd5 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -324,8 +324,9 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func #endif // mksquashfs DB/BTC BTC.squash -b 1048576 -// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 -// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K +// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 -> takes a really long time 2:1 compress +// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K -> takes a long time 2:1 compress + int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; From 994f2341bcedde8f38f966b7ce581bafaaf80a1e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 02:54:15 -0300 Subject: [PATCH 163/333] test --- iguana/iguana_init.c | 2 +- iguana/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 33a90321a..eb780f551 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -333,7 +333,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) for (i=0; ibalanceswritten; i++) if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) break; - if ( i != coin->balanceswritten-1 ) + if ( i != coin->balanceswritten ) { printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); iguana_truncatebalances(coin); diff --git a/iguana/main.c b/iguana/main.c index 18f4f7bd5..49bd66f0c 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -338,7 +338,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu break; if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) return(0); - numhdrsi = hdrsi+1; + numhdrsi = hdrsi; vupdate_sha256(balancehash.bytes,&vstate,0,0); for (iter=0; iter<3; iter++) { From faae64dfefcfce75a9d14c01e09d8416c98b6448 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 03:20:16 -0300 Subject: [PATCH 164/333] test --- iguana/iguana_init.c | 6 +++--- iguana/main.c | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index eb780f551..49e314ea5 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -348,13 +348,13 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); - } + } else printf("missing hdrs.[%d]\n",i); } - char str[65],str2[65]; printf("balancehash.(%s) vs (%s)\n",bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + char str[65],str2[65]; printf("written.%d balancehash.(%s) vs (%s)\n",coin->balanceswritten,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); if ( memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) { printf("balancehash mismatch\n"); - iguana_truncatebalances(coin); + //iguana_truncatebalances(coin); } else printf("MATCHED balancehash numhdrsi.%d\n",coin->balanceswritten); } } diff --git a/iguana/main.c b/iguana/main.c index 49bd66f0c..348d4d1a5 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -323,9 +323,18 @@ void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } #endif -// mksquashfs DB/BTC BTC.squash -b 1048576 -// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 -> takes a really long time 2:1 compress -// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K -> takes a long time 2:1 compress +// mksquashfs DB/BTC BTC.squash -b 1048576 -> 19GB? +// mksquashfs DB/BTC BTC.lzo -comp lzo -b 1048576 -> takes a really long time -> 20GB +// mksquashfs DB/BTC BTC.xz -b 1048576 -comp xz -Xdict-size 512K -> takes a long time -> 16GB +// mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K -> takes a long time -> +/* + mksquashfs DB/BTC BTC.xz -comp xz +mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K +mksquashfs DB/BTC BTC.lzo -comp lzo +mksquashfs DB/BTC BTC.lzo1m -comp lzo -b 1048576 +mksquashfs DB/BTC BTC.squash +mksquashfs DB/BTC BTC.squash1M -b 1048576 +*/ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { From 89537eea02aed1aec48396e2ed23b12cefb97bab Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 03:24:19 -0300 Subject: [PATCH 165/333] test --- iguana/iguana_init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 49e314ea5..f249859cd 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -344,17 +344,19 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) vupdate_sha256(balancehash.bytes,&vstate,0,0); for (i=0; ibalanceswritten; i++) { + numpkinds = numunspents = 0; + Aptr = 0, Uptr = 0; if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); - } else printf("missing hdrs.[%d]\n",i); + } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); } char str[65],str2[65]; printf("written.%d balancehash.(%s) vs (%s)\n",coin->balanceswritten,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); if ( memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) { printf("balancehash mismatch\n"); - //iguana_truncatebalances(coin); + iguana_truncatebalances(coin); } else printf("MATCHED balancehash numhdrsi.%d\n",coin->balanceswritten); } } From a19ae12b3b6bd5b7b94e2a020c10877fdc6f4528 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 03:29:09 -0300 Subject: [PATCH 166/333] test --- iguana/iguana_ramchain.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 82cd218fd..e0238ed37 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1345,14 +1345,14 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); err = 0; } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); - } + } else printf("ramchain map error3 %s\n",fname); } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); } if ( err == 0 ) + { + printf("mapped extra.%s\n",fname); break; - } - if ( err != 0 ) - { + } ramchain->A = 0; ramchain->Uextras = 0; if ( ramchain->debitsfileptr != 0 ) @@ -1367,7 +1367,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * ramchain->lastspendsfileptr = 0; ramchain->lastspendsfilesize = 0; } - } + } } } return(err); From 1c070e5aecf1a8e2da4690f6b3a173f0e0196d47 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 03:33:25 -0300 Subject: [PATCH 167/333] test --- iguana/iguana_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index f249859cd..e09330b23 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -289,7 +289,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( strcmp(checkstr,line+k+1 + 64 + 1) == 0 ) { init_hexbytes_noT(checkstr,hash2.bytes,sizeof(hash2)); - //char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash2),checkstr,bits256_str(str2,allhash)); + char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash2),checkstr,bits256_str(str2,allhash)); if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) { bp->bundleheight = height; From c0bef0cfead6fa7f744adbc80e79c8ac78fe06db Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 03:35:32 -0300 Subject: [PATCH 168/333] test --- iguana/iguana_ramchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index e0238ed37..3ec936f50 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1449,7 +1449,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - //printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; From 39c99e94d0b45c5488e3850610184c8b7ebdb683 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 14:41:35 -0300 Subject: [PATCH 169/333] test --- iguana/iguana_ramchain.c | 44 ++++++++++++++++++++++++++++++++++++++-- iguana/iguana_unspents.c | 26 +++--------------------- iguana/main.c | 4 +++- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 3ec936f50..89b12fa5a 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -805,6 +805,46 @@ void *iguana_ramchain_offset(void *dest,uint8_t *lhash,FILE *fp,uint64_t fpos,vo return((void *)(long)((long)destptr + fpos)); } +void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + struct iguana_pkhash *P,p; struct iguana_unspent *U,u; struct iguana_txid *T,txid; uint32_t i,numpkinds,numtxids,numunspents,tlen,plen,nonz=0; uint8_t *PKbits,*TXbits,*ptr; + if ( ramchain->H.data != 0 ) + { + ptr = ramchain->fileptr; + for (i=0; ifilesize; i++) + if ( ptr[i] != 0 ) + nonz++; + printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); + return; + U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); + T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); + PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + numpkinds = ramchain->H.data->numpkinds; + numunspents = ramchain->H.data->numunspents; + numtxids = ramchain->H.data->numtxids; + tlen = ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits; + plen = ramchain->H.data->numpksparse * ramchain->H.data->pksparsebits; + if ( 0 ) + { + for (i=1; iH.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; @@ -1504,7 +1544,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname { bp->balancefinish = (uint32_t)time(NULL); printf("found balances for %d\n",bp->hdrsi); - } + } else printf("error with extras\n"); } } if ( B != 0 && bp != 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index e475d7c1d..9b0ab8cfb 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -224,26 +224,6 @@ int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf return(n); } -void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain) -{ - struct iguana_pkhash *P,p; struct iguana_unspent *U,u; struct iguana_txid *T,txid; uint32_t i,numpkinds,numtxids,numunspents; - if ( ramchain->H.data != 0 ) - { - U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); - T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); - numpkinds = ramchain->H.data->numpkinds; - numunspents = ramchain->H.data->numunspents; - numtxids = ramchain->H.data->numtxids; - for (i=1; i 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->dirty++ == 100 ) + if ( spentbp->dirty++ == 3 ) { printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -479,12 +459,12 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { if ( spentbp->ramchain.Uextras == 0 ) { - //printf("alloc Uextras.[%d]\n",spentbp->hdrsi); + printf("unspent alloc Uextras.[%d]\n",spentbp->hdrsi); spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); } if ( spentbp->ramchain.A == 0 ) { - //printf("alloc A2.[%d]\n",spentbp->hdrsi); + printf("unspent alloc A2.[%d]\n",spentbp->hdrsi); spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); } } diff --git a/iguana/main.c b/iguana/main.c index 348d4d1a5..cbe73a9df 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -329,7 +329,9 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func // mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K -> takes a long time -> /* mksquashfs DB/BTC BTC.xz -comp xz -mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K + mksquashfs DB/BTC BTC.xzs -b 16384 -comp xz -Xdict-size 8K + mksquashfs DB/BTC BTC.xz1m -b 1048576 -comp xz -Xdict-size 1024K + mksquashfs DB/BTC BTC.xz8k -comp xz -Xdict-size 8K mksquashfs DB/BTC BTC.lzo -comp lzo mksquashfs DB/BTC BTC.lzo1m -comp lzo -b 1048576 mksquashfs DB/BTC BTC.squash From ea8c0655ed7b09fac6dfa9f7e0bce5914bdc41d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 15:15:52 -0300 Subject: [PATCH 170/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 89b12fa5a..0dae823a0 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1372,7 +1372,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * coin->balanceswritten = numhdrsi; coin->balancehash = balancehash; } - else if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) { ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); diff --git a/iguana/main.c b/iguana/main.c index cbe73a9df..bdb5f6705 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -483,7 +483,7 @@ void mainloop(struct supernet_info *myinfo) } else { - //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); + printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); coin->pendbalances--; iguana_balancesQ(coin,bp); } From 97c28d4e6b26d59c3a604e5bf7b33c3079294a24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 15:37:27 -0300 Subject: [PATCH 171/333] test --- iguana/iguana_init.c | 52 +++++++++++++++++++++++++++++++++++++------- iguana/main.c | 2 +- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index e09330b23..ea0f49214 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -340,28 +340,64 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } else { - bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; int32_t numpkinds,numunspents; + bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; int32_t numpkinds,numunspents; uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65]; vupdate_sha256(balancehash.bytes,&vstate,0,0); - for (i=0; ibalanceswritten; i++) + filecrc = 0; + sprintf(crcfname,"DB/%s/balancecrc.%d",coin->symbol,coin->balanceswritten); + if ( (fp= fopen(crcfname,"rb")) != 0 ) + { + if ( fread(&filecrc,1,sizeof(filecrc),fp) != sizeof(filecrc) ) + filecrc = 0; + else if ( fread(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + filecrc = 0; + else if ( memcmp(&balancehash,&coin->balancehash,sizeof(balancehash)) != 0 ) + filecrc = 0; + fclose(fp); + } + if ( filecrc != 0 ) + printf("have filecrc.%08x for %s\n",filecrc,bits256_str(str,balancehash)); + if ( filecrc == 0 ) + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (i=crc=0; ibalanceswritten; i++) { numpkinds = numunspents = 0; Aptr = 0, Uptr = 0; if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { - vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); - vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); + crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); } - char str[65],str2[65]; printf("written.%d balancehash.(%s) vs (%s)\n",coin->balanceswritten,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); - if ( memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) + printf("written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) { - printf("balancehash mismatch\n"); + printf("balancehash or crc mismatch\n"); iguana_truncatebalances(coin); - } else printf("MATCHED balancehash numhdrsi.%d\n",coin->balanceswritten); + } + else + { + printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); + if ( (fp= fopen(crcfname,"wb")) != 0 ) + { + if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + printf("error writing.(%s)\n",crcfname); + fclose(fp); + } + } } } char buf[2048]; iguana_bundlestats(coin,buf); + if ( coin->balanceswritten > 0 ) + { + for (i=0; ibalanceswritten; i++) + iguana_validateQ(coin,coin->bundles[i]); + } if ( coin->balanceswritten < coin->bundlescount ) { for (i=coin->balanceswritten; ibundlescount; i++) diff --git a/iguana/main.c b/iguana/main.c index bdb5f6705..d10cd6507 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -463,7 +463,7 @@ void mainloop(struct supernet_info *myinfo) } for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ||prevbp->balancefinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) break; //prevbp->ramchain.A = 0; //prevbp->ramchain.Uextras = 0; From 81db88422571e4b553e434030210b1aa620723ac Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 15:42:25 -0300 Subject: [PATCH 172/333] test --- iguana/iguana777.c | 1 + iguana/iguana_ramchain.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 8de74e774..e56340f29 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -545,6 +545,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/ro"), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/accounts",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/spends",symbol), OS_ensure_directory(dirname); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 0dae823a0..d8c5ba0bb 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1390,7 +1390,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * } if ( err == 0 ) { - printf("mapped extra.%s\n",fname); + //printf("mapped extra.%s\n",fname); break; } ramchain->A = 0; @@ -1489,7 +1489,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; From c5a0cad9081d3d552c724313ec5c8b35bd730bb6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 15:46:17 -0300 Subject: [PATCH 173/333] test --- iguana/iguana_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index ea0f49214..222e1db11 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -289,7 +289,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( strcmp(checkstr,line+k+1 + 64 + 1) == 0 ) { init_hexbytes_noT(checkstr,hash2.bytes,sizeof(hash2)); - char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash2),checkstr,bits256_str(str2,allhash)); + //char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash2),checkstr,bits256_str(str2,allhash)); if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) { bp->bundleheight = height; @@ -355,7 +355,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) fclose(fp); } if ( filecrc != 0 ) - printf("have filecrc.%08x for %s\n",filecrc,bits256_str(str,balancehash)); + printf("have filecrc.%08x for %s milli.%.0f\n",filecrc,bits256_str(str,balancehash),OS_milliseconds()); if ( filecrc == 0 ) vupdate_sha256(balancehash.bytes,&vstate,0,0); for (i=crc=0; ibalanceswritten; i++) @@ -373,7 +373,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); } - printf("written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + printf("millis %.0f written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) { printf("balancehash or crc mismatch\n"); From 6919f2bac0e26e7df7f70bc5547cf509c3ef2580 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 15:56:30 -0300 Subject: [PATCH 174/333] test --- iguana/iguana777.h | 1 + iguana/iguana_init.c | 40 ++++++++++++++++++++++++---------------- iguana/iguana_ramchain.c | 6 +++++- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index c513112ac..1a5df1b17 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -378,6 +378,7 @@ struct iguana_ramchain struct iguana_kvitem *txids,*pkhashes; struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; + char from_ro,from_roX,from_roA,from_roU; struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; struct iguana_utxo *Uextras; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 222e1db11..0df0c42f8 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -214,7 +214,7 @@ void iguana_truncatebalances(struct iguana_info *coin) void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { - int32_t i,j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; + int32_t i,j,k,m,c,height,flag,bundlei,from_ro; char checkstr[1024],line[1024]; struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,zero,lastbundle; struct iguana_block *block; memset(&zero,0,sizeof(zero)); @@ -330,9 +330,14 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { if ( coin->balanceswritten > 0 ) { + from_ro = 1; for (i=0; ibalanceswritten; i++) + { if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) break; + if ( bp->ramchain.from_ro == 0 || bp->ramchain.from_roX == 0 || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0 ) + from_ro = 0; + } if ( i != coin->balanceswritten ) { printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); @@ -356,24 +361,27 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } if ( filecrc != 0 ) printf("have filecrc.%08x for %s milli.%.0f\n",filecrc,bits256_str(str,balancehash),OS_milliseconds()); - if ( filecrc == 0 ) - vupdate_sha256(balancehash.bytes,&vstate,0,0); - for (i=crc=0; ibalanceswritten; i++) + if ( from_ro == 0 ) { - numpkinds = numunspents = 0; - Aptr = 0, Uptr = 0; - if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + if ( filecrc == 0 ) + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (i=crc=0; ibalanceswritten; i++) { - if ( filecrc == 0 ) + numpkinds = numunspents = 0; + Aptr = 0, Uptr = 0; + if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { - vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); - vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); - } - crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); - crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); - } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); - } - printf("millis %.0f written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); + crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); + } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); + } + } else crc = filecrc; + printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) { printf("balancehash or crc mismatch\n"); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d8c5ba0bb..38625f5a8 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1365,6 +1365,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { + ramchain->from_roA = (iter == 0); numhdrsi = *(int32_t *)ramchain->debitsfileptr; memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); if ( coin->balanceswritten == 0 ) @@ -1383,6 +1384,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) { ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + ramchain->from_roU = (iter == 0); err = 0; } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); } else printf("ramchain map error3 %s\n",fname); @@ -1430,6 +1432,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); ramchain->Xspendptr = ptr; ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + ramchain->from_roX = (iter == 0); return(ramchain->numXspends); //int32_t i; for (i=0; inumXspends; i++) // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); @@ -1474,6 +1477,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname memset(ramchain,0,sizeof(*ramchain)); if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) continue; + ramchain->from_ro = (iter == 0); ramchain->fileptr = ptr; ramchain->filesize = (long)filesize; if ( (ramchain->hashmem= hashmem) != 0 ) @@ -1543,7 +1547,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) { bp->balancefinish = (uint32_t)time(NULL); - printf("found balances for %d\n",bp->hdrsi); + //printf("found balances for %d\n",bp->hdrsi); } else printf("error with extras\n"); } } From 51d3a3797989de966a459937d882e308f01337a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:08:04 -0300 Subject: [PATCH 175/333] test --- iguana/iguana777.c | 1 + iguana/iguana_unspents.c | 2 +- iguana/main.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index e56340f29..72639c895 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -545,6 +545,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/ro/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/ro"), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); sprintf(dirname,"DB/%s/accounts",symbol), OS_ensure_directory(dirname); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9b0ab8cfb..9ae3e2680 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -547,7 +547,7 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->validated <= 1 ) { bp->validated = (uint32_t)time(NULL); - printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + //printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); } return(0); } \ No newline at end of file diff --git a/iguana/main.c b/iguana/main.c index d10cd6507..d0c9eb0f6 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -336,6 +336,8 @@ mksquashfs DB/BTC BTC.lzo -comp lzo mksquashfs DB/BTC BTC.lzo1m -comp lzo -b 1048576 mksquashfs DB/BTC BTC.squash mksquashfs DB/BTC BTC.squash1M -b 1048576 + + sudo mount BTC.xz DB/ro/BTC -t squashfs -o loop */ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) From de6e2662ce0acd2e8212e621779441f57f8135c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:11:45 -0300 Subject: [PATCH 176/333] test --- crypto777/OS_portable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 38bfed58b..9264e4b2a 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -185,7 +185,7 @@ void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) return(0); } *filesizep = filesize; - //printf("mapped %ld -> %p\n",(long)filesize,ptr); + printf("mapped rw.%d %ld -> %s\n",enablewrite,(long)filesize,fname); return(ptr); #endif } From 16794bf9eb06aa838988c376676fea524e7acb26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:17:53 -0300 Subject: [PATCH 177/333] test --- crypto777/OS_portable.c | 2 +- iguana/iguana_ramchain.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 9264e4b2a..6599eb554 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -185,7 +185,7 @@ void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) return(0); } *filesizep = filesize; - printf("mapped rw.%d %ld -> %s\n",enablewrite,(long)filesize,fname); + //printf("mapped rw.%d %ld -> %s\n",enablewrite,(long)filesize,fname); return(ptr); #endif } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 38625f5a8..d686eb40b 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1362,7 +1362,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * err = -1; for (iter=0; iter<2; iter++) { - sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); + sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) { ramchain->from_roA = (iter == 0); @@ -1376,7 +1376,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) { ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); - sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro":"",coin->symbol,ramchain->H.data->height); + sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) { numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; From 00cbc999dd63659298b80f00becede1c377936b6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:21:01 -0300 Subject: [PATCH 178/333] test --- iguana/iguana_ramchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d686eb40b..b9f6cf49e 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -272,7 +272,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, return(-3); } } - else if ( strcmp("DB",dirname) == 0 ) + else if ( strncmp("DB",dirname,strlen("DB")) == 0 ) sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); From a715ae924edf914a587156fa4ab250d3b1eb10e1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:27:37 -0300 Subject: [PATCH 179/333] test --- iguana/iguana_init.c | 3 +++ iguana/iguana_ramchain.c | 10 ++++++---- iguana/iguana_unspents.c | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 0df0c42f8..95b9e5fb9 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -334,7 +334,10 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) for (i=0; ibalanceswritten; i++) { if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) + { + printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); break; + } if ( bp->ramchain.from_ro == 0 || bp->ramchain.from_roX == 0 || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0 ) from_ro = 0; } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index b9f6cf49e..82f2753eb 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1417,11 +1417,12 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { - int32_t hdrsi,iter; bits256 sha256; char fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; + int32_t hdrsi,iter; bits256 sha256; char str[65],fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; for (iter=0; iter<2; iter++) { - sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); - if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + sprintf(fname,"DB/%s%s/spends/%s_%d.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->hdrsi); + //sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); + //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) { @@ -1446,7 +1447,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha ramchain->Xspendinds = 0; } } //else printf("no Xspendfile\n"); - } else printf("couldnt open.(%s)\n",fname); + } } return(ramchain->numXspends); } @@ -1482,6 +1483,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->filesize = (long)filesize; if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); + break; } if ( ramchain->fileptr == 0 ) return(0); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9ae3e2680..ab65d3730 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -269,7 +269,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; int32_t spendind,height,n,numtxid,errs=0,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; - FILE *fp; char fname[1024],str[65],dirname[128]; int32_t hdrsi,retval = -1; + FILE *fp; char fname[1024],str[65]; int32_t retval = -1; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; @@ -338,9 +338,9 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { emitted += emit; memset(zero.bytes,0,sizeof(zero)); - sprintf(dirname,"DB/%s/spends",coin->symbol); + sprintf(fname,"DB/%s/spends/%s_%d.%d",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->hdrsi); vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); - if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { if ( (fp= fopen(fname,"wb")) != 0 ) { @@ -360,7 +360,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); } else printf("Error creating.(%s)\n",fname); - } else printf("error getting utxo fname\n"); + } } if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); From c75e5d91392923a739d5ff291da6587deeae6193 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:34:49 -0300 Subject: [PATCH 180/333] test --- iguana/iguana_ramchain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 82f2753eb..d67ecb7d0 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1417,7 +1417,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { - int32_t hdrsi,iter; bits256 sha256; char str[65],fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; + int32_t iter; bits256 sha256; char str[65],fname[1024]; void *ptr; long filesize; for (iter=0; iter<2; iter++) { sprintf(fname,"DB/%s%s/spends/%s_%d.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->hdrsi); @@ -1446,8 +1446,8 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha munmap(ptr,filesize); ramchain->Xspendinds = 0; } - } //else printf("no Xspendfile\n"); - } + } else printf("no Xspendfile.(%s)\n",fname); + } } return(ramchain->numXspends); } From becfd1f869d2c4734fd36f3e169edf67d504fc08 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:36:23 -0300 Subject: [PATCH 181/333] test --- iguana/iguana_ramchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d67ecb7d0..02fe88ace 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1420,7 +1420,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha int32_t iter; bits256 sha256; char str[65],fname[1024]; void *ptr; long filesize; for (iter=0; iter<2; iter++) { - sprintf(fname,"DB/%s%s/spends/%s_%d.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->hdrsi); + sprintf(fname,"DB/%s%s/spends/%s_%d.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->bundleheight); //sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { From a09d856facb418c2f29c726eb3f36e7678555c7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 16:37:47 -0300 Subject: [PATCH 182/333] test --- iguana/iguana_ramchain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 02fe88ace..c7c4e905c 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1420,7 +1420,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha int32_t iter; bits256 sha256; char str[65],fname[1024]; void *ptr; long filesize; for (iter=0; iter<2; iter++) { - sprintf(fname,"DB/%s%s/spends/%s_%d.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->bundleheight); + sprintf(fname,"DB/%s%s/spends/%s.%d",iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); //sprintf(dirname,"DB/%s%s/spends",iter==0?"ro/":"",coin->symbol); //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { @@ -1446,7 +1446,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha munmap(ptr,filesize); ramchain->Xspendinds = 0; } - } else printf("no Xspendfile.(%s)\n",fname); + } //else printf("no Xspendfile.(%s)\n",fname); } } return(ramchain->numXspends); From 9605e3d6b948fef005b6cde1f766d00e7eb20d75 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:06:00 -0300 Subject: [PATCH 183/333] test --- iguana/iguana_unspents.c | 2 +- iguana/main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ab65d3730..3cf20f2f5 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -338,7 +338,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { emitted += emit; memset(zero.bytes,0,sizeof(zero)); - sprintf(fname,"DB/%s/spends/%s_%d.%d",coin->symbol,bits256_str(str,bp->hashes[0]),bp->n,bp->hdrsi); + sprintf(fname,"DB/%s/spends/%s.%d",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) { diff --git a/iguana/main.c b/iguana/main.c index d0c9eb0f6..e35bc849e 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -337,6 +337,7 @@ mksquashfs DB/BTC BTC.lzo1m -comp lzo -b 1048576 mksquashfs DB/BTC BTC.squash mksquashfs DB/BTC BTC.squash1M -b 1048576 + mksquashfs DB/BTC BTC.xz -comp xz sudo mount BTC.xz DB/ro/BTC -t squashfs -o loop */ From 8b77b57b5073fd81ecc1ca885fe0a1b073a0a5f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:14:20 -0300 Subject: [PATCH 184/333] test --- agents/iguana | Bin 1249988 -> 0 bytes agents/libcrypto777.a | Bin 769434 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 agents/iguana delete mode 100755 agents/libcrypto777.a diff --git a/agents/iguana b/agents/iguana deleted file mode 100755 index 90f8d12ac6f5b546726d0c2536aeaac2f9ef2227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1249988 zcmceIy)SVkP%L=iKHN)&HrU;<}!f>DA-0TT#`iH0O5GZ3wh zz+^PXaWECM)Y_IlZm(C`inm^bpkWdq30N^;RRk-M`Zz;G!ov_y$@ly1b0#@Z=ezyq z`vzwA{;mC5d+oLNUi)!Q9?SL3NU~U@_$NvF4~gjhYg~e)|4LG3@o0hhEf=<;6Luh>&LqB zTVRA2B)NcyU34Um_#Ji`m!JGk{fp@Do_n6a-E(K1;m(^TpcHrG>25<14Nj_rNtur5TzJ^M2i zOq_o<5!j!A{ty`YuJ|rg?7Qe!p|ama|13fNS3;@3EB>qm`7BRR?xhLxcO=OF;so&* zCdfaKAfGD8?z{LujRyQK`sxJvf0TfqKO~UusCuT8+ulL_RoFoB+IO_2ZW1pHVM z5|sPL1o^B;P_N?&;`b!Te{lkS4kw8Jvjp{Bn1KFef_#(&^o0rNUqhk3t6fGVh@YH* zpHC9h_jrPQY7)q~J%OC_66Ev81pVca1og5eDA$sp+!YD(Q4`d+IRSkN^0DK4_UFL_ z@xM;M57!&t)m~R8XqSf)$Ssy2pQjSUeJrA5w`ul=@k+k|J zwP(BTJ98S&>E?bvYjne>psf8Sa37eQzK+FAL(Y4CG4 zpRGck=Sc+xzB9^|uud-t)K*?~Z&kowS;qzXWT~j=-o@2bMRooKwf>?asp#e6# z4a2%pe|3#PxVN%;;eyJuW87Qnuc#`k*3;Bgf|;VS+S1aZ1(lVid`c=y7gPmmOq80^ z+Oq1}#pZMiYHCWW7MbGImZE$iiP{Hi{M8hKb7JqH7S~kJS5>-{j^JDm zSXfa-%7R6Uq}=JA+3upciib)K?`-c(!5||{FDQ(srk8w6)srfUa;N797FJf2+*0}= zqm?YKp#xrumR8p?&!Ss$?-IDAx@t+0sE0uWGerv@EP@1=lonMjSX?SqOsYORLohyR zpCQ>gXR)y1SduJgOx>sHP#1}V4VD0y|W6676&Th2};UKOYRqO zD<&;sskIeL7Whk94?VGoU@&}dX;o=0;)qnJWmRBt(ZULUov3(qjo?KuM~H{wKwH)h z$lMlUj+-J*&m%n3np*%|x`!N*(YUWz~nRpfDRZ8dadsDf-@BUtb-6i{AT zKdGj=qRJl+W)qniKqsp4m)DjqSVY~)mg=Zqbq}J$ES8J_h|gbIuWL_jX~`0FveMex zs_LT3>XHTiis~wYcc)zruq@)y`Bc4$S%JC0Jybp{?(2uIplHoXdVSy@< zzOt^g^nR-MVsdw#RJOQ!kyKh=BUM)4E0tANSJz5)57Z)Y^-|FZ^jLK$8oiKK zEvS;p{H5r$brttkEr7$w$jn~>9cEz*pjjxZsBA$+rGy$(RNXJt1pFoC3u?g~M2Z4R zD_Pma_b;lbl^~5uR1+C3f*^{DI6h(663G|e&nBoroTU|P5r3^8RToaBw0QA?8p&T9 zsDk`Ur7~zlom3LftF{v5EG}KlfdTRHUqT;RB$WwSB7hZS5=e<7S4}mlR8&-El1Lf3 zmiSx8oLI@SlFDkdaqR*!Gn{y_UTSUW;_4+7LW%#un$n_$R1KC3oZ33Di}VmexpROKU4wNvbGQQ`*&KixxZx(HME?EQ&;^ zZAp187-6jh<$=0tC`g<$Ke`RZRly&djM^Zg4M(V~UOF7X#2iY|E9t$JowWpcGW`Po zP{EKZD5xydvZ#pD6O{rjx_ANFw@eSvby6xS!)PoOl`dM~Ux3I9>+1BlAVI=2ecox) zizZE+H1S$#`kdQ+Mc7O(@Xao|M!GdWch>CLz9M~;kH>RfH2Zi-|TadawaI-M!_k0?dNVC?vpxhCPCp3`tV z`cm+<;-rPCl2Fb_AjadrG{J$MCpk)%&M`t@I2b-XCV#E?$1+(D{h!VYOW?ne_zrVR zZbl-m6~CnN#6_=XJZ8F}>#6lnmdU!LN*4S}7GLH}#1Gwrur+xuV8=Ibam6SJC430G zg&&49W<30|n{4MuC|@&$pMwbTaQl__AtY7mH-*pmm;6&q`Hz%ru-TZNpXYw|98#uB zDI;~-n2L&XCCE@V@b?8ylP)swDiME_beVy_C&EWa6Ai4_Cs~xoGW-{@eo4|4g!3~{ zR3lun`?T=sKXLn!Qs%iv{1dnPNdHxw2sfix&xhISlGOw4COS;qp--lX4)F|qvQ2b| zW#}`-L}%IYkIO_iL@t696Wyq)py!+Daod;yg(f-#H1sJp(bI;gl2mS@Lm`GfH70uc z5LJ@uO>{Kq(5JyfHy;W$ndtIRY)NW1(c?P9;MFGj@QJ7-tufKf>%Y^{7^@JD17>l)kGg>qT5V#yNRA*qF-vF+fDTGCVHlcewm4$ZK69& z^eHC#Uo_FLG11qV=$v8WpA9DZwQ(ZcsEK}^ ziQZ+RUvHv!o9NsFihuT)=s9sB+#VDC1`}N~(Qh=-`%LtyCi;Mhev^qVEgaVW|1i<5 zCi+iIbeoCpGSM?kbhn9aH_@k==$R(^bQ3+>ME98JQ%v++6WwK^&oI#y6Md$Mo^PTn zCVHWX?lsYiP4t^h^l}sZ78AY3L^tnv)SKveruYpe`YaQ@$wa@^L~l0H^G)>CCi-nA z`Wh4cb`$+Y6MeRczRpDFo>%;{!9>?@PUs;~6a9{OWVl@>`kf|vw~2n2iN41~zuQFb zG12Fm=$eWCOB21%M4xA(518olO?0VbSpV-a(XA$Wk%?|I(Th#=3=@5UiEcO1Uog=# zP4tB(dbWvPVxmtm(HEKME)%`fL|07oG7~-DM8DTWFEr81P4r?Dy~0EmfgZTVL^toCzG$MGcTm@v=yj(2 zH<;*t6Fq982Tb%X6Mcz^-ff~UHPQE&==COgkBR=EiLROG51HtFCi+iJ^Z^t7VG~_i zG~8Z~nCMm${ZSL$W}-i4qGy=s%S?2;iN4%K&ot44CVIAs-e{svG0{UNy30g=+(cJQ z^e0U8d=tINL@zYaRTI6~M1RsmFE`P{CVGvD{*;McZ=y#`^ac}sg^Au|qCah-H=F3q zCi-d<{bwfn8WVk`iTw;1^aUoSJ)Gwxooj{!}e_lq4y^ zt=283Nbn9`I|)$+FQ1HGd7KMAVlmRhdIs^i{0d?VqQ<%f9#5P^92NLt;$-4=0-sNu zLcB)cG~!g^W`UE4M-Vp%eCk?Y4ok5bfsYbfiHik3NDStsSiZmqh|`E&0`Db0hd5i{ z-Nfm{c7b;gpG#~LxSjYsVoBf@Vwt$_Gzgdf53!B7N8p!;M-z7o{5xVU*&JM9igFtVZBkVlKgA#RA_)%%xW>U*LtrTyn)+ z0^d#i1LACfZzmp0Y!~=u;!B8a0#766k}4(%d;>9;Qn9{oS^r7IcH$m^uOPmZxLe@y z#N&yh0$)sg8Sy%S&nI>euMs$n_;TWAfs=@TMBE_osmZ`UCaw|qC~+onvA_q3vxxHr zK0tg0u}k2+#8(n$3%r|n09;60yFoMf(%G zh1FD9N&yiVZri9N(?1WqH)C2kftiFgKagTSY*0iH=*Bk)mT zg}7MYgT!9qe1Q)T-%RWhcrWoS#MuJxCiW5A1>QlNM{EJn?eksK6H!2Z`4Sd_Hj_@fv~Ch(pB9 z0w)naPTU~yDJSp~#5DpRC2k@v7Wg2sN}Mn70pcf#T>|eV4ije!yqowbV!OaQh$F-{ zf!m2!5K98L5I;@a*DumEftpaehZ%P;VDM)Pr5L+NbmnN6oN`x=*|rGw?;WfSFblsLAbH|)m+kU7d#d*CR+ zf%6pg)1^uCw`^b_4Z-8{H#2CkM;_Ne+6JO{{I-E)#8=dIrS0HP6ic_VYaoEcEsUsy zb|bN(cIfF380i~s`rryDj%P;CK}zjWa5KLnwF4x}u`RSGmEcV;W??q<|8R(fF>^Ne z;HenIAMBnV`zeyhT%T2hjboCJ$)J4#(7qW5OJ9bK83z=`ts?kp|6m>diqd{ z{RF6pkuPdtDNiO7{6`HS`0p}6hE_F~tgI5ETclhw#*pQnK$@~_ zD+N4v{uV6@!(drlf!qaN^_w}fA%Dv14EZx#XEd~1Uhx=Y8kq(~J*Kqvq$-ih5%%8i zAq&j-kydqla4-~=LmjZhMIx_i zB=Vwkv@FzsJ`@c#pf97>r^~q$MIaXp1Slfzsfl~)>G5`^ICK|z#XYvTCxad({FH<3 z3gt)_%HdOc0_jkWZV>0rchB3RrD2pD9$?&exYd52+Tot#E^w=Vo1?z#QFn+Q8~mci zq%L4e@2gRkqW2s_o-B{T6;fn51VVs&3?OuUjR1PPzGwtMB5}bBp$yABLz~8S4Wf%m za$_^%yK}w>JP^F;yp%~&l1E-&>2N)CEz!-K%9MR?PQq*LM z8XXpT3J>}#^b{U+*XbD^Ra3$~NBNMn0{K`{*HBLG`R;o#;9<0=54SGDI4#C@WWBa; za4;6Y;HL1=0#vqhx@e0HAb~brvwK27zW z_`70x*W30$37aVIC5A=0(LDx&y zl|?&+24SB|VZ{+xEZkQeVz>~K3i^Z?E--Lr3+ZqyN6c~o{1_EfAGB93fYz#$9nOBT ztT0B6h~Yz>5Evid8XfgUE@F(EVgRF}=V0_jy*WM1;~evAPY1}2b?{r2nM$B=mZ*9C7X*f#!9rKBp(!0P> zZs-#wvdS3g-#@0Tl~?c?CU?Z+z=ZOZt`QN%;*5%MPEA>^1fv!urz>#Wht{#@s-FqF z0{(GgUhxJyQ?#$nO_SvH9>+L$WXa$!+$T~_LRJwQ-NoLH{Cwyl#(93%%gt10V0xG>uLYJ(<6o!C87+X z&pUT%-Y=j*%eGRu&S<<@-9=lRyL(@6cHb#lqd-jQx+a9j8fL%?LT8-&LfaMfVUBQq z+9Cyxa;SHK2RiMOS5O4*NckXU83imzaP#RZ!EF|f50IJ#&)?JW`=^Z_ilfBwC8ym_Q z7@=H>I>zCVU;d|C{Q!FDQ4eSz>`aq#VHoc7mK^t~habIw{qtt^;cb$aJ=b!=le6Wq z!W@61&@X;kcVw|$oCo|7xT+=rP?QNI;hj)CKtx1=AFUIrBGj7iTb z^j-TUwLcW~s@vp74uQ_-Ms8**>gO0+oYCCSpjZ8*b0kPonL0D2W9A4QRq++NXZ5z4*5@$+^#~b|AhIo+Fk* z=g8}i`P38I>!^Hiiv``m>dE;!(Bo4-Bl%g7F*(t@<869RXwM)Q9}S47#F}JyM7{>i z!P=RcLoXY3&?X=iO78uy%~6cJ+I%#VGuqpt`7!p2@mARD>bn#aq{R8^3@K#_DbYwQ zrU*LVj^gAZfiAkL(%C5H6Nb{?MGrpock5o^r)>Edwl~!j2SH7oS|9gV;~rbwlR=NR z=2mu4V|@l5dO+lOZzqw>NsvikGe9;0Wy28K4jiCREIj48 zw{B2q%VJik;SVB<0eSr@$7UwP@ZciTYY4!NJ$T?T;unE~J6ughG=zwXt}~*Eif%9f zDjHvrvaZ7mQY%595etLI@ER#Y3+7R{!cr-~D4f$vK6^x5W41-0!a=2wA?*K(x=JjZ z<jsJ&~Y(9ifMT?>!VXJA&KBwUom`}b* zWlx}b4)p|m@uL@JtbcSJG?qYm_F@&pWy&P<8|pjz4NPx+1B972FmsqQ114L=@#)}T zZ%Di8Agyb&eSK%1`nG9`>>7Pm2igDv=2`W1eV|5-SSCfcMild^7}{06R1YLeK9umE z9DMvsd*f4Gj2 z=2gOKmY;q#70ZkDx|BA6J28&bz?Cr0G}FZgUT&Q6LklaYStycv6i%UfBE^H=h{qv_ zigULVs#Slw{7O`ljr!MgxDPz#owqx11-yUq!U3L%5Q zUzJfDO-kZ@-RL(QK9Y?d&9xOep5AX1H6J~4m9gKHFX;L(mY?Cjn;fvT@b?v1sFCG^ zr%#_gvHQ~Q%Ny|V$JBNo>O~eez5=tZ?V#g&YDxK|OsTka! zjOC;cdW<3|5AMX=nuMyBydcDu>-;27J*~9;6YRbqv=Z~xE#Z_O(M)1Nf+M=fphvh* z4ef%tZV7vS1Ov$9Q0TMKmroxIAhF^x7CSU3 z(c%rjVGlrW0St3qNFLGc-te8M80<87P%l&j9#jiG0svh^-;x4P`j!+J(zm3rf7Yv4 zg3M5Q&EUg_zD<5uO*?C-vtkVBVqQf^HbZn)AQEqQB+K)LX9^L+#+)f63=?xEIHA1W zIf7pIf2xc+!QsOQM?T^j;|nJn`m*sgD3UIw@6ep{|2a754Q{n_p7Y&^&LfBRW6K0= zQkg7z*UM8+aC+41`>L3Sjp}aYMIXJHose?$h5sPB zp7W3gdcsh4NYj3fyuQGJ#ck^kit_Y5A}pl5mJhWc^7G^z3Vg(Am!j~7WoI-mJk#F# zS-eB zofjN^aA+Grj;}g;2(ZSqdGIq<{XjjaZG&B_M9^7%$W7g&#$Y^aF6_#=`#UVKo?8Y{ zT{-ke{JQ!(ljP8=x-Ufz?SN0+<&3t)lKb0JVD$UbbaS7>Zhw1{KMm7&urmqP|LNcX zi$A$zq=Yi}B3Ea>=G&SkVM}kU!d0JJjj3ZDd8+19kIFCqgSP({*w^5qQScn$NLccY z(sm$K`)dyZmThG_$JE*$AYaMJJawxV8yvaLLsZz_?;GbkZlRw0-8qNkMh<7UM5a#V z92-R{-K={F8UeHJJ?@O=vyF>=mXk^tyB;Hyup4_GGoX!b?0C$8Cc3fTF+*r7GZ-2n zx(tv>9qu-O7$No;03!rCH3tVMH^u^yCp{uldNQ@t1zUt~^1IdzTsQsFduB(23VC*jH4G*ndk^uxiy7IrL%jpw!R0@J-}IUDe>qK24@ z_9$N075g4CazCbt4F#JRxMiZc?Yk8{6ZD)@2S%hzk9~Mlz9QPYGtQ6u&K4Ugq_6n&qfTyY zy_NydZRRZw?V+znVN1Zxwa9oV0zTMV(meZ6L60NdjjqYK-1Gbv<#;16I9Q)tXTS3h z?CtPhGl4?=a?^6842SJR+XMCCm8>t$(5sjOa|Y)@raY?1S9G!GE;$$82~juJkPM$5 zNx2S#Svu5;mAnj9>BbEm5RsRLAus5B%rzlc`BWC_o`3*y*x?8u|WjyEV%&O??&1yK0_1#9i(>^c_x&huuFYKK?3y% zI)DXYz>c}iowM_?r%@fZ=;65-;F}@0T=~}1;2ok!cWD3EGdRfXI>A%=keDL*gYKO7 zQ9>8le9F;;WDieLLi_wzDUp?vAR8PJww4zTkLsWPor2JtzB9;1MI=n0eUO*Z_F0PN zI5|p+w=B0hO>@SX{SV#lO>{Y&Ar4(_zy>)?l+bp$k=Jta(1Razhu!mhn7^&CEi17Z z>KxSCQ57F13afI}V>hs{+k8q+_hYj>;gF~{27-l31& zOUYRg1>1g^+p-u(JULLd_P~d^Iqm)*8{;7u3F9mP#^F?bv-o<{rd)LB1~3P!^Z^$q zd7HK{Hw}XXthkm9Me${ax*sND4!TP3Yuaw`3;Ph(%4uP(%=Sj^alu@%!Adbz9;+k} zkZj>MSf8kSHvSRAN(-KZjW75du~x8_$S~h*vS95kV`C z#}=BlXXD#v#~yswh>Zx^Bvb6xhFWa4)}RLQt>x!YcX#-4N*aQ$_D23fLF0_*^)!U^ zX2kX1*b8>w_-jV3n}JDB46C0jk;kc6n|r{7PyHAdX^#ETze`cug!r%^ph7{Lkb!oB zGZl7}ja+J5K-X$_gQ$M4s9Ut3CqWE3Tb52D{S>MU_4qw&4ugc!MC*;wTdx`>3C!(e9D@!g2ndyr}BzUz?;MKKDDyj#+2ZuhQE!6MX*1-(zkUyhG7N2 z7&;kWdw)Wb7-oYK#xYMgT*)xhp#gbt4dT-vZK1Rm%G^}L7D>LmH8+XoGa=t$!Sw_xgA!< z)3gPY@O-OtJNhgRlJ{#ZKTVcesU-x5>XTtXVxs|^3Qwl+U?Bp_9=i;2@)UYDissPE zV`#Am#pNRS%Y`4Fnz*N4c*4z!ohA!UshabJR~%9`7aD%p*A2z+J9q0w_Wk!FI=aBP z&W3p)^MkuTLl@9+yel`p52EuBS{e)5M-C|^+q~hi9cU-H@nwb#YW?qE@%&c@w((#O+qkjmpcR573>W6+q75hQjYLgW3P39Z;TP(}8={}m1zL&nqL zl~kHtr*gXG;A2P;XNe5Rk1rN^xFlT%`j;e2s$e-*fBCE&pg*r(kXo{GCA-Mgui=5H`ZFeB1>sR0UW*n|Y^}2Yh1WnXN59N(*$0Pc6nS zL3w7UOJT%th>GAG?40h)1yrZ!YdK;d+N(}4c5dgm(kit)AZ&g%1}>+fy4AFSz`>3ihcb*(f~EDExH{2Phen5|(Ov^Ukc}-Ydb^PV49!dxXt0)<|(`s zvtMh+D?)oWZoUGAYd=DN>;1D>cMWO}VpLK^+F)=3w8YZ8a#%k$%Z%TTCXPJ>&BOey zPu>`=?byOUW0=kWfriVV-1tinFPi}k?gx1yl9K|}ddsDD5=NWA@;Lz^- z+u-2FnJC4rM#Z8^v;n3TOy5<|Yp>cv1H-lPHpCe=1Q42!P!Xg(KEO!`ky;DMZYRfC zjP>ePZNmAuHx&7k!-cT}N5OL;off{Uv$cDqm|n3zw0R+j+RDSD&gRae2l%SqnZP~EVx$Cm68B< z8xCuuQ9|!;;&v78SRB;VbUImH1TE`bUe=8AsUzB$c==oW*!QS`QuO<8RKoROWY9k; zoIg)H`a}v0&N^_&)_wI$-b|H4Q^DP4njqTlx6o!+0qS-iVlv)Sh}Zj(_SKHWLO+QH z5yFJz|5fPw;-T8;6K4qh_P5zqTVpHE9AB^>_&$w3Tw2Rh-_o}qeCjrFe?Y(D#7h>f zb0GxsH%}I-;lpN)RSrFeig-KGTxhUzBgWlUtJLb(fmTv@ZCLZTMe<({0{CeCE#hf!pJ#nGVMYH+7nYlX6U8P3JGV!shA0nDWP;dS?gP<1>f6ZFZKSsK zq_~4`SwMisxkqi&=6#8o1-Wq_48!RbANH}VAS1-L&72nG6&=VVFVw#QIk>!X zZik`dDKm`jjtmV?KB~@`_X%xhla;r-WmB^yAUyH33O@`21iP*qp!+?o(yqU2<}8Y zm?l~;YN$uGASzTDD+_IXRkFxE=ip<1Y3)JX;(K71AgKa-A7=p6uAwskIdl!##ieji z5E3P^fop=mB}@|dKBEUl z>rpSaVvOM1q@-pwNF|EBj*}-bPU-1js01z->Bfn47a8gJgi9*Tn4$eIT{C0%o{`=T z@qbsj!5%v<)`@adVGzYe#?w*C5)D0$`NBe%L$ko86PKGm*Vcavsc$_~Ck|{C+jwn= zgn1l7jID=P>)p-;&#=7_pD%IYG5AHXm>d;|76ynG#pMHij*%NDgT`}-H`pyDzYRl9 zaa``aN8EY{rIVGp$yUsi9ZCc@ynI-0<1QU9dBBH#_yUKAR=Jg-ih@-^J`}*GF2b%j z_R6(toYRP1%2tS8+U&-U_DhZP-Zl&iKCWe493Tpfz57R8P|2xGZ^z_@j583(0&H-3 zArOzSxPzxh%FjhrWY6d8M18jSZ)XmLN+jQf@zdIx9k*1yow=fyV)p*s7VJGaqdqm( zl3nPMTE7zF-LIXJ(_pT$dqE_UzC-#YB-?5OKn zIbSZ;at|7&$Toj5JK>a;r|^IcyT+AqTV!isPHO=cZJeq*z829jo%t`=ympyS+6d#G z(U1L6ZoD0QiT=YoC55OND)TPRo@-@Vc2Z5|hUrek*y5bD!k$TuC?n<(aC!hzSMux6n z)B!NmMLn!*3r_Xos^U>6JIv~$eT(F{u=5XV>;|-(SDhnT^mCl{ovoM2pN&Eow>K2E z(qYF+6{D!QZ%RGjZ9R}M5`d&X)c{@MqM2>_bCiPX_0%7n-C$v`Uu#4WV&0~;tsWKa z*Ln%03V~*{u_x1L-qMUYc{VoWuq}mRu=bR>VFIsylXgop9&W*Xhv-HQUO3uhC%}&E zVVIHHZ;{O}PJA8Or@sH_c4t30^guZ2y`xyJC+E#a-R?+A4q_-JxXzK@(COJ~qxQnD zy2HMw=7qM`k8XhtEvde(HtcDZsRdidxN-l`z3k*^RAxyFm&W%qNy#x3x={jS9<^P2 zzYC-@_#EmVdVdi2H^nh*6S6lM?YJz1nunj@93{V2=;|G9*r%JxhqeOB0ws^eyRY`= z!emT$ZZ*VJb^Ts%_*te@+jMzOxtsEoU%TCgn92nC%9NINslsRDlm7Aubd{6jcheH?u-pH@Y(Wcm@P`}~X*UD^cieVVd z_NXUu{j&8~yclHtc`KGrI1%;WKxyjHxj^Hu<03!ma_1u;`~9&MYe7+mg3TWOU;+lrPf79IH4TYo=i)_PG-DS)cY`$ z^02cWwm^z7J>}4Uv%G&f`_v>97@mS2s$C~!{VZi2J_pOX)_N0P8{fbPoq}vddy3}W zyZ||B_5-v5{kR(wsm~BgKj!s3x{=Y&9`&b%o6kX39<^?s{F=*EhLyEefr-}}`Csc3 zm-6&n-McvpF|^A*870Mjjp6Zz48d)dQ`4rYd*54#`ZPr=T^wFmi{Q zgF6dU3hjTPhI)Ho?{~O8SkftL8XAWZ$FTK}9`J*yR2j0&@XS%*M;NQ}P1XVQP)Ne3 z_HVwF!np9CSmkwUMG)n%DhYk%{S2(fc)uE(uWt3YSTW=3fLM`bVy_anFg%ViS`caD zl1PF&VeW9Nnlp-%ke18m8XNrDd<+o0TFYZukJ`sB2%p58dJ&HcPmk(0gN?^yyvo;1 z)ynWjCXDQztlMF4L;uAVsrCR%Bsig!!AoldLpAW*+8w~YoJ0QW@*>sA*iv-M>*ZW| z{Zb2l@&@zN!-3auwOj3LSsKWTpA+oYqELFI3hclw_;lWaAA@^=>HbUM!}Wv1;OS{@ zvkis%)NdIfupi>Zth+xhVRupNKcV2H4wH<17_R5UeRZgpKFTV%d@W{>4A=}DT5KjQ zYjjvag`$mV(oZg;5K4;zm1xa}k2i5i(dJBo5^yhrJ#>JDbGrn(ca*W9QjEo^ZffIj zKDhnU2eJouQ;);NiRAzsS}yQ@0|&)Ok+E~Nr4_@8#0czB`?c|lhKZt+YPRcf7v?Dk z|Mb+2Pl+t+u9jbZGhTdrw_mZu6cuM{3;rc~?XGxS%`us044-TBFlG!9e}iY9m9Q?8 zq2VTQJ%$>}&LnFkeA7?A%ti*WmTTg=2O;i9FVct2RES8cLEbo(+%3jAoE5gq&$r9D z-Hp2gqi{If#s`pLI8NL_vZuW<>OX{o#5SBRr}p=rBOw(12VlnOW$MeayoNxf|{DZ>9ID133A;)uu%5nBt49u-Yl&%)Q<$ zoI$h0mH-gItHkZ+qIi|)WDIEW=*&=~!o*k|kEv8gX-M_>c$Gt(**558M@cs-iORX{deS!8v#W8p9NLP=(9{$pK;+RQnGlBV(D^zt zXdJNzPq;AI*}@DCWClJuOPWt>A~ITISqHt&-C_w9Kd(T3)C6-@;&iyf8XT}Z`tjMB z^&tl&F*1c3Wd|lIolgva%nz<(%tUK*ovBljlbJ+2YmB6g)9*q+dHDU9k887-2> z$5-QdmKLfKUY-EUTyk;f`&?Uw$sSMKU1zl8>ki3|v6S%?^)nuu@_j)($T87B*KPqZ zr#FCU2WHjhBD!`xBQD#@j5+8)!-w?Q)E_f(#bmfu1F7f?Tbe=I!M2GvuRjLF1AVK; z`=T6NUim!U^T$NXHfwlpgygqsiw^9^!z$LFAl-F+s>Ny(e`& zvf0ucNx9H6a11+GQF&tOZ$SF#Bk=qho+Tc2@EAs~XW(aqx7B`i_c5sIG5M|?AWS$( z>P|D|2q`>O#=VDNB~d}o__>KN{@%p(vdNX)hSq+G6 zkEsKfqrO=7$m_q5*AKMCY-(R*Ojetg5sG>u={LxY^YxgTn-9_+1?T;4QHl2~TVS%V z4yTUgvLYV&ijHHrkn#aYo%sIKEoXxDLNxn5TM$s#C1>seeg`q{L4EJ)!1scdPtnHm zJtslDYa2thGb*yZXRDt6u5S_TEqvSA^4-XIo5)b4FGNB2K*#jJJ_I6Tl%@yLKNL8i zh0!;beN8c{?HfeX&)PC~ep^q*sBTOJ&8*)M)=zIELzCI&$hO_wHWS!3Aa+otjCPsO zC*P{Ki>Xb{MOhZ;Rs&qr(spgvC+A3;AW$h5#417`r$N7J9q9W0(6d8yahCv>X2Gd* zU+2t}!E0ds%)~yyAe?mSb>~c*1h;eMm_b3zU{iL^94j@^u@Az59)ushBn7khprjpy z094N<4s5mHZrs;n1E1)JaE)Y73SV&Q(`*SUf|2pE4Jk#qRhh>1ei%D=(UhEb{6A7| zvV$7<5<3Wx*JcSoy8}6gFNh*#@0)skL_OwiX_m*}acTWRulg1S3-P=(N0EQ_UM*D7 zqjr`d5(g6PX$@=?T27-^ zSq@s>*3RY8d9uzZRD$OxFwBI>Z3qburt*n$UVRRJVTW2=@{0rL&J&@|qj8U0etZcu zN6v(n--WL&^%jQSxmC{8AMQP`nO#qwctBqM zJ&_FtOAMxRA-dK*JLQQV)b3~J-Ri*(kUScf^W@B9@GNqSIVR6L0v{fZ5oK8MJI|4V z->D8HM+cm+hup+IW=9sCnjKqwwE=9?=JX<%acv@*tHilfj z1CK~x6A4f{c|ZaRBzTy8j`I0hp7^;O+yV&u)*e?X?0n|zc;rxAK|VoBFm`5)*m)?E z=H#%xx#wX1?D48^aZ)v!_A7B%7#a*LG|k4kMMdjg4)N{}EP-pFZo8fP&@~RCViO$H z7j-XQ@F5-_00SwG%}q^Byo9W+Lf3&A00S<5HxKINp)ms)S+#5b!nqr@hru^G#Q|ov zYL|jG!~g=vf;@3=e2pPDKEw`USO{ER$c^QKl1T$|i}t%?x;gN>{ajJ#Js6IBcei+P zr7_+ig9C9}LT>!Ap26R=QX_HcaN=%MR=#_8ESYhJ`fI5F(W@deVD@;PNMZd^Yg`?` zV+D8PvgTdjWDE@5yD_7TzVjO;r!%nsEPEd5$Lr}kab46!oM-LD4F9Fa%7%?BIY@4_{HXeHg2tGWkIlkfLt#*2dPm8qAsm7q_zFnG+Z9t zgf|jc@^TLQCmfw7+kD?j*eFDT9rBaKXaPBNH-GOuGj8DT*lWl}b{Wuy+b}HYW>#+R&5G-mLJiPl`Scuc)FeHl9pV?^zQerno)_u7y1J;=3dE zGP-u0KM=SM!Rfpfgv{~Cfjj5NRM(>uYhJ~X6^w4y6? zp|+?cqKY0V zBTthSw^Q7*Esd}0(3>jVg3{BI@W?7x!994P$VdE(*2oKoG`J&#nMtr`(|&-S&8@Dn zN+ituoKc}JHX~m}-GMvFw)BxoR=csL21`hr7Wf41UJPbE*nGhtm#1PIMhy2j7(jK< z=d9X%40Bl7uudk~oiX0F@YYZ+uV&<`Tk*OzXFobH4=b(OZy-x<*k!A09f;&ne{U1c z+A(l&Oe(=a@Dv>4>OO4H2CvY)3cQ(&hCL6xXfc1wuRXyC^2<+Tz{%=RpI~08Cl&x7DEBl#n- zO{lcHBX@j(x8X%@9vRxr!vkekFq(uGb0KNlsbpVC53ZF3+mmjNr2Hq!lwj+;&+M#t z=?tElNaFKX8QzljvEBVFHZ}b??}+@>bu|wC;J2gRN*L!#O5_&}77Nam{x&ooi1TM5 z5^Xf9=fxxLkdzlkV%=^Gl*d`UT%6AJmE|I*Q~0fP3@FK!cyCG0hk-V+-Ktoy;mJol z?S3n^n|oKHJP(El7w_LFrV?I$5xR&se1sP{rg*@Rr|r-%ZJq-|3F&zu^qcgY& zUY5M;Tc7%S7XZY#ww$iI_C7eB!Fj&KwuuH;4<-XxI>9)uckCY{kuUG z-NP3tw?^FGsM}Bh%QooEH@m)dt6SY|UyQ?rQTMKIv^glxTe1};WOtL8fiB z;gItJxQ67i;q{dq)djHikAs8poSJR8$EcC`A-OLZ zB~yZ6CYmkMY@mZITHuO^$aWq4oxxY}%Und6xsj!(AirkNg#218C zt!hg}-Z(lz#`!-Jyt&{o*PH38YZW-1K@Wb7JR=-G?Z9}fXGtVKS&TA5WNiaUc#cGG z@*g5&k1CoRo1mK-UcsGFy~*+JoJ}==EaM@%>e_lZR0bVr2Gf2+XA|pLVMDlJpOum<{x^@p7Bl+LqWpWHI zmOdduaI+3X?G}-ZE-Tyl7|PX65*%ieMps>Hg~NKJz-1mHOLV#O;`#K9PLs4`k&oYz zfnk1<9uZk(!^^C0psTK(0_Wz4=eneLQX2@EkqXb449{49+>t9@W~e{9{LSX>+B6sj z@6Ohe(feA6a7L-$uUhu|!NEvw2E@UG72fJgV}jiHUvbWt}y*r%BD&TMusLj48>D>+lPdNrX#not!T@ zzf|nzoPbl6?{hlp{TuD&GwB>$dtd!mI)}U77ygyb?%dlb=*v1?lkhNyUl@wWcUdQ= z;@F}%KC}F*ty0X3prQHe7~X_t-d~`(b$pKV(Cnd#z}5&qO-sUmE$Sn`wvx3~)VDp@ z#Kqw{CQt4Azk}+jZAyu-GjLyGnf#hCE^@TTc2b<&)X?o`u0-AwM{(GU(BD~wtpW9z zR?@5QKv*=4EF8isLwHNAI$u)F4I*L31n2Snh7rccFB3OLyQgA;c=gr6P)P%oE ztO$94kb1#RYzW`O-L}v^Y*iq0?86q~i?x4>Ki3nf8^jx|L>5?^qv!#;?xFhW zdd>RDnV+6rMHKt7Jh7+NT*IAb)^JgDJ3vW(l^MjwJ;l{Ns9+()}`c)gCas#CG- z${Be0IQLVP5{$4}M?I0-E$R;WL88XOH0oD?KFPwHnbY@c}MFcXg!%8eIUkYB^ba{fhoxiJgB zDpvYegbTni%viiJ4J(o>@V%!?UhxGAkGKat5y$P$L%v9*D;c|u*a3*f`yW^IJQJ7| z89Nb2cD+-KbxiWgdCac`O*nYt&&88EziG!6sS|sfY@Vik9Nw)vOh z;%r|%n8A~x-LPXZ%!F6Hvl@Bu#nTVs1+LFf5^$en#l39@ta+n$5I!#8$F{styYLnS zi+dxB%)My0J9xnF4j!BwY*~XCmWy@+1I8Xku&F(^L1v$Ma<<7KCjy`%#+kpdZwi+A zH0ADCE<(AlF&1k%abKI3JWTtk4sG=>2M3#i6sQ&v-U@n`!^;a{W1E8a0mE?0z%pN4 z%*ON9QysAoI+pqUjCc-N%fktG{1(QKAq^!`=fZ^Z4K7`^Ohz@d%3mV_tV-OD>kJNn zj0qFIKKQr@gy{-j7icX~F|HgkRO@;HO1-HV0X*a2&FME5;ir`eHZpGSc|-jxc*x?v zNbUQ@2^zF&7hKdiom;thOzMDo3Rh~-C5PpQT^wF`!}D#--;;B6NiH6BhSyuN6Zc2( zvYI!`@r*In)M|`96N9z<@>d?qX*YIP;EPONf-`HJ+FipcX?f_exjElFwvO+e@Z?lF z(jPrn&${gk2uFF~(*>J7O~IV9Vk4-KCv&vp zbxwJ>I>UJx56@!1eEJ|xlSbe>%d&AccDq_!h%GK};3kn*{Rp>Q)D%38s9g@_bBDjr zccY&D<|$2W_m+HvhlJuU5W?LEFWxrg6YmW2;x$uBGKAsHI*j#euH_qTJM!}3mEPje z4?9$2c(o=2H)qC(t2JYB9S4j*eKR`9P-vdGS~DiFA9lJMx8ZO-NWnS~of@5{Bjr52 zNd81e%7{lgQZAIV)ve;ns@%x8@biLcHgAkH0Bo#fC24MnN}^)E=OKGU$>bv+Q{wSN zs3+`730t+hKV%GSk%`70y3?j1JM4^{b-$gr5VP6Zu?x|t`VE&(Ts{(4y>ErHc|JJM zKKm7}v~llEH;6a>bUgn^_V^oGXT-N071gS29A8z9KViRk0q*K6sscjI_zB||EUu}< z!*r7-&3^<$o3gROA6SI6lR8|y4y6Bgx4pKv zJ_xQ6--h^`pN5|kW9)x$F`VxQ`NAspP?4zh4|+W9S;Si(kM|_w4cSNEnSYm_ZXMHo z5>I#gQ2ud#aZTsq*ec*an{Ne*Sc4w*sQLmIlYFZ`cv)GBo? zJ8d4HeEl=X*ocuE+2y^s3})9e#M_LP8!4Yhh(Qz=xbHLQ2bonE>tft~#w{>KO>z9c zy_)Qw`$kE5cvOz6_Cf2q`NKC&b5>DLaTo7bb8Yn4 z;KAcW==a)vBK8L;81JweE_KUFz1vYvLwCF6&?eSu*;b0v*cH_E(i=wgAfFmhUsl!& z?bHjUPcM}|qu676`P{-*O6dOI55Rk?= zj4Gm?qesgaj%Bf&K&&JqmXS2sWBCXa=9INF>txnx%Te`o+n47$kGj?FtX)~}i-Mi# z!yTTiP6nLzh)wHs^+eWDcUE89;dJNw>QVKiJ8K~8RNKckkF!nPnYAP9?Y1vdo$skf zvrc3kX*-zgJf*&^BEPKn@M;j}N%ifloo$C@=LsJ!jD*fbE6D5pj%vQ%yDHdeN3A@L z%DnK#SD;h4TYy?vI!Ifr^X+kzqq3~1-*LYMS2jG3`w#~)^=K7{CL&ncRkEd>3yw}Y z+tv42C){~)?o|80*-?Zz2h_H#_N(l2*Qt| z|6PPayuCm$Wc+!AVmxkvp#dU?CnGQXC!x!Ee4u#=ip8~VHj*#0l1^SYLPrVbgXOzz z%9Z(cJf_E?)2HU+S!+$`yDu^~!yRwm7$|G*jgAAtUgXwpyz$Q2zR5bpq@n*@>(O^=avnjK(B{Y{#J`#xDGaMkBr zw{sxtDBjtTj%^6^0uOXXXg|6Qv>&?fJc29OSzSW+JquU;FXB|U@(7`><57Zs3)XuhpsUCD8 zbYXOg!^zGQ$o?b>_$&>b;t2XuOm^vv|y1Ld~mWwZoCZM+;D|8*K)|) z_9-t)EU;gbDdbJPMctHpE#nWl5(jYJT>Tk)19+bBOLYJySVnx*gwa2%6oGAHXT5{*JqE$RIvBi5ZE{ z0{bHO+l^j2dx|k1q2oe1|399R^oa{S68bA9q%(Wu|DO|*EGDG7pP)njhu#^dPt6Oz z!iE^0ji%pZbi*meTvT@>r=saM49`TK!y7~M(Hk88#Z<&Mbp9nQW+UA6-irk# z@B9DhICnj+nzNaIP8Ry_#)bkWD3~_WKssyLj``0MzBUU1vE%(B-6in%zUkZ-J3fFN z*@LZpChKj13XR8ncg7#N=yYX+At`n_HV&MJVtHsBFP@8_NwwL90F#Pq+35A6SBYLD zH!f$m+PTpR7h23$LvX3-#p03aec^R%R3(+ad~Kz>bB5IpKiu?G(mH3@8K%9zLS&3L zUizKP&;_ENp)vIhXW7IA?oRiVkH?K(6H7Y@>k=#vYLk%#*E^y9`WfM$i@loNcoWD$ zES#SZ8z_<2->>0D3N9LAL+qmPlk@C&r`yhlWlwmy*t)ZHd2%`)#^oK}qr7c^_f+F?EG_`-rd5^) zr_*@em5lJ=J)vfsUA#b6aztpaL3g-N<{&TAzS0lu>FqVT@2`Zyuf54c5CXiiTFz*2{vEAsH zf;ixO5HDvCkp$)4ZuM_|=mqK3G&5KTB=JkF|NE^W;}5mr-z)gP zB^VHC#G=oB&+wveX9(-0* z-q`EzZ#(;yy&#?O&R%!$WBsMQ;Sp}tg_pC;Nb#yJJKS`**aw<125vUov2drrb-;DO zod8#XI~i_1+^KL2!!ta{rZ_x9fm0ry;e)d%JR{$&Hq-7cbE^$aaH&yvcdc;o@R$oa zjio3&&}gV1JQ?CV&l{=7dwx;fR|fPK{qlM-`knrsUw1HOdeQGl1nKYh1s!*b@q*vu zTzHz#Bb9Ix_Oz)Sp74q_WQ4ELg{|~4I^_&-F^w*mn1=o|BLl7-E~GIH`ac8Gmt;gNuWS_csYw!ALp+p zJfj%P)xe1Gv|@Eearn_ixS0vCNS(1LJgXeG4nVm&qr5EGO36uq^W@i-(^sZGPA5F0 zQcqr~&ZsmBe9;!Tz^G@i=P)Was!K2XMSEbZ5fJC?V>|na5e{MqdCKcoG{S-LWmQIX z0X;4dgfyxxFclf-k(TR`K1L+WzRUGUJ&1%Pe{XtR57lf<&oO$_;|xFRexw^WYfl;X z`7@RsKnvoPWPQ^jDcdyoaZs{jsXvnb6#*`+wPm#hZgK|)F2PI6Eb?3s*Z)84y?K0<#r4M@5HJXMqjgDLqm32n7V1){OLHOUO$|yF73+qg z6f0G#_gbim!Q=whYcyKdZ*gf|YFn$ewU{6#VGZtp)w;AoUFQ-N)C#!4@BKORJa-GY zwElj7{dm2|eP*6{W;t`_Y;)$!<%&+S9B)gVeww$Sx#6Q9Tzs@@!Yge1WBnUgSarHKlzW3!R!dL0xW+ zrIr#DJGRWl`YzS`rR>J!x}#3~;m^3{okC&jhmPd1^*A)Fzy2QK&+1ru_B?*sFI0rz zRntCEbhN48(4As=J-nTRCdNMU=xuO6l>&4rGR_OsQb1alkRcO2C*kXvr0VBNYC-Zkcil`GP?2i4T2|D=QL0i9l4+w^Fx z0!ID{Ae3ch2gHCVI_8Mkc_r?ExYL+cNz-*WU#3=TU#Qy6gPHU3 z%oq6>&Pjn-yBIBJT}>)^7vO-~w1~1slD9Cv)V#sV35b3##P#lY z-}DZt9q07o<-I-PTXNCS4l{f0=nZglE9=RY6?`ne_AnuQm=r!twg-npD)ji~FSPw=QjwmAM1zmJyMMADCD{sdb+TNIDK1ySXm?&>~4X#3hQK z8XJd9`HD?XEg|dKP>Jb&wWFKn_K^@%X8^APosu2eFo3>MB9c6xIZ*`XC-($|J4Pc9 zU!!K!NUz}@ z8kNUAbSWOn-7EMNAX5?XBhsj_RyH6!^reGdSg+nEN~85nLX9%;%^p%q8dg>vRuxI^ z!3QJKO#&yRIWlt^>6j0Q09wjR^aewn*^@?qo7{`xj{QVvItF-*Oh2miI5L?<+eqWj z0Zw%73~MYN(f8Nrd)x<>{9+&x0n|_pbStx~Wa;H?_vSJBH!cg-KY^@uSt-h{r!OOW ztcgvV_a8w`_lBkG>zSU~e)XEA+I}@#m-5`qb0n!VR+?#$c&6K1~Ntzgm(#ON&MpcA}6JS=sq-v);HS77CD^LNppkK}6&SSMcPbD0OEl$lu zg|a8;2@a_{UU-5>)^K$UPjE@B<&q*dFEqv3uFK2^FoAuoeG+udJ>4J?bhW$j$sQ%` z=P73{IT>9s8siX*5%ZC6y^TSV72nfB}HaQRQ6EBtM zYEdwPrG*E?y~1j9({3J-zFYHFi~N{+sw2~zjs9Toth(c!UJY;bXm}0%OG`Jf=<@({ zF|hLhc!i}mFX)R;>A$h)vt!Fw!ViS@pG|T(u@d{>>x(`Lx zXT_y^RYqpc0Og>>1lfu-Uc$2n1WVPJa=;!~#N=#p&tZ4idfm{KaEs~mYd&L5mw44hVMVTD{=`vsW%1Ue|74C3(u)I1V8P=jSebYY z6i@YMP<>-VUq~F3zCp!nhOUYailu)&PeaB!yerVpS#U7h#QWik+;zXVKY=TrIp#(u z#7;h`j%lDg|2=qSr6vCvJeRxgzGbvZgYCPv-cyOeuphc0>Z`T8SyG5D6Q%@Lk=iBU;W)nv9X|0*8yova zk;W5Qjj@InfwLq&F}k*~(#Fb}6217Z!S}%%S@0bcfG@F6wEikzduAmhA;gx%m9f;# zHk~Q6zggsD2&+ytx?e+SbLih3o>PxJT+{#C5_z7Et$Stsxb4?MK9|$BQX1h88e?Gj;eaNX8b${X|Ahu zv>bW3L#_5{K^En3;hjqe$pRxm(paUyXzZ}OI)L^)e$ZWRtyF(8VsC-K(Q%}{wa<1| zZ>^_G691sNW;JK#lIjwxoO=aAdL13z!mMmO;rN>LJuurpgGI%5KtcWs6^s z{<{46b5Lw-;w7QjScs6?g?a=$m0P<`P@U;Z$!tj4?8(uiJoT}Tb8{oicy{?3R&obc zoNK2ZUd|mz-xwIVbAF_ur@m{dsXR->d=mUG@^D#dS;MQKSq3zFEHb;UA0?MX8YGd~ zybWFB`!TR4{YT9RE!qTXG!Lo}-KxTlqI64;9->4?kg#z}?3;RFtm%)MNQ^V#{q<4e zg=<1b41GI(ym*|dG-9neZM)d!)ZkEElcFYMNPmqkZ%t@H-G%6ddn^C_4AHg67~#e4DAMOebJ&g97_$;Z4caPpC{Fp65e zq_Ls%F5NCMJl1r@%{VdU(O)jT=(c*<5^fFWvNVVwAg)P!ZfZ&p$S85LMM$mC-PLyB$N7EV_{T<}}8vWIE z{MHLi_?^iw5ytq-nu*N(l;W~hOFND{Y(tCU9NBag1!~7F@>gwOcEO%JtGC7yOZSUG zwEH1C_hT=(-|+JI-kPULd=RV~q#7;=bki=bZi3|gV76?)UJD>m{kr-jqX*Icu~Em zs^zvg&uWB{smD`Gg2mz2#rB>=afOeqi|>lbRBK&4Z}jP1=+j!93=XE)^O1&6)EiqD zOA;@s=76ijQiO57KDYwjUwr5X10Xol&8$c3rfv6V(&!}|>F^T+lKa9u^+GuxjRol|BIg{=u7id`o)uwvw1uS#( zL%K9b`$6>Dt1L+Sf%Mv|oU}2~%pk~HvmuozTZmNQ9Oog|tsR7s$ULic+njAWXPEwS zBYJkWj1NhV{ftUcx!Z2b(`5E!U|}bM##2^2^Dk3w8tEkbxZyL-px!0g&~&R-CJwHd z@|-@`0<^Pun%P}__VR60Vj%lpgO|H2Q4fG@fXbOq?OSH(R#67k_BhQ+1T%FrplD*K z%vZMyC_nofw)${3D7#XvrzALiIjB6!_c+LpsSw);?gMVZ{e#Pqc^FEjn`=`Bma*q?JqL7~1jWBju zpiwpRO&=nw;+EkRc5)#30n|*wBZ5qwH1?%fZAGx^>AMjweiQpXqNL1>c_=)DQH1=_ zR8BXWQ`BAmvA*kTM5od=u+yf&bV2NBflR}YtcX_0?k`b9=9`7_n`+b3MHACE2*c39 zTg-qp^dFI{;ut@MzI1v2=+G5Yx2#D$YD^G{G6_+d#kC9^wCXi$HQwUj!5FmT;h1f7 ztB*w{BS}$WELaa!-p4D9Ltak-#Wk6vud2MC7Y!>Tk%ym`9lVBcJB@$iqrUUT>%4u6 z$MM*WlJ!o_=$juJ6p3CZ5aT@YB5MdqCAoxOCb+WU;|=kHIYqgVdx-WMiiK9Y zMsgy$VgBHkiTBXhp>*mT=YFdGd$!@VURdTMjS&&nbW(K_6SOUpKaa`0x|4ZzCsntv zb{N$%kBv*{e8Ur^63q^ydzoWd6u_^Nt=7H`>o-J_+mdVc?Y?^O4a(?2YGd2_uh{C7 z>+n)sk0T9`_Jd)+xFe3V(i{$COO}cO$?kmd1CfrFZuSG=C_Q(+_<`UpBM@Cot=KBJ zWf0fTx0&hKV}9mLs9(bq6`4KgsHQJdO-Aa4Xw$L8#r+5nCUv4evkiZ286wZ4Ubc;b z=s;_(W1qKOV{}8ra{4YAx_|&n$!frp(J=r<5kC$9rrsyfegK_*q#97VAG4M-TR}tH z<^r40q*Oy~-O&SlY56@y(LDay@X5ybk7|Z~5=qKRXPE5Q>7F52z9d?o1)T>bb(!M| z>)GKe*0Yn<6KU*6HIG2^N;3P=Jk$+NE#N_OPcU{%~htHYzaWeIb&J%J$swc6~U17dF4_7Q%Bfr}HL|&*n_x%#ZiDJd1B# zWg7QoW==eW`)bNFT7v*k1o7eP#7k1mVjNM*NaL$X-FvEKirQ<+eRrE}G$eg@n|*h$ z54zjzyL)}m-DY)H-`cdLwA{lRxNW`r+ewp9)VjtG1o2R#hB)ff;#ZvV zGEV`MTY_-fZUE+2?vWj#ktlX6I#SD$1U(+BP%ZV77;SB;@kwd3+*7xz2Qd4)skSLL zx`Y07jwsQ;0CBxAWGmteQ1HR~gvCId@S?l?UscJRlUS-YN9maYHi&lF#Q%NR--K9l z<}`6=6fHn=2{i_FGooygwwL4~b`$4nWj7hvCVX+P%p|C>q|I=s!uNrLmzx3nD?)$y zZrm56we2R%0QYcPSx*FIt4XH#(-^yZRJ(N>h(8Xqn^LnCpKttj2H(ox23-3!^6T4WtN}szdbBbr!!!UqDU#Hbt5Q1 zlD0FFlo*Z5CU}V)DgN7K>ghfDmamTCE37(?<>cY^bM<~Y@4H@!HR%?cTgV8x+WBW$ z`CD9)4~?!Vp7T0yFw~I)&CUdCKhGrKrzJf@m#7V$UR6OP`K{8^hwzIefM1cHIJ)eu z2!v)5)TS*|MIjY6Px2aIy3y5+*IBZgR8PbF-MDjd>RjD=I*`(}P51FzUQ(An_|BV% z*PGt&E`GXp%8f6$d^E=SvBuv4PHwBmnIsP2dQa0ASOhB!bLt3WGEj3}7d0H6bI3Tm zenm4c%sGY9dLB}np5etkZEDTP%3(ZbOM zV^^a_8}6&Tm-}yesGG@?dBL!cJBMMXW(aJVC5SMgo~JqbTizT!J{HQqz1Gl5eZl=7 zVO;1BbsVH3e;y(;?gi9-C3Q|8Mb-M(IlZRB9(bzDKFJ|L|2n5vSJ(s5vtpgoX9kJL z)z@g&nr;&?>Y8TXOg?tZ%)^w$j*2g0`UW+So_QBJxD1vO&UUMz%P#7ZYO?(1JAD3@ z4M{cCBQm==Nls+;%tn6Xq!R1BS&h%xQeOWo!ETaNn_Ej8g2ts^= zy6U$=s^hexq4j7;YBW8(nRP)0N77MT?iOX?o>T3=_S+(BN8-AHKCJIZ@&KUALBckE z6hq&epBj5llB{iRiehbS9Gd`R#|w<5RkKs?3CD@L#7Z^2!9*GZ$8*Pe0@F#>(>ii@ zvwj+K5$zVFr>kEno1K)+OlrD7m9iOuY-xZ6U&#HY>%M$@q1LM*g^6#Qx8HGjt;8)? zcZL?*?P43!7|ymu_JBAbjyHt$7Ax03J>Tme743Ur@TlwCQw}`f97kj2++2ZPuat zeg~hrEsSgVM68GJT>1)|Y~PXe6;&0mku82JJgC{?FG8f6E&d>YYGyDW&<_OhZxLipoiPb$)b4Z51b*is+3<3=$r((v=1h&r*zzQjOjpEMJ9UFOw`YFC*A=iZ(!Ufk|@$2BmokdoJx2Uj$G zjjrdC^>iiuMN7X!KTo*5FO%TnYpPAnkIgy$$G^VgfR-BTlmx??^eihof*OFzi1ZB2 z7w7ToSQ2AX_j$wnJlD5IzR`RTeI!L>#Mru5Q%h3M%-gs-*)vrS-L2<0Hg8ow!ib2Fp^}PqJk36uLvs|e3OCaHsV{NKW|L`yCebe>8YaM&r z7$)BBomxW$(MSBp-%Y(g@8jK7!_qm6{`%W%ISsyms9;Oht)iMq#-)2Ki*?RtiZ{;t zsNbNEFda{bre{m)$lnj3m%8?*x?_m zC{@k3HL0`hban;l!+c#F0GT12;)7B?(Bg@u=i0Kw)X~y|w0r6_;|+(Lp?I#%%~d7S z=F8I!rWi428qJc{ac$G(Tu}xxxJOV5#B#M*Yg02yX)7z-!3cLsHy>6Z`kW}6Q?@rX zr53ZQ+=wRsRbUbh8TBkG>24BM810w@VEwB%^otE%oS9-P(htB@g40}4zR?|h3DJEv zx;WiR^?v#qT<>FmdUK=&dQw1LUf(QL$@~85YedtpHg4FkA-e9_5qrE8o%U)y|KhLJV7QdzLA>PXy7~3>^e9q8 z*6^Ne_q-r=q-sRT@>s*mTf_!+d4(E;jVcE|yF2-g89pcr=u z5a4MzzTk5>hK(Rl>HTmdOW&zVWcAWVHK~6K!lz32Bb3~T)O*svm&(UL+9Aa%4N~r3 zCkZc2BD<<`3^gM~dasb$6lWVHo~4c|)k8H8zSBH#ZfkvFTZx!_k|$!iKb;D`aXWlXhMHcVW%_Nt2m<1U0lgOG0MfmN9@YVNyJ)za!!20IcJ`Ij$Q7#xZ#(4 zLWk3n_-(!LBFvwuzfR<_X5#)=*^1i$n}fekC3IZvTeS^o=V$f4?#(=y9wubJ3U^&;16 zV~74ccHx1sbad3<O!RBVVZ)-%$0 zql(oB#kMIbwoSI!3>CXFD7NaVa45dfRp|SSf!gj+vFn0j3yO*@@Wo0ajkl=SuY+Q< zii*w3*7jW$yE7=3$QApJMw(EurcpgSw2l(Aww)|0M#z#Qu|9UX55S1F2ZGNJDf;}7 z?w>#Vi|})t2|C?F`uq@X*%X}jzK-h~=TaA^IgYGW&i3StPj--=uGO8u+xFojZMg?I zZQBLcV|85{mOOG80b%HA+oGUXOL-+)-ak6?$eKCJE%#mb(yt7@wW-cXqdaIJmi@7P zUwsA7b%a-axr^AY<{96xsBGw|M6@~2g2KAN`jF~MrKK!(*M;>gj4y|NmSS6e+)Qo? z!quCX7KIMqlrp#X&5TbN97~NDf?3GD$?$xTy8gT(w^|Kde$)8owwHp=e}m3r^{1g* z*kEE=L6g_yk>XHZHn>3XfZQ+(CKBqsqk6PfSd&DpSmzqik~2RrZJG)vdC7X^ zI`6=&G@6&=o5>%P&3{1of(JeSfUp|A_aj zRf`_R{mP0)m*>AxoR-FxAFrucB z-uW#lUGCqoCupT`qt8qxT=!Cnc78NNQ*5U#@7LqBPpZBNoqzO^YJS{4-Rij|S5F(| z+YYz{nWjm=JS4tJ;?z(`L)%FGm zdueq3{ItJ7Ynj;>v#5;zwwE@Lz9*NiQu@YRdaTmZbLqEfK67y{-K_WHbLj__J~5k? zm+;@`RD-A{U`p3faOY|PHT6b;^->BCCf}WoC-9Fxz+G21x~)j-x|#Ry68KlRRrdR8 zdMmg}ucm1d@zyQdW6547-epqrxDDj@66+#0^I}aulvKB@1djXC7VzCct6~iw_m0dk zy*c&Le^RSqkeHCu=>T7!0H!OeD6^$3i*3n29#fM z{{iZl0U8IWGYyMMW79q}tX_dHmK2oGUV-aiWp%^H!xBeQ4~?sTG_L+J%)z$QWXF!B z50%5-twFV)NmgM|g^Oh+)xIZr0;AZeIA49t)y4`8qe_p7B%k+>!%mJQpYV^vk>Wad zv_)ocwE7PZ>c5p&LH)LfRR6W)HB%wryOkfncOyTH{hCL$QoFXde)_TMqex?!G_e36 zuN`OGiz`~l+n5qDN{v=sSe1inGv0jyKj^(T-0aJ2sU&wnC zjN)TOj3&~jI%LWhC#%X8uKyKQC08%Bbx!hGLzSh=7_0>q+S}()U)wIUqpa=73Rv0- z*V(8}EYjI?&NC~*iSwLl0r8y{mbWiu&HIeZr?(=*=h1iM&kq5^oO%Y0E}@%UZx&?2 zJ)_iHo1y_b9P8KoZogs8%kFk7-?Z%&^sQVF5OU5??#l-e;Q@)Gr_V(X5#8u?*IlV$ zZZm>-dr%{zHw)aK;7GbGG6c^%^#+R(C0Xd~JS}hFPd8Xg$i-Njf@SK}tHe$$QH>;! z;|&IG!z|*qKI?u$_X9rMzFze3P4WYJJEW2H^V#%&2cNYlFrtYYq%?Me&wBBLZt!{4 z=Vsw^A!!evdlOmsG?^-!gU?f!7sKZhagEH_#FL0&7o-%)b{7x{Y~5YkKc(rp2Zi0od{w)MvzzyA&gHyCy0<4~K= zH8o?oUhHcq*Xi!|FOb-=X<*pybO(}S;AYi;t&GErxg6=hU$_hx&$e8r8+g&Q8PL;H;)$Pob#*kP`%U22BMp zLsRrEkEbX8AM>!>wF4wcWB>Dd9e=dP$MaeJ-SKgPq?vB`c%0A8;^V7`G#($zFQUBU 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
%>-sSX2@t5Uzl@wIy?ezNb>M{zr_118o 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

)E_~rtH964*Ez}qHgHE0I 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 z

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

_iQYH5n?S%& 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 }O9QXX3pfcZW<$Z1~-sNkb;Z&e_&zS8QCY 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

GJ&5BX<{m&3(8;EZ5?{R4|Y|bP_c& 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

#n+hG86bz$A>pH0*_0n1q36s81M#85o8W zFbV@dBR#BxNf?4@*aovO3Il(^FJTZSU>NqpC``jR9EM3KH=LwlHO#^w3=C0T7=#fR zhMh19<1h~UU=pTa8Vc2-m3)MDsvlRLNAc6s z$5j}H8^%>H47_h#^}`IT7(jmJxN3&cx#KDZV;>+~9Rs95Zufk54g1s;c`(fzX zaWx3zpCNskc-NC22D?ZP(=hNP^}l9Zg<#;zlmn(=3TC>o=PBf0p`0)XBQOj*VFbn{ ze8afPz{EF*{|EAiVd%LDyI>Ob!oWuIg<&`W>wTt z!+scpX&8T;e4eE|PY@5LoRIft=Z_%imu_$c8pJx2K7C})oLgr0Hq!UXJq$vwoE?|X?a z-w#mVes-J^zKxOR_fc!6}M zkY0Eu>0#yrq<@ig^Y*At7@5CEWngI09u<5E`8j)345mN2N2Ou-l0C{8hMy!Kn7DF} zO2RD6%J-|#_cD5;dsGBQKfOmKVC)*~fSyk5_y_u72TZ_T7`T3q8h{x%0fVdesODG5 z=SK2@sV>SR{L&s3*iHN|Q(kDmD2#Oz4wG;YCcd^uh5pI+ukTTD7`TOUL8F&){fqo> zr(DpugM4A?u05*y-`ICI>0ki1!R+_2U%vP4QT;Fo(=ZH&VHA3@v@5KJNf?A_*bK8U z0t4Tteqj*CVHozoC``dP9E3@jg=ttZLV9Sx_z%zn)36f;euy5Jff;CQq26Ew21Y4A ztb-XCg2p|R2S#92!eO_B!-Rz2OZg-mrX?H>OE~n55&k2}2O}^D6R;U(U_`=`*d^gG zF5$3G!eL6}KgO;c<-ZR*U<^iK8g@hDe(Zoz*bh@M4Fg-T14f|S$eD!I(DM`QfMM7S z6EFg^uoH%UiXAWx`(Os9pr@aD-Ge@8z!YqN#shm)7{*`+%)l57{sKE-0uIB#Htg7o z-d_?Q27X0+nEEw#!*GiDFb$0f^gW0kn0*L2Ol`;ReWZT`IgCDz9428FW?|iazCT5I zgny!cLC+xh9>DHDlP`=uL-}CrFQkX@A<8w0erUkhU#VXhc$W0glcC-Yk{*U(9CpAI zjKR?J)DO(Sz<-GUH|&5048ag=gUP>>FHF6F-@){Yge%JZ3hf9Jqxdn5kCWb0=1Ic{ z%)m~Vg>mTFL%YD#Ui84kKI|(i^ThU}55{2|3?5*7fC-p{X*d8qlcbYyH~}-T!Arb@ z*a6e9A7)@0X5lal{fGMTm9f9V4jA|BRVkP*+pCOn;`{chn6P}W>VuvcghK-k!Vt{D z2&~|GVhkEE0UKa&=3dnXjl?WV@JWOpPWZ`t zRVR$kpBNIU7=tm`3zP5Pt32G_5cmM$Fawh?@#OzocG;zakz?!3>Q4 zn)>1X{Lq86H;lnvn0SbIFz_4V!3eB=E8n*h55{3Pj6RJ2z|bSagQ-XH*SArBFbs_W z;=?fP7CG#f@4utn4C)02VFreUk7Fl{K0&=ePnvkgQQt5KjVCD&j6Fp-%)()q`2+bL z&vzJxnL)y#@fZC01oD9mF#ZB|zzj?ZU!;AY=Oya1mh!Q-%VfGd38z%ov_}j4q z*1=d7KY)=D+8c()C_jwnu=7OZ5=#}p<1JiH=1#go?uO zS7<+I^pOAi(F?;cvX1qm0+TQWBi}|ZOx=kcAH?pv35S_`uop(|r`|0R5+h`cd0A^qo zM!fsDkBRiYeJTu775h{YW)I(|Jgt16wNC}1QMpew!;F8QiplrDKJHf{{Zae4KZ$Zx z5e|)`2^YSZd|>jJeX9B#>iMnvR0oX01dPFcn1UG?dD}h}Sc;vn0j6LWW?%>O80dut z?1dqigb_FZV=w~~Z~~@aAWV8#2R+B_Qz2-;HW-3Y7=hg|1`{v=`(X;EVFnIE&+*j9 zxul2HFa(1z0-IqBMqmPV!W4|d4D5rR6R0m}z(E*-Sr~y8=aC*7FaaB23Wi|@c0f-p z<%b6Bg&~-P5jX&2Far~C0;XW#eA2@@=y^NkhX!neAsB@b*bS2~0i!2kCrrG9a>ER) zSVnjqcEHR#sUH|RiTZ(wld=0l^qV<^!wBq#p?6bGm<^KuhtYcq`NHg}gu~1kq=&{? zq`!dlutE4i$_H)^!01PjoeJ&(?8R=nQIq6{r zR$N5AT#SC0fgQq2s81M)P;U9Yf^x(3rPSX?=tu3eFHC%l{Dd9Y4U;RedpY@DNjMCD ziu#1XtI!7nQS^x%W?&jtUyS`%Qx7otY3zn+I3RMEfu2?9{V3mIGYo!)e4%k2@nNWw z_Jxt_Y0pdG4de?GuonhCi$3`dJrTaIroLd}M)biHjKIw2i3dY5{167ZXr~pF7dFGx z8uEq4TIvsGzDj*uN`7BMAI!iojP~H~FbjKOXan^JliwixGW6U;IE>y*`CxK0`LrX4 zA()13Fax8|a~J*rgLmUUBL5!cxE%Qp&<8U=q+h|nz379fAJMKKIWK65DsHcVh8j*Mfy)rKd>2k zc2Zs#fJqpEX^}sJUtK{yL*x&$FbzG=QZFKhfluNW&ry#s4%=Y#dBzEtff*QhfqYhC z&nu*d#u(+ll6+tkMqxKh!2}HEXisR2Q;tvZ9R^_tHp4KCz!>a=Nf?J&*bj|8wHb0E|}dR~6S`53GZM*^~o@U}~5-^S@ggL7&?J^fUy%v2aS`74}+&+-)iiJ%`jNMUq$8nd&vg|PRCA|gu^f!M(>T- z^$F~P28_YrC(#SjSCYSckD~8$#J`4mhl%yr36npfUO&(G$4L*3C&)*>!+w}blaGA= z19r!-<7xZ~28XC$7=>Ap{}sExK>I&SxnS@)`~gN_pU5-#A2gn)J->)PSO>GP8Akp_ zIbj<1!q6_tDe@PvA0}TU|1R{tgq<)BV=(zL@nGZ??1aW{^sb>^D-Wnn=sEU)O2NQs z2UNwED9`)@Dh!Q_4yaz3g-MwF$N`mwvE>I;^;+Uxd_aYu@zDdS4Mr|Ipb{|r$pdN_ zMz1=c8orFZ*Bnq07+8-!;Y|lrM&vNmjh@Y@Ge z6h`jAUYJQ7P@b<6?>h%n5N2T*8h2s`Ol&3}7{2R(3VaRyFbK1EAK*SH%F%}&82mov zf=L+YLGKT+7e=?B2O9SrP-z&4S(v&PyVoKAF?wJcCSm42;=%0w2b8g%?^~%C82`xu z)eW<-4;nu^peA6VpYmRY7j=YQO|Me>z4;qGmOFxnD`a-1dSAW zU>eqao%9b94`v^tp5^;?^uX}L)YCVx8yYb92=>FsqtrXh4q!J7KSud)!XI`J4wEnn zBflpe3_MObVdx3;ZG=w}4`yK$rk|p|VC)a*lkYpp?`HJ;iEtQvn({->pRpTepTXW+ z2p>W(4E>e*g=rYPm3*Hi9n8Wcj6Fv<3}guJr5<1h3_g!un1aJF{5R_3o75xhfYHB` z9(rCN9L8bYZSY0HVelo=!!#U*(P6@GC!d!Ihe_B6!~Y;0W?|hX(!WAD4DKczrr|J* z{*&-;k^WzV!zAp3DVTz3I0!@krXFB;1V8vT@ki;8FbaEN9429GjCe2s19wo49Q6i6 zFanb>1~ae^CdR2J7~DhsC-9TK=!F^B2O|^M2@^2z9qfX2(AbAw7}}2?!Z1w0zyaD5 z2H~)TL(g{!ht)6wgD^Ttdx`u%-f)g+X ztA9W}97}#M17k2)Lpm6SNtl2G(0B{!Ve+ly_e09_HtGcijY-uH!!Qj~a2OiLp??ed zVH?aGk6vh;fL<7d1273QFbyYQ76$IYk7{WL7=$4hgHf1*y)X;=Ve;*hDhoX)PO6G~ zi4P4JhaurRNGI|-+5?8)Nj@-h67}~ZzFpxxk z3i_dOD)k3LFb1Qr55{2%CgC7V!z>J*hJ8OK9&Cn57=>Bb3nTTU6FD4)q0`ClKEh!L z#vAZs7&#NWU;<9S*jebiAA3HCKA3%?~Hjj3JaTpaj?1mYb5H7%8 z7-%N`PtXe+U=W6340gc8BJ76Y7VLpZ==mx6!D?tMCLK(`4j5}izi9+$bFg`|g`i|`K^fNA-@9D9C_ zJ+J|$VFwIeOni}FN`5eW8TS7I`=9{>?bMU-W0X_afnP}YmDIyF+GiE{z!)5aNjL%1 zFz`#-4c5WLwd4nl&)_F8d>!_S91g<_to{|@o%kh;!e*FVO@1(PBlQadpU1vmlkSW7 z1I)q>80y0Bpyx~E4~;LAK80Ohp})a69Dv4GvFkzF=WCP;CVD8pa2??=8z=lB?7N9@ zn1S8UxP^KaISl*;dte=m!4S;A4j8=^J75-OV7Qm~+ll{8>I)`eCrraQ^xRJUNjMyY zF_;zkCi?Tk=z(Dv`!;?919wngFad*)VApr>2N;2I`F(0reXMA>QBO9^KX&E2=x32yI}yvp#l3~5T=Al?1mv&@jLWD14dv2 zjKMI>z;5XIG39|#I1JOU;xXj+kq#O#1S2p4v#?X-_mjVThl9|wm3&1GD|TSVPsj&` zVF!%$Q@_yIM)>auhXzc+FigV^n1L~vg}u=8OZ-N@L(k)U{}uiT6Dj-xW?&RX9;7@l z3KKB+8}ftU?brolu;K~wg9gk#Ont!Qqv(O20rbEK?1oX8fHBw)r)38nCkD(8ScAy7Fe@}WCgTpWjE1pFDIQ|P`Fa#5@4Thc|Jz$8pdI2?u<==mdhhG<8agfaR4SK1F|o+TcPJx96zguTy`A56nx znEV_0J&iyAop2b3F_?zEFbk8=vx{;GUmzU}LeC)Kuo@;_q#j^k82vEvGUbP{e^6h4 zCS8{Lgy9kN!5AEX(NX*ZreMW0$aC~J=$XL3VHEbkBut5XKk@!TJQ##Y*eu@U>F9x2UP-wdJsB6n4NkjKL)Ag&CNH zkr@ZouzZJg&yxOd;=?$M!wl?)$yo=vPm*%_(GSxw3_Wi+$o-Po1LH6T`(YfWVFC_I zcmVww!eIyWyb=3hr0Sp=gvQYaRmJnfd-Fln20b+gRUb^e?Vy@~Sy=ryb(b5a2MZCCmbeV2aKM9y)gJb>hA@@=N{xf zNy>K?b_qX7d0(VFA?$*QdDsn&`IHaF&c?2nhzA>BxbdKh$amNaGcXAQP1FPQG!t(a zIqZgkF!{hZoDexQUdEpD52`3ke)ynD!SqE3Rp1}Q|0w!ln*Yi7HP{IwU!ophu$ywh*jFjnzbNlI@`K^8 zlO6^(q8G+)p+5gjx?aMe=Qi2{8n>elreP9>?jS!HzVo08WhqY|?E>TX&@M22KYB)J zhX+UxOPO|K|wyhVwjSoq@7r zXCGD(FFPzC@*4gfd-I4o$%-Rzk8i#kS>lJkHliYj^M^mM&|ls1hRW+IVxA8kbLL5> z)gCYD=kTwQfBopaPE45R53Kc`?XT|gwfK`|z7=J&{ME?j`77pC5?s%}Rs5^Cbws_% z%OCUofgW$8zk022p5N#yZ}Ml$eE%VlF;AzPZ>5tww(u|8JEAU^d`P$6+w8Ai=bP_0 zddeI9b!%rV^as0UHu)1}-o3N@!Fm2VRL=KT6BRX$lD)Py2di%zQCqD1*LxR;o&}T6(;`dETjtbU9klF&8^xn?}?I%bpEVj`d>Cy7Cr(U61HlJ9D1Dq3f^~f2`bh zF~w>)TN_3k+b~;S4|-DH8c}mByEb@1XQ+JOH!^X@*gCfluy!akosBgTO{RLXxp(! z%C*Fw_IjV4-VEK|?dTgwjHuImrar5^&zAOXL4hwzL7etpBn>5YY$9Fy&JlIiVMTW6 z`khiAv0C56Ojko%^7?k8FZF{Fb!lRiUB>eTjQUl)>NmkF?`vOgt|bI|Lk)9`_YIx8{|Ktrxtkw@>L?# z{kui__hP@{U26Ak-D>7|vW)oM#P7^2fl^;9k!O)#W7ik<6#BQ*UmE>k-+5j)@3wS` zUE9!S+&7}QMc%RtH}3K^`D10?du+p+?S8+T_!;6e#Oivq`aS++^?TZ;Yvy8qYPRoc zx@zeFVvk?-Gq}}e>xf!Q{hIBr%dt@WNVmH#ht=+B89dGQSV_9<&+tDH=yp6u+Jk=8 zReoK5w39GC((apxAM77d*NTAn>%7!^kHlYFzR2vq!Rw2=uTHm zEB!v`UE!~z1KRyw@{?D3rAhZANvGRc*C)fn$EnS;^&s9+w|AYm+}c%k+a)68{$?YW5-fp{_stz`Mn@S1-`bs{Lv^`YN`Ks2A+^ z(BqYRKTOZ?-R3@S&KHf1{HtQT>HGDFy2ADo_wvNcuAJ&6<}{=2T8^G{YDCr8{(h+O zyv+L<*Me%d)ARHe^d%k|QE$UW4?X=Ne}(>?@9knQ@<&Ck{fc(8=F>&~q_LRMm9c>q zWg47c=}i=Tm3~=XLI3{Eh}!F7rydt+KWiS-m%|_$m7T_%L}2%w;~@#ev!17^{IzDkOy}-|Eb^aAy`L}ZMm^s6jw<^NW6dM}3hyUmJYOrttmWSp;>Vt_)-!s1 zV!hSn^G5W@LCaJlXOqn{>VCay{u0Q*C}Vqx}wqF=KJDw?s$Qlmzvq=abuEvvQLhv z)2)2gd6(Gsot&I)KRflO#|>S7tn=s= zJEyNGX~)_l7$5({I!emp%)@#ejZbvVU_4`KEzV(Alhng<(nU%47D;D)#J*L?JCT2y zc}w(dkabz%I!KSVdb~NuA20JY&79u8xv1EVzP=&HzQX+sX04sUo}+7~7uTNRzPi22 z{q$$jzhK!Yn8UvsNQ2vUZ&9T;Ib{iFjw3nrc0R|xLhN+L zk?RVE5nV4eZ(#h*$CJ2xq+RQg_akr967xT4hgRes-pzQ2-Jh86dt_g`R`!+RCt=@- zxNecBIQxkn(nolwW5o8`Y1a#~K7N;b_b}HB;%7tXi~emy?YH~ewE9?_&G7jSF|SLx z=LA@9^KQv^^S7)&F1O~1M&u31PqgG0Tk_?|!!GexA@4vgJ|=oDv*Pz4kGaI(jJ&r* zzts0OLV#H@8rCczw@6O{@93o5P4LD_-B`Q74z5P%B!d+ znFqHLUN<_TZnnc){Sj|$miAw>`StidM7#v?^85I8GS3y(Pm4c$y!U2Te-!&_jv_tp z2t7^w(fVlrM?SziL%T}kt;j>XE3{JN-cA0%NBk91o_6F7dq>m)(V@%30TF9E`G}vc zA-sd|8TNSS)(-j{rO6-n`o8S$r;C}+bpPCmzPf`WO57s<5r5f@+(15V`-|RB>2X~9 zOOu>feW}!6^!b7I|2NXT75LQWp@fLr!*72*^b)lLCd~+p}41YH1DwO)$PP#hMeaGJaIOkAP z=2gy(e(OGP*yjLM6t=s3RLPv3|42S_kY|uTQqC7WZ=k<-c=c6~|(*IVY zFLF5VqGP{WpwF479eoS^QD2=jyIXJa9W`A@BPlo(WbiFLAZsMcN%9Z)N0ppQNdATM zrn7Ht6sM@BD5d8CdL>j((#E6l@1sW5?bf*6!&FPV;a75=89Uq;B(-6-8VxAhX6^T@ zNtbvd@4U0pS?6rd`Ia7kEWb}2?p;J_sFIS>mRUY5PI|AKN?gSAfar`6~SA3Lf} zuAB8&%KR{nT0aIr~gqe=@(nFx`A38YQ1?=!^4iVNsX=h>^ms=fvCl1{-scK?jpd1A z?^e=PpD?Oq+RlGOz5{u{MZODpg^PR=xyMCb^*`(nv8z=79OPLSc_Z@S61kLbIr0qh zjOE`wa{g{#=U`MhxoBL_9a;QjBk8)|KB}s$abcaDrxorS<=lRlX`2zo-f+yv5$iaD zv;`>QBYwXNeQhU>s(m70=2$D^lX-o{`@0gymwK!^hWX?jF6BpVl*mPYBl2qGuU7vm z;t!YTk$iiQXG-Lve>3tyNDW<&a)u0M&tQ|x)?tFuSqmmiBguQI;a zSx@}_lcv^BEApg^yd8O;i+nZmgo}J5@?IDD7UXdk`F7;pF7hGdF&B9bd8dnfHiKx? zMP7@%!$m$9dBjD&40)T2d?oU*i+m08W*7M;s;iM$PE{H z6&v|qwqh|;`sgv0kSbD7aN3Tm;kM)qX zZnpM23#`lkdLG+C{6O&4#cxIR5b+Iu6Jfc%-g5RUOG?+5F|U`!qRaZ)ywD`|GUqtP zmwMib&EMucbgs;!)aTVqLW}eyv{crE3!U|#q-!T#2kG>FPtRZZblxR)!o|f2t4Ozr zbScsuF7;!5M7|Yy|9eNL>~D7$7xGRwsjtRbBvfa1VRZ?HGk7v9+ zop**yetLh$^~ovclKJ&1Wp3agwPZJ=PJ&UF5aME8aIX-?_*Q7x^;e z4KDJP$ipu3HOM<$PzvexA0M zRi^(-d(NTav+o~OYq{QN`iHas)B81Nzs}%P?)#O`wL|H3n)vZ*^abaSDw@OowDZ?S zu+o#V5w0(_SC-6S*R#r*NNA&GRpJ$P^F4py`uPbrg%er4l+qclXuEb@LUmrqW zBdX?d;G0C>i~KG2t(Wpz_favit(Ee2%{dN?t|idCgW~Qb*rn74=! z3KiaaIsS3{VmIN&dH?%z*T0kbzeRS97*vnBd zgudVfqxO9$hq#}TMY^nKrWSWWrS~?sYL|80+>`Nt^yjaySod3SU!2_6$b_K^53uyI zT(4JFk#4wcRB>Eue`G%FL7sJyZ$>`hBHxDGbKz7yJCRqo$afqF>mhRV<#IjJ=}$xG zGcMu!hTWg09bdTqd${i-?)^#68&a-0T=)&G7*$tFJuqGs-iP{0>Y+tnpSsk#KGmYf zo?4=|ldh9=k4ZXR&oV)IA1JJ6(ceQn<5I?_;(D|8tIUcoPwh|3NVlDIeV2`@Z;F1s z4sqsHJr6Msb|L@rPe!d}-&ZQ(0ern*CRCd+C0t{o}l%_Okt>m2|0VM%72H@x~hW zoOH3Gbb4zq*o)X=u3BwsxKFh zk9xeF;tz=KMZN!V-=!~m{+*t!gD8mpZXHnj~qpji}oY>U_sKaA$>=T-`KO-p)ftGUAb?H^gk<2 zuQyiW7u!kS{l(YMFRI?lc)Dg(ecbkoLyQyn#ntY9q01-swWF_XE$5K7KIi_7l5>W0 z{mD~&+uikP|ENOWR`hjr7oVF*Ki`2|e&h3({4IX7R<1X8`Ig8!<=Za)FiHHtS2)+Q z`dvYM-wbT1Mn}G(sbbHZ(~1ApQS~8PKj*dj{PR;p=0HwICeMQNPhEb}HIVN0TGwnv z-|*K))u>&chiISp5xynv^{K}nDOdR!%(whz=ho74g}mn$)Pi*+ZPtjSn@c)l1K0WO zaZ=x}W35-R0ey#_!P<{{CigXR}QN?9h`y>6W2YCqjjUv_K;Br}yURc=g zCEixC_rJuGe1?dZB_7KokLMioyj0TXkXL+tR6Q?polleG^BprE=RB*Xf$@=euUEUR zL|^QtQMIYK-Sm3O*?;QuVCLUhzFXbfP4@%wt8HT6&D5i<58qqw)8|}NL@kEeS6LmonYJ#ox_av>K`+6ud)Ue`Ag zulK*ilYCYZFH1bSpYD%xIwSHm$gA%vmP`JdB!A@Jk@(Jdz%Irfmd)!Q#2X;qMH0{Y zNdFi@9=QAUYsWcE)~WA}s`b`*S9rgg)8DN9H~UGSdpqj&z4U|CGWma>{%iL)J)cNF zkin?18|eG7wh%u{{0pu8d%SJ3uh!4caUfLfdpj9A{mmY4cag68hf~MfN#q9dYo*R~ z{Yv|W3#(VRZ|w)zzy6na(vGdfOB1hfycKyn^5GJ>EorbSokjn;cU0YM_b;cvI@j&2cFrE>3%mC(J+6u$wxh4&K7I?? z*5@`(TjPE<=)1~YpZ1#?^le4oz*hDd{B5?I+`@OB?iJE+c1nIf88x3z((T&nXWjah z!iJT2lf;X?ig>jjWc+;<@mh%&!#lE>A=F6Xts#EN7z2tsIJ+3b{uiIqnd^fr4)9YmECq3wk z^V{CX^LPFu?X)?>`3~|gi7-D7mU&l{w&xDw1^7+yL&cMPa>VN-UgmB^>za}lw4=Au6v06^=IP`{8sxi{+9AZxXRS3pDr}7 zvo0gN;&HCCPM4o!zg)NVJ$8tG!4&1$jK2OSoO4KPf6P9^y56@)Zsz$QT8j49_Ihp? z=_k_s_WBHzmH3CAxApZ^eI1$g*Kxk5-0iXNE2?i~Kl>-H` *&Vltj%t7dp`WYv~ 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 diff --git a/agents/libcrypto777.a b/agents/libcrypto777.a deleted file mode 100755 index 7a71827dea6ea98a80b1dfac2e3dca12d560f271..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769434 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 Jc478SIPu`--ycD^U=NODoHFK$iBB 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 #{v5-RyF%pEFj_y7QYoNF!?g5sUV}MDDPNgIfr+ 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 Date: Wed, 23 Mar 2016 17:39:26 -0300 Subject: [PATCH 185/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 4 ++-- iguana/iguana_recv.c | 2 +- iguana/iguana_unspents.c | 5 +++++ iguana/main.c | 35 ++++++++++++++--------------------- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 1a5df1b17..d624eeec8 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -39,7 +39,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_MAXPENDHDRS 1 #define _IGUANA_MAXPENDING 3 #define IGUANA_MINPENDBUNDLES 2 -#define IGUANA_MAXPENDBUNDLES 2 +#define IGUANA_MAXPENDBUNDLES 64 #define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 29fe97d51..988ada3f2 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -514,7 +514,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int bp->issued[i] = block->issued = now; } } - printf("kill peer.%d %s reissued\n",i,addr->ipaddr); + printf("slow peer.%d dead.%u (%s) reissued.%d\n",i,addr->dead,addr->ipaddr,flag); } } } @@ -848,7 +848,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { 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); + //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; coin->numemitted++; } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 167fbfa7e..dfd2c335d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -191,7 +191,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else if ( 0 && coin->enableCACHE != 0 ) + else //if ( 0 && coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 3cf20f2f5..a9e252671 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -44,6 +44,11 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdris,uint32_t return(0); } +void iguana_realtime_update(struct iguana_info *coin) +{ + +} + 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) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; diff --git a/iguana/main.c b/iguana/main.c index e35bc849e..58dcbb076 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -450,33 +450,29 @@ void mainloop(struct supernet_info *myinfo) if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 && coin->started != 0 ) { flag++; + iguana_realtime_update(coin); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { - if ( bp->ramchain.Uextras == 0 ) - { - printf("alloc Uextras.[%d]\n",bp->hdrsi); - bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); - } - if ( bp->ramchain.A == 0 ) - { - printf("alloc A2.[%d]\n",bp->hdrsi); - bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); - } for (j=0; jhdrsi; j++) { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) break; - //prevbp->ramchain.A = 0; - //prevbp->ramchain.Uextras = 0; } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { - //printf("hdrsi.%d start balances.%d\n",bp->hdrsi,bp->bundleheight); - //bp->ramchain.A = 0; - //bp->ramchain.Uextras = 0; - iguana_balancecalc(ptr->coin,bp,bp == coin->current); + if ( bp->ramchain.Uextras == 0 ) + { + printf("alloc Uextras.[%d]\n",bp->hdrsi); + bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); + } + if ( bp->ramchain.A == 0 ) + { + printf("alloc A2.[%d]\n",bp->hdrsi); + bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); + } + iguana_balancecalc(ptr->coin,bp,bp->hdrsi >= coin->balanceswritten); bp->queued = 0; if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) { @@ -496,12 +492,9 @@ void mainloop(struct supernet_info *myinfo) } } iguana_jsonQ(); + pangea_queues(SuperNET_MYINFO(0)); if ( flag == 0 ) - { - pangea_queues(SuperNET_MYINFO(0)); - usleep(1000000); - } - else usleep(100000); + usleep(100000); } } From f9795d9051321ec9d7226a9c45b9a13563906556 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:41:06 -0300 Subject: [PATCH 186/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 72639c895..02fd9f10e 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -572,7 +572,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->endPEND = 2; if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); - else coin->enableCACHE = mult != 0; + else coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; From da447b9b52f860774a958fad13bb96c3f6eba10e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:41:41 -0300 Subject: [PATCH 187/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index dfd2c335d..167fbfa7e 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -191,7 +191,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else //if ( 0 && coin->enableCACHE != 0 ) + else if ( 0 && coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; From d4e0485e100d2722ac94336d2d4abef202973f4c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:43:28 -0300 Subject: [PATCH 188/333] test --- iguana/iguana777.c | 4 ++-- iguana/iguana_recv.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 02fd9f10e..f980f8fa9 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -570,16 +570,16 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->endPEND = 1024; else if ( coin->endPEND < 2 ) coin->endPEND = 2; + coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); - else coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); coin->MAXMEM = juint(json,"RAM"); if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; coin->MAXMEM *= (1024 * 1024 * 1024); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) coin->polltimeout = 10; - char str[65]; printf("MAXMEM.%s\n",mbstr(str,coin->MAXMEM)); + char str[65]; printf("MAXMEM.%s enablecache.%d\n",mbstr(str,coin->MAXMEM),coin->enableCACHE); coin->active = juint(json,"active"); if ( (coin->minconfirms = minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 167fbfa7e..dfd2c335d 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -191,7 +191,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else if ( 0 && coin->enableCACHE != 0 ) + else //if ( 0 && coin->enableCACHE != 0 ) printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; From 113a1f8bf6a84706e10e5fd33c0bfec02b3af4b1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 17:49:22 -0300 Subject: [PATCH 189/333] test --- iguana/iguana_recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index dfd2c335d..a47308227 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -191,8 +191,8 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else //if ( 0 && coin->enableCACHE != 0 ) - printf("validated.(%s)\n",bits256_str(str,origtxdata->block.RO.hash2)); + else if ( 1 && coin->enableCACHE != 0 ) + printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); From d654ab949dfc0a84d2af7d7e65335640e14326ab Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:22:05 -0300 Subject: [PATCH 190/333] test --- iguana/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 58dcbb076..282b7aa1a 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -449,7 +449,6 @@ void mainloop(struct supernet_info *myinfo) for (i=0; iactive != 0 && (bp= coin->current) != 0 && coin->started != 0 ) { - flag++; iguana_realtime_update(coin); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { @@ -476,13 +475,14 @@ void mainloop(struct supernet_info *myinfo) bp->queued = 0; if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) { + flag++; iguana_balanceflush(ptr->coin,bp->hdrsi,3); printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); } } else { - printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); + //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); coin->pendbalances--; iguana_balancesQ(coin,bp); } From e64109d93e2f3b28e6b43ac7f61072c666b2bf2e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:22:53 -0300 Subject: [PATCH 191/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 282b7aa1a..4d7d3f668 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -456,7 +456,7 @@ void mainloop(struct supernet_info *myinfo) { for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) break; } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) From f7162d4784a38c2f51eb3c077e9853c6071dc30d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:23:24 -0300 Subject: [PATCH 192/333] test --- iguana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/main.c b/iguana/main.c index 4d7d3f668..7450a3fb3 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -456,7 +456,7 @@ void mainloop(struct supernet_info *myinfo) { for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish == 0 ) break; } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) From 01802d842130e75b2157df8235666f58a316258c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:27:11 -0300 Subject: [PATCH 193/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/iguana_recv.c | 2 +- iguana/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index c7c4e905c..7c885d4e7 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1550,7 +1550,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname { bp->balancefinish = (uint32_t)time(NULL); //printf("found balances for %d\n",bp->hdrsi); - } else printf("error with extras\n"); + } //else printf("error with extras\n"); } } if ( B != 0 && bp != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index a47308227..bb1f1740e 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -191,7 +191,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return; } - else if ( 1 && coin->enableCACHE != 0 ) + else if ( 0 && coin->enableCACHE != 0 ) printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); copyflag = coin->enableCACHE; bp = 0, bundlei = -2; diff --git a/iguana/main.c b/iguana/main.c index 7450a3fb3..4e40734e5 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -471,7 +471,7 @@ void mainloop(struct supernet_info *myinfo) printf("alloc A2.[%d]\n",bp->hdrsi); bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); } - iguana_balancecalc(ptr->coin,bp,bp->hdrsi >= coin->balanceswritten); + iguana_balancecalc(ptr->coin,bp,bp->hdrsi >= coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten); bp->queued = 0; if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) { From 504a20a7a00a1d3c2538b3850cd9ef3559372368 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:49:40 -0300 Subject: [PATCH 194/333] test --- iguana/iguana777.h | 1 + iguana/iguana_unspents.c | 4 ++-- iguana/main.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index d624eeec8..037173998 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -802,6 +802,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_realtime_update(struct iguana_info *coin); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index a9e252671..ed108b753 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -46,7 +46,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdris,uint32_t void iguana_realtime_update(struct iguana_info *coin) { - + //bp->hdrsi >= coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten } 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) @@ -455,7 +455,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( spentbp->dirty++ == 3 ) + if ( (spentbp->dirty++ % 100000) == 3 ) { printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); diff --git a/iguana/main.c b/iguana/main.c index 4e40734e5..41e2da335 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -471,7 +471,7 @@ void mainloop(struct supernet_info *myinfo) printf("alloc A2.[%d]\n",bp->hdrsi); bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); } - iguana_balancecalc(ptr->coin,bp,bp->hdrsi >= coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten); + iguana_balancecalc(ptr->coin,bp,0); bp->queued = 0; if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) { From ac12c55e905c1ea22a35f7be615230fd57f3c6bb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:53:11 -0300 Subject: [PATCH 195/333] test --- iguana/iguana_unspents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ed108b753..af2a088b7 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -455,11 +455,12 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( (spentbp->dirty++ % 100000) == 3 ) + if ( (bp == spentbp && spentbp->dirty == 0) || (bp == spentbp != 0 && (spentbp->dirty % 100000) == 3) ) { printf("prefetch.[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); } + spentbp->dirty++; //if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) From 27d7d960fe239596940eb3d8070c7b71ee31c4d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:54:54 -0300 Subject: [PATCH 196/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index af2a088b7..ffc907a9a 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -457,7 +457,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { if ( (bp == spentbp && spentbp->dirty == 0) || (bp == spentbp != 0 && (spentbp->dirty % 100000) == 3) ) { - printf("prefetch.[%d]\n",spentbp->hdrsi); + printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); } spentbp->dirty++; From 0c489ce00821159b678ebac66b1ea901188b57eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 18:56:26 -0300 Subject: [PATCH 197/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ffc907a9a..448f96f69 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -455,7 +455,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( (bp == spentbp && spentbp->dirty == 0) || (bp == spentbp != 0 && (spentbp->dirty % 100000) == 3) ) + if ( (bp == spentbp && spentbp->dirty == 0) || (spentbp != bp && (spentbp->dirty % 100000) == 3) ) { printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 4d89c7a131f78b9bba946b351c061484ae4893bc Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 19:04:14 -0300 Subject: [PATCH 198/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/iguana_unspents.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 7c885d4e7..eaf0eb284 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -814,7 +814,7 @@ void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *r for (i=0; ifilesize; i++) if ( ptr[i] != 0 ) nonz++; - printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); + //printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); return; U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 448f96f69..3e849c719 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -455,9 +455,9 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( (bp == spentbp && spentbp->dirty == 0) || (spentbp != bp && (spentbp->dirty % 100000) == 3) ) + if ( (bp == spentbp && spentbp->dirty == 0) || (spentbp != bp && (spentbp->dirty % 10000) == 3) ) { - printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); } spentbp->dirty++; From 09f2527ab6d4e9a602ca0a4763f0c5919ed9859a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 19:13:55 -0300 Subject: [PATCH 199/333] test --- iguana/iguana777.c | 5 +---- iguana/iguana777.h | 2 +- iguana/iguana_unspents.c | 3 ++- iguana/main.c | 3 ++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index f980f8fa9..e593617e5 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -435,7 +435,7 @@ void iguana_helper(void *arg) void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[1024]; + struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[65]; uint32_t now; n = (int32_t)(long)coins[0]; coins++; @@ -502,9 +502,6 @@ void iguana_coinloop(void *arg) //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers } - //fprintf(stderr,"call stats\n"); - iguana_bundlestats(coin,str); - //fprintf(stderr,"call process\n"); flag += iguana_processrecv(coin); if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 037173998..344c85503 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -424,7 +424,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,nexttime,currenttime; + 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; double avetime,threshold,metric; uint64_t datasize,estsize; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 3e849c719..3daa5eb94 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -455,10 +455,11 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( (bp == spentbp && spentbp->dirty == 0) || (spentbp != bp && (spentbp->dirty % 10000) == 3) ) + if ( now > bp->lastprefetch+30 ) { //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); + bp->lastprefetch = now; } spentbp->dirty++; //if ( incremental == 0 ) diff --git a/iguana/main.c b/iguana/main.c index 41e2da335..4f16b75b8 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -438,7 +438,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu void mainloop(struct supernet_info *myinfo) { - int32_t i,j,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; + int32_t i,j,flag; char str[2048]; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; sleep(3); printf("mainloop\n"); while ( 1 ) @@ -449,6 +449,7 @@ void mainloop(struct supernet_info *myinfo) for (i=0; iactive != 0 && (bp= coin->current) != 0 && coin->started != 0 ) { + iguana_bundlestats(coin,str); iguana_realtime_update(coin); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { From a9e5c49a769adbdea154cdda26b14560ddc2f33d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:26:00 -0300 Subject: [PATCH 200/333] test --- iguana/iguana777.c | 23 +--- iguana/iguana777.h | 4 +- iguana/iguana_bundles.c | 2 +- iguana/iguana_peers.c | 2 +- iguana/iguana_ramchain.c | 114 ++++-------------- iguana/iguana_unspents.c | 253 ++++++++++++++++++++++++++++++++++++++- iguana/main.c | 133 +------------------- 7 files changed, 283 insertions(+), 248 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index e593617e5..a7a3c0d4a 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -352,26 +352,6 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m return(0); } -void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental) -{ - uint32_t starttime; - if ( bp->balancefinish > 1 ) - { - printf("make sure DB files have this bp.%d\n",bp->hdrsi); - iguana_validateQ(coin,bp); - return; - } - starttime = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,bp,incremental) < 0 ) - { - printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); - exit(-1); - } - bp->balancefinish = (uint32_t)time(NULL); - printf("GENERATED BALANCES for ht.%d duration %d seconds\n",bp->bundleheight,bp->balancefinish - (uint32_t)starttime); - iguana_validateQ(coin,bp); -} - void iguana_helper(void *arg) { FILE *fp = 0; cJSON *argjson=0; int32_t type,helperid=rand(),flag,idle=0; @@ -435,7 +415,7 @@ void iguana_helper(void *arg) void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[65]; + struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[2065]; uint32_t now; n = (int32_t)(long)coins[0]; coins++; @@ -502,6 +482,7 @@ void iguana_coinloop(void *arg) //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers } + iguana_bundlestats(coin,str); flag += iguana_processrecv(coin); if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 344c85503..9b1c792f0 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -797,12 +797,14 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist); 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,int32_t incremental); +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain); void iguana_realtime_update(struct iguana_info *coin); +int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 988ada3f2..d651aa8f4 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -917,7 +917,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; now = (uint32_t)time(NULL); - dispflag = (rand() % 1000) == 0; + dispflag = 1;//(rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; count = coin->bundlescount; //sortbuf = calloc(count,sizeof(*sortbuf)*2); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 64a63ead0..fc5cd7f64 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1085,7 +1085,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) addr->dead = 1; } } - printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); + //printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); if ( addr->vinsfp != 0 ) fclose(addr->vinsfp); if ( addr->voutsfp != 0 ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index eaf0eb284..205ed5aba 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1273,7 +1273,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * return(0); } -int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag) +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag) { struct iguana_kvitem *item,*tmp; if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) @@ -1326,18 +1326,7 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag ramchain->numXspends = 0; ramchain->Xspendinds = 0; } - if ( ramchain->debitsfileptr != 0 ) - { - munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); - ramchain->debitsfileptr = 0; - ramchain->debitsfilesize = 0; - } - if ( ramchain->lastspendsfileptr != 0 ) - { - munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); - ramchain->lastspendsfileptr = 0; - ramchain->lastspendsfilesize = 0; - } + iguana_purgevolatiles(coin,ramchain); if ( deleteflag != 0 ) memset(ramchain,0,sizeof(*ramchain)); return(0); @@ -1345,7 +1334,7 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; int32_t iter,err=0,numhdrsi; char fname[1024]; bits256 balancehash; + RAMCHAIN_DECLARE; int32_t err=0; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); @@ -1357,60 +1346,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * 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 - { - err = -1; - for (iter=0; iter<2; iter++) - { - sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); - if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) - { - ramchain->from_roA = (iter == 0); - numhdrsi = *(int32_t *)ramchain->debitsfileptr; - memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); - if ( coin->balanceswritten == 0 ) - { - coin->balanceswritten = numhdrsi; - coin->balancehash = balancehash; - } - if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) - { - ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); - sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); - if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) - { - numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; - memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); - if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) - { - ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); - ramchain->from_roU = (iter == 0); - err = 0; - } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); - } else printf("ramchain map error3 %s\n",fname); - } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); - } - if ( err == 0 ) - { - //printf("mapped extra.%s\n",fname); - break; - } - ramchain->A = 0; - ramchain->Uextras = 0; - if ( ramchain->debitsfileptr != 0 ) - { - munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); - ramchain->debitsfileptr = 0; - ramchain->debitsfilesize = 0; - } - if ( ramchain->lastspendsfileptr != 0 ) - { - munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); - ramchain->lastspendsfileptr = 0; - ramchain->lastspendsfilesize = 0; - } - } - } + else err = iguana_mapvolatiles(coin,ramchain); } return(err); } @@ -2035,7 +1971,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru { ptr = mapchain->fileptr; fsize = mapchain->filesize; mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(mapchain,1); + iguana_ramchain_free(coin,mapchain,1); memset(&R,0,sizeof(R)); R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; iguana_ramchain_link(&R,block->RO.hash2,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); @@ -2059,7 +1995,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru bp->numspends += ramchain->H.data->numspends; bp->rawscriptspace += ramchain->H.data->scriptspace; } - iguana_ramchain_free(&R,1); + iguana_ramchain_free(coin,&R,1); } else { @@ -2077,7 +2013,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru block->fpos = -1, block->fpipbits = block->RO.recvlen = 0; //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); ramchain->H.ROflag = 0; - iguana_ramchain_free(ramchain,0); + iguana_ramchain_free(coin,ramchain,0); return(fpos); } @@ -2171,7 +2107,7 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs return(num); } -void iguana_bundlemapfree(struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) +void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) { int32_t j,n = (endi - starti + 1); for (j=0; jH.data->lhashes[i].uints[0]); printf("%llx ht.%d bundlehashes.%s\n",(long long)mapchain->H.data->sha256.txid,mapchain->height,coin->symbol); - iguana_ramchain_free(mapchain,cmpflag); + iguana_ramchain_free(coin,mapchain,cmpflag); } iguana_mempurge(hashmem); } @@ -2373,7 +2309,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str filesizes = mycalloc('f',bp->n,sizeof(*filesizes)); if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) != bp->n ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("iguana_bundlesaveHT: no bundlefiles error\n"); return(-1); } @@ -2408,7 +2344,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str mapchain->H.ROflag = 1; if ( fpos > filesize ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",fpos,filesize,bp->hdrsi,bundlei); break; } @@ -2454,7 +2390,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str block->RO.recvlen = 0; bp->issued[bundlei] = 0; } - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } @@ -2468,7 +2404,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) < 0 ) { printf("error iguana_ramchain_alloc for bundleheight.%d\n",bp->bundleheight); - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } iguana_ramchain_link(dest,bp->hashes[starti],bp->hashes[endi],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); @@ -2489,7 +2425,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str block->fpipbits = 0; bp->issued[i] = 0; block->issued = 0; - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } //destB[i] = block->RO; @@ -2538,7 +2474,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str //char str[65]; printf("d.%d ht.%d %s saved lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); retval = 0; } else bp->generrs++; - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); if ( retval == 0 )//|| bp->generrs > 3 ) { char dirname[1024]; @@ -2556,18 +2492,18 @@ 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(dest,0); + iguana_ramchain_free(coin,dest,0); bp->ramchain = newchain; //printf("finished bundlesave.%d\n",bp->bundleheight); return(retval); } -void iguana_mergefree(struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) +void iguana_mergefree(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) { if ( A != 0 ) - iguana_ramchain_free(A,0); + iguana_ramchain_free(coin,A,0); if ( B != 0 ) - iguana_ramchain_free(B,0); + iguana_ramchain_free(coin,B,0); if ( mem != 0 ) iguana_mempurge(mem); if ( hashmemA != 0 ) @@ -2600,7 +2536,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st if ( A == 0 || B == 0 || A->H.data == 0 || B->H.data == 0 || (A->H.data->allocsize + B->H.data->allocsize) > IGUANA_MAXRAMCHAINSIZE ) { printf("MERGE error %d[%d] %d[%d]\n",A->height,A->numblocks,B->height,B->numblocks); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } if ( A->H.data != 0 && B->H.data != 0 && B->height == A->height+A->numblocks ) @@ -2608,7 +2544,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks) < 0 ) { printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } depth++; @@ -2625,7 +2561,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st { printf("merging isnt setup to save the blockROs\n"); printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%ld bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,time(NULL)-now,bp->bundleheight,nextbp->bundleheight); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); bp->mergefinish = 0; nextbp->mergefinish = (uint32_t)time(NULL); bp->nextbp = nextbp->nextbp; @@ -2638,9 +2574,9 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st else { bp->mergefinish = nextbp->mergefinish = 0; - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); } - iguana_ramchain_free(dest,0); + iguana_ramchain_free(coin,dest,0); depth--; } else printf("error merging A.%d [%d] and B.%d [%d]\n",A->height,A->numblocks,B->height,B->numblocks); coin->merging--; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 3daa5eb94..1dbd12517 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -274,7 +274,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; int32_t spendind,height,n,numtxid,errs=0,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; - FILE *fp; char fname[1024],str[65]; int32_t retval = -1; + FILE *fp; char fname[1024],str[65]; uint32_t now; int32_t retval = -1; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; @@ -292,6 +292,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) ptr = mycalloc('x',sizeof(*ptr),n); total += n; height = bp->bundleheight; + now = (uint32_t)time(NULL); //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); for (spendind=ramchain->H.data->firsti; spendindhdrsi,s)) != 0 ) { + if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) + { + //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + bp->lastprefetch = now; + } + spentbp->dirty++; if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) { ptr[emit].hdrsi = spentbp->hdrsi; @@ -369,7 +377,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) } if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); - printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d | ",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d\n",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); if ( errs != 0 ) exit(-1); return(-errs); @@ -455,14 +463,14 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > bp->lastprefetch+30 ) + if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); bp->lastprefetch = now; } spentbp->dirty++; - //if ( incremental == 0 ) + if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) { @@ -549,6 +557,243 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 return(-errs); } + +void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + ramchain->A = 0; + ramchain->Uextras = 0; + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } +} + +int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + int32_t iter,numhdrsi,err = -1; char fname[1024]; bits256 balancehash; + for (iter=0; iter<2; iter++) + { + sprintf(fname,"DB/%s%s/accounts/debits.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->A) * ramchain->H.data->numpkinds ) + { + ramchain->from_roA = (iter == 0); + numhdrsi = *(int32_t *)ramchain->debitsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( coin->balanceswritten == 0 ) + { + coin->balanceswritten = numhdrsi; + coin->balancehash = balancehash; + } + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->A = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + sprintf(fname,"DB/%s%s/accounts/lastspends.%d",iter==0?"ro/":"",coin->symbol,ramchain->H.data->height); + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + { + numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + if ( numhdrsi == coin->balanceswritten || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 ) + { + ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(bits256)); + ramchain->from_roU = (iter == 0); + err = 0; + } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } else printf("ramchain map error3 %s\n",fname); + } else printf("ramchain map error balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } + if ( err == 0 ) + { + //printf("mapped extra.%s\n",fname); + break; + } + iguana_purgevolatiles(coin,ramchain); + } + return(err); +} + +void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + if ( ramchain != 0 && ramchain->H.data != 0 ) + { + ramchain->A = calloc(sizeof(*ramchain->A),ramchain->H.data->numpkinds + 16); + ramchain->Uextras = calloc(sizeof(*ramchain->Uextras),ramchain->H.data->numunspents + 16); + if ( ramchain->debitsfileptr != 0 ) + { + memcpy(ramchain->A,(void *)((long)ramchain->debitsfileptr + sizeof(int32_t) + sizeof(bits256)),sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + memcpy(ramchain->Uextras,(void *)((long)ramchain->lastspendsfileptr + sizeof(int32_t) + sizeof(bits256)),sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } + } else printf("illegal ramchain.%p\n",ramchain); +} + +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) +{ + int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; + char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; + struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (hdrsi=0; hdrsibundlescount; hdrsi++) + if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) + break; + if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) + return(0); + numhdrsi = hdrsi; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (iter=0; iter<3; iter++) + { + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= 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 ( iter == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + else if ( iter == 1 ) + { + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + err = -1; + if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) ) + { + if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) + { + if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) + { + //bp->dirty = 0; + err = 0; + free(bp->ramchain.A), bp->ramchain.A = 0; + free(bp->ramchain.Uextras), bp->ramchain.Uextras = 0; + printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); + } + } + } + if ( err != 0 ) + { + printf("balanceflush.%s error iter.%d hdrsi.%d\n",coin->symbol,iter,hdrsi); + fclose(fp); + fclose(fp2); + return(-1); + } + fclose(fp), fclose(fp2); + } + else + { + printf("error opening %s or %s %p\n",fname,fname2,fp); + if ( fp != 0 ) + fclose(fp); + } + } + else if ( iter == 2 ) + { + sprintf(destfname,"DB/%s/accounts/debits.%d",coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname,destfname); + return(-1); + } + sprintf(destfname,"DB/%s/accounts/lastspends.%d",coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname2,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname2,destfname); + return(-1); + } + printf("%s %s\n",fname,destfname); + /*if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) + { + sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); + sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); + OS_removefile(destfname,0); + }*/ + } + } + else + { + printf("error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",hdrsi,Aptr,Uptr,numpkinds,numunspents); + return(-1); + } + } + } + coin->balancehash = balancehash; + coin->balanceswritten = numhdrsi; + for (hdrsi=0; hdrsibundles[hdrsi]) == 0 || iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) + 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)); + return(coin->balanceswritten); +} + +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental) +{ + uint32_t starttime,j,flag = 0; struct iguana_bundle *prevbp; + if ( bp->balancefinish > 1 ) + { + printf("make sure DB files have this bp.%d\n",bp->hdrsi); + iguana_validateQ(coin,bp); + return(flag); + } + if ( bp != 0 && coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) + { + for (j=0; jhdrsi; j++) + { + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish == 0 ) + break; + } + if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) + { + starttime = (uint32_t)time(NULL); + for (j=0; j<=bp->hdrsi; j++) + iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); + if ( iguana_balancegen(coin,bp,incremental) < 0 ) + { + printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); + exit(-1); + } + bp->balancefinish = (uint32_t)time(NULL); + printf("GENERATED BALANCES for ht.%d duration %d seconds\n",bp->bundleheight,bp->balancefinish - (uint32_t)starttime); + bp->queued = 0; + iguana_validateQ(coin,bp); + if ( bp->hdrsi >= coin->longestchain/coin->chain->bundlesize-1 && bp->hdrsi >= coin->balanceswritten ) + { + iguana_balanceflush(coin,bp->hdrsi,3); + printf("balanceswritten.%d flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + } + flag++; + } + else + { + //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); + coin->pendbalances--; + iguana_balancesQ(coin,bp); + } + } + return(flag); +} + int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp) { if ( bp->validated <= 1 ) diff --git a/iguana/main.c b/iguana/main.c index 4f16b75b8..5d4ca577f 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -341,104 +341,10 @@ mksquashfs DB/BTC BTC.squash1M -b 1048576 sudo mount BTC.xz DB/ro/BTC -t squashfs -o loop */ -int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) -{ - int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; - char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash; FILE *fp,*fp2; - struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; - vupdate_sha256(balancehash.bytes,&vstate,0,0); - for (hdrsi=0; hdrsibundlescount; hdrsi++) - if ( (bp= coin->bundles[hdrsi]) == 0 || bp->balancefinish <= 1 || bp->ramchain.H.data == 0 || bp->ramchain.A == 0 || bp->ramchain.Uextras == 0 ) - break; - if ( hdrsi <= coin->balanceswritten || hdrsi < refhdrsi ) - return(0); - numhdrsi = hdrsi; - vupdate_sha256(balancehash.bytes,&vstate,0,0); - for (iter=0; iter<3; iter++) - { - for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= 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 ( iter == 0 ) - { - vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); - vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); - } - else if ( iter == 1 ) - { - if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) - { - err = -1; - if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) ) - { - if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) - { - if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) - { - //bp->dirty = 0; - err = 0; - printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); - } - } - } - if ( err != 0 ) - { - printf("balanceflush.%s error iter.%d hdrsi.%d\n",coin->symbol,iter,hdrsi); - fclose(fp); - fclose(fp2); - return(-1); - } - fclose(fp), fclose(fp2); - } - else - { - printf("error opening %s or %s %p\n",fname,fname2,fp); - if ( fp != 0 ) - fclose(fp); - } - } - else if ( iter == 2 ) - { - sprintf(destfname,"DB/%s/accounts/debits.%d",coin->symbol,bp->bundleheight); - if ( OS_copyfile(fname,destfname,1) < 0 ) - { - printf("balances error copying (%s) -> (%s)\n",fname,destfname); - return(-1); - } - sprintf(destfname,"DB/%s/accounts/lastspends.%d",coin->symbol,bp->bundleheight); - if ( OS_copyfile(fname2,destfname,1) < 0 ) - { - printf("balances error copying (%s) -> (%s)\n",fname2,destfname); - return(-1); - } - printf("%s %s\n",fname,destfname); - /*if ( hdrsi > numhdrsi-purgedist && numhdrsi >= purgedist ) - { - sprintf(destfname,"DB/%s/accounts/debits_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); - OS_removefile(destfname,0); - sprintf(destfname,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,numhdrsi-purgedist,bp->bundleheight); - OS_removefile(destfname,0); - }*/ - } - } else printf("error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",hdrsi,Aptr,Uptr,numpkinds,numunspents); - } - } - coin->balancehash = balancehash; - coin->balanceswritten = numhdrsi; - char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash)); - return(coin->balanceswritten); -} void mainloop(struct supernet_info *myinfo) { - int32_t i,j,flag; char str[2048]; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp,*prevbp = 0; + int32_t i,flag; struct iguana_info *coin; struct iguana_helper *ptr; struct iguana_bundle *bp; sleep(3); printf("mainloop\n"); while ( 1 ) @@ -449,45 +355,10 @@ void mainloop(struct supernet_info *myinfo) for (i=0; iactive != 0 && (bp= coin->current) != 0 && coin->started != 0 ) { - iguana_bundlestats(coin,str); iguana_realtime_update(coin); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { - if ( (bp= ptr->bp) != 0 && ptr->coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) - { - for (j=0; jhdrsi; j++) - { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish == 0 ) - break; - } - if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) - { - if ( bp->ramchain.Uextras == 0 ) - { - printf("alloc Uextras.[%d]\n",bp->hdrsi); - bp->ramchain.Uextras = calloc(sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents + 16); - } - if ( bp->ramchain.A == 0 ) - { - printf("alloc A2.[%d]\n",bp->hdrsi); - bp->ramchain.A = calloc(sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds + 16); - } - iguana_balancecalc(ptr->coin,bp,0); - bp->queued = 0; - if ( bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) - { - flag++; - iguana_balanceflush(ptr->coin,bp->hdrsi,3); - printf("flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize); - } - } - else - { - //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); - coin->pendbalances--; - iguana_balancesQ(coin,bp); - } - } + iguana_balancecalc(ptr->coin,ptr->bp,0); myfree(ptr,ptr->allocsize); } } From d22e898b06a47d2ff84d3100380d4f2fc2bb2214 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:32:02 -0300 Subject: [PATCH 201/333] test --- iguana/iguana_unspents.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 1dbd12517..bf19768bd 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -274,7 +274,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; int32_t spendind,height,n,numtxid,errs=0,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; - FILE *fp; char fname[1024],str[65]; uint32_t now; int32_t retval = -1; + FILE *fp; char fname[1024],str[65]; uint32_t now=0; int32_t retval = -1; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; @@ -304,13 +304,15 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) numtxid++; } u = 0; + if ( (spendind & 0xff) == 1 ) + now = (uint32_t)time(NULL); if ( s->external != 0 && s->prevout >= 0 ) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) { - //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + printf("u current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); bp->lastprefetch = now; } @@ -387,12 +389,11 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { uint32_t unspentind,pkind,txidind; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; uint32_t numtxid,now,h,refheight; + struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; uint32_t numtxid,now=0,h,refheight; int32_t flag,hdrsi,spendind,n,errs=0,emit=0; struct iguana_utxo *utxo,*Uextras; ramchain = &bp->ramchain; Uextras = 0; A2 = 0; - //printf("BALANCEGEN.%d\n",bp->bundleheight); if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); @@ -404,6 +405,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); return(0); } + printf("BALANCEGEN.%d\n",bp->bundleheight); for (spendind=ramchain->H.data->firsti; spendind (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } else continue; - now = (uint32_t)time(NULL); + if ( (spendind & 0xff) == 1 ) + now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) { - //printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); bp->lastprefetch = now; } From 81052333d89e86f269587bff09c71b3daaad0efe Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:33:45 -0300 Subject: [PATCH 202/333] test --- iguana/iguana_unspents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index bf19768bd..fecf2506a 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -310,7 +310,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { printf("u current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -405,7 +405,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); return(0); } - printf("BALANCEGEN.%d\n",bp->bundleheight); + printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); for (spendind=ramchain->H.data->firsti; spendind 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 837c18404d84fba773dea2a1455c06cd7b592b55 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:35:06 -0300 Subject: [PATCH 203/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index fecf2506a..f746a117f 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -312,7 +312,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { - printf("u current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); bp->lastprefetch = now; } @@ -468,7 +468,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { - printf("current.%d prefetch.[%d]\n",spentbp == bp,spentbp->hdrsi); + printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); bp->lastprefetch = now; } From e69119809dd9b779e63ce860aac4282a8781811b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:36:19 -0300 Subject: [PATCH 204/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f746a117f..ca632672a 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -314,7 +314,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); - bp->lastprefetch = now; + spentbp->lastprefetch = now; } spentbp->dirty++; if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) @@ -470,7 +470,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); - bp->lastprefetch = now; + spentbp->lastprefetch = now; } spentbp->dirty++; if ( incremental == 0 ) From 22c5fc155b2f561c008bf498a7c4e026338a96f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:38:29 -0300 Subject: [PATCH 205/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ca632672a..14d6e08f4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -312,7 +312,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { - printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } @@ -468,7 +468,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) { - printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } From 373e148c07c1b7e38fe346fd85f5f194dd549af3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:45:30 -0300 Subject: [PATCH 206/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_unspents.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d651aa8f4..84d95cb84 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1058,7 +1058,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"%s u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d M.%d %s",coin->symbol,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); + sprintf(str,"%s u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,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+10 ) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 14d6e08f4..6fb58da78 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -310,7 +310,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -466,7 +466,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 3641bb04a776d26691c87348778c73ca7954b463 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:55:04 -0300 Subject: [PATCH 207/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_peers.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 84d95cb84..6c47b091e 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -766,7 +766,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-1 ) + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-coin->MAXBUNDLES ) return(0); for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index fc5cd7f64..71160308d 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1081,7 +1081,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 100) == 0 ) { - printf("isRT and low rank.%d ",addr->rank); + //printf("isRT and low rank.%d ",addr->rank); addr->dead = 1; } } From f6ae7cec196793c79110917a26d72e591072d600 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 20:57:14 -0300 Subject: [PATCH 208/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 6fb58da78..fa37aab50 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -310,7 +310,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -466,7 +466,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 14d995d1baeaab5ea2008c6aa1af99683a164ca5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:10:36 -0300 Subject: [PATCH 209/333] test --- iguana/iguana777.c | 10 +++++----- iguana/iguana_unspents.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index a7a3c0d4a..53868133f 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -533,19 +533,19 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; - mult = (strcmp("BTC",coin->symbol) != 0) ? 64 : 1; + mult = (strcmp("BTC",coin->symbol) != 0) ? 512 : 1; maxval = (strcmp("BTC",coin->symbol) != 0) ? 2048 : 64; if ( (coin->startPEND= juint(json,"startpend")) == 0 ) coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; - if ( coin->startPEND > 1024 ) - coin->startPEND = 1024; + if ( coin->startPEND > 2048 ) + coin->startPEND = 2048; else if ( coin->startPEND < 2 ) coin->startPEND = 2; coin->MAXBUNDLES = coin->startPEND; if ( (coin->endPEND= juint(json,"endpend")) == 0 ) coin->endPEND = IGUANA_MINPENDBUNDLES * mult; - if ( coin->endPEND > 1024 ) - coin->endPEND = 1024; + if ( coin->endPEND > 2048 ) + coin->endPEND = 2048; else if ( coin->endPEND < 2 ) coin->endPEND = 2; coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index fa37aab50..4e6f88ba2 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -16,13 +16,35 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" -int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdris,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) +int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) { - struct iguana_hhutxo *hhutxo; struct iguana_hhaccount *hhacct; - uint8_t buf[sizeof(spent_hdris) + sizeof(uint32_t)]; + struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; + uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; printf("unexpected utxoupdate\n"); exit(-1); - memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdris,sizeof(spent_hdris)); + if ( spent_hdrsi < 0 ) + { + if ( coin->utxotable != 0 ) + { + HASH_ITER(hh,coin->utxotable,hhutxo,tmputxo) + { + HASH_DEL(coin->utxotable,hhutxo); + free(hhutxo); + } + coin->utxotable = 0; + } + if ( coin->accountstable != 0 ) + { + HASH_ITER(hh,coin->accountstable,hhacct,tmpacct) + { + HASH_DEL(coin->accountstable,hhacct); + free(hhacct); + } + coin->accountstable = 0; + } + return(0); + } + memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); if ( hhutxo != 0 && hhutxo->u.spentflag != 0 ) @@ -310,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+600 || (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -466,7 +488,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+600 || (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -743,6 +765,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } coin->balancehash = balancehash; coin->balanceswritten = numhdrsi; + iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables for (hdrsi=0; hdrsibundles[hdrsi]) == 0 || iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) printf("error mapping bundle.[%d]\n",hdrsi); From 5095b3bb99b67ff743f36290ad1c6cc0b8d23e78 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:20:57 -0300 Subject: [PATCH 210/333] test --- iguana/iguana_unspents.c | 9 ++++++++- iguana/main.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 4e6f88ba2..60feffcfb 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -767,8 +767,15 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu coin->balanceswritten = numhdrsi; iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables for (hdrsi=0; hdrsibundles[hdrsi]) == 0 || iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) + if ( (bp= coin->bundles[hdrsi]) == 0 ) + { + if ( bp->ramchain.A != 0 ) + free(bp->ramchain.A); + if ( bp->ramchain.Uextras != 0 ) + free(bp->ramchain.Uextras); + if ( iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) 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)); return(coin->balanceswritten); } diff --git a/iguana/main.c b/iguana/main.c index 5d4ca577f..26840841d 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1127,7 +1127,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":64,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":3333,\"endpend\":3333,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From 7112e3dc69ffa5073b0738fb8b36ba8f5e7a9df7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:21:28 -0300 Subject: [PATCH 211/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 60feffcfb..c81fac535 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -332,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+600 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -488,7 +488,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+600 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 592fbc7d2ecca7df4c8623cd412c4856f3e5cb11 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:27:18 -0300 Subject: [PATCH 212/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_unspents.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 9b1c792f0..7fb4afd16 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -373,7 +373,7 @@ struct iguana_ramchain_hdr struct iguana_ramchain { - struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; + struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize,allocatedA,allocatedU; uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; struct iguana_kvitem *txids,*pkhashes; struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c81fac535..32457c7e4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -648,8 +648,16 @@ void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramch { if ( ramchain != 0 && ramchain->H.data != 0 ) { - ramchain->A = calloc(sizeof(*ramchain->A),ramchain->H.data->numpkinds + 16); - ramchain->Uextras = calloc(sizeof(*ramchain->Uextras),ramchain->H.data->numunspents + 16); + if ( ramchain->allocatedA == 0 ) + { + ramchain->A = calloc(sizeof(*ramchain->A),ramchain->H.data->numpkinds + 16); + ramchain->allocatedA = sizeof(*ramchain->A) * ramchain->H.data->numpkinds; + } + if ( ramchain->allocatedU == 0 ) + { + ramchain->Uextras = calloc(sizeof(*ramchain->Uextras),ramchain->H.data->numunspents + 16); + ramchain->allocatedU = sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents; + } if ( ramchain->debitsfileptr != 0 ) { memcpy(ramchain->A,(void *)((long)ramchain->debitsfileptr + sizeof(int32_t) + sizeof(bits256)),sizeof(*ramchain->A) * ramchain->H.data->numpkinds); @@ -770,9 +778,17 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu if ( (bp= coin->bundles[hdrsi]) == 0 ) { if ( bp->ramchain.A != 0 ) + { free(bp->ramchain.A); + bp->ramchain.A = 0; + bp->ramchain.allocatedA = 0; + } if ( bp->ramchain.Uextras != 0 ) + { free(bp->ramchain.Uextras); + bp->ramchain.Uextras = 0; + bp->ramchain.allocatedU = 0; + } if ( iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) printf("error mapping bundle.[%d]\n",hdrsi); } From 6865fed5d8c06a7d6a3f814a69ed92dbcf052e24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:33:52 -0300 Subject: [PATCH 213/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 32457c7e4..d79811229 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -332,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 10000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -488,7 +488,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 10000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From 8b4cfa044a8bcd20a1fa043cd2926488a9ff5f05 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:37:23 -0300 Subject: [PATCH 214/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d79811229..e6dd6da3e 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -332,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 10000) == 0 ) + if ( now > spentbp->lastprefetch+13 || (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -488,7 +488,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+3 )//|| (spentbp->dirty % 10000) == 0 ) + if ( now > spentbp->lastprefetch+13 || (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From c6d8225634fc8dc40acf2dfaa7528dc6f9d4ba7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:38:07 -0300 Subject: [PATCH 215/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index e6dd6da3e..32457c7e4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -332,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+13 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -488,7 +488,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+13 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From daa545d19b104765d8644c095a036a6fb31235c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 21:58:18 -0300 Subject: [PATCH 216/333] test --- iguana/iguana_unspents.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 32457c7e4..08416627b 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -495,7 +495,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 spentbp->lastprefetch = now; } spentbp->dirty++; - if ( incremental == 0 ) + /*if ( incremental == 0 ) { if ( spentbp->ramchain.Uextras == 0 ) { @@ -507,7 +507,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("unspent alloc A2.[%d]\n",spentbp->hdrsi); spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); } - } + }*/ Uextras = spentbp->ramchain.Uextras; A2 = spentbp->ramchain.A; if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) @@ -718,8 +718,8 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu { //bp->dirty = 0; err = 0; - free(bp->ramchain.A), bp->ramchain.A = 0; - free(bp->ramchain.Uextras), bp->ramchain.Uextras = 0; + //free(bp->ramchain.A), bp->ramchain.A = 0; + //free(bp->ramchain.Uextras), bp->ramchain.Uextras = 0; printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); } } @@ -766,7 +766,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } else { - printf("error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",hdrsi,Aptr,Uptr,numpkinds,numunspents); + printf("balanceflush iter.%d error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",iter,hdrsi,Aptr,Uptr,numpkinds,numunspents); return(-1); } } From 321745041c35d98dc31422fc2e586a2539d5b34b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 22:08:44 -0300 Subject: [PATCH 217/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_recv.c | 4 +++- iguana/iguana_unspents.c | 21 ++++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 7fb4afd16..9004491d2 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -787,7 +787,7 @@ int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint3 void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp); -int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental); +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); struct iguana_bloominds iguana_calcbloom(bits256 hash2); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index bb1f1740e..49389096c 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -976,6 +976,8 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) threshold = 1000; else threshold = 300; + if ( strcmp(coin->symbol,"BTC") != 0 ) + threshold *= 10; if ( coin->blocks.hwmchain.height < coin->longestchain && ((strcmp(coin->symbol,"BTC") != 0 && coin->backstop != coin->blocks.hwmchain.height+1) || lag > threshold) ) { coin->backstop = coin->blocks.hwmchain.height+1; @@ -1005,7 +1007,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) iguana_blockQ("mainchain",coin,0,-1,hash2,lag > 100 * threshold); flag++; char str[65]; - if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + if ( 1 && (rand() % 1000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) printf("%s %s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",coin->symbol,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 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 08416627b..b72d8a5bc 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -332,7 +332,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -407,15 +407,18 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) return(-errs); } -int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental) +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,pkind,txidind; struct iguana_account *A2; + uint32_t unspentind,pkind,txidind,numtxid,now=0,h,refheight; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; uint32_t numtxid,now=0,h,refheight; - int32_t flag,hdrsi,spendind,n,errs=0,emit=0; struct iguana_utxo *utxo,*Uextras; + struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; + int32_t flag,hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_utxo *utxo,*Uextras; ramchain = &bp->ramchain; Uextras = 0; A2 = 0; + if ( startheight == bp->bundleheight && endheight == bp->bundleheight+bp->n-1 ) + incremental = 0; + else incremental = 1; if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); @@ -436,6 +439,10 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); numtxid++; } + if ( refheight < startheight ) + continue; + if ( refheight > endheight ) + break; s = &S[spendind]; u = 0; unspentind = 0; @@ -488,7 +495,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+30 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) { //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -817,7 +824,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int starttime = (uint32_t)time(NULL); for (j=0; j<=bp->hdrsi; j++) iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); - if ( iguana_balancegen(coin,bp,incremental) < 0 ) + if ( iguana_balancegen(coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1) < 0 ) { printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); exit(-1); From 435e99085a295c34bd50260e473f6f784d97b8d8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 22:12:40 -0300 Subject: [PATCH 218/333] test --- iguana/iguana_bundles.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 6c47b091e..0bd6e087d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -290,7 +290,10 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund if ( iguana_bundlefind(coin,&bp,bundleip,bundlehash2) != 0 ) { if ( bp->bundleheight >= 0 && bp->bundleheight != (bundleheight - *bundleip) ) + { printf("bundlecreate warning: bp->bundleheight %d != %d (bundleheight %d - %d bundlei)\n",bp->bundleheight,(bundleheight - *bundleip),bundleheight,*bundleip); + return(0); + } else if ( bits256_nonz(bp->allhash) == 0 ) bp->allhash = allhash; return(bp); From 0bd458b88f012cefd781f288e181d257b4d748ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 23:00:31 -0300 Subject: [PATCH 219/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_unspents.c | 14 ++++++++++---- iguana/main.c | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 9004491d2..3057c64bb 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -797,7 +797,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist); int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); -int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental); +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index b72d8a5bc..6a0066e9d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -20,8 +20,6 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t { struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; - printf("unexpected utxoupdate\n"); - exit(-1); if ( spent_hdrsi < 0 ) { if ( coin->utxotable != 0 ) @@ -44,6 +42,8 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t } return(0); } + printf("unexpected utxoupdate\n"); + exit(-1); memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); @@ -440,9 +440,15 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 numtxid++; } if ( refheight < startheight ) + { + printf("balancegen: refheight.%d < startheight.%d\n",refheight,startheight); continue; + } if ( refheight > endheight ) + { + printf("balancegen: refheight.%d > endheight.%d\n",refheight,endheight); break; + } s = &S[spendind]; u = 0; unspentind = 0; @@ -803,7 +809,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu return(coin->balanceswritten); } -int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t incremental) +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { uint32_t starttime,j,flag = 0; struct iguana_bundle *prevbp; if ( bp->balancefinish > 1 ) @@ -824,7 +830,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int starttime = (uint32_t)time(NULL); for (j=0; j<=bp->hdrsi; j++) iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); - if ( iguana_balancegen(coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1) < 0 ) + if ( iguana_balancegen(coin,bp,startheight,endheight) < 0 ) { printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); exit(-1); diff --git a/iguana/main.c b/iguana/main.c index 26840841d..1c095dd44 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -358,7 +358,8 @@ void mainloop(struct supernet_info *myinfo) iguana_realtime_update(coin); if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) { - iguana_balancecalc(ptr->coin,ptr->bp,0); + if ( ptr->coin != 0 && (bp= ptr->bp) != 0 ) + iguana_balancecalc(ptr->coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); myfree(ptr,ptr->allocsize); } } From 4abe904d4a425c35c587d638017aa2df553310f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 23:02:38 -0300 Subject: [PATCH 220/333] test --- iguana/iguana_unspents.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 6a0066e9d..435483025 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -433,12 +433,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; - } if ( refheight < startheight ) { printf("balancegen: refheight.%d < startheight.%d\n",refheight,startheight); @@ -496,7 +490,16 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } - else continue; + else + { + if ( spendind == nextT[numtxid].firstvin ) + { + refheight = bp->bundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } + continue; + } if ( (spendind & 0xff) == 1 ) now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) @@ -580,6 +583,12 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 errs++; printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); } + if ( spendind == nextT[numtxid].firstvin ) + { + refheight = bp->bundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } } if ( numtxid != bp->ramchain.H.data->numtxids ) { From 3c69a79940969e3d3ec760fdafe5ee785e0a8b10 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 23:04:40 -0300 Subject: [PATCH 221/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 435483025..f5cb92e08 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -495,7 +495,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 if ( spendind == nextT[numtxid].firstvin ) { refheight = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); numtxid++; } continue; @@ -586,7 +586,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 if ( spendind == nextT[numtxid].firstvin ) { refheight = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); numtxid++; } } From dcdc33ecda8bf9b8c4cfc5c499bb00374f235529 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 23:06:48 -0300 Subject: [PATCH 222/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f5cb92e08..58d874432 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -494,7 +494,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { if ( spendind == nextT[numtxid].firstvin ) { - refheight = bp->bundleheight + numtxid; + refheight = bp->bundleheight++; printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); numtxid++; } @@ -585,7 +585,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } if ( spendind == nextT[numtxid].firstvin ) { - refheight = bp->bundleheight + numtxid; + refheight = bp->bundleheight++; printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); numtxid++; } From 9fb3789bd33ca6e9996e38b6884dd49ff94ac980 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 23 Mar 2016 23:08:50 -0300 Subject: [PATCH 223/333] test --- iguana/iguana_unspents.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 58d874432..ef6926bb7 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -319,12 +319,6 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; - } u = 0; if ( (spendind & 0xff) == 1 ) now = (uint32_t)time(NULL); @@ -365,6 +359,12 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) break; } } + if ( spendind == nextT[numtxid].firstvin ) + { + height = bp->bundleheight++; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } } if ( numtxid != bp->ramchain.H.data->numtxids ) { From 036658e97feac67e9461fe950319a5ebe845d91f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 04:54:01 -0300 Subject: [PATCH 224/333] test --- iguana/iguana_unspents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ef6926bb7..48a65ea75 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -315,6 +315,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) total += n; height = bp->bundleheight; now = (uint32_t)time(NULL); + // iterate by height! //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); for (spendind=ramchain->H.data->firsti; spendind endheight ) + if ( 0 && refheight > endheight ) { printf("balancegen: refheight.%d > endheight.%d\n",refheight,endheight); break; From 59aa3d5e0bbaa4dd39d175b99e30d5e375680437 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 04:55:56 -0300 Subject: [PATCH 225/333] test --- iguana/iguana_unspents.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 48a65ea75..7f23d019c 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -315,11 +315,16 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) total += n; height = bp->bundleheight; now = (uint32_t)time(NULL); - // iterate by height! //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } u = 0; if ( (spendind & 0xff) == 1 ) now = (uint32_t)time(NULL); @@ -360,12 +365,6 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) break; } } - if ( spendind == nextT[numtxid].firstvin ) - { - height = bp->bundleheight++; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; - } } if ( numtxid != bp->ramchain.H.data->numtxids ) { @@ -434,6 +433,12 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } if ( refheight < startheight ) { printf("balancegen: refheight.%d < startheight.%d\n",refheight,startheight); @@ -441,7 +446,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } if ( 0 && refheight > endheight ) { - printf("balancegen: refheight.%d > endheight.%d\n",refheight,endheight); + printf("balancegen: refheight.%d < startheight.%d\n",refheight,startheight); break; } s = &S[spendind]; @@ -491,16 +496,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } - else - { - if ( spendind == nextT[numtxid].firstvin ) - { - refheight = bp->bundleheight++; - printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); - numtxid++; - } - continue; - } + else continue; if ( (spendind & 0xff) == 1 ) now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) @@ -584,12 +580,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 errs++; printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); } - if ( spendind == nextT[numtxid].firstvin ) - { - refheight = bp->bundleheight++; - printf("height.%d firstvin.%d\n",refheight,nextT[numtxid].firstvin); - numtxid++; - } } if ( numtxid != bp->ramchain.H.data->numtxids ) { From bcf2f2f013ae5053220a44291457d69e8c48bbfd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 05:25:36 -0300 Subject: [PATCH 226/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 0bd6e087d..a7c59f975 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -769,7 +769,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-coin->MAXBUNDLES ) + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 49389096c..afa166a53 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -787,9 +787,8 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } if ( bits256_nonz(prev->RO.prev_block) != 0 ) { - if ( (prev= iguana_blockfind(coin,prev->RO.prev_block)) == 0 ) - prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1); - prev->newtx = 1; + if ( (prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1)) != 0 ) + prev->newtx = 1; } else prev = 0; } } From bc9862fbb1c7568355ba4bf4c4fafca8f5459d27 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 06:46:50 -0300 Subject: [PATCH 227/333] test --- deprecated/obsolete.h | 70 ++++++++ iguana/iguana777.h | 7 +- iguana/iguana_bundles.c | 2 + iguana/iguana_unspents.c | 353 ++++++++++++++++++++------------------- 4 files changed, 257 insertions(+), 175 deletions(-) diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 3aca5b870..4aaef9172 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14412,5 +14412,75 @@ len = 0; //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); + + int32_t iguana_spendfind(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t spendind,int32_t emit) + { + struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; + struct iguana_bundle *spentbp; struct iguana_txid *T; + ramchain = &bp->ramchain; + if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 || ramchain->Xspendinds == 0 ) + return(-1); + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + s = &S[spendind]; + u = 0; + unspentind = 0; + hdrsi = -1; + spentbp = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( emit >= ramchain->numXspends ) + errs++; + else + { + h = ramchain->Xspendinds[emit].height; + unspentind = ramchain->Xspendinds[emit].ind; + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + spentbp = coin->bundles[hdrsi]; + else + { + printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); + return(-1); + } + //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + emit++; + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + hdrsi = bp->hdrsi; + h = refheight; + if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[txidind].firstvout + s->prevout; + if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + { + printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); + return(-1); + } + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + return(-1); + } + //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); + } + else return(0); + if ( (spendind & 0xff) == 1 ) + now = (uint32_t)time(NULL); + if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + { + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } + } + + } #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 3057c64bb..53ef31c92 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,8 +23,9 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 - +//#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS + #define IGUANA_MAXCOINS 64 #define IGUANA_MAXDELAY_MILLIS (3600 * 1000) @@ -338,12 +339,12 @@ struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((pack // dynamic struct iguana_account { int64_t total; uint32_t lastind; } __attribute__((packed)); -struct iguana_utxo { uint32_t prevunspentind,height:31,spentflag:1; } __attribute__((packed)); +struct iguana_utxo { uint64_t prevunspentind:26,height:24,spentflag:1,tbd:13; } __attribute__((packed)); struct iguana_hhaccount { UT_hash_handle hh; uint8_t buf[6]; struct iguana_account a; } __attribute__((packed)); struct iguana_hhutxo { UT_hash_handle hh; uint8_t buf[6]; struct iguana_utxo u; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_spendvector { uint32_t ind,height; uint16_t hdrsi; } __attribute__((packed)); // unspentind +struct iguana_spendvector { uint64_t hdrsi:14,ind:26,height:24; } __attribute__((packed)); // unspentind //struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind struct iguana_txblock diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a7c59f975..b146645d2 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -769,8 +769,10 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; +#ifdef IGUANA_SERIALIZE_BALANCEGEN if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); +#endif for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 7f23d019c..2cf8b0ef8 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -295,17 +295,18 @@ uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; - int32_t spendind,height,n,numtxid,errs=0,emit=0; uint32_t unspentind; struct iguana_bundle *spentbp; - FILE *fp; char fname[1024],str[65]; uint32_t now=0; int32_t retval = -1; + int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; uint32_t unspentind; + struct iguana_bundle *spentbp; struct iguana_blockRO *B; + FILE *fp; char fname[1024],str[65]; uint32_t now=0; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; //printf("UTXO gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); + B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - numtxid = 1; if ( ramchain->Xspendinds != 0 ) { //printf("iguana_utxogen: already have Xspendinds[%d]\n",ramchain->numXspends); @@ -313,62 +314,79 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) } ptr = mycalloc('x',sizeof(*ptr),n); total += n; - height = bp->bundleheight; now = (uint32_t)time(NULL); //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); - for (spendind=ramchain->H.data->firsti; spendindH.data->firsti; + for (i=0; in; i++) { - s = &S[spendind]; - if ( spendind == nextT[numtxid].firstvin ) + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { - height = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; + printf("utxogen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i); + myfree(ptr,sizeof(*ptr) * n); + return(-1); } - u = 0; - if ( (spendind & 0xff) == 1 ) - now = (uint32_t)time(NULL); - if ( s->external != 0 && s->prevout >= 0 ) + for (j=0; jhdrsi,s)) != 0 ) + now = (uint32_t)time(NULL); + if ( txidind != nextT[txidind].txidind || spendind != nextT[txidind].firstvin ) { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) - { - //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; - } - spentbp->dirty++; - if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) - { - ptr[emit].hdrsi = spentbp->hdrsi; - ptr[emit].height = height; - //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); - emit++; - } - else - { - printf("utxogen: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); - errs++; - } - if ( spentbp == bp ) - { - char str[65]; - printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); - errs++; - } + printf("utxogen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin\n",txidind,nextT[txidind].txidind,spendind,nextT[txidind].firstvin); + myfree(ptr,sizeof(*ptr) * n); + return(-1); } - else + for (k=0; khdrsi); - break; + s = &S[spendind]; + u = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) + { + /*if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } + spentbp->dirty++;*/ + if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + { + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].height = bp->bundleheight + i; + //ptr[emit].txi = j; + //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); + emit++; + } + else + { + printf("utxogen: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); + errs++; + } + if ( spentbp == bp ) + { + char str[65]; + printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + errs++; + } + } + else + { + errs++; + printf("utxogen: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; + } + } } } } - if ( numtxid != bp->ramchain.H.data->numtxids ) + if ( txidind != bp->ramchain.H.data->numtxids ) + { + printf("numtxid.%d != bp numtxids %d\n",txidind,bp->ramchain.H.data->numtxids); + errs++; + } + if ( spendind != bp->ramchain.H.data->numspends ) { - printf("numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); + printf("spendind.%d != bp numspends %d\n",spendind,bp->ramchain.H.data->numspends); errs++; } if ( errs == 0 && emit >= 0 ) @@ -409,9 +427,9 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,pkind,txidind,numtxid,now=0,h,refheight; struct iguana_account *A2; + uint32_t unspentind,pkind,txidind,numtxid,now=0,h,i,j,k,refheight; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; + struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; struct iguana_blockRO *B; int32_t flag,hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_utxo *utxo,*Uextras; ramchain = &bp->ramchain; Uextras = 0; @@ -422,6 +440,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); numtxid = 1; refheight = bp->bundleheight; @@ -430,160 +449,150 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); return(0); } + iguana_ramchain_prefetch(coin,&bp->ramchain); printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); - for (spendind=ramchain->H.data->firsti; spendindH.data->firsti; + for (i=0; in; i++) { - if ( spendind == nextT[numtxid].firstvin ) + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { - refheight = bp->bundleheight + numtxid; - //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); - numtxid++; + printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i); + return(-1); } - if ( refheight < startheight ) + for (j=0; j endheight ) - { - printf("balancegen: refheight.%d < startheight.%d\n",refheight,startheight); - break; - } - s = &S[spendind]; - u = 0; - unspentind = 0; - hdrsi = -1; - spentbp = 0; - if ( s->external != 0 && s->prevout >= 0 ) - { - if ( emit >= ramchain->numXspends ) - errs++; - else - { - h = ramchain->Xspendinds[emit].height; - unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) - spentbp = coin->bundles[hdrsi]; - else - { - printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); - errs++; - } - //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); - emit++; - } - } - else if ( s->prevout >= 0 ) - { - spentbp = bp; - hdrsi = bp->hdrsi; - h = refheight; - if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) - { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[txidind].firstvout + s->prevout; - if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) - { - printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); - errs++; - } - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); - errs++; - } - //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); - } - else continue; - if ( (spendind & 0xff) == 1 ) now = (uint32_t)time(NULL); - if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) - { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + if ( txidind != nextT[txidind].txidind || spendind != nextT[txidind].firstvin ) { - //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; + printf("balancegen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin\n",txidind,nextT[txidind].txidind,spendind,nextT[txidind].firstvin); + return(-1); } - spentbp->dirty++; - /*if ( incremental == 0 ) + for (k=0; kramchain.Uextras == 0 ) + s = &S[spendind]; + u = 0; + unspentind = 0; + hdrsi = -1; + spentbp = 0; + if ( s->external != 0 && s->prevout >= 0 ) { - printf("unspent alloc Uextras.[%d]\n",spentbp->hdrsi); - spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); + if ( emit >= ramchain->numXspends ) + errs++; + else + { + h = ramchain->Xspendinds[emit].height; + unspentind = ramchain->Xspendinds[emit].ind; + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + spentbp = coin->bundles[hdrsi]; + else + { + printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); + errs++; + } + //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + emit++; + } } - if ( spentbp->ramchain.A == 0 ) + else if ( s->prevout >= 0 ) { - printf("unspent alloc A2.[%d]\n",spentbp->hdrsi); - spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); + spentbp = bp; + hdrsi = bp->hdrsi; + h = refheight; + if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[txidind].firstvout + s->prevout; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + errs++; + } + //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } - }*/ - Uextras = spentbp->ramchain.Uextras; - A2 = spentbp->ramchain.A; - if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) - { - spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); - u = &spentU[unspentind]; - if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) + else continue; + //if ( (spendind & 0xff) == 1 ) + // now = (uint32_t)time(NULL); + if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - flag = -1; - if ( incremental == 0 ) + /*if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + }*/ + spentbp->dirty++; + Uextras = spentbp->ramchain.Uextras; + A2 = spentbp->ramchain.A; + if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) { - if ( Uextras == 0 || A2 == 0 ) - { - printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); - errs++; - } - else + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[unspentind]; + if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) + flag = -1; + if ( incremental == 0 ) + { + if ( Uextras == 0 || A2 == 0 ) + { + printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); + errs++; + } + else + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevunspentind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = h; + A2[pkind].total += u->value; + A2[pkind].lastind = unspentind;//spendind; + flag = 0; + } + } + } + else { - utxo->prevunspentind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = h; - A2[pkind].total += u->value; - A2[pkind].lastind = unspentind;//spendind; - flag = 0; + if ( bp != spentbp ) + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); + } + else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); + } + if ( flag != 0 ) + { + errs++; + printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); + getchar(); } } - } - else - { - if ( bp != spentbp ) + else { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); + errs++; + printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); } - else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); - } - if ( flag != 0 ) - { - errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); - getchar(); } } else { errs++; - printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); + printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); } } } - else - { - errs++; - printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); - } } - if ( numtxid != bp->ramchain.H.data->numtxids ) + if ( txidind != bp->ramchain.H.data->numtxids ) + { + printf("numtxid.%d != bp numtxids %d\n",txidind,bp->ramchain.H.data->numtxids); + errs++; + } + if ( spendind != bp->ramchain.H.data->numspends ) { - printf("iguana_balancegen: numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); + printf("spendind.%d != bp numspends %d\n",spendind,bp->ramchain.H.data->numspends); errs++; } if ( emit != ramchain->numXspends ) @@ -822,7 +831,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int { for (j=0; jhdrsi; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish == 0 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) break; } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) From 1fbadaaa7f8037ea83319e66ffb22b36af2a4520 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 06:55:28 -0300 Subject: [PATCH 228/333] test --- iguana/iguana_unspents.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 2cf8b0ef8..d26c860ff 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -297,7 +297,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) static uint64_t total,emitted; int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; uint32_t unspentind; struct iguana_bundle *spentbp; struct iguana_blockRO *B; - FILE *fp; char fname[1024],str[65]; uint32_t now=0; + FILE *fp; char fname[1024],str[65]; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; @@ -314,7 +314,6 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) } ptr = mycalloc('x',sizeof(*ptr),n); total += n; - now = (uint32_t)time(NULL); //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); txidind = spendind = ramchain->H.data->firsti; for (i=0; in; i++) @@ -327,7 +326,6 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) } for (j=0; jH.data + ramchain->H.data->Soffset); B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - numtxid = 1; refheight = bp->bundleheight; if ( ramchain->Xspendinds == 0 ) { @@ -454,19 +451,20 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 txidind = spendind = ramchain->H.data->firsti; for (i=0; in; i++) { + printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { - printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i); + printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); return(-1); } for (j=0; j Date: Thu, 24 Mar 2016 06:59:01 -0300 Subject: [PATCH 229/333] test --- iguana/iguana_unspents.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d26c860ff..4770d60d5 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -425,7 +425,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,pkind,txidind,h,i,j,k,refheight; struct iguana_account *A2; + uint32_t unspentind,pkind,txidind,h,i,j,k,ind; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; struct iguana_blockRO *B; int32_t flag,hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_utxo *utxo,*Uextras; @@ -440,7 +440,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - refheight = bp->bundleheight; if ( ramchain->Xspendinds == 0 ) { printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); @@ -495,16 +494,16 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { spentbp = bp; hdrsi = bp->hdrsi; - h = refheight; - if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + h = bp->bundleheight + i; + if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) { T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[txidind].firstvout + s->prevout; + unspentind = T[ind].firstvout + s->prevout; //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); } else { - printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + printf("iguana_balancegen txidind overflow %u vs %u\n",ind,spentbp->ramchain.H.data->numtxids); errs++; } //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); From e49c55d14d6caea70f8a6608bf74382ef75844a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 07:00:34 -0300 Subject: [PATCH 230/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 4770d60d5..3705ceb3c 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -450,7 +450,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 txidind = spendind = ramchain->H.data->firsti; for (i=0; in; i++) { - printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); + //printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); @@ -463,7 +463,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("balancegen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin errs.%d\n",txidind,nextT[txidind].txidind,spendind,nextT[txidind].firstvin,errs); return(-1); } - printf("txidind.%d txi.%d numvins.%d spendind.%d\n",txidind,j,nextT[txidind].numvins,spendind); + //printf("txidind.%d txi.%d numvins.%d spendind.%d\n",txidind,j,nextT[txidind].numvins,spendind); for (k=0; k Date: Thu, 24 Mar 2016 07:56:19 -0300 Subject: [PATCH 231/333] test --- iguana/iguana777.c | 18 ++++--- iguana/iguana777.h | 3 +- iguana/iguana_bundles.c | 11 ++-- iguana/iguana_init.c | 106 +-------------------------------------- iguana/iguana_unspents.c | 101 ++++++++++++++++++++++++++++++++++++- 5 files changed, 120 insertions(+), 119 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 53868133f..2895fdc90 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -535,26 +535,28 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->mapflags = mapflags; mult = (strcmp("BTC",coin->symbol) != 0) ? 512 : 1; maxval = (strcmp("BTC",coin->symbol) != 0) ? 2048 : 64; + coin->MAXMEM = juint(json,"RAM"); + if ( coin->MAXMEM == 0 ) + coin->MAXMEM = IGUANA_DEFAULTRAM; + if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM <= 4 ) + maxval = coin->MAXMEM; + coin->MAXMEM *= (1024L * 1024 * 1024); if ( (coin->startPEND= juint(json,"startpend")) == 0 ) coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; - if ( coin->startPEND > 2048 ) - coin->startPEND = 2048; + if ( coin->startPEND > maxval ) + coin->startPEND = maxval; else if ( coin->startPEND < 2 ) coin->startPEND = 2; coin->MAXBUNDLES = coin->startPEND; if ( (coin->endPEND= juint(json,"endpend")) == 0 ) coin->endPEND = IGUANA_MINPENDBUNDLES * mult; - if ( coin->endPEND > 2048 ) - coin->endPEND = 2048; + if ( coin->endPEND > maxval ) + coin->endPEND = maxval; else if ( coin->endPEND < 2 ) coin->endPEND = 2; coin->enableCACHE = (strcmp("BTC",coin->symbol) != 0); if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); - coin->MAXMEM = juint(json,"RAM"); - if ( coin->MAXMEM == 0 ) - coin->MAXMEM = IGUANA_DEFAULTRAM; - coin->MAXMEM *= (1024 * 1024 * 1024); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) coin->polltimeout = 10; char str[65]; printf("MAXMEM.%s enablecache.%d\n",mbstr(str,coin->MAXMEM),coin->enableCACHE); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 53ef31c92..6f141c9e9 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -458,7 +458,7 @@ 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; bits256 balancehash; + 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 longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; struct tai starttime; double startmillis; struct iguana_chain *chain; @@ -806,6 +806,7 @@ void iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *r void iguana_realtime_update(struct iguana_info *coin); int32_t iguana_mapvolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_volatileinit(struct iguana_info *coin); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b146645d2..9d33b8ead 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -557,7 +557,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[i]) != 0 ) { - if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || (bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) > 0 ) + if ( block->fpipbits == 0 || block->RO.recvlen == 0 || block->fpos < 0 || ((bp->hdrsi != 0 || i > 0) && bits256_nonz(block->RO.prev_block) == 0) ) { if ( block->issued == 0 || now > block->issued+lag ) { @@ -769,10 +769,11 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -#ifdef IGUANA_SERIALIZE_BALANCEGEN - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) - return(0); -#endif + if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) + { + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) + return(0); + } for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 95b9e5fb9..5426e17a7 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -184,37 +184,9 @@ int32_t iguana_savehdrs(struct iguana_info *coin) return(retval); } -void iguana_truncatebalances(struct iguana_info *coin) -{ - int32_t i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; - for (i=0; ibalanceswritten; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - bp->balancefinish = 0; - ramchain = &bp->ramchain; - if ( ramchain->debitsfileptr != 0 ) - { - munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); - ramchain->debitsfileptr = 0; - ramchain->debitsfilesize = 0; - ramchain->A = 0; - } - if ( ramchain->lastspendsfileptr != 0 ) - { - munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); - ramchain->lastspendsfileptr = 0; - ramchain->lastspendsfilesize = 0; - ramchain->Uextras = 0; - } - } - } - coin->balanceswritten = 0; -} - void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { - int32_t i,j,k,m,c,height,flag,bundlei,from_ro; char checkstr[1024],line[1024]; + int32_t i,j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,zero,lastbundle; struct iguana_block *block; memset(&zero,0,sizeof(zero)); @@ -329,81 +301,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( iter == 1 ) { if ( coin->balanceswritten > 0 ) - { - from_ro = 1; - for (i=0; ibalanceswritten; i++) - { - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) - { - printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); - break; - } - if ( bp->ramchain.from_ro == 0 || bp->ramchain.from_roX == 0 || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0 ) - from_ro = 0; - } - if ( i != coin->balanceswritten ) - { - printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); - iguana_truncatebalances(coin); - } - else - { - bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate; int32_t numpkinds,numunspents; uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65]; - vupdate_sha256(balancehash.bytes,&vstate,0,0); - filecrc = 0; - sprintf(crcfname,"DB/%s/balancecrc.%d",coin->symbol,coin->balanceswritten); - if ( (fp= fopen(crcfname,"rb")) != 0 ) - { - if ( fread(&filecrc,1,sizeof(filecrc),fp) != sizeof(filecrc) ) - filecrc = 0; - else if ( fread(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) - filecrc = 0; - else if ( memcmp(&balancehash,&coin->balancehash,sizeof(balancehash)) != 0 ) - filecrc = 0; - fclose(fp); - } - if ( filecrc != 0 ) - printf("have filecrc.%08x for %s milli.%.0f\n",filecrc,bits256_str(str,balancehash),OS_milliseconds()); - if ( from_ro == 0 ) - { - if ( filecrc == 0 ) - vupdate_sha256(balancehash.bytes,&vstate,0,0); - for (i=crc=0; ibalanceswritten; i++) - { - numpkinds = numunspents = 0; - Aptr = 0, Uptr = 0; - if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) - { - if ( filecrc == 0 ) - { - vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); - vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); - } - crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); - crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); - } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); - } - } else crc = filecrc; - printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); - if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) - { - printf("balancehash or crc mismatch\n"); - iguana_truncatebalances(coin); - } - else - { - printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); - if ( (fp= fopen(crcfname,"wb")) != 0 ) - { - if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) - printf("error writing.(%s)\n",crcfname); - fclose(fp); - } - } - } - } - char buf[2048]; - iguana_bundlestats(coin,buf); + coin->balanceswritten = iguana_volatileinit(coin); if ( coin->balanceswritten > 0 ) { for (i=0; ibalanceswritten; i++) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 3705ceb3c..c4a52a3c9 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -601,10 +601,13 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 return(-errs); } - void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) { + if ( ramchain->allocatedA != 0 && ramchain->A != 0 ) + free(ramchain->A); ramchain->A = 0; + if ( ramchain->allocatedU != 0 && ramchain->Uextras != 0 ) + free(ramchain->Uextras); ramchain->Uextras = 0; if ( ramchain->debitsfileptr != 0 ) { @@ -694,6 +697,101 @@ void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramch } else printf("illegal ramchain.%p\n",ramchain); } +void iguana_truncatebalances(struct iguana_info *coin) +{ + int32_t i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + bp->balancefinish = 0; + ramchain = &bp->ramchain; + iguana_purgevolatiles(coin,ramchain); + } + } + coin->balanceswritten = 0; +} + +int32_t iguana_volatileinit(struct iguana_info *coin) +{ + bits256 balancehash; struct iguana_utxo *Uptr; struct iguana_account *Aptr; + struct sha256_vstate vstate; int32_t i,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; + uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65],buf[2048]; + from_ro = 1; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 || bp->utxofinish <= 1 ) + { + printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); + break; + } + if ( bp->ramchain.from_ro == 0 || bp->ramchain.from_roX == 0 || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0 ) + from_ro = 0; + } + if ( i != coin->balanceswritten ) + { + printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); + iguana_truncatebalances(coin); + } + else + { + vupdate_sha256(balancehash.bytes,&vstate,0,0); + filecrc = 0; + sprintf(crcfname,"DB/%s/balancecrc.%d",coin->symbol,coin->balanceswritten); + if ( (fp= fopen(crcfname,"rb")) != 0 ) + { + if ( fread(&filecrc,1,sizeof(filecrc),fp) != sizeof(filecrc) ) + filecrc = 0; + else if ( fread(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + filecrc = 0; + else if ( memcmp(&balancehash,&coin->balancehash,sizeof(balancehash)) != 0 ) + filecrc = 0; + fclose(fp); + } + if ( filecrc != 0 ) + printf("have filecrc.%08x for %s milli.%.0f\n",filecrc,bits256_str(str,balancehash),OS_milliseconds()); + if ( from_ro == 0 ) + { + if ( filecrc == 0 ) + vupdate_sha256(balancehash.bytes,&vstate,0,0); + for (i=crc=0; ibalanceswritten; i++) + { + numpkinds = numunspents = 0; + Aptr = 0, Uptr = 0; + if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + } + crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); + crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); + } else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); + } + } else crc = filecrc; + printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 ) + { + printf("balancehash or crc mismatch\n"); + iguana_truncatebalances(coin); + } + else + { + printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); + if ( (fp= fopen(crcfname,"wb")) != 0 ) + { + if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + printf("error writing.(%s)\n",crcfname); + fclose(fp); + } + } + } + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_bundlestats(coin,buf); + return(coin->balanceswritten); +} + int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; @@ -812,6 +910,7 @@ 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)); + coin->balanceswritten = iguana_volatileinit(coin); return(coin->balanceswritten); } From 9bf9fba28ac24d19e02e428c801af04a391ccde7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 07:57:48 -0300 Subject: [PATCH 232/333] test --- iguana/iguana_unspents.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c4a52a3c9..ea1fe3a18 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -425,7 +425,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,pkind,txidind,h,i,j,k,ind; struct iguana_account *A2; + uint32_t unspentind,pkind,txidind,h,i,j,k,ind,now; struct iguana_account *A2; struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; struct iguana_blockRO *B; int32_t flag,hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_utxo *utxo,*Uextras; @@ -458,6 +458,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } for (j=0; j (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } else continue; - //if ( (spendind & 0xff) == 1 ) - // now = (uint32_t)time(NULL); if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - /*if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) - { - //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; - }*/ + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } spentbp->dirty++; Uextras = spentbp->ramchain.Uextras; A2 = spentbp->ramchain.A; From f9e6a70eead45f34eaf42c1359d67f478e385996 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 08:26:39 -0300 Subject: [PATCH 233/333] test --- iguana/iguana_unspents.c | 137 +++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ea1fe3a18..e67836378 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -66,6 +66,74 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t return(0); } +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t height,uint32_t spendind,struct iguana_bundle *spentbp,uint32_t unspentind) +{ + struct iguana_unspent *u,*spentU; struct iguana_account *A2; + int32_t flag,errs=0; struct iguana_utxo *utxo,*Uextras; uint32_t pkind; + if ( incremental == 0 ) + { + Uextras = spentbp->ramchain.Uextras; + A2 = spentbp->ramchain.A; + } + else + { + Uextras = 0; + A2 = 0; + } + if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) + { + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[unspentind]; + if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) + { + flag = -1; + if ( incremental == 0 ) + { + if ( Uextras == 0 || A2 == 0 ) + { + printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); + errs++; + } + else + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevunspentind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = height; + A2[pkind].total += u->value; + A2[pkind].lastind = unspentind; + flag = 0; + } + } + } + else + { + if ( bp != spentbp ) + { + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); + } + else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); + } + if ( flag != 0 ) + { + errs++; + printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); + getchar(); + } + } + else + { + errs++; + printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); + } + } + return(-errs); +} + void iguana_realtime_update(struct iguana_info *coin) { //bp->hdrsi >= coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten @@ -425,13 +493,10 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,pkind,txidind,h,i,j,k,ind,now; struct iguana_account *A2; - struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; + uint32_t unspentind,txidind,h,i,j,k,ind,now; struct iguana_ramchain *ramchain; struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; struct iguana_blockRO *B; - int32_t flag,hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_utxo *utxo,*Uextras; + int32_t hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_spend *S,*s; ramchain = &bp->ramchain; - Uextras = 0; - A2 = 0; if ( startheight == bp->bundleheight && endheight == bp->bundleheight+bp->n-1 ) incremental = 0; else incremental = 1; @@ -468,9 +533,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 for (k=0; kexternal != 0 && s->prevout >= 0 ) { @@ -480,7 +543,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 { h = ramchain->Xspendinds[emit].height; unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi < bp->hdrsi ) spentbp = coin->bundles[hdrsi]; else { @@ -494,7 +557,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else if ( s->prevout >= 0 ) { spentbp = bp; - hdrsi = bp->hdrsi; h = bp->bundleheight + i; if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) { @@ -507,71 +569,18 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("iguana_balancegen txidind overflow %u vs %u\n",ind,spentbp->ramchain.H.data->numtxids); errs++; } - //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); } else continue; if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) { - //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } spentbp->dirty++; - Uextras = spentbp->ramchain.Uextras; - A2 = spentbp->ramchain.A; - if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) - { - spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); - u = &spentU[unspentind]; - if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) - { - flag = -1; - if ( incremental == 0 ) - { - if ( Uextras == 0 || A2 == 0 ) - { - printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); - errs++; - } - else - { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - { - utxo->prevunspentind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = h; - A2[pkind].total += u->value; - A2[pkind].lastind = unspentind;//spendind; - flag = 0; - } - } - } - else - { - if ( bp != spentbp ) - { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); - } - else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,h); - } - if ( flag != 0 ) - { - errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); - getchar(); - } - } - else - { - errs++; - printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); - } - } + if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) + errs++; } else { From 24ef664be8282fe7531b24350c2aa7919bb1bdc1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 08:59:29 -0300 Subject: [PATCH 234/333] test --- iguana/iguana777.c | 3 ++- iguana/iguana_bundles.c | 1 - iguana/iguana_unspents.c | 43 ++++++++++++++++++++++++++++------------ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 2895fdc90..1ee35700b 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -385,6 +385,7 @@ void iguana_helper(void *arg) } if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { + coin->numbundlesQ--; idle = 0; if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) { @@ -539,7 +540,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM <= 4 ) - maxval = coin->MAXMEM; + maxval = (int32_t)coin->MAXMEM; coin->MAXMEM *= (1024L * 1024 * 1024); if ( (coin->startPEND= juint(json,"startpend")) == 0 ) coin->startPEND = IGUANA_MAXPENDBUNDLES * mult; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 9d33b8ead..543951a9d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -821,7 +821,6 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; - coin->numbundlesQ--; iguana_bundlecalcs(coin,bp); //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); bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index e67836378..c7c9dc314 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -16,6 +16,24 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" +struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_unspentind) +{ + struct iguana_hhutxo *hhutxo; uint8_t buf[sizeof(spent_unspentind) + sizeof(spent_hdrsi)]; + memcpy(&buf[sizeof(spent_unspentind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); + memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); + HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); + return(hhutxo); +} + +struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_pkind) +{ + struct iguana_hhaccount *hhacct; uint8_t buf[sizeof(spent_pkind) + sizeof(spent_hdrsi)]; + memcpy(&buf[sizeof(spent_pkind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); + memcpy(buf,(void *)&spent_pkind,sizeof(spent_pkind)); + HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhacct); + return(hhacct); +} + int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) { struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; @@ -44,16 +62,11 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t } printf("unexpected utxoupdate\n"); exit(-1); - memcpy(&buf[sizeof(uint32_t)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); - memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); - HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); - if ( hhutxo != 0 && hhutxo->u.spentflag != 0 ) + if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); HASH_ADD(hh,coin->utxotable,buf,sizeof(buf),hhutxo); - memcpy(buf,(void *)&spent_pkind,sizeof(spent_pkind)); - HASH_FIND(hh,coin->accountstable,buf,sizeof(buf),hhacct); - if ( hhacct == 0 ) + if ( (hhacct= iguana_hhaccountfind(coin,spent_hdrsi,spent_pkind)) == 0 ) { hhacct = calloc(1,sizeof(*hhacct)); HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); @@ -134,11 +147,6 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc return(-errs); } -void iguana_realtime_update(struct iguana_info *coin) -{ - //bp->hdrsi >= coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten -} - 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) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; @@ -609,6 +617,15 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 return(-errs); } +void iguana_realtime_update(struct iguana_info *coin) +{ + struct iguana_bundle *bp; + if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten ) + { + + } +} + void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) { if ( ramchain->allocatedA != 0 && ramchain->A != 0 ) @@ -898,7 +915,6 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } coin->balancehash = balancehash; coin->balanceswritten = numhdrsi; - iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables for (hdrsi=0; hdrsibundles[hdrsi]) == 0 ) { @@ -919,6 +935,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu } char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash)); coin->balanceswritten = iguana_volatileinit(coin); + iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables return(coin->balanceswritten); } From a486a99adb2c6c7b055b802b499475a608f08d44 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 09:08:28 -0300 Subject: [PATCH 235/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 1ee35700b..145dfee87 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -385,10 +385,10 @@ void iguana_helper(void *arg) } if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { - coin->numbundlesQ--; idle = 0; if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) { + coin->numbundlesQ--; if ( coin->started != 0 && time(NULL) >= bp->nexttime ) flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); else iguana_bundleQ(ptr->coin,bp,1000); From edbbb5549c3f9a32f6afdee74424cfb7e4059dee Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 09:16:32 -0300 Subject: [PATCH 236/333] test --- deprecated/obsolete.h | 21 +++++++++++++++++++++ iguana/iguana_bundles.c | 23 +---------------------- iguana/iguana_unspents.c | 3 +-- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 4aaef9172..73361d511 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14482,5 +14482,26 @@ len = 0; } } + if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) + { + for (bundlei=0; bundlein; bundlei++) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( checki == bundlei ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + fclose(fp); + else break; + } + } + if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) + { + printf("RT bundls\n"); + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + + } + } + } #endif diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 543951a9d..f22db8f3a 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -806,7 +806,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,checki,retval=0,max,bundlei,hdrsi,counter = 0; char fname[1024]; struct iguana_bundle *currentbp,*lastbp; FILE *fp; static bits256 zero; + int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; if ( coin->started == 0 ) { printf("%s not ready yet\n",coin->symbol); @@ -872,27 +872,6 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru counter = iguana_bundleissue(coin,bp,max,timelimit); 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 ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) - { - for (bundlei=0; bundlein; bundlei++) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( checki == bundlei ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - fclose(fp); - else break; - } - } - if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) - { - printf("RT bundls\n"); - if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) - { - - } - } - } } iguana_bundleQ(coin,bp,1000); return(retval); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c7c9dc314..80bd97acf 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -60,8 +60,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t } return(0); } - printf("unexpected utxoupdate\n"); - exit(-1); + printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); From 6d89379a25cac752f5ed7e70b56f67cc7616fffe Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:31:41 -0300 Subject: [PATCH 237/333] test --- iguana/iguana777.h | 1 + iguana/iguana_bundles.c | 10 +++---- iguana/iguana_ramchain.c | 28 ++++++++++++------- iguana/iguana_unspents.c | 58 ++++++++++++++++++++++++++-------------- iguana/main.c | 2 +- 5 files changed, 63 insertions(+), 36 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 6f141c9e9..27617edf0 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -473,6 +473,7 @@ struct iguana_info 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; int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified; uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp; double backstopmillis; bits256 backstophash2; int64_t spaceused; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index f22db8f3a..36ec3a06c 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -542,7 +542,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); + } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,now > block->issued+lag*3); flag++; } //else printf("%d ",now - block->issued); } @@ -564,21 +564,19 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int block->numrequests++; if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current || now > block->issued+lag*3); 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 if ( bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) { if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current || now > bp->issued[i]+lag*3); bp->issued[i] = now; counter++; } @@ -1042,7 +1040,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"%s u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->hdrsi:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,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,"%s u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,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,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,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+10 ) { diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 205ed5aba..d4d72c012 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2279,17 +2279,27 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana } -/*{ - RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; - if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) == 0 ) +int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) +{ + RAMCHAIN_DECLARE; int32_t i,numblocks = 0; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; + mem->alignflag = sizeof(uint32_t); + hashmem->alignflag = sizeof(uint32_t); + scriptspace = numexternaltxids = numtxids = coin->chain->bundlesize * 2; + numunspents = numspends = numpkinds = numtxids * 2; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + } + if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) { - iguana_ramchain_link(dest,bp->hashes[starti],bp->hashes[endi],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); - dest->expanded = 1; - dest->H.scriptoffset = 1; - _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(coin,dest,&HASHMEM,0); + iguana_ramchain_link(ramchain,hash2,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); + ramchain->expanded = 1; + ramchain->H.scriptoffset = 1; + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + iguana_ramchain_extras(coin,ramchain,hashmem,0); } -}*/ + return(rdata->allocsize); +} // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 80bd97acf..e531a30df 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -108,15 +108,20 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) + if ( 1 ) + flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); + else { - utxo->prevunspentind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = height; - A2[pkind].total += u->value; - A2[pkind].lastind = unspentind; - flag = 0; + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevunspentind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = height; + A2[pkind].total += u->value; + A2[pkind].lastind = unspentind; + flag = 0; + } } } } @@ -616,15 +621,6 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 return(-errs); } -void iguana_realtime_update(struct iguana_info *coin) -{ - struct iguana_bundle *bp; - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten ) - { - - } -} - void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) { if ( ramchain->allocatedA != 0 && ramchain->A != 0 ) @@ -723,14 +719,13 @@ void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramch void iguana_truncatebalances(struct iguana_info *coin) { - int32_t i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; + int32_t i; struct iguana_bundle *bp; for (i=0; ibalanceswritten; i++) { if ( (bp= coin->bundles[i]) != 0 ) { bp->balancefinish = 0; - ramchain = &bp->ramchain; - iguana_purgevolatiles(coin,ramchain); + iguana_purgevolatiles(coin,&bp->ramchain); } } coin->balanceswritten = 0; @@ -816,6 +811,28 @@ int32_t iguana_volatileinit(struct iguana_info *coin) return(coin->balanceswritten); } +void iguana_RTramchainfree(struct iguana_info *coin) +{ + +} + +void iguana_RTramchainalloc(struct iguana_info *coin) +{ + if ( coin->RTramchain.H.data == 0 ) + { + + } +} + +void iguana_realtime_update(struct iguana_info *coin) +{ + struct iguana_bundle *bp; + if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten ) + { + iguana_RTramchainalloc(coin); + } +} + int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) { int32_t hdrsi,numpkinds,iter,numhdrsi,numunspents,err; struct iguana_bundle *bp; @@ -935,6 +952,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu char str[65]; printf("BALANCES WRITTEN for %d bundles %s\n",coin->balanceswritten,bits256_str(str,coin->balancehash)); coin->balanceswritten = iguana_volatileinit(coin); iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables + iguana_RTramchainfree(coin); return(coin->balanceswritten); } diff --git a/iguana/main.c b/iguana/main.c index 1c095dd44..8e4910050 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1128,7 +1128,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":3333,\"endpend\":3333,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From fc9032ec8b3d53e814f3425248d7e4e4d18a01e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:33:58 -0300 Subject: [PATCH 238/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index e531a30df..c8c7ab142 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -60,7 +60,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t } return(0); } - printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); + //printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); From afb72ec87fd992f5488c9e340f023e4036d6fb2d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:36:11 -0300 Subject: [PATCH 239/333] test --- iguana/iguana_unspents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c8c7ab142..219dcc0bc 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -60,7 +60,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t } return(0); } - //printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); + printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); @@ -108,9 +108,9 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else { - if ( 1 ) + if ( 0 ) flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); - else + else if ( 0 ) { utxo = &Uextras[unspentind]; if ( utxo->spentflag == 0 ) From 1d50f004f2d21844593081ad80f487b92f00630f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:39:44 -0300 Subject: [PATCH 240/333] test --- iguana/iguana_unspents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 219dcc0bc..9af37f579 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -123,6 +123,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc flag = 0; } } + flag = 0; } } else @@ -138,7 +139,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc if ( flag != 0 ) { errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevunspentind,utxo->spentflag,utxo->height); + printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d\n",pkind,spentbp->hdrsi,unspentind); getchar(); } } From 448329d1ecedcddafc470cb5e2cfe1c83fa4f8f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:44:09 -0300 Subject: [PATCH 241/333] test --- iguana/iguana_unspents.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9af37f579..dda356037 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -108,22 +108,16 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else { - if ( 0 ) - flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); - else if ( 0 ) + utxo = &Uextras[unspentind]; + if ( utxo->spentflag == 0 ) { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - { - utxo->prevunspentind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = height; - A2[pkind].total += u->value; - A2[pkind].lastind = unspentind; - flag = 0; - } + utxo->prevunspentind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = height; + A2[pkind].total += u->value; + A2[pkind].lastind = unspentind; + flag = 0; } - flag = 0; } } else @@ -523,7 +517,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); return(0); } - iguana_ramchain_prefetch(coin,&bp->ramchain); + iguana_ramchain_prefetch(coin,ramchain); printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); txidind = spendind = ramchain->H.data->firsti; for (i=0; in; i++) @@ -592,8 +586,8 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 spentbp->lastprefetch = now; } spentbp->dirty++; - if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) - errs++; + //if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) + // errs++; } else { From c8811bfaa15247b2f7d6f65227b236fbd82747c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:47:26 -0300 Subject: [PATCH 242/333] test --- iguana/iguana_unspents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index dda356037..33f8be51d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -580,14 +580,14 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else continue; if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + if ( now > spentbp->lastprefetch || (spentbp->dirty % 50000) == 0 ) { iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } spentbp->dirty++; - //if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) - // errs++; + if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) + errs++; } else { From 000a953b02e951fc797311cddf5998396a11dc89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 10:52:01 -0300 Subject: [PATCH 243/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 33f8be51d..c7a2168d1 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -580,7 +580,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else continue; if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( now > spentbp->lastprefetch || (spentbp->dirty % 50000) == 0 ) + if ( 0 && (now > spentbp->lastprefetch || (spentbp->dirty % 50000) == 0) ) { iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; From 2b25df90c5a79c5664f45c11f0e9d090dd1aef05 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 12:53:57 -0300 Subject: [PATCH 244/333] test --- deprecated/obsolete.h | 12 ++++ iguana/iguana777.h | 10 ++- iguana/iguana_bundles.c | 6 +- iguana/iguana_peers.c | 4 +- iguana/iguana_ramchain.c | 134 +++++++++++++++++++++------------------ iguana/iguana_unspents.c | 56 +++++++++++++--- iguana/main.c | 2 +- 7 files changed, 149 insertions(+), 75 deletions(-) diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 73361d511..b39849342 100755 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -14503,5 +14503,17 @@ len = 0; } } } + /*for (j=0; jn; i++) { if ( (block= bp->blocks[i]) != 0 ) @@ -602,7 +602,9 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); if ( 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)); + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1)) == i ) + OS_removefile(fname,0); + char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue %s\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname); block->fpipbits = 0; block->fpos = -1; block->queued = 0; diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 71160308d..a4c94e4f4 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -695,7 +695,7 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) { - //printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); + printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); iA->status = IGUANA_PEER_CONNECTING; addr->pending = (uint32_t)time(NULL); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); @@ -755,7 +755,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) expand_ipbits(checkaddr,ipbits); if ( strcmp(checkaddr,ipaddr) == 0 ) { - //printf("valid ipaddr.(%s) MAXPEERS.%d\n",ipaddr,coin->MAXPEERS); + printf("valid ipaddr.(%s) MAXPEERS.%d\n",ipaddr,coin->MAXPEERS); if ( (iA= iguana_iAddrhashfind(coin,ipbits,1)) != 0 ) { if ( iA->status != IGUANA_PEER_CONNECTING && iA->status != IGUANA_PEER_READY && iA->status != IGUANA_PEER_ELIGIBLE ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d4d72c012..f84669269 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2086,23 +2086,32 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p return(num); } +void *iguana_bundlefile(struct iguana_info *coin,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) +{ + int32_t checki,hdrsi; char fname[1024]; void *ptr = 0; static bits256 zero; + *filesizep = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + return(0); + } + if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) + { + printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + return(0); + } + return(ptr); +} + int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp,int32_t starti,int32_t endi) { - int32_t bundlei,checki,hdrsi,num = 0; char fname[1024]; static bits256 zero; + int32_t bundlei,num = 0; for (bundlei=starti; bundlei<=endi; bundlei++) { - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - return(bp == coin->current ? num : 0); - } - if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) - { - printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); - return(bp == coin->current ? num : 0); - } + if ( (ptrs[num]= iguana_bundlefile(coin,&filesizes[num],bp,bundlei)) != 0 ) + num++; + else return(bp == coin->current ? num : 0); //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); - num++; } return(num); } @@ -2278,7 +2287,6 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana return(mapchain); } - int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) { RAMCHAIN_DECLARE; int32_t i,numblocks = 0; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; @@ -2289,7 +2297,21 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram for (i=0; ibundlescount; i++) if ( (bp= coin->bundles[i]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) { - } + if ( rdata->numtxids > numtxids ) + numtxids = rdata->numtxids; + if ( rdata->numpkinds > numpkinds ) + numpkinds = rdata->numpkinds; + if ( rdata->numspends > numspends ) + numspends = rdata->numspends; + if ( rdata->numunspents > numunspents ) + numunspents = rdata->numunspents; + if ( rdata->numexternaltxids > numexternaltxids ) + numexternaltxids = rdata->numexternaltxids; + if ( rdata->scriptspace > scriptspace ) + scriptspace = rdata->scriptspace; + } + numtxids *= 1.5; numexternaltxids *= 1.5, scriptspace *= 1.5; + numunspents *= 1.5, numspends *= 1.5, numpkinds *= 1.5; if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) { iguana_ramchain_link(ramchain,hash2,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); @@ -2301,12 +2323,42 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram return(rdata->allocsize); } +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) +{ + int32_t firsti = 1; RAMCHAIN_DECLARE; + mapchain->fileptr = ptr; + mapchain->filesize = filesize; + mapchain->H.data = (void *)(long)((long)ptr + block->fpos); + mapchain->H.ROflag = 1; + if ( block->fpos > filesize ) + { + printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",block->fpos,filesize,bp->hdrsi,bundlei); + return(-1); + } + _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); + if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) + { + printf("iguana_bundlesaveHT.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); + //getchar(); + return(-1); + } + else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) + { + char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + return(-1); + } + iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( bp->blocks[bundlei]->RO.txn_count == 0 ) + bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + return(0); +} + // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { static int depth; static bits256 zero; RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; - void **ptrs,*ptr; long *filesizes,filesize; uint32_t *ipbits; char fname[1024]; + void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; int32_t i,starti,endi,bp_n,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; @@ -2330,61 +2382,23 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str sigspace = pubkeyspace = 0; for (bundlei=starti,numtxids=numunspents=numspends=scriptspace=0; bundlei<=endi; bundlei++) { - if ( (block= bp->blocks[bundlei]) != 0 ) - fpipbits = block->fpipbits, fpos = block->fpos; - else fpipbits = fpos = 0; - mapchain = &R[bundlei]; - /*for (j=0; jfileptr = ptr; - mapchain->filesize = filesize; - mapchain->H.data = (void *)(long)((long)ptr + fpos); - mapchain->H.ROflag = 1; - if ( fpos > filesize ) - { - iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); - 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 ) + 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("iguana_bundlesaveHT.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); - //getchar(); + printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2)); break; } - else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) - { - char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + fpipbits = block->fpipbits, fpos = block->fpos; + mapchain = &R[bundlei]; + if ( iguana_mapchaininit(coin,mapchain,bp,bundlei,block,ptrs[bundlei],filesizes[bundlei]) < 0 ) break; - } - iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); numtxids += (mapchain->H.data->numtxids - 1); numunspents += (mapchain->H.data->numunspents - 1); numspends += (mapchain->H.data->numspends - 1); scriptspace += 1;//iguana_ramchain_scriptspace(coin,&sigsize,&pubkeysize,mapchain); //sigspace += sigsize; //pubkeyspace += pubkeysize; - 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)); - break; - } //printf("%x ",(uint32_t)block->RO.hash2.ulongs[3]); - if ( bp->blocks[bundlei]->RO.txn_count == 0 ) - bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + // _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); //printf("(%d %d).%d ",mapchain->H.data->numtxids,bp->blocks[bundlei]->RO.txn_count,numtxids); //printf("%d ",numtxids); } @@ -2438,7 +2452,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } - //destB[i] = block->RO; + destB[i] = block->RO; } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index c7a2168d1..b907c0cc9 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -34,7 +34,7 @@ struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint16_t return(hhacct); } -int32_t iguana_utxoupdate(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) { struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; @@ -808,24 +808,64 @@ int32_t iguana_volatileinit(struct iguana_info *coin) void iguana_RTramchainfree(struct iguana_info *coin) { - + iguana_ramchain_free(coin,&coin->RTramchain,1); } -void iguana_RTramchainalloc(struct iguana_info *coin) +void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { + struct iguana_ramchain *dest = &coin->RTramchain; if ( coin->RTramchain.H.data == 0 ) { - + iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); + dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; + dest->externalind = dest->H.stacksize = 0; + dest->H.scriptoffset = 1; } } -void iguana_realtime_update(struct iguana_info *coin) +int32_t iguana_realtime_update(struct iguana_info *coin) { - struct iguana_bundle *bp; - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten ) + struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err; + struct iguana_block *block; struct iguana_blockRO *B; struct iguana_ramchain *dest,blockR; + long filesize; void *ptr; + 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 ) { - iguana_RTramchainalloc(coin); + iguana_RTramchainalloc(coin,bp); + if ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight < coin->blocks.hwmchain.height) + { + dest = &coin->RTramchain; + B = (void *)(long)((long)rdata + rdata->Boffset); + bundlei = (coin->RTheight % coin->chain->bundlesize); + if ( (block= bp->blocks[bundlei]) != 0 ) + { + iguana_blocksetcounters(coin,block,dest); + coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + B[bundlei] = block->RO; + if ( (ptr= iguana_bundlefile(coin,&filesize,bp,bundlei)) != 0 ) + { + if ( iguana_mapchaininit(coin,&blockR,bp,bundlei,block,ptr,filesize) == 0 ) + { + if ( (err= iguana_ramchain_iterate(coin,dest,&blockR,bp)) != 0 ) + { + printf("error adding height.%d\n",bp->bundleheight+bundlei); + if ( (block= bp->blocks[bundlei]) != 0 ) + { + block->queued = 0; + block->fpipbits = 0; + bp->issued[bundlei] = 0; + block->issued = 0; + } + return(-1); + } + printf("added RTheight.%d hwm.%d longest.%d\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain); + coin->RTheight++; + coin->RTramchain.H.data->numblocks = bundlei + 1; + } else printf("error mapchaininit\n"); + } + } else return(-1); + } } + return(0); } int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t purgedist) diff --git a/iguana/main.c b/iguana/main.c index 8e4910050..64ae87bda 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1128,7 +1128,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":8,\"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 ) From 6b88b20d29106266ad08b8862089f1b224648eb5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 16:37:01 -0300 Subject: [PATCH 245/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_bundles.c | 2 +- iguana/iguana_peers.c | 29 ++++++++++++++++++++--------- iguana/main.c | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 145dfee87..cc52bbe36 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -425,6 +425,7 @@ void iguana_coinloop(void *arg) { 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; @@ -432,7 +433,6 @@ void iguana_coinloop(void *arg) } } coin = coins[0]; - iguana_rwiAddrind(coin,0,0,0); iguana_possible_peer(coin,"127.0.0.1"); memset(zero.bytes,0,sizeof(zero)); if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2bd927d04..2bfd7f3a7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -636,7 +636,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 { if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) { - if ( now > bp->issued[i]+60 ) + if ( now > bp->issued[i]+20 ) { bp->issued[i] = now; //printf("speculative.[%d:%d]\n",bp->hdrsi,i); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index a4c94e4f4..e07471c01 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -68,7 +68,7 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ iA = tmp; if ( ind <= 0 ) ind = coin->numiAddrs + 1; - //printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,iA->ipbits,iA->ind); + printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,(uint32_t)iA->ipbits,ind); if ( (item= _iguana_hashset(coin,iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) { *item = *iA; @@ -138,14 +138,23 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana fseek(fp,m*sizeof(tmp),SEEK_SET); fwrite(&tmp,1,sizeof(tmp),fp); } - //printf("m.%d %x\n",m,tmp.ipbits); + //printf("rwiAddrind m.%d %x\n",m,(uint32_t)tmp.ipbits); m++; coin->numiAddrs = m; expand_ipbits(hexstr,tmp.ipbits); iguana_possible_peer(coin,hexstr); } + else + { + expand_ipbits(hexstr,tmp.ipbits); + printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)tmp.ipbits); + tmp.status = 0; + fseek(fp,i * sizeof(tmp),SEEK_SET); + if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) + printf("error writing peer.%d\n",i); + } portable_mutex_unlock(&coin->peers_mutex); - } + } else printf("skip.%d ipbits.%x\n",i,(uint32_t)tmp.ipbits); } fclose(fp); printf("i.%d m.%d numiAddrs.%d\n",i,m,coin->numiAddrs); @@ -180,6 +189,8 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana fp = fopen(fname,"wb"); if ( fp != 0 ) { + if ( ind <= 0 ) + ind = coin->numiAddrs++; fseek(fp,ind * sizeof(*iA),SEEK_SET); if ( ftell(fp) == ind * sizeof(*iA) ) { @@ -191,7 +202,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - //printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,iA->ipbits,ind,iA->hh. itemind,retval); + printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,(uint32_t)iA->ipbits,ind,iA->hh. itemind,retval); } } } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); @@ -247,8 +258,8 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar } else printf("killconnection cant get ind for ipaddr.%s\n",addr->ipaddr); memset(addr,0,sizeof(*addr)); addr->usock = -1; - if ( rank > 0 ) - iguana_possible_peer(coin,ipaddr); + //if ( rank > 0 ) + // iguana_possible_peer(coin,ipaddr); } int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) @@ -688,9 +699,9 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { //printf("%x\n",iA->ipbits); //portable_mutex_unlock(&coin->peers_mutex); - if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 )//i < coin->MAXPEERS && i < IGUANA_MAXPEERS && addr != 0 ) + if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { - //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); + printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING ) { if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) @@ -734,7 +745,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) return((uint32_t)time(NULL)); } #endif - //printf("check possible peer.(%s)\n",ipaddr); + printf("check possible peer.(%s)\n",ipaddr); for (i=n=0; iMAXPEERS; i++) { if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) diff --git a/iguana/main.c b/iguana/main.c index 64ae87bda..ed450b367 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1128,7 +1128,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":8,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From ff461e8ad8851385d687eec2ada7c49be14cc2d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 16:50:18 -0300 Subject: [PATCH 246/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_peers.c | 4 ++-- iguana/iguana_unspents.c | 5 ++++- iguana/main.c | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index cc52bbe36..a84ad3056 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -464,7 +464,7 @@ void iguana_coinloop(void *arg) } if ( coin->bindsock >= 0 ) { - if ( coin->peers.numranked < 8 && now > coin->lastpossible+60 ) + if ( coin->peers.numranked < coin->MAXPEERS/2 && now > coin->lastpossible ) { //fprintf(stderr,"possible\n"); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index e07471c01..b4263a4fc 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -745,12 +745,12 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) return((uint32_t)time(NULL)); } #endif - printf("check possible peer.(%s)\n",ipaddr); + //printf("check possible peer.(%s)\n",ipaddr); for (i=n=0; iMAXPEERS; i++) { if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) { - printf("(%s) already active\n",ipaddr); + //printf("(%s) already active\n",ipaddr); free_queueitem(ipaddr); return((uint32_t)time(NULL)); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index b907c0cc9..718afb0d9 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -813,9 +813,12 @@ void iguana_RTramchainfree(struct iguana_info *coin) void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { - struct iguana_ramchain *dest = &coin->RTramchain; + int32_t mult; struct iguana_ramchain *dest = &coin->RTramchain; if ( coin->RTramchain.H.data == 0 ) { + mult = (strcmp("BTC",coin->symbol) == 0) ? 2048 : 4; + if ( coin->RTmem.ptr == 0 ) + iguana_meminit(&coin->RTmem,coin->symbol,0,IGUANA_MAXPACKETSIZE*mult + 65536*3,0); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; diff --git a/iguana/main.c b/iguana/main.c index ed450b367..9fd74ed40 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1128,7 +1128,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From 22add2a915793106af19f900212dffc198510d41 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 17:02:32 -0300 Subject: [PATCH 247/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_peers.c | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index a84ad3056..9f61b4168 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -364,7 +364,7 @@ void iguana_helper(void *arg) fp = fopen(fname,"wb");*/ if ( argjson != 0 ) free_json(argjson); - printf("HELPER.%d started\n",helperid); + printf("HELPER.%d started arg.(%s)\n",helperid,arg!=0?arg:0); memset(&MEM,0,sizeof(MEM)); MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index b4263a4fc..ddb561acf 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -18,7 +18,7 @@ #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbits,int32_t createflag); -struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint64_t ipbits,int32_t itemind) +struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind) { struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0; expand_ipbits(str,ipbits); @@ -61,7 +61,7 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ return(0); } portable_mutex_lock(&coin->peers_mutex); - if ( (item= _iguana_hashfind(coin,iA->ipbits)) == 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)iA->ipbits)) == 0 ) { tmp = mycalloc('i',1,sizeof(*iA)); *tmp = *iA; @@ -69,7 +69,7 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ if ( ind <= 0 ) ind = coin->numiAddrs + 1; printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,(uint32_t)iA->ipbits,ind); - if ( (item= _iguana_hashset(coin,iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) + if ( (item= _iguana_hashset(coin,(uint32_t)iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) { *item = *iA; iA = item; @@ -93,11 +93,11 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi portable_mutex_lock(&coin->peers_mutex); if ( ipbits != 0 ) { - if ( (item= _iguana_hashfind(coin,ipbits)) == 0 && createflag != 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) == 0 && createflag != 0 ) { ind = coin->numiAddrs + 1; - _iguana_hashset(coin,ipbits,ind); - if ( (item= _iguana_hashfind(coin,ipbits)) != 0 ) + _iguana_hashset(coin,(uint32_t)ipbits,ind); + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) != 0 ) coin->numiAddrs++; } } @@ -107,7 +107,7 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { - FILE *fp; char fname[512],hexstr[65]; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; + FILE *fp; char fname[512],hexstr[65]; uint32_t ipbits; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; sprintf(fname,"DB/%s_peers.dat",coin->symbol); OS_compatible_path(fname); if ( rwflag < 0 || iA == 0 ) @@ -123,7 +123,8 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( ftell(fp) == i*sizeof(tmp) && fread(&tmp,1,sizeof(tmp),fp) == sizeof(tmp) && tmp.ipbits != 0 ) { portable_mutex_lock(&coin->peers_mutex); - HASH_FIND(hh,coin->iAddrs,&tmp.ipbits,sizeof(tmp.ipbits),ptr); + ipbits = (uint32_t)tmp.ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); if ( ptr == 0 ) { ptr = mycalloc('t',1,sizeof(*ptr)); @@ -131,7 +132,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana printf("fatal alloc error in hashset\n"), exit(-1); ptr->hh.itemind = m; ptr->ipbits = tmp.ipbits; - HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(tmp.ipbits),ptr); + HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(ipbits),ptr); if ( i != m ) { tmp.hh.itemind = m; @@ -141,20 +142,20 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana //printf("rwiAddrind m.%d %x\n",m,(uint32_t)tmp.ipbits); m++; coin->numiAddrs = m; - expand_ipbits(hexstr,tmp.ipbits); + expand_ipbits(hexstr,ipbits); iguana_possible_peer(coin,hexstr); } else { - expand_ipbits(hexstr,tmp.ipbits); - printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)tmp.ipbits); + expand_ipbits(hexstr,ipbits); + printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)ipbits); tmp.status = 0; fseek(fp,i * sizeof(tmp),SEEK_SET); if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) printf("error writing peer.%d\n",i); } portable_mutex_unlock(&coin->peers_mutex); - } else printf("skip.%d ipbits.%x\n",i,(uint32_t)tmp.ipbits); + } else printf("skip.%d ipbits.%x\n",i,(uint32_t)ipbits); } fclose(fp); printf("i.%d m.%d numiAddrs.%d\n",i,m,coin->numiAddrs); @@ -189,6 +190,13 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana fp = fopen(fname,"wb"); if ( fp != 0 ) { + ipbits = (uint32_t)iA->ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); + if ( ptr != 0 && ptr->hh.itemind != ind ) + { + printf("mismatch iAddr ind.%d != %d\n",ptr->hh.itemind,ind); + ind = ptr->hh.itemind; + } if ( ind <= 0 ) ind = coin->numiAddrs++; fseek(fp,ind * sizeof(*iA),SEEK_SET); @@ -202,7 +210,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,(uint32_t)iA->ipbits,ind,iA->hh. itemind,retval); + printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); } } } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); From 6a9983e4a40c63620dec21b9701cd323bfa7c198 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 17:14:55 -0300 Subject: [PATCH 248/333] test --- iguana/iguana777.c | 4 ++-- iguana/iguana_peers.c | 29 +++++++++++++---------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 9f61b4168..c8b663c46 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -181,7 +181,7 @@ int32_t iguana_peermetrics(struct iguana_info *coin) coin->peers.avemetric = (sum / i); if ( i >= (coin->MAXPEERS - 1) && slowest != 0 ) { - printf("prune slowest peer.(%s) numranked.%d\n",slowest->ipaddr,n); + printf("prune slowest peer.(%s) numranked.%d MAXPEERS.%d\n",slowest->ipaddr,n,coin->MAXPEERS); slowest->dead = 1; } } @@ -364,7 +364,7 @@ void iguana_helper(void *arg) fp = fopen(fname,"wb");*/ if ( argjson != 0 ) free_json(argjson); - printf("HELPER.%d started arg.(%s)\n",helperid,arg!=0?arg:0); + printf("HELPER.%d started arg.(%s)\n",helperid,(char *)(arg!=0?arg:0)); memset(&MEM,0,sizeof(MEM)); MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index ddb561acf..e5ba089f6 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -117,7 +117,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana { fseek(fp,0,SEEK_END); n = (int32_t)(ftell(fp) / sizeof(*iA)); - for (i=m=0; ihh.itemind = m; ptr->ipbits = tmp.ipbits; HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(ipbits),ptr); - if ( i != m ) - { - tmp.hh.itemind = m; - fseek(fp,m*sizeof(tmp),SEEK_SET); - fwrite(&tmp,1,sizeof(tmp),fp); - } - //printf("rwiAddrind m.%d %x\n",m,(uint32_t)tmp.ipbits); + tmp.hh.itemind = m; + fseek(fp,m*sizeof(tmp),SEEK_SET); + fwrite(&tmp,1,sizeof(tmp),fp); + expand_ipbits(hexstr,ipbits); + printf("create rwiAddrind m.%-4d %08x %s\n",m,(uint32_t)tmp.ipbits,hexstr); m++; coin->numiAddrs = m; - expand_ipbits(hexstr,ipbits); iguana_possible_peer(coin,hexstr); } - else + /*else { expand_ipbits(hexstr,ipbits); - printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)ipbits); + //printf("status.%d ipbits.%x\n",tmp.status,(uint32_t)ipbits); tmp.status = 0; fseek(fp,i * sizeof(tmp),SEEK_SET); if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) printf("error writing peer.%d\n",i); - } + }*/ portable_mutex_unlock(&coin->peers_mutex); - } else printf("skip.%d ipbits.%x\n",i,(uint32_t)ipbits); + } } fclose(fp); printf("i.%d m.%d numiAddrs.%d\n",i,m,coin->numiAddrs); @@ -210,7 +207,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); + printf("W status.%d ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA->status,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); } } } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); @@ -709,7 +706,7 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) //portable_mutex_unlock(&coin->peers_mutex); if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { - printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); + //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING ) { if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) @@ -774,7 +771,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) expand_ipbits(checkaddr,ipbits); if ( strcmp(checkaddr,ipaddr) == 0 ) { - printf("valid ipaddr.(%s) MAXPEERS.%d\n",ipaddr,coin->MAXPEERS); + //printf("valid ipaddr.(%s) MAXPEERS.%d\n",ipaddr,coin->MAXPEERS); if ( (iA= iguana_iAddrhashfind(coin,ipbits,1)) != 0 ) { if ( iA->status != IGUANA_PEER_CONNECTING && iA->status != IGUANA_PEER_READY && iA->status != IGUANA_PEER_ELIGIBLE ) From afae00e89f154bf6f055dbfe2e5c9a0eea7702ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 17:18:13 -0300 Subject: [PATCH 249/333] test --- iguana/iguana_peers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index e5ba089f6..8b648efea 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -207,7 +207,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - printf("W status.%d ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA->status,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); + //printf("W status.%d ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",iA->status,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); } } } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); @@ -711,7 +711,7 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) { - printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); + //printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); iA->status = IGUANA_PEER_CONNECTING; addr->pending = (uint32_t)time(NULL); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); From 1340bac101cb6105fa782e293b19e57d816e9ca9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:19:30 -0300 Subject: [PATCH 250/333] test --- iguana/iguana777.c | 22 +++++++++++++--------- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 7 ++++--- iguana/iguana_ramchain.c | 10 +++++----- iguana/iguana_unspents.c | 6 ++++-- iguana/main.c | 1 + 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index c8b663c46..dc75ef4ca 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -289,15 +289,19 @@ void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t ti void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 'V'; - ptr->starttime = (uint32_t)time(NULL); - ptr->timelimit = 0; - //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); - queue_enqueue("validateQ",&validateQ,&ptr->DL,0); + if ( bp->validated == 0 ) + { + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'V'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + bp->validated = 1; + //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("validateQ",&validateQ,&ptr->DL,0); + } } void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index e2200ce6b..18007859f 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -483,7 +483,7 @@ struct iguana_info uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; - struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; + struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; char lastdispstr[2048]; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2bfd7f3a7..cea2461d7 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1042,11 +1042,12 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"%s u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d) L.%d [%d:%d] M.%d %s",coin->symbol,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,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,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,"%s u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] Q.%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,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,coin->numbundlesQ,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)); //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+10 ) + if ( time(NULL) > coin->lastdisp+3 && strcmp(str,coin->lastdispstr) != 0 ) { - printf("%s\n",str); + printf("%s %d:%02d:%02d %03.3f\n",str,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis); + strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); coin->lastdisp = (uint32_t)time(NULL); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index f84669269..6596a218f 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2097,7 +2097,7 @@ void *iguana_bundlefile(struct iguana_info *coin,long *filesizep,struct iguana_b } if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) { - printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + //printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); return(0); } return(ptr); @@ -2320,12 +2320,13 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); iguana_ramchain_extras(coin,ramchain,hashmem,0); } - return(rdata->allocsize); + return(ramchain->H.data->allocsize); } 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) { int32_t firsti = 1; RAMCHAIN_DECLARE; + memset(mapchain,0,sizeof(*mapchain)); mapchain->fileptr = ptr; mapchain->filesize = filesize; mapchain->H.data = (void *)(long)((long)ptr + block->fpos); @@ -2338,8 +2339,7 @@ int32_t iguana_mapchaininit(struct iguana_info *coin,struct iguana_ramchain *map _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) { - printf("iguana_bundlesaveHT.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); - //getchar(); + printf("iguana_mapchaininit.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); return(-1); } else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) @@ -2380,7 +2380,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str bp_n = (endi - starti + 1); scriptspace = 1; sigspace = pubkeyspace = 0; - for (bundlei=starti,numtxids=numunspents=numspends=scriptspace=0; bundlei<=endi; bundlei++) + for (bundlei=starti,numtxids=numunspents=numspends=0; bundlei<=endi; bundlei++) { 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 ) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 718afb0d9..34b41e6af 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -819,6 +819,8 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) mult = (strcmp("BTC",coin->symbol) == 0) ? 2048 : 4; if ( coin->RTmem.ptr == 0 ) iguana_meminit(&coin->RTmem,coin->symbol,0,IGUANA_MAXPACKETSIZE*mult + 65536*3,0); + if ( coin->RThashmem.ptr == 0 ) + iguana_meminit(&coin->RThashmem,coin->symbol,0,IGUANA_MAXPACKETSIZE*mult + 65536*3,0); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; @@ -834,7 +836,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); - if ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight < coin->blocks.hwmchain.height) + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) { dest = &coin->RTramchain; B = (void *)(long)((long)rdata + rdata->Boffset); @@ -860,7 +862,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } return(-1); } - printf("added RTheight.%d hwm.%d longest.%d\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain); + char str[65]; printf("RTheight.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld %s\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize,mbstr(str,dest->H.data->allocsize)); coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); diff --git a/iguana/main.c b/iguana/main.c index 9fd74ed40..2d37d571d 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -358,6 +358,7 @@ void mainloop(struct supernet_info *myinfo) 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); myfree(ptr,ptr->allocsize); From afcbb50c4bf0351a4d078ebecd9cb90111ef655a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:22:16 -0300 Subject: [PATCH 251/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index cea2461d7..8386bff4d 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1042,11 +1042,11 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"%s u.%d b.%d v.%d/%d (%d/%d 1st.%d) to %d N[%d] Q.%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,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,coin->numbundlesQ,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)); + sprintf(str,"%s 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,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)); //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("%s %d:%02d:%02d %03.3f\n",str,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis); + printf("%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); strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); From afc3cbdd7b86344d847890c53d5012f62f550430 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:29:40 -0300 Subject: [PATCH 252/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_unspents.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 8386bff4d..9bbb8bb28 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1042,7 +1042,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) coin->spaceused = spaceused; coin->numverified = numv; char str4[65],str5[65]; - sprintf(str,"%s 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,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)); + 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)); //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 ) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 34b41e6af..28c89ef89 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -866,8 +866,13 @@ int32_t iguana_realtime_update(struct iguana_info *coin) coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); - } - } else return(-1); + } else printf("no ptr for RTheight.%d\n",coin->RTheight); + } + else + { + printf("no blockptr for RTheight.%d\n",coin->RTheight); + return(-1); + } } } return(0); From 7870ab876ce12decd59b56806eb13fe726e4748a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:36:50 -0300 Subject: [PATCH 253/333] test --- iguana/iguana_msg.c | 2 +- iguana/iguana_peers.c | 4 +++- iguana/iguana_unspents.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index dad820714..5794a5107 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -170,7 +170,7 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->dead = (uint32_t)time(NULL); if ( (vers->nServices & (1<<7)) == (1<<7) ) addr->supernet = 1; - else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); + //else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) coin->longestchain = vers->nStartingHeight; iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 8b648efea..d8882bb33 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -318,7 +318,9 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) if ( result != 0 ) { if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) - printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } if ( sock >= 0 ) closesocket(sock); return(-1); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 28c89ef89..59425d220 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -862,7 +862,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } return(-1); } - char str[65]; printf("RTheight.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld %s\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize,mbstr(str,dest->H.data->allocsize)); + char str[65]; printf(">>>> RTheight.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld %s\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize,mbstr(str,dest->H.data->allocsize)); coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); @@ -875,6 +875,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } } } + printf(" bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize && bp->hdrsi %d == %d coin->balanceswritten && coin->RTheight %d >= %d bp->bundleheight && coin->RTheight %d < %d bp->bundleheight+bp->n\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize,bp->hdrsi,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->RTheight,bp->bundleheight+bp->n); return(0); } From 03de0e50b45bccbae5834786964a28b56a5485c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:39:18 -0300 Subject: [PATCH 254/333] test --- iguana/main.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/iguana/main.c b/iguana/main.c index 2d37d571d..89f9f420f 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -353,15 +353,19 @@ void mainloop(struct supernet_info *myinfo) if ( 1 ) { for (i=0; iactive != 0 && (bp= coin->current) != 0 && coin->started != 0 ) + if ( (coin= Coins[i]) != 0 && coin->active != 0 && (bp= coin->current) != 0 ) { - iguana_realtime_update(coin); - if ( (ptr= queue_dequeue(&balancesQ,0)) != 0 ) + printf("check %s started.%p\n",coin->symbol,coin->started); + if ( coin->started != 0 ) { - flag++; - if ( ptr->coin != 0 && (bp= ptr->bp) != 0 ) - iguana_balancecalc(ptr->coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); - myfree(ptr,ptr->allocsize); + 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); + myfree(ptr,ptr->allocsize); + } } } } From 89484d1a130620f39f764cde6a2721dbd3214d98 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:47:52 -0300 Subject: [PATCH 255/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/iguana_unspents.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 6596a218f..878d78a9a 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1048,7 +1048,7 @@ int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace else { printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks,scriptspace)); - printf("NEED %ld realloc for %ld\n",(long)offset,(long)mem->totalsize); + printf("NEED %ld realloc for totalsize %ld\n",(long)offset,(long)mem->totalsize); getchar(); exit(-1); iguana_mempurge(mem); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 59425d220..10c37ace9 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -817,10 +817,11 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) if ( coin->RTramchain.H.data == 0 ) { mult = (strcmp("BTC",coin->symbol) == 0) ? 2048 : 4; + printf("mult.%d\n",mult); if ( coin->RTmem.ptr == 0 ) - iguana_meminit(&coin->RTmem,coin->symbol,0,IGUANA_MAXPACKETSIZE*mult + 65536*3,0); + iguana_meminit(&coin->RTmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); if ( coin->RThashmem.ptr == 0 ) - iguana_meminit(&coin->RThashmem,coin->symbol,0,IGUANA_MAXPACKETSIZE*mult + 65536*3,0); + iguana_meminit(&coin->RThashmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; From 392f00117dbdd88c50f48f5e826fe8e68b901590 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:50:13 -0300 Subject: [PATCH 256/333] test --- iguana/iguana_unspents.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 10c37ace9..e31372992 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -816,8 +816,7 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) int32_t mult; struct iguana_ramchain *dest = &coin->RTramchain; if ( coin->RTramchain.H.data == 0 ) { - mult = (strcmp("BTC",coin->symbol) == 0) ? 2048 : 4; - printf("mult.%d\n",mult); + mult = (strcmp("BTC",coin->symbol) == 0) ? 1024 : 4; if ( coin->RTmem.ptr == 0 ) iguana_meminit(&coin->RTmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); if ( coin->RThashmem.ptr == 0 ) @@ -876,7 +875,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } } } - printf(" bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize && bp->hdrsi %d == %d coin->balanceswritten && coin->RTheight %d >= %d bp->bundleheight && coin->RTheight %d < %d bp->bundleheight+bp->n\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize,bp->hdrsi,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->RTheight,bp->bundleheight+bp->n); + //printf(" bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize && bp->hdrsi %d == %d coin->balanceswritten && coin->RTheight %d >= %d bp->bundleheight && coin->RTheight %d < %d bp->bundleheight+bp->n\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize,bp->hdrsi,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->RTheight,bp->bundleheight+bp->n); return(0); } From aaca44394adfd58551ccabdc2e8fcf553594930f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 18:52:28 -0300 Subject: [PATCH 257/333] test --- iguana/iguana_unspents.c | 4 ++-- iguana/main.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index e31372992..f0881bffd 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -866,11 +866,11 @@ int32_t iguana_realtime_update(struct iguana_info *coin) coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); - } else printf("no ptr for RTheight.%d\n",coin->RTheight); + } //else printf("no ptr for RTheight.%d\n",coin->RTheight); } else { - printf("no blockptr for RTheight.%d\n",coin->RTheight); + //printf("no blockptr for RTheight.%d\n",coin->RTheight); return(-1); } } diff --git a/iguana/main.c b/iguana/main.c index 89f9f420f..60ba2e764 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -355,7 +355,6 @@ void mainloop(struct supernet_info *myinfo) for (i=0; iactive != 0 && (bp= coin->current) != 0 ) { - printf("check %s started.%p\n",coin->symbol,coin->started); if ( coin->started != 0 ) { iguana_realtime_update(coin); From 52fe7deed0e7c64fa00c3f5ee0c782a12a5de1a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 19:04:36 -0300 Subject: [PATCH 258/333] test --- iguana/iguana_unspents.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f0881bffd..f351b0306 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -813,9 +813,33 @@ void iguana_RTramchainfree(struct iguana_info *coin) void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t mult; struct iguana_ramchain *dest = &coin->RTramchain; + int32_t mult,i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; + if ( coin->RTramchain.H.data != 0 ) + { + changed = (rand() % 1000) == 0; + if ( coin->RTheight != bp->bundleheight + coin->RTramchain.H.data->numblocks ) + changed++; + else + { + B = (void *)(long)((long)coin->RTramchain.H.data + coin->RTramchain.H.data->Boffset); + for (i=0; iRTramchain.H.data->numblocks; i++) + if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) + { + printf("mismatched hash2 at %d\n",bp->bundleheight+i); + changed++; + break; + } + } + if ( changed != 0 ) + { + printf("RTramchain changed %d\n",coin->RTheight); + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + } + iguana_RTramchainfree(coin); + } if ( coin->RTramchain.H.data == 0 ) { + printf("ALLOC RTramchain\n"); mult = (strcmp("BTC",coin->symbol) == 0) ? 1024 : 4; if ( coin->RTmem.ptr == 0 ) iguana_meminit(&coin->RTmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); From 1f8aa678dbe02cae98330628afa5004df9d55d09 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 19:13:28 -0300 Subject: [PATCH 259/333] test --- iguana/iguana_unspents.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f351b0306..a5b554fbe 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -813,10 +813,9 @@ void iguana_RTramchainfree(struct iguana_info *coin) void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t mult,i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; + uint32_t size,i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; if ( coin->RTramchain.H.data != 0 ) { - changed = (rand() % 1000) == 0; if ( coin->RTheight != bp->bundleheight + coin->RTramchain.H.data->numblocks ) changed++; else @@ -840,11 +839,11 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) if ( coin->RTramchain.H.data == 0 ) { printf("ALLOC RTramchain\n"); - mult = (strcmp("BTC",coin->symbol) == 0) ? 1024 : 4; + size = (strcmp("BTC",coin->symbol) == 0) ? 1.5*1024*1024*1024 : 16*1024*1024; if ( coin->RTmem.ptr == 0 ) - iguana_meminit(&coin->RTmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); - if ( coin->RThashmem.ptr == 0 ) - iguana_meminit(&coin->RThashmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); + iguana_meminit(&coin->RTmem,coin->symbol,0,size + 65536*3,0); + //if ( coin->RThashmem.ptr == 0 ) + // iguana_meminit(&coin->RThashmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; From a0fd6b7dd12bde3eba4b4804bec5e26f15bc41a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 19:16:08 -0300 Subject: [PATCH 260/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index a5b554fbe..2ccc01b64 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -842,8 +842,8 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) size = (strcmp("BTC",coin->symbol) == 0) ? 1.5*1024*1024*1024 : 16*1024*1024; if ( coin->RTmem.ptr == 0 ) iguana_meminit(&coin->RTmem,coin->symbol,0,size + 65536*3,0); - //if ( coin->RThashmem.ptr == 0 ) - // iguana_meminit(&coin->RThashmem,coin->symbol,0,(uint64_t)IGUANA_MAXPACKETSIZE*mult + 65536*3,0); + if ( coin->RThashmem.ptr == 0 ) + iguana_meminit(&coin->RThashmem,coin->symbol,0,65536*3,0); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; From 2f91ac8afa6ea3d465c9ad0d1b1e8aa11e2a3070 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 19:17:13 -0300 Subject: [PATCH 261/333] test --- iguana/iguana_unspents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 2ccc01b64..d8bd5964a 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -842,9 +842,9 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) size = (strcmp("BTC",coin->symbol) == 0) ? 1.5*1024*1024*1024 : 16*1024*1024; if ( coin->RTmem.ptr == 0 ) iguana_meminit(&coin->RTmem,coin->symbol,0,size + 65536*3,0); - if ( coin->RThashmem.ptr == 0 ) - iguana_meminit(&coin->RThashmem,coin->symbol,0,65536*3,0); - iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); + //if ( coin->RThashmem.ptr == 0 ) + // iguana_meminit(&coin->RThashmem,coin->symbol,0,65536*3,0); + iguana_ramchainopen(coin,dest,&coin->RTmem,0,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; dest->H.scriptoffset = 1; From 48e16812d085601c628dbab13955290fdf4fcf5a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 19:17:44 -0300 Subject: [PATCH 262/333] test --- iguana/iguana_ramchain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 878d78a9a..a6036ca37 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2291,7 +2291,8 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram { RAMCHAIN_DECLARE; int32_t i,numblocks = 0; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; mem->alignflag = sizeof(uint32_t); - hashmem->alignflag = sizeof(uint32_t); + if ( hashmem != 0 ) + hashmem->alignflag = sizeof(uint32_t); scriptspace = numexternaltxids = numtxids = coin->chain->bundlesize * 2; numunspents = numspends = numpkinds = numtxids * 2; for (i=0; ibundlescount; i++) From fcb1874fed49c7095fb166f65755c6493e303c27 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 20:28:41 -0300 Subject: [PATCH 263/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_ramchain.c | 24 ++++++++++++------ iguana/iguana_unspents.c | 53 +++++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 18007859f..e1b87e140 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -812,7 +812,7 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); -void *iguana_bundlefile(struct iguana_info *coin,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); +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); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index a6036ca37..b03df9772 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -2086,9 +2086,9 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p return(num); } -void *iguana_bundlefile(struct iguana_info *coin,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) { - int32_t checki,hdrsi; char fname[1024]; void *ptr = 0; static bits256 zero; + int32_t checki,hdrsi; void *ptr = 0; static bits256 zero; *filesizep = 0; if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { @@ -2105,10 +2105,10 @@ void *iguana_bundlefile(struct iguana_info *coin,long *filesizep,struct iguana_b int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp,int32_t starti,int32_t endi) { - int32_t bundlei,num = 0; + int32_t bundlei,num = 0; char fname[1024]; for (bundlei=starti; bundlei<=endi; bundlei++) { - if ( (ptrs[num]= iguana_bundlefile(coin,&filesizes[num],bp,bundlei)) != 0 ) + if ( (ptrs[num]= iguana_bundlefile(coin,fname,&filesizes[num],bp,bundlei)) != 0 ) num++; else return(bp == coin->current ? num : 0); //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); @@ -2289,10 +2289,10 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) { - RAMCHAIN_DECLARE; int32_t i,numblocks = 0; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; + RAMCHAIN_DECLARE; int32_t i,numblocks = coin->chain->bundlesize; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t hashsize,allocsize; + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; mem->alignflag = sizeof(uint32_t); - if ( hashmem != 0 ) - hashmem->alignflag = sizeof(uint32_t); + hashmem->alignflag = sizeof(uint32_t); scriptspace = numexternaltxids = numtxids = coin->chain->bundlesize * 2; numunspents = numspends = numpkinds = numtxids * 2; for (i=0; ibundlescount; i++) @@ -2313,6 +2313,16 @@ int64_t iguana_ramchainopen(struct iguana_info *coin,struct iguana_ramchain *ram } numtxids *= 1.5; numexternaltxids *= 1.5, scriptspace *= 1.5; numunspents *= 1.5, numspends *= 1.5, numpkinds *= 1.5; + if ( mem->ptr == 0 ) + { + allocsize = _iguana_rdata_action(0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + iguana_meminit(mem,coin->symbol,0,allocsize + 65536*3,0); + } + if ( hashmem->ptr == 0 ) + { + hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); + iguana_meminit(hashmem,coin->symbol,0,hashsize + 65536*3,0); + } if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) { iguana_ramchain_link(ramchain,hash2,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d8bd5964a..54ca6ec94 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -813,9 +813,10 @@ void iguana_RTramchainfree(struct iguana_info *coin) void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { - uint32_t size,i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; + uint32_t i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; if ( coin->RTramchain.H.data != 0 ) { + i = 0; if ( coin->RTheight != bp->bundleheight + coin->RTramchain.H.data->numblocks ) changed++; else @@ -824,27 +825,22 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) for (i=0; iRTramchain.H.data->numblocks; i++) if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) { - printf("mismatched hash2 at %d\n",bp->bundleheight+i); + char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); changed++; break; } } if ( changed != 0 ) { - printf("RTramchain changed %d\n",coin->RTheight); + printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight, coin->RTramchain.H.data->numblocks); coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_RTramchainfree(coin); } - iguana_RTramchainfree(coin); } if ( coin->RTramchain.H.data == 0 ) { printf("ALLOC RTramchain\n"); - size = (strcmp("BTC",coin->symbol) == 0) ? 1.5*1024*1024*1024 : 16*1024*1024; - if ( coin->RTmem.ptr == 0 ) - iguana_meminit(&coin->RTmem,coin->symbol,0,size + 65536*3,0); - //if ( coin->RThashmem.ptr == 0 ) - // iguana_meminit(&coin->RThashmem,coin->symbol,0,65536*3,0); - iguana_ramchainopen(coin,dest,&coin->RTmem,0,bp->bundleheight,bp->hashes[0]); + iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; dest->H.scriptoffset = 1; @@ -853,9 +849,9 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_realtime_update(struct iguana_info *coin) { - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err; - struct iguana_block *block; struct iguana_blockRO *B; struct iguana_ramchain *dest,blockR; - long filesize; void *ptr; + 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 ) { iguana_RTramchainalloc(coin,bp); @@ -864,31 +860,34 @@ int32_t iguana_realtime_update(struct iguana_info *coin) dest = &coin->RTramchain; B = (void *)(long)((long)rdata + rdata->Boffset); bundlei = (coin->RTheight % coin->chain->bundlesize); - if ( (block= bp->blocks[bundlei]) != 0 ) + if ( (block= bp->blocks[bundlei]) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) { iguana_blocksetcounters(coin,block,dest); - coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; B[bundlei] = block->RO; - if ( (ptr= iguana_bundlefile(coin,&filesize,bp,bundlei)) != 0 ) + if ( (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) { if ( iguana_mapchaininit(coin,&blockR,bp,bundlei,block,ptr,filesize) == 0 ) { - if ( (err= iguana_ramchain_iterate(coin,dest,&blockR,bp)) != 0 ) + if ( (err= iguana_ramchain_iterate(coin,dest,&blockR,bp)) != 0 || bits256_cmp(blockR.H.data->firsthash2,block->RO.hash2) != 0 ) { - printf("error adding height.%d\n",bp->bundleheight+bundlei); + printf("ERRO [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + printf("mapped.%s\n",bits256_str(str,blockR.H.data->firsthash2)); if ( (block= bp->blocks[bundlei]) != 0 ) { block->queued = 0; block->fpipbits = 0; bp->issued[bundlei] = 0; block->issued = 0; + OS_removefile(fname,0); } return(-1); } - char str[65]; printf(">>>> RTheight.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld %s\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize,mbstr(str,dest->H.data->allocsize)); + flag++; coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); + iguana_ramchain_free(coin,&blockR,1); } //else printf("no ptr for RTheight.%d\n",coin->RTheight); } else @@ -898,7 +897,21 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } } } - //printf(" bp->hdrsi %d == %d coin->longestchain/coin->chain->bundlesize && bp->hdrsi %d == %d coin->balanceswritten && coin->RTheight %d >= %d bp->bundleheight && coin->RTheight %d < %d bp->bundleheight+bp->n\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize,bp->hdrsi,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->RTheight,bp->bundleheight+bp->n); + if ( dest != 0 && flag != 0 ) + { + n = 0; + while ( block != 0 ) + { + if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) + { + printf("blockhash error at %d\n",coin->RTheight-n-1); + break; + } + block = iguana_blockfind(coin,block->RO.prev_block); + n++; + } + 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); } From 79c6e79eec2f16880c0299ff3688227197f35de6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 22:23:09 -0300 Subject: [PATCH 264/333] test --- iguana/iguana777.c | 4 +- iguana/iguana_bundles.c | 4 +- iguana/iguana_peers.c | 4 +- iguana/iguana_unspents.c | 96 +++++++++++++++++++++++++++++++--------- 4 files changed, 81 insertions(+), 27 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index dc75ef4ca..122f5908c 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -486,8 +486,8 @@ void iguana_coinloop(void *arg) { //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers + iguana_bundlestats(coin,str); } - iguana_bundlestats(coin,str); flag += iguana_processrecv(coin); if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); @@ -495,7 +495,7 @@ void iguana_coinloop(void *arg) } } if ( flag == 0 ) - usleep(10000); + usleep(100000); } } diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 9bbb8bb28..d198691ad 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -583,7 +583,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) { if ( bp == coin->current ) - printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + printf("[%d:%d] ",bp->hdrsi,i); iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); bp->issued[i] = now; counter++; @@ -1046,7 +1046,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) //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("%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 %03.3f\n",str,coin->numbundlesQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis); strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index d8882bb33..2d9e342c3 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1068,8 +1068,8 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) usleep(100000); } else if ( addr->rank != 1 ) - usleep(coin->polltimeout*3000 + 1*(rand() % (coin->polltimeout*3000))); - else usleep(1000); + usleep(coin->polltimeout*5000 + 1*(rand() % (coin->polltimeout*3000))); + else usleep(10000); } else run >>= 2; } if ( flag != 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 54ca6ec94..604b1d15e 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -60,7 +60,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t } return(0); } - printf("unexpected utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); + printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); @@ -82,16 +82,8 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc { struct iguana_unspent *u,*spentU; struct iguana_account *A2; int32_t flag,errs=0; struct iguana_utxo *utxo,*Uextras; uint32_t pkind; - if ( incremental == 0 ) - { - Uextras = spentbp->ramchain.Uextras; - A2 = spentbp->ramchain.A; - } - else - { - Uextras = 0; - A2 = 0; - } + Uextras = spentbp->ramchain.Uextras; + A2 = spentbp->ramchain.A; if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) { spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); @@ -370,9 +362,8 @@ uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; - int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; uint32_t unspentind; - struct iguana_bundle *spentbp; struct iguana_blockRO *B; - FILE *fp; char fname[1024],str[65]; + int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; uint32_t unspentind,now; + struct iguana_bundle *spentbp; struct iguana_blockRO *B; FILE *fp; char fname[1024],str[65]; bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; @@ -401,6 +392,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) } for (j=0; jhdrsi,s)) != 0 ) { - /*if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } - spentbp->dirty++;*/ + spentbp->dirty++; if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) { ptr[emit].hdrsi = spentbp->hdrsi; @@ -580,7 +572,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else continue; if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( 0 && (now > spentbp->lastprefetch || (spentbp->dirty % 50000) == 0) ) + if ( 1 && (now > spentbp->lastprefetch+10 || (spentbp->dirty % 50000) == 0) ) { iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; @@ -808,6 +800,7 @@ int32_t iguana_volatileinit(struct iguana_info *coin) void iguana_RTramchainfree(struct iguana_info *coin) { + iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables iguana_ramchain_free(coin,&coin->RTramchain,1); } @@ -847,6 +840,65 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) } } +int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) +{ + struct iguana_txid *nextT,*T; int32_t spendind,txidind,j,k; struct iguana_bundle *spentbp; + uint32_t unspentind,ind; struct iguana_blockRO *B; struct iguana_spend *S,*s; bits256 prevhash; + if ( RTramchain->H.data == 0 || RTramchain->H.data->numspends < 1 ) + return(0); + B = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Boffset); + S = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Soffset); + nextT = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Toffset); + txidind = B[bundlei].firsttxidind; + spendind = B[bundlei].firstvin; + for (j=0; jexternal != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,RTramchain,bp->hdrsi,s)) == 0 || unspentind == 0 || unspentind >= RTramchain->H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) + { + char str[65]; + printf("RTutxogen: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+bundlei,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + return(-1); + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[ind].firstvout + s->prevout; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("RTutxogen txidind overflow %u vs %u\n",ind,spentbp->ramchain.H.data->numtxids); + return(-1); + } + } + else continue; + if ( spentbp != 0 && unspentind != 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + { + if ( iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) + { + printf("iguana_volatileupdate error h.%d spendind.%d spent.%d u.%d\n",bp->bundleheight+bundlei,spendind,spentbp->hdrsi,unspentind); + return(-1); + } + } + } + } + return(0); +} + int32_t iguana_realtime_update(struct iguana_info *coin) { struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err,n,flag=0; @@ -871,7 +923,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) { if ( (err= iguana_ramchain_iterate(coin,dest,&blockR,bp)) != 0 || bits256_cmp(blockR.H.data->firsthash2,block->RO.hash2) != 0 ) { - printf("ERRO [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + printf("ERROR [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); printf("mapped.%s\n",bits256_str(str,blockR.H.data->firsthash2)); if ( (block= bp->blocks[bundlei]) != 0 ) { @@ -884,6 +936,8 @@ int32_t iguana_realtime_update(struct iguana_info *coin) return(-1); } flag++; + if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) + return(-1); coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); @@ -908,7 +962,8 @@ int32_t iguana_realtime_update(struct iguana_info *coin) break; } block = iguana_blockfind(coin,block->RO.prev_block); - n++; + if ( n++ >= bp->n ) + break; } 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); } @@ -1029,11 +1084,10 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu bp->ramchain.allocatedU = 0; } if ( iguana_mapvolatiles(coin,&bp->ramchain) != 0 ) - printf("error mapping bundle.[%d]\n",hdrsi); + 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)); coin->balanceswritten = iguana_volatileinit(coin); - iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables iguana_RTramchainfree(coin); return(coin->balanceswritten); } From 3bc504a1ebf0e919a76bff2f0f6b5d5516033b05 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 24 Mar 2016 23:01:14 -0300 Subject: [PATCH 265/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index e1b87e140..3ab599a30 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -//#define IGUANA_SERIALIZE_BALANCEGEN +#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d198691ad..c488a572f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -769,7 +769,9 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; +#ifndef IGUANA_SERIALIZE_BALANCEGEN if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) +#endif { if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); From de0588d000b43650accbd64af1443da610606fb9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 00:07:38 -0300 Subject: [PATCH 266/333] test --- iguana/iguana_bundles.c | 10 +++++----- iguana/main.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c488a572f..d15200e3f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -987,11 +987,6 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } else { - if ( ++pending == coin->MAXBUNDLES ) - { - lastpending = bp; - //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); - } if ( firstgap == 0 && (bp->emitfinish == 0 || bp->n < coin->chain->bundlesize) ) { //printf("firstgap <- [%d] emit.%u bp->n.%d\n",bp->hdrsi,bp->emitfinish,bp->n); @@ -999,6 +994,11 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } if ( bp->emitfinish == 0 ) { + if ( ++pending == coin->MAXBUNDLES ) + { + lastpending = bp; + //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); + } spaceused += bp->estsize; //sortbuf[m*2] = bp->metric; //sortbuf[m*2 + 1] = i; diff --git a/iguana/main.c b/iguana/main.c index 60ba2e764..7cccb541c 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1132,7 +1132,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":64,\"endpend\":64,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From 45016d454db1356207d92a688f89d8085513b444 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 00:22:24 -0300 Subject: [PATCH 267/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d15200e3f..272a9136f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -503,7 +503,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { - if ( numpeers > 64 || addr->laggard++ > 13 ) + if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) addr->dead = (uint32_t)time(NULL); for (j=0; jn; j++) { From dd6b8ac942cd27e11ea1dcc649031868a1f77329 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 01:38:10 -0300 Subject: [PATCH 268/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_unspents.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 3ab599a30..e1b87e140 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -#define IGUANA_SERIALIZE_BALANCEGEN +//#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 604b1d15e..474bcbd57 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -407,7 +407,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + if ( now > spentbp->lastprefetch+60 || (spentbp->dirty % 150000) == 0 ) { //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); @@ -572,7 +572,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else continue; if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( 1 && (now > spentbp->lastprefetch+10 || (spentbp->dirty % 50000) == 0) ) + if ( 1 && (now > spentbp->lastprefetch+60 || (spentbp->dirty % 150000) == 0) ) { iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; From b93da5458b2ea426ef094976d04dfbd08454c39c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 01:56:34 -0300 Subject: [PATCH 269/333] test --- iguana/iguana_unspents.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 474bcbd57..ebdbf1721 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -872,6 +872,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i } else if ( s->prevout >= 0 ) { + printf("s.%p bp.%p data.%p\n",s,bp,spentbp->ramchain.H.data); spentbp = bp; if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) { From f617d77104c482840629ec7b53fe017016f295d9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 12:47:03 -0300 Subject: [PATCH 270/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ebdbf1721..329d02ad3 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -889,7 +889,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i else continue; if ( spentbp != 0 && unspentind != 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) + if ( 0 && iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) { printf("iguana_volatileupdate error h.%d spendind.%d spent.%d u.%d\n",bp->bundleheight+bundlei,spendind,spentbp->hdrsi,unspentind); return(-1); From 3db076a0bba0dc9062be91bd844aa64c12d3107d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 12:52:10 -0300 Subject: [PATCH 271/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 329d02ad3..198ff9d93 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -870,7 +870,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i return(-1); } } - else if ( s->prevout >= 0 ) + else if ( 0 && s->prevout >= 0 ) { printf("s.%p bp.%p data.%p\n",s,bp,spentbp->ramchain.H.data); spentbp = bp; @@ -889,7 +889,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i else continue; if ( spentbp != 0 && unspentind != 0 && unspentind < spentbp->ramchain.H.data->numunspents ) { - if ( 0 && iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) + if ( iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) { printf("iguana_volatileupdate error h.%d spendind.%d spent.%d u.%d\n",bp->bundleheight+bundlei,spendind,spentbp->hdrsi,unspentind); return(-1); From 86565e605c0ee29cfce55d36bf9346a79353ba4a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 16:04:32 -0300 Subject: [PATCH 272/333] test --- iguana/iguana777.h | 21 ++- iguana/iguana_bundles.c | 2 +- iguana/iguana_peers.c | 10 +- iguana/iguana_ramchain.c | 48 ++--- iguana/iguana_unspents.c | 384 +++++++++++++++++++-------------------- 5 files changed, 225 insertions(+), 240 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index e1b87e140..d581cb2bc 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -325,26 +325,27 @@ struct iguana_ledger //struct iguana_account accounts[]; } __attribute__((packed)); -// ramchain append only structs -> canonical 32bit inds and ledgerhashes -struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,ipbits; uint8_t rmd160[20]; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; uint32_t sequenceid,scriptpos; int16_t prevout; uint16_t vinscriptlen,spendind,ipbits; } __attribute__((packed)); +// ramchain temp file structures +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_spend256 { bits256 prevhash2; uint32_t sequenceid,scriptpos; int16_t prevout; uint16_t vinscriptlen,spendind,fileid; } __attribute__((packed)); +// permanent readonly structs struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos,ipbits; uint16_t hdrsi,type:4,scriptlen:14; int16_t vout; } __attribute__((packed)); +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t fileid,scriptlen; uint16_t hdrsi:11,type:5; int16_t vout; } __attribute__((packed)); -struct iguana_spend { uint32_t spendtxidind,sequenceid,scriptpos,ipbits; int16_t prevout; uint16_t scriptlen:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 +struct iguana_spend { uint32_t spendtxidind,sequenceid,scriptpos; int16_t prevout; uint16_t fileid,scriptlen:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset // dynamic -struct iguana_account { int64_t total; uint32_t lastind; } __attribute__((packed)); -struct iguana_utxo { uint64_t prevunspentind:26,height:24,spentflag:1,tbd:13; } __attribute__((packed)); +struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); +struct iguana_utxo { uint32_t fromheight,prevunspentind:31,spentflag:1; } __attribute__((packed)); struct iguana_hhaccount { UT_hash_handle hh; uint8_t buf[6]; struct iguana_account a; } __attribute__((packed)); struct iguana_hhutxo { UT_hash_handle hh; uint8_t buf[6]; struct iguana_utxo u; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_spendvector { uint64_t hdrsi:14,ind:26,height:24; } __attribute__((packed)); // unspentind +struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; uint16_t hdrsi,bundlei; } __attribute__((packed)); // unspentind //struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind struct iguana_txblock @@ -475,7 +476,7 @@ struct iguana_info 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; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis; 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; @@ -788,7 +789,7 @@ uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8 int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); -int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 272a9136f..bee5113f2 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -784,7 +784,7 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->startutxo == 0 ) { bp->startutxo = (uint32_t)time(NULL); - if ( (retval= iguana_utxogen(coin,bp)) >= 0 ) + if ( (retval= iguana_spendvectors(coin,bp)) >= 0 ) { if ( retval > 0 ) { diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 2d9e342c3..a43b2bf6c 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -959,8 +959,8 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr) void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf;//,serialized[64]; - uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; + struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf; uint32_t ipbits; + int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; for (i=0; iSEROUT)/sizeof(*addr->SEROUT); i++) @@ -976,19 +976,19 @@ 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,"DB/%s/vouts/%08x.vouts",coin->symbol,ipbits); + sprintf(fname,"DB/%s/vouts/%04d.vouts",coin->symbol,addr->addrind); if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->voutsfp,0,SEEK_END); else addr->voutsfp = fopen(fname,"wb+"); if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) { - sprintf(fname,"purgeable/%s/%08x.vins",coin->symbol,ipbits); + sprintf(fname,"purgeable/%s/%04d.vins",coin->symbol,addr->addrind); if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->vinsfp,0,SEEK_END); else addr->vinsfp = fopen(fname,"wb+"); } //addr->pubkey = GENESIS_PUBKEY; + ipbits = (uint32_t)addr->ipbits; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); addr->maxfilehash2 = IGUANA_MAXFILEITEMS; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index b03df9772..5d88ef289 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -461,7 +461,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee V.spendlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,V.spendscript,asmstr,u->rmd160,type,(const struct vin_info *)&V,vout); if ( (V.spendlen != scriptlen || memcmp(V.spendscript,script,scriptlen) != 0) && addr != 0 && addr->voutsfp != 0 ) { - u->ipbits = (uint32_t)addr->ipbits; + u->fileid = (uint32_t)addr->addrind; u->scriptpos = (uint32_t)ftell(addr->voutsfp); if ( fwrite(script,1,scriptlen,addr->voutsfp) != scriptlen ) printf("error writing scriptlen.%d\n",scriptlen); @@ -470,7 +470,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee else { u->scriptpos = 0; - u->ipbits = 0; + u->fileid = 0; } } else u->scriptpos = 0; u->txidind = ramchain->H.txidind; @@ -478,7 +478,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee return(unspentind); } -uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint32_t ipbits,uint32_t fpos,int32_t scriptlen) +uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint16_t fileid,uint32_t fpos,int32_t scriptlen) { uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t pkind;//,checklen,metalen; uint8_t _script[IGUANA_MAXSCRIPTSIZE],*checkscript; unspentind = ramchain->H.unspentind++; @@ -502,9 +502,9 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); } //else printf("RO spendscript match.%d\n",scriptlen); }*/ - if ( u->ipbits != ipbits || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastind) || u->vout != vout || u->hdrsi != hdrsi ) + if ( u->fileid != fileid || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) { - printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->ipbits,u->scriptpos,u->scriptlen,ipbits,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastind,vout,hdrsi); + printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->fileid,u->scriptpos,u->scriptlen,fileid,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); exit(-1); return(0); } @@ -517,15 +517,15 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 //else pubkeyoffset = 0; u->vout = vout, u->hdrsi = hdrsi; u->txidind = ramchain->H.txidind, u->pkind = pkind; - u->prevunspentind = A[pkind].lastind; - u->ipbits = ipbits; + u->prevunspentind = A[pkind].lastunspentind; + u->fileid = fileid; u->scriptlen = scriptlen; u->scriptpos = fpos; u->type = type; } //printf("%p A[%d] last <- U%d\n",&A[pkind],pkind,unspentind); A[pkind].total += value; - A[pkind].lastind = unspentind; + A[pkind].lastunspentind = unspentind; return(unspentind); } @@ -579,7 +579,7 @@ int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txi return(-2); } -uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint32_t ipbits,uint32_t scriptpos,int32_t vinscriptlen) +uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint16_t fileid,uint32_t scriptpos,int32_t vinscriptlen) { struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; @@ -657,7 +657,7 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 s->sequenceid = sequence; s->external = external, s->spendtxidind = txidind, s->prevout = prev_vout; - s->ipbits = ipbits; + s->fileid = fileid; s->scriptpos = scriptpos; s->scriptlen = vinscriptlen; /*static uint64_t good,bad; @@ -724,7 +724,7 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer s->spendind = spendind; if ( (s->vinscriptlen= vinscriptlen) > 0 && vinscript != 0 && addr != 0 && addr->vinsfp != 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE) { - s->ipbits = (uint32_t)addr->ipbits; + s->fileid = (uint32_t)addr->addrind; s->scriptpos = (uint32_t)ftell(addr->vinsfp); if ( fwrite(vinscript,1,vinscriptlen,addr->vinsfp) != vinscriptlen ) printf("error writing vinscriptlen.%d\n",vinscriptlen); @@ -1260,7 +1260,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * { if ( memcmp(&ramchain->A[k],&ramchain->creditsA[k],sizeof(ramchain->A[k])) != 0 ) { - printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastind,ramchain->creditsA[k].lastind); + printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastunspentind,ramchain->creditsA[k].lastunspentind); //return(-14); } //if ( memcmp(&ramchain->P2[k],&ramchain->roP2[k],sizeof(ramchain->P2[k])) != 0 ) @@ -1614,7 +1614,7 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { RAMCHAIN_DECLARE; RAMCHAIN_DESTDECLARE; - int32_t j,hdrsi,prevout,scriptlen; uint32_t scriptpos,ipbits,sequenceid,destspendind=0,desttxidind=0; + int32_t j,hdrsi,prevout,scriptlen; uint32_t scriptpos,sequenceid,destspendind=0,desttxidind=0; uint16_t fileid; bits256 prevhash; uint64_t value; uint8_t type; struct iguana_unspent *u; struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *rmd160; //if ( dest != 0 ) @@ -1654,7 +1654,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } for (j=0; jnumvouts; j++) { - ipbits = 0; + fileid = 0; scriptpos = 0; scriptlen = 0; if ( ramchain->H.unspentind < rdata->numunspents ) @@ -1665,7 +1665,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = u->value; hdrsi = u->hdrsi; type = u->type; - ipbits = u->ipbits; + fileid = u->fileid; scriptpos = u->scriptpos; scriptlen = u->scriptlen; if ( u->pkind < rdata->numpkinds ) @@ -1677,7 +1677,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); }*/ //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,scriptpos,scriptlen) == 0 ) return(-3); } } @@ -1687,7 +1687,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = U[ramchain->H.unspentind].value; rmd160 = U[ramchain->H.unspentind].rmd160; type = U[ramchain->H.unspentind].type & 0xf; - ipbits = U[ramchain->H.unspentind].ipbits; + fileid = U[ramchain->H.unspentind].fileid; scriptpos = U[ramchain->H.unspentind].scriptpos; scriptlen = U[ramchain->H.unspentind].scriptlen; /*if ( U[ramchain->H.unspentind].scriptoffset != 0 ) @@ -1710,7 +1710,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain if ( dest != 0 ) { //fprintf(stderr,"dest add %p[%d] type.%d offset.%d vs %d\n",scriptdata,scriptlen,type,dest->H.scriptoffset,dest->H.data->scriptspace); - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,fileid,scriptpos,scriptlen) == 0 ) return(-5); } //else printf("addunspent20 done\n"); } else return(-6); @@ -1733,19 +1733,19 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain tx = &T[ramchain->H.txidind]; for (j=0; jnumvins; j++) { - ipbits = 0; + fileid = 0; scriptpos = 0; scriptlen = 0; if ( ramchain->expanded != 0 ) { - ipbits = Sx[ramchain->H.spendind].ipbits; + fileid = Sx[ramchain->H.spendind].fileid; scriptpos = Sx[ramchain->H.spendind].scriptpos; scriptlen = Sx[ramchain->H.spendind].scriptlen; //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,&Sx[ramchain->H.spendind]); //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); //fprintf(stderr,"from expanded iter\n"); - if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) { char str[65]; printf("hdrsi.%d txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",bp->bundleheight,ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); @@ -1762,7 +1762,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain sequenceid = S[ramchain->H.spendind].sequenceid; prevhash = S[ramchain->H.spendind].prevhash2; prevout = S[ramchain->H.spendind].prevout; - ipbits = S[ramchain->H.spendind].ipbits; + fileid = S[ramchain->H.spendind].fileid; scriptpos = S[ramchain->H.spendind].scriptpos; scriptlen = S[ramchain->H.spendind].vinscriptlen; /*if ( S[ramchain->H.spendind].scriptoffset != 0 ) @@ -1781,7 +1781,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) { - if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) return(-9); //printf("from dest iter scriptspace.%d\n",dest->H.stacksize); } @@ -2391,7 +2391,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str bp_n = (endi - starti + 1); scriptspace = 1; sigspace = pubkeyspace = 0; - for (bundlei=starti,numtxids=numunspents=numspends=0; bundlei<=endi; bundlei++) + for (bundlei=starti,numtxids=numunspents=scriptspace=numspends=0; bundlei<=endi; bundlei++) { 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 ) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 198ff9d93..fbad8b85e 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -34,7 +34,7 @@ struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint16_t return(hhacct); } -int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,int32_t hdrsi,uint32_t spendind,uint32_t height) +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) { struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; @@ -60,7 +60,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t } return(0); } - printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),hdrsi,height%coin->chain->bundlesize,spendind); + printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),fromheight/coin->chain->bundlesize,fromheight%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) return(-1); hhutxo = calloc(1,sizeof(*hhutxo)); @@ -71,71 +71,44 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); } hhutxo->u.spentflag = 1; - hhutxo->u.height = height; - hhutxo->u.prevunspentind = hhacct->a.lastind; - hhacct->a.lastind = spent_unspentind; + hhutxo->u.fromheight = fromheight; + hhutxo->u.prevunspentind = hhacct->a.lastunspentind; + hhacct->a.lastunspentind = spent_unspentind; hhacct->a.total += spent_value; return(0); } -int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t height,uint32_t spendind,struct iguana_bundle *spentbp,uint32_t unspentind) +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) { - struct iguana_unspent *u,*spentU; struct iguana_account *A2; - int32_t flag,errs=0; struct iguana_utxo *utxo,*Uextras; uint32_t pkind; - Uextras = spentbp->ramchain.Uextras; - A2 = spentbp->ramchain.A; - if ( incremental != 0 || (A2 != 0 && Uextras != 0) ) + struct iguana_account *A2; struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo; + if ( (rdata= ramchain->H.data) != 0 ) { - spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); - u = &spentU[unspentind]; - if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) + if ( incremental == 0 ) { - flag = -1; - if ( incremental == 0 ) + A2 = ramchain->A; + if ( ramchain->Uextras != 0 && A2 != 0 ) { - if ( Uextras == 0 || A2 == 0 ) + utxo = &ramchain->Uextras[spent_unspentind]; + if ( utxo->spentflag == 0 ) { - printf("null ptrs.[%d] %p %p\n",spentbp->hdrsi,spentbp->ramchain.Uextras,spentbp->ramchain.A); - errs++; + utxo->prevunspentind = A2[spent_pkind].lastunspentind; + utxo->spentflag = 1; + utxo->fromheight = fromheight; + A2[spent_pkind].total += spent_value; + A2[spent_pkind].lastunspentind = spent_unspentind; + return(0); } - else - { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - { - utxo->prevunspentind = A2[pkind].lastind; - utxo->spentflag = 1; - utxo->height = height; - A2[pkind].total += u->value; - A2[pkind].lastind = unspentind; - flag = 0; - } - } - } - else - { - if ( bp != spentbp ) - { - utxo = &Uextras[unspentind]; - if ( utxo->spentflag == 0 ) - flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); - } - else flag = iguana_utxoupdate(coin,spentbp->hdrsi,unspentind,pkind,u->value,bp->hdrsi,spendind,height); - } - if ( flag != 0 ) - { - errs++; - printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d\n",pkind,spentbp->hdrsi,unspentind); - getchar(); - } + } else printf("null ptrs.[%d] u.%u p.%u %.8f from ht.%d s.%u\n",spent_hdrsi,spent_unspentind,spent_pkind,dstr(spent_value),fromheight,spendind); } - else + else // do the equivalent of historical, ie mark as spent, linked list, balance { - errs++; - printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) + return(0); } + printf("iguana_volatileupdate: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d\n",spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); + exit(-1); } - return(-errs); + 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) @@ -158,7 +131,7 @@ struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_r { *ramchainp = ramchain; *balancep = ACCTS[pkind].total; - *lastunspentindp = ACCTS[pkind].lastind; + *lastunspentindp = ACCTS[pkind].lastunspentind; *p = P[pkind]; return(p); } //else printf("not found pkind.%d vs num.%d\n",pkind,ramchain->H.data->numpkinds); @@ -191,7 +164,7 @@ char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) } return(clonestr("{\"error\":\"no bundle\"}")); } -struct iguana_bundle *iguana_spent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spend_hdrsi,struct iguana_spend *s) +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]; struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; @@ -231,7 +204,7 @@ struct iguana_bundle *iguana_spent(struct iguana_info *coin,bits256 *prevhashp,u if ( hdrsi > spend_hdrsi || (spentbp= coin->bundles[hdrsi]) == 0 ) printf("illegal hdrsi.%d when [%d] spentbp.%p\n",hdrsi,spend_hdrsi,spentbp);//, getchar(); //else if ( spentbp->ramchain.spents[unspentind].ind != 0 || hdrsi < 0 ) - // printf("DOUBLE SPEND? U%d %p bp.[%d] unspentind.%u already has %u, no room\n",unspentind,&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spentbp->ramchain.spents[unspentind].ind);//, getchar(); + // printf("DOUBLE SPEND? U%d %p bp.[%d] unspentind.%u already has %u, no room\n",unspentind,&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spentbp->ramchain.spents[unspentind].ind);//, getchar(); else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) printf("illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi);//, getchar(); else return(spentbp); @@ -359,15 +332,16 @@ uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array return(rmdarray); } -int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; - int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; uint32_t unspentind,now; + int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; long fsize; + uint32_t spent_unspentind,spent_pkind,now; struct iguana_bundle *spentbp; struct iguana_blockRO *B; FILE *fp; char fname[1024],str[65]; - bits256 prevhash,zero,sha256; struct iguana_unspent *u; long fsize; struct iguana_txid *nextT; + bits256 prevhash,zero,sha256; struct iguana_unspent *u,*spentU; struct iguana_txid *nextT; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; - //printf("UTXO gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); + //printf("iguana_spendvectors gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) return(0); B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); @@ -375,7 +349,7 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); if ( ramchain->Xspendinds != 0 ) { - //printf("iguana_utxogen: already have Xspendinds[%d]\n",ramchain->numXspends); + //printf("iguana_spendvectors: already have Xspendinds[%d]\n",ramchain->numXspends); return(0); } ptr = mycalloc('x',sizeof(*ptr),n); @@ -405,41 +379,48 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) u = 0; if ( s->external != 0 && s->prevout >= 0 ) { - if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s)) != 0 && spentbp->ramchain.H.data != 0 ) { - if ( now > spentbp->lastprefetch+60 || (spentbp->dirty % 150000) == 0 ) + if ( spentbp == bp ) + { + char str[65]; + printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + errs++; + } + if ( now > spentbp->lastprefetch+60 || (spentbp->dirty % 100000) == 0 ) { - //printf("u current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } spentbp->dirty++; - if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < spentbp->ramchain.H.data->numpkinds ) { - ptr[emit].hdrsi = spentbp->hdrsi; - ptr[emit].height = bp->bundleheight + i; - //ptr[emit].txi = j; - //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); - emit++; + + if ( (ptr[emit].unspentind= spent_unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + { + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].pkind = spent_pkind; + ptr[emit].value = u->value; + ptr[emit].bundlei = i; + //ptr[emit].txi = j; + //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); + emit++; + } + else + { + printf("spendvectors: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); + errs++; + } } else { - printf("utxogen: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); - errs++; - } - if ( spentbp == bp ) - { - char str[65]; - printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; + printf("spendvectors: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; } } - else - { - errs++; - printf("utxogen: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); - break; - } } } } @@ -460,27 +441,24 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) memset(zero.bytes,0,sizeof(zero)); sprintf(fname,"DB/%s/spends/%s.%d",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); - //if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + if ( (fp= fopen(fname,"wb")) != 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; + fsize = ftell(fp); + fclose(fp); + if ( iguana_Xspendmap(coin,ramchain,bp) < 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; - fsize = ftell(fp); - fclose(fp); - if ( iguana_Xspendmap(coin,ramchain,bp) < 0 ) - { - printf("error mapping Xspendmap.(%s)\n",fname); - retval = -1; - } - //int32_t i; for (i=0; inumXspends; i++) - // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); - //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); - } else printf("Error creating.(%s)\n",fname); - } + printf("error mapping Xspendmap.(%s)\n",fname); + retval = -1; + } + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + } else printf("Error creating.(%s)\n",fname); } if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); @@ -492,26 +470,28 @@ int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t unspentind,txidind,h,i,j,k,ind,now; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; struct iguana_blockRO *B; - int32_t hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_spend *S,*s; + uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,k,now; uint64_t spent_value; + struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; + struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; + struct iguana_txid *T,*nextT; struct iguana_blockRO *B; + int32_t spent_hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_spend *S,*s; ramchain = &bp->ramchain; if ( startheight == bp->bundleheight && endheight == bp->bundleheight+bp->n-1 ) incremental = 0; else incremental = 1; - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) - return(0); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); - nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) + return(-1); + S = (void *)(long)((long)rdata + rdata->Soffset); + B = (void *)(long)((long)rdata + rdata->Boffset); + nextT = (void *)(long)((long)rdata + rdata->Toffset); if ( ramchain->Xspendinds == 0 ) { printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); - return(0); + return(-1); } iguana_ramchain_prefetch(coin,ramchain); printf("BALANCEGEN.%d hdrs.%d\n",bp->bundleheight,bp->hdrsi); - txidind = spendind = ramchain->H.data->firsti; + txidind = spendind = rdata->firsti; for (i=0; in; i++) { //printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); @@ -532,59 +512,54 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 for (k=0; kexternal != 0 && s->prevout >= 0 ) { if ( emit >= ramchain->numXspends ) errs++; else { - h = ramchain->Xspendinds[emit].height; - unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi < bp->hdrsi ) - spentbp = coin->bundles[hdrsi]; - else - { - printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); - errs++; - } - //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + spend = &ramchain->Xspendinds[emit]; + spent_value = spend->value; + spent_pkind = spend->pkind; + spent_unspentind = spend->unspentind; + spent_hdrsi = spend->hdrsi; + h = spend->bundlei + (spent_hdrsi * coin->chain->bundlesize); emit++; } } else if ( s->prevout >= 0 ) { - spentbp = bp; h = bp->bundleheight + i; - if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) + spent_hdrsi = bp->hdrsi; + if ( s->spendtxidind != 0 && s->spendtxidind < rdata->numtxids ) { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[ind].firstvout + s->prevout; + T = (void *)(long)((long)rdata + rdata->Toffset); + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; + spentU = (void *)(long)((long)rdata + rdata->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < rdata->numpkinds ) + spent_value = u->value; //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); } else { - printf("iguana_balancegen txidind overflow %u vs %u\n",ind,spentbp->ramchain.H.data->numtxids); + printf("iguana_balancegen [%d] txidind overflow %u vs %u\n",bp->hdrsi,s->spendtxidind,rdata->numtxids); errs++; } } else continue; - if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + if ( spent_unspentind > 0 && spent_pkind > 0 ) { - if ( 1 && (now > spentbp->lastprefetch+60 || (spentbp->dirty % 150000) == 0) ) - { - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; - } - spentbp->dirty++; - if ( iguana_volatileupdate(coin,incremental,bp,h,spendind,spentbp,unspentind) < 0 ) + if ( iguana_volatileupdate(coin,incremental,ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) errs++; } else { errs++; - printf("iguana_balancegen: error with unspentind.%d vs max.%d spentbp.%p\n",unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1,spentbp); + printf("iguana_balancegen: error with unspentind.%d [%d]\n",spent_unspentind,spent_hdrsi); } } } @@ -608,6 +583,69 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 return(-errs); } +int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) +{ + struct iguana_txid *T,*spentT; int32_t height,spendind,txidind,j,k; bits256 prevhash; + struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; + struct iguana_ramchaindata *RTdata; + uint32_t spent_unspentind; struct iguana_blockRO *B; struct iguana_spend *S,*s; + if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) + { + printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); + return(0); + } + B = (void *)(long)((long)RTdata + RTdata->Boffset); + S = (void *)(long)((long)RTdata + RTdata->Soffset); + T = (void *)(long)((long)RTdata + RTdata->Toffset); + txidind = B[bundlei].firsttxidind; + spendind = B[bundlei].firstvin; + height = bp->bundleheight + bundlei; + for (j=0; jexternal != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s)) == 0 || spent_unspentind == 0 || spent_unspentind >= RTdata->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) + { + char str[65]; + printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + return(-1); + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + if ( spentbp->ramchain.H.data != 0 && s->spendtxidind != 0 && s->spendtxidind < spentbp->ramchain.H.data->numtxids ) + { + spentT = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + spent_unspentind = spentT[s->spendtxidind].firstvout + s->prevout; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("RTutxo txidind overflow %u vs %u\n",s->spendtxidind,spentbp->ramchain.H.data != 0?spentbp->ramchain.H.data->numtxids:-1); + return(-1); + } + } + else return(0); // coinbase always already spent + if ( spentbp != 0 && spentbp->ramchain.H.data != 0 && spent_unspentind != 0 && spent_unspentind < spentbp->ramchain.H.data->numunspents ) + { + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[spent_unspentind]; + return(iguana_volatileupdate(coin,1,RTramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height)); + } + } + } + return(-1); +} + void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) { if ( ramchain->allocatedA != 0 && ramchain->A != 0 ) @@ -800,7 +838,7 @@ int32_t iguana_volatileinit(struct iguana_info *coin) void iguana_RTramchainfree(struct iguana_info *coin) { - iguana_utxoupdate(coin,-1,0,0,0,-1,0,-1); // free hashtables + iguana_utxoupdate(coin,-1,0,0,0,0,-1); // free hashtables iguana_ramchain_free(coin,&coin->RTramchain,1); } @@ -840,66 +878,6 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) } } -int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) -{ - struct iguana_txid *nextT,*T; int32_t spendind,txidind,j,k; struct iguana_bundle *spentbp; - uint32_t unspentind,ind; struct iguana_blockRO *B; struct iguana_spend *S,*s; bits256 prevhash; - if ( RTramchain->H.data == 0 || RTramchain->H.data->numspends < 1 ) - return(0); - B = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Boffset); - S = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Soffset); - nextT = (void *)(long)((long)RTramchain->H.data + RTramchain->H.data->Toffset); - txidind = B[bundlei].firsttxidind; - spendind = B[bundlei].firstvin; - for (j=0; jexternal != 0 && s->prevout >= 0 ) - { - if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,RTramchain,bp->hdrsi,s)) == 0 || unspentind == 0 || unspentind >= RTramchain->H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) - { - char str[65]; - printf("RTutxogen: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+bundlei,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); - return(-1); - } - } - else if ( 0 && s->prevout >= 0 ) - { - printf("s.%p bp.%p data.%p\n",s,bp,spentbp->ramchain.H.data); - spentbp = bp; - if ( (ind= s->spendtxidind) != 0 && ind < spentbp->ramchain.H.data->numtxids ) - { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[ind].firstvout + s->prevout; - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("RTutxogen txidind overflow %u vs %u\n",ind,spentbp->ramchain.H.data->numtxids); - return(-1); - } - } - else continue; - if ( spentbp != 0 && unspentind != 0 && unspentind < spentbp->ramchain.H.data->numunspents ) - { - if ( iguana_volatileupdate(coin,1,bp,bp->bundleheight+bundlei,spendind,spentbp,unspentind) < 0 ) - { - printf("iguana_volatileupdate error h.%d spendind.%d spent.%d u.%d\n",bp->bundleheight+bundlei,spendind,spentbp->hdrsi,unspentind); - return(-1); - } - } - } - } - return(0); -} - int32_t iguana_realtime_update(struct iguana_info *coin) { struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,err,n,flag=0; @@ -963,9 +941,15 @@ int32_t iguana_realtime_update(struct iguana_info *coin) break; } block = iguana_blockfind(coin,block->RO.prev_block); - if ( n++ >= bp->n ) + n++; + if ( coin->RTgenesis != 0 && n >= bp->n ) break; } + if ( coin->RTgenesis == 0 && n == coin->RTheight ) + { + 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); } return(0); From f50915617d9af04d47f88b0a7220d04737d89552 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 16:06:10 -0300 Subject: [PATCH 273/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 122f5908c..0e563e5ef 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -524,7 +524,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; if ( (coin->MAXPENDING= maxpending) <= 0 ) - coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 64*_IGUANA_MAXPENDING; + coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 4*_IGUANA_MAXPENDING; coin->myservices = services; printf("ensure directories\n"); sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); From 4c93b55ffa2fb150bdfe27423cba69c0e1584a20 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 16:13:16 -0300 Subject: [PATCH 274/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 2 +- iguana/iguana_unspents.c | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index d581cb2bc..ec0b9e360 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -//#define IGUANA_SERIALIZE_BALANCEGEN +#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index bee5113f2..824ed9a57 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -769,7 +769,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -#ifndef IGUANA_SERIALIZE_BALANCEGEN +#ifndef IGUANA_SERIALIZE_SPENDVECTORGEN if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) #endif { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index fbad8b85e..cd6e635db 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1079,7 +1079,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi,int32_t pu int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) { - uint32_t starttime,j,flag = 0; struct iguana_bundle *prevbp; + uint32_t starttime,j=0,flag = 0; struct iguana_bundle *prevbp; if ( bp->balancefinish > 1 ) { printf("make sure DB files have this bp.%d\n",bp->hdrsi); @@ -1088,10 +1088,23 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } if ( bp != 0 && coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { - for (j=0; jhdrsi; j++) +#ifdef IGUANA_SERIALIZE_BALANCEGEN + for (j=0; jbundlescount; j++) { - if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) + { + j = -1; break; + } + } +#endif + if ( j == 0 ) + { + for (; jhdrsi; j++) + { + if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) + break; + } } if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { From 92303a74f7d74c5519f6b79470f62f22b1e179a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 17:41:52 -0300 Subject: [PATCH 275/333] test --- iguana/iguana_blocks.c | 4 +++- iguana/iguana_bundles.c | 41 +++++++++++++++++++--------------------- iguana/iguana_recv.c | 10 +++++----- iguana/iguana_unspents.c | 3 ++- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index e4b85d431..219fe020b 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -270,10 +270,12 @@ int32_t iguana_blockunmain(struct iguana_info *coin,struct iguana_block *block) struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_block *newblock) { int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0,*next; - bits256 *hash2p=0; double prevPoW = 0.; + bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp; if ( newblock == 0 ) return(0); hwmchain = &coin->blocks.hwmchain; + if ( hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi) ) + return(0); if ( (block= iguana_blockfind(coin,newblock->RO.hash2)) != 0 ) { if ( memcmp(coin->chain->genesis_hashdata,block->RO.hash2.bytes,sizeof(bits256)) == 0 ) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 824ed9a57..a2204f617 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -227,13 +227,16 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo } else { -//char str[65]; printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d)\n",bits256_str(str,hash2),bp->bundleheight,bundlei); + char str[65]; block->hdrsi = bp->hdrsi; block->bundlei = bundlei; bp->hashes[bundlei] = block->RO.hash2; if ( bp->speculative != 0 && bundlei < bp->numspec ) bp->speculative[bundlei] = bp->hashes[bundlei]; - bp->blocks[bundlei] = block; + if ( bp->blocks[bundlei] == 0 ) + bp->blocks[bundlei] = block; + else if ( bp->blocks[bundlei] != block ) + printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d) block.%p there\n",bits256_str(str,hash2),bp->bundleheight,bundlei,bp->blocks[bundlei]); otherbp = 0; if ( (otherbp= iguana_bundlefind(coin,&otherbp,&otherbundlei,hash2)) != 0 || (bundlei % (bundlesize-1)) == 0) { @@ -399,17 +402,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int starti = coin->current->hdrsi; else starti = 0; priority = (bp->hdrsi < starti + coin->peers.numranked); - /*lag = (bp->hdrsi - starti); - lag *= lag; - if ( (i= sqrt(bp->hdrsi)) < 2 ) - i = 2; - if ( lag < i ) - lag = i; - else if ( lag > 10*i ) - lag = 10*i;*/ if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 30; - else lag = 3; + lag = 30 + (bp->hdrsi - starti); + else lag = 3 + (bp->hdrsi - starti)/10; if ( (numpeers= coin->peers.numranked) > 3 )//&& bp->currentflag < bp->n ) { if ( numpeers > 0xff ) @@ -517,7 +512,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int bp->issued[i] = block->issued = now; } } - printf("slow peer.%d dead.%u (%s) reissued.%d\n",i,addr->dead,addr->ipaddr,flag); + printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); } } } @@ -550,8 +545,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } - if ( bp == coin->current ) - return(counter); + //if ( bp == coin->current ) + // return(counter); } for (i=0; in; i++) { @@ -600,17 +595,19 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) 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 ) + if ( iguana_blockvalidate(coin,&valid,block,1) < 0 || block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1)) == i ) + fname[0] = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,block->RO.hash2,zero,1)) != i ) + printf("checki.%d vs %d mismatch?\n",checki,i); + if ( fname[0] != 0 ) OS_removefile(fname,0); - char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue %s\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname); + char str[65]; printf(">>>>>>> ipbits.%x block contents error at ht.%d\n",bp->bundleheight+i); + //patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); block->fpipbits = 0; block->fpos = -1; block->queued = 0; block->RO.recvlen = 0; - memset(bp->hashes[i].bytes,0,sizeof(bp->hashes[i])); - bp->blocks[i] = 0; //iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1); } else ready++; } else printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); @@ -621,12 +618,12 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) { int32_t counter=0; - //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); int32_t i; uint32_t now; if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; + if ( bp == coin->current ) + 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); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } if ( bp->speculative != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index afa166a53..865b3e076 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -508,7 +508,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; bits256 *blockhashes,allhash; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; + int32_t i,bundlei,match; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; if ( blocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); @@ -516,7 +516,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig } if ( blocks != 0 && n > 0 ) { - if ( 0 && n >= coin->chain->bundlesize ) + /*if ( 0 && n >= coin->chain->bundlesize ) { blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); for (i=0; ichain->bundlesize; i++) @@ -540,7 +540,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig } } free(blockhashes); - } + }*/ for (i=match=0; i 0 ) { coin->backstopmillis = OS_milliseconds(); - iguana_blockQ("mainchain",coin,0,-1,hash2,lag > 100 * threshold); + iguana_blockQ("mainchain",coin,0,-1,hash2,lag > threshold); flag++; char str[65]; if ( 1 && (rand() % 1000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) @@ -1012,7 +1012,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { int32_t j; - memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + //memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); bp->blocks[bundlei] = 0; for (j=0; j<1&&bundlei+j+1n; j++) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index cd6e635db..9029fd761 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -387,8 +387,9 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; } - if ( now > spentbp->lastprefetch+60 || (spentbp->dirty % 100000) == 0 ) + if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 10000) == 0 ) { + printf("prefetch[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } From 2ec5403d06de2320cf40e088c9de883c27abdc1e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 17:42:20 -0300 Subject: [PATCH 276/333] test --- iguana/iguana_bundles.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a2204f617..c9230f384 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -602,8 +602,8 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) printf("checki.%d vs %d mismatch?\n",checki,i); if ( fname[0] != 0 ) OS_removefile(fname,0); - char str[65]; printf(">>>>>>> ipbits.%x block contents error at ht.%d\n",bp->bundleheight+i); - //patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + printf(">>>>>>> block contents error at ht.%d\n",bp->bundleheight+i); + //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); block->fpipbits = 0; block->fpos = -1; block->queued = 0; From f32bdb5839d064626444d7c0238a103c39b97601 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 17:47:10 -0300 Subject: [PATCH 277/333] test --- iguana/iguana_unspents.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9029fd761..b3b6fecb4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -336,17 +336,17 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) { static uint64_t total,emitted; int32_t spendind,n,txidind,errs=0,emit=0,i,j,k,retval = -1; long fsize; - uint32_t spent_unspentind,spent_pkind,now; + uint32_t spent_unspentind,spent_pkind,now; struct iguana_ramchaindata *rdata; struct iguana_bundle *spentbp; struct iguana_blockRO *B; FILE *fp; char fname[1024],str[65]; - bits256 prevhash,zero,sha256; struct iguana_unspent *u,*spentU; struct iguana_txid *nextT; + bits256 prevhash,zero,sha256; struct iguana_unspent *u,*spentU; struct iguana_txid *T; struct iguana_spend *S,*s; struct iguana_spendvector *ptr; struct iguana_ramchain *ramchain; ramchain = &bp->ramchain; //printf("iguana_spendvectors gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) + if ( (rdata= ramchain->H.data) == 0 || (n= rdata->numspends) < 1 ) return(0); - B = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Boffset); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + B = (void *)(long)((long)rdata + rdata->Boffset); + S = (void *)(long)((long)rdata + rdata->Soffset); + T = (void *)(long)((long)rdata + rdata->Toffset); if ( ramchain->Xspendinds != 0 ) { //printf("iguana_spendvectors: already have Xspendinds[%d]\n",ramchain->numXspends); @@ -355,7 +355,8 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) ptr = mycalloc('x',sizeof(*ptr),n); total += n; //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); - txidind = spendind = ramchain->H.data->firsti; + txidind = spendind = rdata->firsti; + iguana_ramchain_prefetch(coin,ramchain); for (i=0; in; i++) { if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) @@ -367,13 +368,13 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) for (j=0; jbundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; } - if ( now > spentbp->lastprefetch+10 || (spentbp->dirty % 10000) == 0 ) + if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 10000) == 0 ) { printf("prefetch[%d]\n",spentbp->hdrsi); iguana_ramchain_prefetch(coin,&spentbp->ramchain); From c37a8a8c50124a5e82abe09d78919c0f023139ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 17:49:42 -0300 Subject: [PATCH 278/333] test --- iguana/iguana_unspents.c | 2 +- iguana/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index b3b6fecb4..55fa4f56d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -390,7 +390,7 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) } if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 10000) == 0 ) { - printf("prefetch[%d]\n",spentbp->hdrsi); + printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } diff --git a/iguana/main.c b/iguana/main.c index 7cccb541c..60ba2e764 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1132,7 +1132,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":64,\"endpend\":64,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From dcb63f5865ff9fbc7e0a2426e3ccade727a568f9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 17:53:25 -0300 Subject: [PATCH 279/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 55fa4f56d..4c48eb7c5 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -388,9 +388,9 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; } - if ( now > spentbp->lastprefetch+10 )//|| (spentbp->dirty % 10000) == 0 ) + if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 10000) == 0 ) { - printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } From 33d31a37f83feea210fbc7518e59ca27442f236b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:12:24 -0300 Subject: [PATCH 280/333] test --- iguana/iguana777.c | 2 +- iguana/iguana_bundles.c | 5 +++-- iguana/iguana_peers.c | 2 +- iguana/iguana_unspents.c | 2 +- iguana/main.c | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 0e563e5ef..406140bf1 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -317,7 +317,7 @@ void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->balancefinish == 0 ) bp->balancefinish = 1; coin->pendbalances++; - //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); } diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index c9230f384..89d53f1b2 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -789,14 +789,15 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) bp->utxofinish = (uint32_t)time(NULL); bp->balancefinish = 0; } - if ( bp->balancefinish <= 1 ) + if ( bp->balancefinish == 0 ) iguana_balancesQ(coin,bp); return(1); } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); } else if ( bp->utxofinish != 0 ) { - iguana_balancesQ(coin,bp); + if ( bp->balancefinish == 0 ) + iguana_balancesQ(coin,bp); return(1); } } // else printf("%u notready postfinish.%d startutxo.%u prevbp.%d %u current.%d\n",(uint32_t)time(NULL),bp->hdrsi,bp->startutxo,prevbp!=0?prevbp->hdrsi:-1,prevbp!=0?prevbp->emitfinish:0,coin->current!=0?coin->current->hdrsi:-1); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index a43b2bf6c..70c487efd 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -137,7 +137,7 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana fseek(fp,m*sizeof(tmp),SEEK_SET); fwrite(&tmp,1,sizeof(tmp),fp); expand_ipbits(hexstr,ipbits); - printf("create rwiAddrind m.%-4d %08x %s\n",m,(uint32_t)tmp.ipbits,hexstr); + //printf("create rwiAddrind m.%-4d %08x %s\n",m,(uint32_t)tmp.ipbits,hexstr); m++; coin->numiAddrs = m; iguana_possible_peer(coin,hexstr); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 4c48eb7c5..d0c1dadef 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1091,7 +1091,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int if ( bp != 0 && coin != 0 && (bp->hdrsi == 0 || (prevbp= coin->bundles[bp->hdrsi-1]) != 0) ) { #ifdef IGUANA_SERIALIZE_BALANCEGEN - for (j=0; jbundlescount; j++) + for (j=0; jbundlescount-1; j++) { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 ) { diff --git a/iguana/main.c b/iguana/main.c index 60ba2e764..4fd416d32 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1132,7 +1132,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":512,\"endpend\":512,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":2048,\"endpend\":2048,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From 3da233bd9a64f822427eb60249d8423669aa412c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:13:40 -0300 Subject: [PATCH 281/333] test --- iguana/iguana777.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 406140bf1..0e563e5ef 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -317,7 +317,7 @@ void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) if ( bp->balancefinish == 0 ) bp->balancefinish = 1; coin->pendbalances++; - printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); } From b5d48e86f5db298946f1ae9a6b48259f4b6a2ff9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:17:31 -0300 Subject: [PATCH 282/333] test --- iguana/iguana_unspents.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d0c1dadef..55f704be4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1100,14 +1100,19 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } } #endif + printf("A [%d] j.%d\n",bp->hdrsi,j); if ( j == 0 ) { for (; jhdrsi; j++) { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) + { + j = -1 break; + } } } + printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { starttime = (uint32_t)time(NULL); From 774b42f5a7966ef3471016adf6e094bdc3cffe54 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:17:43 -0300 Subject: [PATCH 283/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 55f704be4..ba0c0e167 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1107,7 +1107,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) { - j = -1 + j = -1; break; } } From 309785133c7f22d39106b62a1a5d6665dca54155 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:19:41 -0300 Subject: [PATCH 284/333] test --- iguana/iguana_unspents.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ba0c0e167..a88c6a8e2 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1100,10 +1100,9 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } } #endif - printf("A [%d] j.%d\n",bp->hdrsi,j); - if ( j == 0 ) + if ( j != -1 ) { - for (; jhdrsi; j++) + for (j=0; jhdrsi; j++) { if ( (prevbp= coin->bundles[j]) == 0 || prevbp->utxofinish <= 1 || prevbp->balancefinish <= 1 ) { From 9fcd5dac0544b51f372db419677c3fb6f05392b1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:38:25 -0300 Subject: [PATCH 285/333] test --- iguana/iguana_unspents.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index a88c6a8e2..589a12228 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -97,11 +97,12 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc A2[spent_pkind].total += spent_value; A2[spent_pkind].lastunspentind = spent_unspentind; return(0); - } + } else printf("spent_unspentind[%d] in hdrs.[%d] is spent\n",spent_unspentind,spent_hdrsi); } else printf("null ptrs.[%d] u.%u p.%u %.8f from ht.%d s.%u\n",spent_hdrsi,spent_unspentind,spent_pkind,dstr(spent_value),fromheight,spendind); } else // do the equivalent of historical, ie mark as spent, linked list, balance { + printf("call RT utxo\n"); if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) return(0); } @@ -475,17 +476,14 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,k,now; uint64_t spent_value; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; - struct iguana_txid *T,*nextT; struct iguana_blockRO *B; - int32_t spent_hdrsi,spendind,n,errs=0,incremental,emit=0; struct iguana_spend *S,*s; + struct iguana_txid *T; struct iguana_blockRO *B; + int32_t spent_hdrsi,spendind,n,errs=0,emit=0; struct iguana_spend *S,*s; ramchain = &bp->ramchain; - if ( startheight == bp->bundleheight && endheight == bp->bundleheight+bp->n-1 ) - incremental = 0; - else incremental = 1; if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) return(-1); S = (void *)(long)((long)rdata + rdata->Soffset); B = (void *)(long)((long)rdata + rdata->Boffset); - nextT = (void *)(long)((long)rdata + rdata->Toffset); + T = (void *)(long)((long)rdata + rdata->Toffset); if ( ramchain->Xspendinds == 0 ) { printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); @@ -496,7 +494,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 txidind = spendind = rdata->firsti; for (i=0; in; i++) { - //printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); + printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); @@ -505,13 +503,13 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 for (j=0; jhdrsi; if ( s->spendtxidind != 0 && s->spendtxidind < rdata->numtxids ) { - T = (void *)(long)((long)rdata + rdata->Toffset); spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; spentU = (void *)(long)((long)rdata + rdata->Uoffset); u = &spentU[spent_unspentind]; @@ -555,7 +552,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 else continue; if ( spent_unspentind > 0 && spent_pkind > 0 ) { - if ( iguana_volatileupdate(coin,incremental,ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) + if ( iguana_volatileupdate(coin,0,ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) errs++; } else @@ -1111,7 +1108,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } } } - printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); + //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { starttime = (uint32_t)time(NULL); From f26a46dec7178875e03cbefe69478a328323377f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:44:53 -0300 Subject: [PATCH 286/333] test --- iguana/iguana_unspents.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 589a12228..7b67e7b8b 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -78,17 +78,17 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t return(0); } -int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +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; - if ( (rdata= ramchain->H.data) != 0 ) + if ( (rdata= spentchain->H.data) != 0 ) { if ( incremental == 0 ) { - A2 = ramchain->A; - if ( ramchain->Uextras != 0 && A2 != 0 ) + A2 = spentchain->A; + if ( spentchain->Uextras != 0 && A2 != 0 ) { - utxo = &ramchain->Uextras[spent_unspentind]; + utxo = &spentchain->Uextras[spent_unspentind]; if ( utxo->spentflag == 0 ) { utxo->prevunspentind = A2[spent_pkind].lastunspentind; @@ -476,7 +476,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,k,now; uint64_t spent_value; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; - struct iguana_txid *T; struct iguana_blockRO *B; + struct iguana_txid *T; struct iguana_blockRO *B; struct iguana_bundle *spentbp; int32_t spent_hdrsi,spendind,n,errs=0,emit=0; struct iguana_spend *S,*s; ramchain = &bp->ramchain; if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) @@ -550,9 +550,9 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 } } else continue; - if ( spent_unspentind > 0 && spent_pkind > 0 ) + if ( spent_unspentind > 0 && spent_pkind > 0 && (spentbp= coin->bundles[spent_hdrsi]) != 0 ) { - if ( iguana_volatileupdate(coin,0,ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) + if ( iguana_volatileupdate(coin,0,&spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) errs++; } else @@ -638,7 +638,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i { spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); u = &spentU[spent_unspentind]; - return(iguana_volatileupdate(coin,1,RTramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height)); + return(iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height)); } } } From 9c2613b617245460200a884d41a48274d65b25ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 18:49:46 -0300 Subject: [PATCH 287/333] test --- iguana/iguana_unspents.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 7b67e7b8b..f6f6ee99d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -102,7 +102,6 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else // do the equivalent of historical, ie mark as spent, linked list, balance { - printf("call RT utxo\n"); if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) return(0); } @@ -494,7 +493,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 txidind = spendind = rdata->firsti; for (i=0; in; i++) { - printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); + //printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) { printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); @@ -508,7 +507,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 printf("balancegen: txidind %u != %u T[txidind].firsttxidind || spendind %u != %u T[txidind].firstvin errs.%d\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin,errs); return(-1); } - printf("txidind.%d txi.%d numvins.%d spendind.%d\n",txidind,j,T[txidind].numvins,spendind); + //printf("txidind.%d txi.%d numvins.%d spendind.%d\n",txidind,j,T[txidind].numvins,spendind); for (k=0; k Date: Fri, 25 Mar 2016 18:54:56 -0300 Subject: [PATCH 288/333] test --- iguana/iguana777.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index ec0b9e360..e617ce50f 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,8 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -#define IGUANA_SERIALIZE_BALANCEGEN +//#define IGUANA_SERIALIZE_SPENDVECTORGEN +//#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 From f8817df4e2d69a686b67a9d49b5ce4feb37ef708 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 20:50:12 -0300 Subject: [PATCH 289/333] test --- iguana/iguana777.c | 16 ++++++--- iguana/iguana777.h | 1 + iguana/iguana_bundles.c | 59 ++++++++++++++++++++---------- iguana/iguana_peers.c | 2 +- iguana/iguana_recv.c | 77 ++++++++++++++++++++++++---------------- iguana/iguana_unspents.c | 10 +++--- 6 files changed, 106 insertions(+), 59 deletions(-) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 0e563e5ef..aa33ad6f4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -340,6 +340,7 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m } else if ( ptr->type == 'B' ) { + printf("helper bundleiters\n"); iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); } else if ( ptr->type == 'E' ) @@ -358,7 +359,7 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m void iguana_helper(void *arg) { - FILE *fp = 0; cJSON *argjson=0; int32_t type,helperid=rand(),flag,idle=0; + FILE *fp = 0; cJSON *argjson=0; int32_t type,helperid=rand(),flag,allcurrent,idle=0; struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) helperid = juint(argjson,"helperid"); @@ -375,6 +376,7 @@ void iguana_helper(void *arg) { //iguana_jsonQ(); cant do this here flag = 0; + allcurrent = 1; if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) { if ( ptr->bp != 0 && (coin= ptr->coin) != 0 ) @@ -387,7 +389,7 @@ void iguana_helper(void *arg) } myfree(ptr,ptr->allocsize); } - if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) { idle = 0; if ( (bp= ptr->bp) != 0 && (coin= ptr->coin) != 0 ) @@ -396,6 +398,8 @@ void iguana_helper(void *arg) if ( coin->started != 0 && time(NULL) >= bp->nexttime ) flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit); 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); myfree(ptr,ptr->allocsize); flag++; @@ -412,8 +416,10 @@ void iguana_helper(void *arg) } } if ( flag == 0 ) - usleep(1000000); - else usleep(100000); + usleep(100000); + else if ( allcurrent != 0 ) + usleep(25000); + else usleep(2500); } } @@ -452,7 +458,7 @@ void iguana_coinloop(void *arg) now = (uint32_t)time(NULL); if ( coin->active != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+200 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) + 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 ) { fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); coin->isRT = 1; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index e617ce50f..d6d74ab19 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -816,6 +816,7 @@ void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); 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); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 89d53f1b2..d0424be6b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -390,7 +390,7 @@ void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) { - int32_t i,j,k,len,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard,flag=0,finished,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; + int32_t i,j,k,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard,flag=0,finished,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; struct iguana_peer *addr; uint32_t now; struct iguana_block *block; bits256 hashes[50]; uint8_t serialized[sizeof(hashes) + 256]; if ( bp == 0 ) @@ -430,8 +430,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( block->fpipbits == 0 ) { hashes[k++] = bp->hashes[i]; - bp->issued[i] = now; - block->issued = now; + bp->issued[i] = block->issued = now; block->peerid = j + 1; block->numrequests++; } @@ -509,7 +508,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int counter++; block->peerid = 0; iguana_blockQ("kick",coin,bp,j,block->RO.hash2,bp == coin->current); - bp->issued[i] = block->issued = now; + if ( bp == coin->current ) + bp->issued[i] = block->issued = now; } } printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); @@ -531,22 +531,29 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( now > block->issued+lag ) { counter++; + saved = block->issued; + if ( bp == coin->current ) + forceflag = (now > block->issued + lag); + else forceflag = (now > block->issued + 3*lag); if ( priority != 0 ) { //printf("[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); - if ( bp == coin->current && now > block->issued+lag*3 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,forceflag); + if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,now > block->issued+lag*3); + } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); + if ( forceflag != 0 ) + bp->issued[i] = block->issued = now; + else bp->issued[i] = block->issued = saved; flag++; } //else printf("%d ",now - block->issued); } } if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); - } - //if ( bp == coin->current ) - // return(counter); + } + if ( bp == coin->current ) + return(counter); } for (i=0; in; i++) { @@ -622,7 +629,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 if ( coin->enableCACHE != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) { char str[64]; - if ( bp == coin->current ) + if ( 0 && bp == coin->current ) 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); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } @@ -726,9 +733,15 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) } else if ( bp == coin->current ) { - char str[65]; printf("missing [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); - if ( now > bp->issued[bundlei]+10 ) - iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],0); + char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + if ( block != 0 ) + { + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + } + //else if ( now > bp->issued[bundlei]+1 ) + iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); } } /*else @@ -766,13 +779,13 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -#ifndef IGUANA_SERIALIZE_SPENDVECTORGEN +//#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) -#endif { if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); } +//#endif for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; @@ -821,8 +834,16 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; - iguana_bundlecalcs(coin,bp); - //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 != coin->current || bp->dirty != 0 ) + { + iguana_bundlecalcs(coin,bp); + bp->dirty = 0; + } + if ( bp->hdrsi == coin->bundlescount-1 ) + { + iguana_autoextend(coin,bp); + //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); + } bp->nexttime = (uint32_t)(time(NULL) + 1);//(bp->hdrsi - starti) + 1); if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) iguana_bundlehdr(coin,bp,starti); @@ -870,6 +891,8 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru { max = bp->n; 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); } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 70c487efd..36de9963c 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1097,7 +1097,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } } - else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 100) == 0 ) + else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 10) == 0 ) { //printf("isRT and low rank.%d ",addr->rank); addr->dead = 1; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 865b3e076..eaa619e78 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -44,7 +44,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( addr->msgcounts.verack == 0 ) { printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); - return(-1); + //return(-1); } lastreq2 = lastreq; lastreq = hash2; @@ -196,10 +196,14 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i copyflag = coin->enableCACHE; bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); - if ( bp != 0 && bp->emitfinish != 0 ) + if ( bp != 0 ) { - //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); - return; + if ( bp->emitfinish != 0 ) + { + //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + return; + } + bp->dirty++; } if ( copyflag != 0 && recvlen != 0 && (bp == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { @@ -547,6 +551,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig bp = 0, bundlei = -1; if ( (bp= iguana_bundleset(coin,&block,&bundlei,&blocks[i])) != 0 ) { + bp->dirty++; //printf("{%d:%d} ",bp->hdrsi,bundlei); if ( i == 0 ) firstbp = bp; @@ -574,9 +579,26 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig return(req); } +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) +{ + char hashstr[65],str[65],str2[65]; struct iguana_bundle *newbp; int32_t bundlei; static bits256 zero; + if ( bp->hdrsi == coin->bundlescount-1 && bits256_nonz(bp->nextbundlehash2) != 0 ) + { + init_hexbytes_noT(hashstr,bp->nextbundlehash2.bytes,sizeof(bits256)); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,bp->nextbundlehash2,zero,1); + if ( newbp != 0 ) + { + printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); + if ( newbp->queued == 0 ) + iguana_bundleQ(coin,newbp,1000); + } + } +} + struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i,len; struct iguana_bundle *bp,*newbp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; struct iguana_block *block; + int32_t bundlei,i,len; struct iguana_bundle *bp; bits256 allhash,zero; uint8_t serialized[512]; struct iguana_peer *addr; struct iguana_block *block; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; if ( num < 2 ) @@ -589,33 +611,22 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { + bp->dirty++; bp->hdrtime = (uint32_t)time(NULL); blockhashes[0] = bp->hashes[0]; iguana_blockQ("recvhash0",coin,bp,0,blockhashes[0],0); if ( num >= coin->chain->bundlesize ) { - iguana_blockQ("recvhash1",coin,0,-1,blockhashes[coin->chain->bundlesize],0); - //printf("call allhashes\n"); - if ( bp->hdrsi == coin->bundlescount-1 ) + if ( bits256_nonz(bp->nextbundlehash2) == 0 && num > coin->chain->bundlesize ) { - init_hexbytes_noT(hashstr,blockhashes[coin->chain->bundlesize].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,blockhashes[coin->chain->bundlesize],zero,1); - if ( newbp != 0 ) - { - char str2[65]; - printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,blockhashes[coin->chain->bundlesize]),newbp->bundleheight); - if ( newbp->queued == 0 ) - iguana_bundleQ(coin,newbp,1000); - } + bp->nextbundlehash2 = blockhashes[coin->chain->bundlesize]; + iguana_blockQ("recvhash1",coin,0,-1,bp->nextbundlehash2,0); } - else if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) + //printf("call allhashes\n"); + if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_autoextend(coin,bp); + if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) return(req); - else if ( bp == coin->current ) - { - //for (i=0; in; i++) - // iguana_blockQ("reissue",coin,bp,i,bp->hashes[i],0); - } //printf("done allhashes\n"); } if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) @@ -646,7 +657,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct bp->hdrtime = (uint32_t)time(NULL); iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],0); iguana_blockQ("recvhash3",coin,bp,0,blockhashes[0],0); - iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); + //iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); //printf("matched bundle.%d\n",bp->bundleheight); return(req); } else printf("unexpected mismatch??\n"); @@ -749,6 +760,8 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } } } + if ( bp != 0 ) + bp->dirty++; if ( 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i; static int32_t numrecv; @@ -761,7 +774,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv,req->copyflag); } - if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) + if ( 1 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && coin->enableCACHE != 0 ) { //printf("reissue hdrs request for [%d]\n",bp->hdrsi); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); @@ -975,7 +988,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) threshold = 1000; else threshold = 300; - if ( strcmp(coin->symbol,"BTC") != 0 ) + if ( strcmp(coin->symbol,"BTC") == 0 ) threshold *= 10; if ( coin->blocks.hwmchain.height < coin->longestchain && ((strcmp(coin->symbol,"BTC") != 0 && coin->backstop != coin->blocks.hwmchain.height+1) || lag > threshold) ) { @@ -1006,8 +1019,8 @@ int32_t iguana_reqblocks(struct iguana_info *coin) iguana_blockQ("mainchain",coin,0,-1,hash2,lag > threshold); flag++; char str[65]; - if ( 1 && (rand() % 1000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) - printf("%s %s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",coin->symbol,bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); + if ( 1 && (rand() % 10000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + printf("%s %s MAIN.%d t %.3flag %.3f\n",coin->symbol,bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,lag); } else if ( bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { @@ -1105,8 +1118,10 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { if ( (bp= coin->bundles[i]) != 0 && (bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { - lag = 30; - if ( bp->bundleheight < coin->longestchain && time(NULL) > bp->issuetime+lag ) + if ( bp == coin->current ) + lag = 3; + else lag = 30; + if ( time(NULL) > bp->issuetime+lag ) { //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f6f6ee99d..89183730d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -102,6 +102,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else // do the equivalent of historical, ie mark as spent, linked list, balance { + printf("RT "); if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) return(0); } @@ -388,13 +389,12 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; } - if ( now > spentbp->lastprefetch+30 )//|| (spentbp->dirty % 10000) == 0 ) + if ( now > spentbp->lastprefetch+30 ) { //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } - spentbp->dirty++; spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); u = &spentU[spent_unspentind]; if ( (spent_pkind= u->pkind) != 0 && spent_pkind < spentbp->ramchain.H.data->numpkinds ) @@ -600,6 +600,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i height = bp->bundleheight + bundlei; for (j=0; jhdrsi,bundlei,B[bundlei].txn_count); if ( txidind != T[txidind].txidind || spendind != T[txidind].firstvin ) { printf("RTutxogen: txidind %u != %u nextT[txidind].firsttxidind || spendind %u != %u nextT[txidind].firstvin\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin); @@ -632,13 +633,13 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i return(-1); } } - else return(0); // coinbase always already spent + else continue; // coinbase always already spent if ( spentbp != 0 && spentbp->ramchain.H.data != 0 && spent_unspentind != 0 && spent_unspentind < spentbp->ramchain.H.data->numunspents ) { spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); u = &spentU[spent_unspentind]; return(iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height)); - } + } else printf("RTutxo error spentbp.%p u.%u\n",spentbp,spent_unspentind); } } return(-1); @@ -915,6 +916,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) flag++; if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) return(-1); + //printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); coin->RTheight++; coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); From f3001bd7c8060897a25b03a13ae68f09d4679596 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 20:57:03 -0300 Subject: [PATCH 290/333] test --- iguana/iguana_ramchain.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 5d88ef289..45295e4b1 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -168,7 +168,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl if ( setind == 0 ) sparsehits++; else if ( setind != x ) - printf("sparseadd index collision setind.%d != x.%d\n",setind,x); + printf("sparseadd index collision setind.%d != x.%d refsize.%d keylen.%d\n",setind,x,refsize,keylen); return(x); } } @@ -178,6 +178,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind) { uint32_t ind; + char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; return(iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T))); } @@ -185,6 +186,9 @@ uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits2 uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind) { uint32_t ind,key2; uint64_t key0,key1; + int32_t i; for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); memcpy(&key0,rmd160,sizeof(key0)); memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); From 32a6f04895e558269d9a5ed2253769f7bc6eb455 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 20:59:07 -0300 Subject: [PATCH 291/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 89183730d..688687f59 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -629,7 +629,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i } else { - printf("RTutxo txidind overflow %u vs %u\n",s->spendtxidind,spentbp->ramchain.H.data != 0?spentbp->ramchain.H.data->numtxids:-1); + printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,spentbp->ramchain.H.data != 0?spentbp->ramchain.H.data->numtxids:-1); return(-1); } } From 158e4a56d0d56394ec720d06de55bf6b38232ded Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:11:45 -0300 Subject: [PATCH 292/333] test --- iguana/iguana_bundles.c | 5 +++++ iguana/iguana_ramchain.c | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index d0424be6b..88c1df909 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -865,6 +865,11 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru if ( iguana_bundleready(coin,bp) == bp->n ) { printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT.%s bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",coin->symbol,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); + if ( bp->emitfinish != 0 ) + { + printf("already EMIT for bundle.%d\n",bp->hdrsi); + return(0); + } bp->emitfinish = 1; iguana_bundletweak(coin,bp); sleep(1); // just in case data isnt totally sync'ed to HDD diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 45295e4b1..ce583bc3d 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -177,18 +177,25 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind) { - uint32_t ind; - char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); + uint32_t ind,retval; + //char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; + if ( (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),0,T,sizeof(*T))) != 0 ) + { + char str[65]; + if ( txidind != 0 ) + printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); + return(retval); + } return(iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T))); } uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind) { uint32_t ind,key2; uint64_t key0,key1; - int32_t i; for (i=0; i<20; i++) - printf("%02x",rmd160[i]); - char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); memcpy(&key0,rmd160,sizeof(key0)); memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); From d22e234dfa6bbe353e8079840de01a8bd41eb594 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:15:56 -0300 Subject: [PATCH 293/333] test --- iguana/iguana_ramchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index ce583bc3d..a387383a5 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1658,7 +1658,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain if ( dest != 0 ) { char str[65]; - if ( 0 && ramchain->expanded == 0 ) + //if ( 0 && ramchain->expanded == 0 ) printf("add hdrsi.%d dest.%p txidind.%d %s\n",dest->H.hdrsi,ramchain,dest->H.txidind,bits256_str(str,tx->txid)); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-2); From 8e8bb9b3e30aa9eef5cfcb589c6f3648aed90222 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:23:48 -0300 Subject: [PATCH 294/333] test --- iguana/iguana_ramchain.c | 6 +++--- iguana/iguana_unspents.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index a387383a5..bbd165ec9 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1637,7 +1637,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - //else fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); + fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; @@ -1651,7 +1651,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { if ( 0 && ramchain->expanded == 0 && dest != 0 ) - printf("ITER TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); + 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]; if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-1); @@ -1659,7 +1659,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { char str[65]; //if ( 0 && ramchain->expanded == 0 ) - printf("add hdrsi.%d dest.%p txidind.%d %s\n",dest->H.hdrsi,ramchain,dest->H.txidind,bits256_str(str,tx->txid)); + 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); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-2); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 688687f59..b234337d4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -916,8 +916,8 @@ int32_t iguana_realtime_update(struct iguana_info *coin) flag++; if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) return(-1); - //printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); coin->RTheight++; + printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); coin->RTramchain.H.data->numblocks = bundlei + 1; } else printf("error mapchaininit\n"); iguana_ramchain_free(coin,&blockR,1); From d13b418c3f7af3b24f7673ff9a7981790a3668a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:28:33 -0300 Subject: [PATCH 295/333] test --- iguana/iguana_ramchain.c | 4 ++-- iguana/iguana_recv.c | 2 +- iguana/iguana_unspents.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index bbd165ec9..c1e3fb684 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1657,8 +1657,8 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain return(-1); if ( dest != 0 ) { - char str[65]; - //if ( 0 && ramchain->expanded == 0 ) + //char str[65]; + if ( 0 && ramchain->expanded == 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); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-2); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index eaa619e78..244f237b6 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -43,7 +43,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, } if ( addr->msgcounts.verack == 0 ) { - printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); + printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); //return(-1); } lastreq2 = lastreq; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index b234337d4..d85a1d6f1 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -885,7 +885,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight < coin->blocks.hwmchain.height) { dest = &coin->RTramchain; B = (void *)(long)((long)rdata + rdata->Boffset); From 169ddb48e0f4224955757d196223b944921b1277 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:42:31 -0300 Subject: [PATCH 296/333] test --- iguana/iguana_unspents.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d85a1d6f1..a18c660e3 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -102,8 +102,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else // do the equivalent of historical, ie mark as spent, linked list, balance { - printf("RT "); - if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) < 0 ) return(0); } printf("iguana_volatileupdate: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d\n",spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); @@ -838,6 +837,7 @@ int32_t iguana_volatileinit(struct iguana_info *coin) void iguana_RTramchainfree(struct iguana_info *coin) { iguana_utxoupdate(coin,-1,0,0,0,0,-1); // free hashtables + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; iguana_ramchain_free(coin,&coin->RTramchain,1); } @@ -863,7 +863,7 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) if ( changed != 0 ) { printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight, coin->RTramchain.H.data->numblocks); - coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + //coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; iguana_RTramchainfree(coin); } } @@ -885,7 +885,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight < coin->blocks.hwmchain.height) + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) { dest = &coin->RTramchain; B = (void *)(long)((long)rdata + rdata->Boffset); @@ -911,11 +911,15 @@ int32_t iguana_realtime_update(struct iguana_info *coin) block->issued = 0; OS_removefile(fname,0); } + iguana_RTramchainfree(coin); return(-1); } flag++; if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) + { + iguana_RTramchainfree(coin); return(-1); + } coin->RTheight++; printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); coin->RTramchain.H.data->numblocks = bundlei + 1; From d4ac6a001cd666a5e39689084abd5813f16c5389 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:53:14 -0300 Subject: [PATCH 297/333] test --- iguana/iguana_unspents.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index a18c660e3..0cbde0a6f 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -16,18 +16,20 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" -struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_unspentind) +struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint8_t *ubuf,uint16_t spent_hdrsi,uint32_t spent_unspentind) { struct iguana_hhutxo *hhutxo; uint8_t buf[sizeof(spent_unspentind) + sizeof(spent_hdrsi)]; + memcpy(buf,ubuf,sizeof(buf)); memcpy(&buf[sizeof(spent_unspentind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); memcpy(buf,(void *)&spent_unspentind,sizeof(spent_unspentind)); HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhutxo); return(hhutxo); } -struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint16_t spent_hdrsi,uint32_t spent_pkind) +struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint8_t *pkbuf,uint16_t spent_hdrsi,uint32_t spent_pkind) { struct iguana_hhaccount *hhacct; uint8_t buf[sizeof(spent_pkind) + sizeof(spent_hdrsi)]; + memcpy(buf,pkbuf,sizeof(buf)); memcpy(&buf[sizeof(spent_pkind)],(void *)&spent_hdrsi,sizeof(spent_hdrsi)); memcpy(buf,(void *)&spent_pkind,sizeof(spent_pkind)); HASH_FIND(hh,coin->utxotable,buf,sizeof(buf),hhacct); @@ -37,6 +39,8 @@ struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint16_t int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) { struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; + uint8_t pkbuf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; + uint8_t ubuf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; uint8_t buf[sizeof(spent_hdrsi) + sizeof(uint32_t)]; if ( spent_hdrsi < 0 ) { @@ -61,13 +65,18 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t return(0); } printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),fromheight/coin->chain->bundlesize,fromheight%coin->chain->bundlesize,spendind); - if ( (hhutxo= iguana_hhutxofind(coin,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) + if ( (hhutxo= iguana_hhutxofind(coin,ubuf,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) + { + printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); return(-1); + } hhutxo = calloc(1,sizeof(*hhutxo)); + memcpy(buf,ubuf,sizeof(buf)); HASH_ADD(hh,coin->utxotable,buf,sizeof(buf),hhutxo); - if ( (hhacct= iguana_hhaccountfind(coin,spent_hdrsi,spent_pkind)) == 0 ) + if ( (hhacct= iguana_hhaccountfind(coin,pkbuf,spent_hdrsi,spent_pkind)) == 0 ) { hhacct = calloc(1,sizeof(*hhacct)); + memcpy(buf,pkbuf,sizeof(buf)); HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); } hhutxo->u.spentflag = 1; From 909bfd308a64c05755664835255273e1fe2fc02c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 21:56:20 -0300 Subject: [PATCH 298/333] test --- iguana/iguana_bundles.c | 6 +++--- iguana/iguana_unspents.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 88c1df909..e56ae56cc 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -779,13 +779,13 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -//#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN - if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) +#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN + //if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) { if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); } -//#endif +#endif for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 0cbde0a6f..a1a41fea8 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -79,6 +79,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t memcpy(buf,pkbuf,sizeof(buf)); HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); } + printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); hhutxo->u.spentflag = 1; hhutxo->u.fromheight = fromheight; hhutxo->u.prevunspentind = hhacct->a.lastunspentind; @@ -111,7 +112,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc } else // do the equivalent of historical, ie mark as spent, linked list, balance { - if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) < 0 ) + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) return(0); } printf("iguana_volatileupdate: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d\n",spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); From 65862a8e2f7d0984ecadc13b840167632e6abefb Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:05:02 -0300 Subject: [PATCH 299/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/iguana_recv.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index c1e3fb684..05fdfe126 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -183,7 +183,7 @@ uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits2 if ( (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),0,T,sizeof(*T))) != 0 ) { char str[65]; - if ( txidind != 0 ) + if ( txidind != 0 && retval != txidind ) printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); return(retval); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 244f237b6..6b2528ca5 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -44,7 +44,8 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( addr->msgcounts.verack == 0 ) { printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); - //return(-1); + iguana_send_version(coin,addr,coin->myservices); + return(-1); } lastreq2 = lastreq; lastreq = hash2; From 6623b2c59f46d7cea8be03e098785c14198d799e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:21:26 -0300 Subject: [PATCH 300/333] test --- iguana/iguana_recv.c | 2 +- iguana/iguana_unspents.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 6b2528ca5..cffc38861 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1201,7 +1201,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle req->height = height; req->bundlei = bundlei; char str2[65]; - if ( 0 && (bundlei % 250) == 0 ) + if ( Q == &coin->blocksQ && queue_size(Q) > 100000 ) printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); if ( block != 0 ) { diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index a1a41fea8..77df7da86 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -592,7 +592,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp,int3 int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) { - struct iguana_txid *T,*spentT; int32_t height,spendind,txidind,j,k; bits256 prevhash; + struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; struct iguana_ramchaindata *RTdata; uint32_t spent_unspentind; struct iguana_blockRO *B; struct iguana_spend *S,*s; @@ -630,15 +630,14 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i else if ( s->prevout >= 0 ) { spentbp = bp; - if ( spentbp->ramchain.H.data != 0 && s->spendtxidind != 0 && s->spendtxidind < spentbp->ramchain.H.data->numtxids ) + if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) { - spentT = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - spent_unspentind = spentT[s->spendtxidind].firstvout + s->prevout; + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); } else { - printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,spentbp->ramchain.H.data != 0?spentbp->ramchain.H.data->numtxids:-1); + printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,RTdata->numtxids); return(-1); } } @@ -647,7 +646,8 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i { spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); u = &spentU[spent_unspentind]; - return(iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height)); + if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) + return(-1); } else printf("RTutxo error spentbp.%p u.%u\n",spentbp,spent_unspentind); } } @@ -1124,7 +1124,7 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } } //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); - if ( bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) + if ( bp->bundleheight+bp->n >= coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) { starttime = (uint32_t)time(NULL); for (j=0; j<=bp->hdrsi; j++) From 9cbf63bcf4002dec7599481f69039ba07553e3a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:24:31 -0300 Subject: [PATCH 301/333] test --- iguana/iguana_ramchain.c | 2 +- iguana/iguana_unspents.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 05fdfe126..8d610a5a6 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1637,7 +1637,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); + //fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 77df7da86..d835fbca5 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -64,7 +64,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t } return(0); } - printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),fromheight/coin->chain->bundlesize,fromheight%coin->chain->bundlesize,spendind); + //printf("utxoupdate spenthdrsi.%d pkind.%d %.8f from [%d:%d] spendind.%u\n",spent_hdrsi,spent_pkind,dstr(spent_value),fromheight/coin->chain->bundlesize,fromheight%coin->chain->bundlesize,spendind); if ( (hhutxo= iguana_hhutxofind(coin,ubuf,spent_hdrsi,spent_unspentind)) != 0 && hhutxo->u.spentflag != 0 ) { printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); @@ -79,7 +79,7 @@ int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t memcpy(buf,pkbuf,sizeof(buf)); HASH_ADD(hh,coin->accountstable,buf,sizeof(buf),hhacct); } - printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); + //printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); hhutxo->u.spentflag = 1; hhutxo->u.fromheight = fromheight; hhutxo->u.prevunspentind = hhacct->a.lastunspentind; From 2c9b3daaf7a254f5301b10c0e038587998e35d80 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:27:16 -0300 Subject: [PATCH 302/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index d835fbca5..5fff2f557 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -648,7 +648,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i u = &spentU[spent_unspentind]; if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) return(-1); - } else printf("RTutxo error spentbp.%p u.%u\n",spentbp,spent_unspentind); + } else printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1); } } return(-1); From 399e452b97b70279894b472ad5e2a78aa87e6be8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:36:19 -0300 Subject: [PATCH 303/333] test --- iguana/iguana_unspents.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 5fff2f557..54342d58d 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -594,7 +594,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i { struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; - struct iguana_ramchaindata *RTdata; + struct iguana_ramchaindata *RTdata,*rdata; uint32_t spent_unspentind; struct iguana_blockRO *B; struct iguana_spend *S,*s; if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) { @@ -620,16 +620,18 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i s = &S[spendind]; if ( s->external != 0 && s->prevout >= 0 ) { - if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s)) == 0 || spent_unspentind == 0 || spent_unspentind >= RTdata->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s)) == 0 || spent_unspentind == 0 || spent_unspentind >= spentbp->ramchain.H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) { char str[65]; printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); return(-1); } + rdata = spentbp->ramchain.H.data; } else if ( s->prevout >= 0 ) { spentbp = bp; + rdata = RTramchain->H.data; if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) { spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; @@ -642,13 +644,13 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i } } else continue; // coinbase always already spent - if ( spentbp != 0 && spentbp->ramchain.H.data != 0 && spent_unspentind != 0 && spent_unspentind < spentbp->ramchain.H.data->numunspents ) + if ( spentbp != 0 && rdata != 0 && spent_unspentind != 0 && spent_unspentind < rdata->numunspents ) { - spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + spentU = (void *)(long)((long)rdata + rdata->Uoffset); u = &spentU[spent_unspentind]; if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) return(-1); - } else printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,spentbp!=0?spentbp->ramchain.H.data->numunspents:-1); + } else printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); } } return(-1); From e06b2819c20f650f110b5cf9fddc4b4c3d4d2359 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:49:38 -0300 Subject: [PATCH 304/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 9 ++++----- iguana/iguana_unspents.c | 13 ++++++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index e56ae56cc..0a4974a5f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -415,7 +415,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + if ( (addr= coin->peers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) { now = (uint32_t)time(NULL); for (i=j,k=doneval=maxval=0; in&&krecvQ\n"); + int32_t newhwm = 0,hwmheight,flag = 0; + hwmheight = coin->blocks.hwmchain.height; flag += iguana_processrecvQ(coin,&newhwm); - //fprintf(stderr,"iguana_reqhdrs\n"); flag += iguana_reqhdrs(coin); - //fprintf(stderr,"iguana_reqblocks\n"); - //flag += iguana_reqblocks(coin); + if ( hwmheight != coin->blocks.hwmchain.height ) + flag = 1; return(flag); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 54342d58d..378dbe852 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -856,15 +856,15 @@ void iguana_RTramchainfree(struct iguana_info *coin) void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) { uint32_t i,changed = 0; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; - if ( coin->RTramchain.H.data != 0 ) + if ( dest->H.data != 0 ) { i = 0; - if ( coin->RTheight != bp->bundleheight + coin->RTramchain.H.data->numblocks ) + if ( coin->RTheight != bp->bundleheight + dest->H.data->numblocks ) changed++; else { - B = (void *)(long)((long)coin->RTramchain.H.data + coin->RTramchain.H.data->Boffset); - for (i=0; iRTramchain.H.data->numblocks; i++) + B = (void *)(long)((long)dest->H.data + dest->H.data->Boffset); + for (i=0; iH.data->numblocks; i++) if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) { char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); @@ -874,7 +874,7 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) } if ( changed != 0 ) { - printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight, coin->RTramchain.H.data->numblocks); + printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,dest->H.data->numblocks); //coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; iguana_RTramchainfree(coin); } @@ -886,6 +886,7 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; dest->H.scriptoffset = 1; + printf("ALLOC RTramchain %p\n"); } } @@ -897,6 +898,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); + printf("RTheight.%d rdata.%p\n",coin->RTheight,dest->H.data); while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) { dest = &coin->RTramchain; @@ -929,6 +931,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) flag++; if ( iguana_RTutxo(coin,bp,dest,bundlei) < 0 ) { + printf("RTutxo error -> RTramchainfree\n"); iguana_RTramchainfree(coin); return(-1); } From abb598a8ed9b1874434383c41d84ca0f719bde85 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:52:00 -0300 Subject: [PATCH 305/333] test --- iguana/iguana_unspents.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 378dbe852..10ad4efcb 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -886,7 +886,6 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; dest->H.scriptoffset = 1; - printf("ALLOC RTramchain %p\n"); } } @@ -898,7 +897,7 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); - printf("RTheight.%d rdata.%p\n",coin->RTheight,dest->H.data); + printf("RTheight.%d rdata.%p\n",coin->RTheight,coin->RTramchain.H.data); while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) { dest = &coin->RTramchain; From 88ca57bd900542809c36f759740cc99f0634144d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 22:54:17 -0300 Subject: [PATCH 306/333] test --- iguana/iguana_unspents.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 10ad4efcb..ec4465b17 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -599,7 +599,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) { printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); - return(0); + return(-1); } B = (void *)(long)((long)RTdata + RTdata->Boffset); S = (void *)(long)((long)RTdata + RTdata->Soffset); @@ -650,10 +650,15 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i u = &spentU[spent_unspentind]; if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) return(-1); - } else printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); + } + else + { + printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); + return(-1); + } } } - return(-1); + return(0); } void iguana_purgevolatiles(struct iguana_info *coin,struct iguana_ramchain *ramchain) @@ -897,7 +902,6 @@ int32_t iguana_realtime_update(struct iguana_info *coin) 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 ) { iguana_RTramchainalloc(coin,bp); - printf("RTheight.%d rdata.%p\n",coin->RTheight,coin->RTramchain.H.data); while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height) { dest = &coin->RTramchain; From 9d08cab114c2cc8acc001abc4c89dd7d2f2329b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 23:37:50 -0300 Subject: [PATCH 307/333] test --- iguana/iguana_accept.c | 5 +++-- iguana/iguana_bundles.c | 14 +++++++++++++- iguana/iguana_msg.c | 2 +- iguana/iguana_peers.c | 4 ++-- iguana/iguana_unspents.c | 24 +++++++++++++++++------- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index a4a836d69..4504292a3 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -77,7 +77,7 @@ void iguana_acceptloop(void *args) if ( poll(&pfd,1,100) <= 0 ) continue; clilen = sizeof(cli_addr); - printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); sock = accept(coin->bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { @@ -86,7 +86,6 @@ void iguana_acceptloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); - printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); for (i=0; ipeers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) @@ -101,6 +100,7 @@ void iguana_acceptloop(void *args) } if ( sock < 0 ) continue; + printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { @@ -119,6 +119,7 @@ void iguana_acceptloop(void *args) { printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); addr->usock = sock; + addr->dead = 0; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 0a4974a5f..b433a8aa1 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -403,8 +403,10 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int else starti = 0; priority = (bp->hdrsi < starti + coin->peers.numranked); if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 30 + (bp->hdrsi - starti); + lag = 10 + (bp->hdrsi - starti); else lag = 3 + (bp->hdrsi - starti)/10; + if ( coin->current != bp ) + lag *= 3; if ( (numpeers= coin->peers.numranked) > 3 )//&& bp->currentflag < bp->n ) { if ( numpeers > 0xff ) @@ -988,6 +990,16 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) } // else break; } } + else if ( bp == coin->current ) + { + for (j=0; jn; j++) + if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && time(NULL) > block->issued+10 ) + { + printf("current stop [%d:%d]\n",bp->hdrsi,j); + iguana_blockQ("currentstop",coin,0,-1,block->RO.hash2,1); + block->issued = (uint32_t)time(NULL); + } + } //bp->rank = 0; estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); //bp->metric = bp->numhashes; diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 5794a5107..aa7fdc6f0 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -172,7 +172,7 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->supernet = 1; //else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) - coin->longestchain = vers->nStartingHeight; + coin->longestchain = (vers->nStartingHeight + coin->longestchain + 1) >> 1; iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 36de9963c..f83420a55 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -576,8 +576,8 @@ void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t he //iguana_set_iAddrheight(coin,addr->ipbits,height); addr->height = height; } - if ( height > coin->longestchain ) - coin->longestchain = height; + if ( height > 0 && height > coin->longestchain ) + coin->longestchain = (height + coin->longestchain + 1) >> 1; } int32_t iguana_iAddrheight(struct iguana_info *coin,uint64_t ipbits) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index ec4465b17..586b454a4 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -886,7 +886,7 @@ void iguana_RTramchainalloc(struct iguana_info *coin,struct iguana_bundle *bp) } if ( coin->RTramchain.H.data == 0 ) { - printf("ALLOC RTramchain\n"); + //printf("ALLOC RTramchain\n"); iguana_ramchainopen(coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; @@ -941,13 +941,23 @@ int32_t iguana_realtime_update(struct iguana_info *coin) coin->RTheight++; printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); coin->RTramchain.H.data->numblocks = bundlei + 1; - } else printf("error mapchaininit\n"); - iguana_ramchain_free(coin,&blockR,1); - } //else printf("no ptr for RTheight.%d\n",coin->RTheight); + } + else + { + printf("error mapchaininit\n"); + iguana_ramchain_free(coin,&blockR,1); + return(-1); + } + } + else + { + printf("no ptr for RTheight.%d\n",coin->RTheight); + return(-1); + } } else { - //printf("no blockptr for RTheight.%d\n",coin->RTheight); + printf("no blockptr for RTheight.%d\n",coin->RTheight); return(-1); } } @@ -1131,8 +1141,8 @@ int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int } } } - //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); - if ( bp->bundleheight+bp->n >= coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 && bp->hdrsi == j ) + // printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); + if ( bp->bundleheight+bp->n < coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 && (bp->hdrsi == 0 || bp->hdrsi == j) ) { starttime = (uint32_t)time(NULL); for (j=0; j<=bp->hdrsi; j++) From 2eddc1d57ee696345e688db7fa5217bcc106f7fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 23:54:36 -0300 Subject: [PATCH 308/333] test --- iguana/iguana777.h | 3 ++- iguana/iguana_msg.c | 8 +++++++- iguana/iguana_recv.c | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index d6d74ab19..da3b47283 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -461,7 +461,8 @@ struct iguana_info 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 longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; + uint32_t lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; + int32_t longestchain,badlongestchain,longestchain_strange; struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index aa7fdc6f0..1658c9b25 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -172,7 +172,13 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->supernet = 1; //else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) - coin->longestchain = (vers->nStartingHeight + coin->longestchain + 1) >> 1; + { + if ( coin->badlongestchain != 0 && vers->nStartingHeight >= coin->badlongestchain ) + { + printf("peer.(%s) gives badlongestchain.%d\n",addr->ipaddr,vers->nStartingHeight); + addr->dead = 1; + } else coin->longestchain = (vers->nStartingHeight + coin->longestchain + 1) >> 1; + } iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 94f0a81a0..016cdbfe2 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -630,7 +630,20 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct return(req); //printf("done allhashes\n"); } - if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) + else if ( bp->hdrsi == coin->bundlescount-1 ) + { + if ( num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) + { + printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); + if ( coin->longestchain_strange++ > 10 ) + { + coin->badlongestchain = coin->longestchain; + coin->longestchain = bp->bundleheight+num; + coin->longestchain_strange = 0; + } + } + } + if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); if ( bp->speculative == 0 ) From fc548d92a2eab6f223c4124792e01489a93a8dd5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 25 Mar 2016 23:58:23 -0300 Subject: [PATCH 309/333] test --- iguana/iguana_recv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 016cdbfe2..6a5a9bbbc 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -632,10 +632,11 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } else if ( bp->hdrsi == coin->bundlescount-1 ) { + printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) { printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); - if ( coin->longestchain_strange++ > 10 ) + if ( coin->longestchain_strange++ > 3 ) { coin->badlongestchain = coin->longestchain; coin->longestchain = bp->bundleheight+num; @@ -1137,7 +1138,8 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) else lag = 30; if ( time(NULL) > bp->issuetime+lag ) { - //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); + if ( bp == coin->current ) + printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); From c14768c05d104678d7e5f4dd92edaf1a3a908179 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:00:55 -0300 Subject: [PATCH 310/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 6a5a9bbbc..2b6e3bbd6 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -608,7 +608,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - if ( 0 && num > 2 ) + //if ( 0 && num > 2 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { From cfc707b9f6537451abcf549ba70d301852321d99 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:05:30 -0300 Subject: [PATCH 311/333] test --- iguana/iguana_recv.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 2b6e3bbd6..52b5596cf 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -511,6 +511,20 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl return(iguana_bundlefind(coin,&bp,bundleip,hash2)); } +void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) +{ + if ( num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) + { + printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); + if ( coin->longestchain_strange++ > 3 ) + { + coin->badlongestchain = coin->longestchain; + coin->longestchain = bp->bundleheight+num; + coin->longestchain_strange = 0; + } + } +} + struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) { int32_t i,bundlei,match; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; @@ -555,7 +569,10 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig bp->dirty++; //printf("{%d:%d} ",bp->hdrsi,bundlei); if ( i == 0 ) + { firstbp = bp; + iguana_checklongestchain(coin,bp,n); + } if ( bundlei == i+1 && bp == firstbp ) match++; else @@ -608,7 +625,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //iguana_blockQ(coin,0,-1,blockhashes[1],0); //iguana_blockQ(coin,0,-4,blockhashes[1],1); char str[65]; - //if ( 0 && num > 2 ) + if ( 0 && num > 2 ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { @@ -631,19 +648,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //printf("done allhashes\n"); } else if ( bp->hdrsi == coin->bundlescount-1 ) - { - printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); - if ( num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) - { - printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); - if ( coin->longestchain_strange++ > 3 ) - { - coin->badlongestchain = coin->longestchain; - coin->longestchain = bp->bundleheight+num; - coin->longestchain_strange = 0; - } - } - } + iguana_checklongestchain(coin,bp,num); if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); From 88590712d8e5898f6bf43e4032e1278a1b84d7fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:06:13 -0300 Subject: [PATCH 312/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 52b5596cf..466cf7a13 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -513,7 +513,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { - if ( num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) + if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) { printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); if ( coin->longestchain_strange++ > 3 ) From a3198b5e8e1a1a7a6913e1b3963ce7b21007c0f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:08:19 -0300 Subject: [PATCH 313/333] test --- iguana/iguana_recv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 466cf7a13..e8aef0f19 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -513,6 +513,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { + printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) { printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); From 95c48ca72249171c16e070a1ec2399ad7e704f59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:12:26 -0300 Subject: [PATCH 314/333] test --- iguana/iguana_recv.c | 4 ++-- iguana/main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index e8aef0f19..c682df2fc 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -513,11 +513,11 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { - printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); + printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) { printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); - if ( coin->longestchain_strange++ > 3 ) + if ( coin->longestchain_strange++ > 10 ) { coin->badlongestchain = coin->longestchain; coin->longestchain = bp->bundleheight+num; diff --git a/iguana/main.c b/iguana/main.c index 4fd416d32..313b75020 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1178,7 +1178,7 @@ void iguana_main(void *arg) #endif for (i=0; i Date: Sat, 26 Mar 2016 00:14:18 -0300 Subject: [PATCH 315/333] test --- iguana/iguana_recv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index c682df2fc..5ac87ebdb 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -513,10 +513,9 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { - printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); - if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+bp->n ) + if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+num+3 ) { - printf("suspicious longestchain.%d vs [%d:%d] %d\n",coin->longestchain,bp->hdrsi,num,bp->bundleheight+num); + printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); if ( coin->longestchain_strange++ > 10 ) { coin->badlongestchain = coin->longestchain; From 04434078886b65201b5a736cb0b5ba3d05ba928d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:27:02 -0300 Subject: [PATCH 316/333] test --- iguana/iguana_bundles.c | 15 ++++++++------- iguana/iguana_recv.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index b433a8aa1..2717e0f0f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -611,13 +611,12 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) printf("checki.%d vs %d mismatch?\n",checki,i); if ( fname[0] != 0 ) OS_removefile(fname,0); - printf(">>>>>>> block contents error at ht.%d\n",bp->bundleheight+i); + printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); block->fpipbits = 0; block->fpos = -1; block->queued = 0; block->RO.recvlen = 0; - //iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1); } else ready++; } else printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); } @@ -928,8 +927,8 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) void iguana_bundlestats(struct iguana_info *coin,char *str) { - int32_t i,n,m,j,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; + int32_t i,n,m,j,numv,r,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; struct iguana_block *block,*prev; uint32_t now; struct iguana_peer *addr; now = (uint32_t)time(NULL); dispflag = 1;//(rand() % 1000) == 0; numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; @@ -993,11 +992,13 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( bp == coin->current ) { for (j=0; jn; j++) - if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && time(NULL) > block->issued+10 ) + if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && time(NULL) > block->issued+3 ) { - printf("current stop [%d:%d]\n",bp->hdrsi,j); - iguana_blockQ("currentstop",coin,0,-1,block->RO.hash2,1); + 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_blockQ("currentstop",coin,bp,j,block->RO.hash2,1); block->issued = (uint32_t)time(NULL); + break; } } //bp->rank = 0; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 5ac87ebdb..11ff75956 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -513,6 +513,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { + int32_t i; struct iguana_peer *addr; if ( num > 10 && num < bp->n && coin->longestchain > bp->bundleheight+num+3 ) { printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); @@ -521,6 +522,12 @@ void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp, coin->badlongestchain = coin->longestchain; coin->longestchain = bp->bundleheight+num; coin->longestchain_strange = 0; + for (i=0; ipeers.numranked; i++) + if ( (addr= coin->peers.ranked[i]) != 0 && addr->height >= coin->badlongestchain ) + { + printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); + addr->dead = 1; + } } } } @@ -1139,11 +1146,11 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) if ( (bp= coin->bundles[i]) != 0 && (bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { if ( bp == coin->current ) - lag = 3; + lag = 13; else lag = 30; if ( time(NULL) > bp->issuetime+lag ) { - if ( bp == coin->current ) + if ( 0 && bp == coin->current ) printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; From 6b49aa0fe0b7f8140e4ab9912ce3ed724f72449f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:34:20 -0300 Subject: [PATCH 317/333] test --- iguana/iguana_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 1658c9b25..4bdc8f9d9 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -170,7 +170,7 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->dead = (uint32_t)time(NULL); if ( (vers->nServices & (1<<7)) == (1<<7) ) addr->supernet = 1; - //else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); + printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) { if ( coin->badlongestchain != 0 && vers->nStartingHeight >= coin->badlongestchain ) From dc5b51a4023980d747186b427cc49ce9bb43f1b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:37:46 -0300 Subject: [PATCH 318/333] test --- iguana/iguana_bundles.c | 3 ++- iguana/iguana_recv.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2717e0f0f..69edf7262 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -514,7 +514,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int bp->issued[i] = block->issued = now; } } - printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); + if ( flag != 0 ) + printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); } } } diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 11ff75956..63ed306c5 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -44,7 +44,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( addr->msgcounts.verack == 0 ) { printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); - iguana_send_version(coin,addr,coin->myservices); + //iguana_send_version(coin,addr,coin->myservices); return(-1); } lastreq2 = lastreq; From 1e29511958b6748a8e149eda940230631118a32c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:44:44 -0300 Subject: [PATCH 319/333] test --- iguana/iguana_bundles.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 69edf7262..6add02827 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -505,7 +505,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( (block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0 ) { - printf("%d ",j); + if ( bp == coin->current ) + printf("%d ",j); flag++; counter++; block->peerid = 0; @@ -514,7 +515,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int bp->issued[i] = block->issued = now; } } - if ( flag != 0 ) + if ( flag != 0 && bp == coin->current ) printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); } } From 7397d7a54331f7bda30e0f2ff6436844f9b566ac Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 00:59:48 -0300 Subject: [PATCH 320/333] test --- iguana/iguana_bundles.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 6add02827..e4525826f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -782,13 +782,13 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN +//#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN //if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) { - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-coin->MAXBUNDLES ) return(0); } -#endif +//#endif for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; From 3e24e16eb6ea28fea9e7a03b5abd76622ae2f991 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 01:49:55 -0300 Subject: [PATCH 321/333] test --- iguana/SuperNET.c | 1 + iguana/iguana_bundles.c | 9 +++++++-- iguana/iguana_recv.c | 1 + iguana/main.c | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index 64ebd198c..95d3854f1 100755 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -788,6 +788,7 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de if ( method != 0 && strcmp(method,"stop") == 0 ) { addr->dead = (uint32_t)time(NULL); + addr->rank = 0; free_json(json); if ( ptr != 0 ) free(ptr); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index e4525826f..a4aeb458f 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -500,7 +500,10 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( peercounts[i] > threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) { if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) + { addr->dead = (uint32_t)time(NULL); + addr->rank = 0; + } for (j=0; jn; j++) { if ( (block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0 ) @@ -545,7 +548,9 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,forceflag); if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); + } + else if ( forceflag != 0 ) + iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0); if ( forceflag != 0 ) bp->issued[i] = block->issued = now; else bp->issued[i] = block->issued = saved; @@ -785,7 +790,7 @@ int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) //#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN //if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) { - if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-coin->MAXBUNDLES ) + if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); } //#endif diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 63ed306c5..295a820bc 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -527,6 +527,7 @@ void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp, { printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); addr->dead = 1; + addr->rank = 0; } } } diff --git a/iguana/main.c b/iguana/main.c index 313b75020..7e72f26c4 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1132,7 +1132,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":2048,\"endpend\":2048,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From 450a79efe58142668dac2f90b3dc49cb2af9eaaf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 01:55:38 -0300 Subject: [PATCH 322/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index da3b47283..dabe8391a 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -41,7 +41,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_MAXPENDHDRS 1 #define _IGUANA_MAXPENDING 3 #define IGUANA_MINPENDBUNDLES 2 -#define IGUANA_MAXPENDBUNDLES 64 +#define IGUANA_MAXPENDBUNDLES 32 #define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index a4aeb458f..586e30d80 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -787,13 +787,13 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) { struct iguana_bundle *prevbp; int32_t i,retval; -//#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN +#ifdef IGUANA_SERIALIZE_SPENDVECTORGEN //if ( coin->MAXMEM <= 4*(1024L * 1024 * 1024) ) { if ( (prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)-0*coin->MAXBUNDLES ) return(0); } -//#endif +#endif for (i=0; ihdrsi; i++) if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish < coin->startutc ) break; From a4e0eb193e550d3b2b3f905412c0b76dedc201e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 02:19:38 -0300 Subject: [PATCH 323/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_bundles.c | 10 +++++----- iguana/iguana_peers.c | 2 +- iguana/iguana_recv.c | 12 +++++++++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index dabe8391a..ed7463ad1 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -461,7 +461,7 @@ struct iguana_info 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; + uint32_t lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks,backlog; int32_t longestchain,badlongestchain,longestchain_strange; struct tai starttime; double startmillis; struct iguana_chain *chain; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 586e30d80..75af37430 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -541,7 +541,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int saved = block->issued; if ( bp == coin->current ) forceflag = (now > block->issued + lag); - else forceflag = (now > block->issued + 3*lag); + else forceflag = (now > block->issued + 10*lag); if ( priority != 0 ) { //printf("[%d:%d] ",bp->hdrsi,i); @@ -561,8 +561,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } - if ( bp == coin->current ) - return(counter); + //if ( bp == coin->current ) + // return(counter); } for (i=0; in; i++) { @@ -575,7 +575,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int block->numrequests++; if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current || now > block->issued+lag*3); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,bp == coin->current && now > block->issued+lag); bp->issued[i] = block->issued = now; counter++; if ( --max <= 0 ) @@ -587,7 +587,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int { if ( bp == coin->current ) printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current || now > bp->issued[i]+lag*3); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],bp == coin->current && now > bp->issued[i]+lag*3); bp->issued[i] = now; counter++; } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index f83420a55..2b5aef7aa 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1069,7 +1069,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } else if ( addr->rank != 1 ) usleep(coin->polltimeout*5000 + 1*(rand() % (coin->polltimeout*3000))); - else usleep(10000); + else usleep(10000 + coin->backlog); } else run >>= 2; } if ( flag != 0 ) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 295a820bc..4416a58bf 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1181,7 +1181,7 @@ struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct 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 height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; + queue_t *Q; char *str; int32_t n,height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; if ( bits256_nonz(hash2) == 0 ) { printf("cant queue zerohash bundlei.%d\n",bundlei); @@ -1229,8 +1229,14 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle req->height = height; req->bundlei = bundlei; char str2[65]; - if ( Q == &coin->blocksQ && queue_size(Q) > 100000 ) - printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + if ( Q == &coin->blocksQ ) + { + if ( (n= queue_size(Q)) > 100000 ) + { + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + coin->backlog = n; + } else coin->backlog >>= 1; + } if ( block != 0 ) { block->numrequests++; From 34ab58bffec08b3195f415567fe554d1566ac3b8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 02:44:39 -0300 Subject: [PATCH 324/333] test --- iguana/iguana_bundles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 75af37430..e45425413 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -999,7 +999,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( bp == coin->current ) { for (j=0; jn; j++) - if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && time(NULL) > block->issued+3 ) + if ( (block= bp->blocks[j]) != 0 && (block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) && time(NULL) > block->issued+3 ) { 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); From 4ef49fd1b9f85498aa7d3f9e17c60168821eced7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 02:47:51 -0300 Subject: [PATCH 325/333] test --- iguana/iguana_recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 4416a58bf..9a3fd843b 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -43,7 +43,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, } if ( addr->msgcounts.verack == 0 ) { - printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); + //printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); //iguana_send_version(coin,addr,coin->myservices); return(-1); } From 173b98d70e238ab7a938cb5b13f168a51352cc13 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 03:19:27 -0300 Subject: [PATCH 326/333] test --- iguana/iguana777.h | 2 +- iguana/iguana_unspents.c | 16 ++++++++++++---- iguana/main.c | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index ed7463ad1..080a6eccd 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -23,7 +23,7 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); #define IGUANA_MAXSCRIPTSIZE 10001 -//#define IGUANA_SERIALIZE_SPENDVECTORGEN +#define IGUANA_SERIALIZE_SPENDVECTORGEN //#define IGUANA_SERIALIZE_BALANCEGEN //#define IGUANA_DISABLEPEERS diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 586b454a4..9f672e4e9 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -398,9 +398,9 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); errs++; } - if ( now > spentbp->lastprefetch+30 ) + if ( now > spentbp->lastprefetch+10 ) { - //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } @@ -951,13 +951,21 @@ int32_t iguana_realtime_update(struct iguana_info *coin) } else { - printf("no ptr for RTheight.%d\n",coin->RTheight); + //printf("no fileptr for RTheight.%d\n",coin->RTheight); return(-1); } } else { - printf("no blockptr for RTheight.%d\n",coin->RTheight); + if ( block == 0 ) + printf("no blockptr.%p for RTheight.%d\n",block,coin->RTheight); + else + { + block->queued = 0; + block->fpipbits = 0; + bp->issued[bundlei] = 0; + block->issued = 0; + } return(-1); } } diff --git a/iguana/main.c b/iguana/main.c index 7e72f26c4..dec4e2c5d 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1132,7 +1132,7 @@ void iguana_main(void *arg) sleep(1); char *str; //iguana_launchcoin(MYINFO.rpcsymbol,cJSON_Parse("{}")); - if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":128,\"endpend\":128,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0)) != 0 ) + if ( 1 && (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"startpend\":64,\"endpend\":32,\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":512,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"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 ) From e91812bb035467c8f24d53927f4da459b37c836d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 03:35:31 -0300 Subject: [PATCH 327/333] test --- iguana/iguana_unspents.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9f672e4e9..f6abea16a 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -595,7 +595,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; struct iguana_ramchaindata *RTdata,*rdata; - uint32_t spent_unspentind; struct iguana_blockRO *B; struct iguana_spend *S,*s; + uint32_t spent_unspentind,now; struct iguana_blockRO *B; struct iguana_spend *S,*s; if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) { printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); @@ -607,6 +607,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i txidind = B[bundlei].firsttxidind; spendind = B[bundlei].firstvin; height = bp->bundleheight + bundlei; + now = (uint32_t)time(NULL); for (j=0; jhdrsi,bundlei,B[bundlei].txn_count); @@ -627,6 +628,12 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i return(-1); } rdata = spentbp->ramchain.H.data; + if ( now > spentbp->lastprefetch+10 ) + { + printf("RT prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } } else if ( s->prevout >= 0 ) { From da85d9da20e2229a891d16a760dc7f8f335b6d92 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:00:12 -0300 Subject: [PATCH 328/333] test --- iguana/iguana_bundles.c | 6 +++--- iguana/main.c | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index e45425413..29e7d0c78 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -533,7 +533,7 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int } for (i=0; in; i++) { - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) + if ( (block= bp->blocks[i]) != 0 && (bits256_nonz(block->RO.prev_block) == 0 || block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) ) { if ( now > block->issued+lag ) { @@ -561,8 +561,8 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); } - //if ( bp == coin->current ) - // return(counter); + if ( bp == coin->current ) + return(counter); } for (i=0; in; i++) { diff --git a/iguana/main.c b/iguana/main.c index dec4e2c5d..3c86d5496 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1187,3 +1187,20 @@ void iguana_main(void *arg) mainloop(&MYINFO); } +/* +getinfo +sendtoaddress +encryptwallet +sendfrom +walletlock +walletpassphrase +validateaddress +walletpassphrasechange +listreceivedbyaddress +listtransactions + +not implemented yet but needed by GUI + +addmultisigaddress (for generating address) +setaccount (to give labels to address) + */ From f4857bd06e402e003360feffc982c9cb69896abd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:09:14 -0300 Subject: [PATCH 329/333] test --- crypto777/iguana_OS.c | 2 +- iguana/iguana_bundles.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index bf9048c59..31d14dc6f 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -81,8 +81,8 @@ long myallocated(uint8_t type,long change) Total_allocated += change; if ( Total_allocated > HWM_allocated ) { - printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); HWM_allocated = Total_allocated * 1.5; + printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); } } return(total); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 29e7d0c78..2e7bd8586 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -999,7 +999,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) else if ( bp == coin->current ) { for (j=0; jn; j++) - if ( (block= bp->blocks[j]) != 0 && (block->RO.recvlen == 0 || block->fpipbits == 0 || block->fpos < 0) && time(NULL) > block->issued+3 ) + 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); From 3465507edfa2f7cfafbffb8656a07f6034e050af Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:20:21 -0300 Subject: [PATCH 330/333] test --- iguana/iguana_bundles.c | 2 +- iguana/iguana_recv.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2e7bd8586..041923d8e 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -648,7 +648,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 { if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) { - if ( now > bp->issued[i]+20 ) + if ( now > bp->issued[i]+60 ) { bp->issued[i] = now; //printf("speculative.[%d:%d]\n",bp->hdrsi,i); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 9a3fd843b..918f47737 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1233,8 +1233,9 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle { if ( (n= queue_size(Q)) > 100000 ) { - printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); - coin->backlog = n; + if ( n > 200000 ) + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + coin->backlog = n*10; } else coin->backlog >>= 1; } if ( block != 0 ) From 639e9e682f6485ac944c9aff65a7c7e71d7729cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:27:01 -0300 Subject: [PATCH 331/333] test --- iguana/iguana_unspents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index f6abea16a..63a354959 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -400,7 +400,7 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp) } if ( now > spentbp->lastprefetch+10 ) { - printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } @@ -630,7 +630,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i rdata = spentbp->ramchain.H.data; if ( now > spentbp->lastprefetch+10 ) { - printf("RT prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + //printf("RT prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain); spentbp->lastprefetch = now; } From a5cda34a9e340ba9a46eeadb05c2d28896e8f351 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:46:56 -0300 Subject: [PATCH 332/333] test --- iguana/iguana_unspents.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 63a354959..9f8533b69 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -608,6 +608,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i spendind = B[bundlei].firstvin; height = bp->bundleheight + bundlei; now = (uint32_t)time(NULL); + iguana_ramchain_prefetch(coin,RTramchain); for (j=0; jhdrsi,bundlei,B[bundlei].txn_count); From ef3b8321fedb4253c10e009160103d37c2ddb3fa Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 26 Mar 2016 04:52:58 -0300 Subject: [PATCH 333/333] test --- iguana/iguana_unspents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 9f8533b69..07cc3e01c 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -629,7 +629,7 @@ int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct i return(-1); } rdata = spentbp->ramchain.H.data; - if ( now > spentbp->lastprefetch+10 ) + if ( now > spentbp->lastprefetch+1 ) { //printf("RT prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain);