diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 38d9b62aa..d684b257a 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -262,11 +262,11 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ return(n); } -int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr) +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2) { int32_t recvlen; uint8_t *data,space[16384],*allocptr; if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&recvlen,space,sizeof(space),blockstr)) != 0 ) - gecko_blockarrived(myinfo,virt,&virt->internaladdr,data,recvlen); + gecko_blockarrived(myinfo,virt,"127.0.0.1",data,recvlen,hash2); if ( allocptr != 0 ) free(allocptr); return(recvlen); @@ -654,6 +654,7 @@ INT_AND_ARRAY(basilisk,result,basilisktag,vals) ptr = calloc(1,sizeof(*ptr)); ptr->retstr = jprint(vals,0); ptr->basilisktag = basilisktag; + strcpy(ptr->remoteaddr,remoteaddr); printf("(%s) -> Q.%u results vals.(%s)\n",ptr->CMD,basilisktag,ptr->retstr); queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); return(clonestr("{\"result\":\"queued basilisk return\"}")); @@ -723,6 +724,36 @@ HASH_ARRAY_STRING(basilisk,VPNlogout,pubkey,vals,hexstr) #include "../includes/iguana_apiundefs.h" +void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr) +{ + uint8_t *data,space[16384],*allocptr = 0; struct iguana_info *virt; char *symbol,*str,*type; int32_t datalen; cJSON *retjson; bits256 hash2; + if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) + { + if ( (symbol= jstr(retjson,"coin")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( (data= get_dataptr(0,&allocptr,&datalen,space,sizeof(space),jstr(retjson,"data"))) != 0 ) + { + str = 0; + if ( (type= jstr(retjson,"type")) != 0 ) + { + hash2 = jbits256(retjson,"pubkey"); + if ( strcmp(type,"HDR") == 0 ) + str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"BLK") == 0 ) + str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"GTX") == 0 ) + str = gecko_txarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + } + if ( str != 0 ) + free(str); + if ( allocptr != 0 ) + free(allocptr); + } + } + free_json(retjson); + } +} + void basilisks_loop(void *arg) { basilisk_metricfunc metricfunc; struct iguana_info *btcd,*virt,*hhtmp; struct basilisk_item *ptr,*tmp,*pending,*parent; int32_t i,iter,maxmillis,done,flag,n; cJSON *valsobj,*retjson; uint32_t now; struct supernet_info *myinfo = arg; @@ -759,6 +790,9 @@ void basilisks_loop(void *arg) free_json(retjson); } } + else if ( strcmp(ptr->CMD,"RET") == 0 ) + { + } } } free(ptr); @@ -861,12 +895,9 @@ void basilisks_loop(void *arg) //portable_mutex_lock(&Allcoins_mutex); HASH_ITER(hh,myinfo->allcoins,virt,hhtmp) { - if ( iguana_processrecv(myinfo,virt) == 0 ) - { - bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33); - //printf("mine.%s %s\n",virt->symbol,mineraddr); - gecko_miner(myinfo,btcd,virt,maxmillis,mineraddr); - } + bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33); + //printf("mine.%s %s\n",virt->symbol,mineraddr); + gecko_miner(myinfo,btcd,virt,maxmillis,mineraddr); flag++; } //portable_mutex_unlock(&Allcoins_mutex); @@ -903,10 +934,12 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender // gecko chains { (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain + { (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list + { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx + { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers + { (void *)"BLK", &basilisk_respond_geckoblock }, // reports block + { (void *)"GTX", &basilisk_respond_geckotx }, // reports tx { (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp - { (void *)"GTX", &basilisk_respond_geckotx }, - { (void *)"BLK", &basilisk_respond_geckoblock }, - { (void *)"GEN", &basilisk_respond_geckogenesis }, // unencrypted low level functions, used by higher level protocols and virtual network funcs { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus @@ -993,7 +1026,11 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender } if ( coin != 0 ) { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node + if ( strcmp(type,"RET") == 0 ) + { + retstr = _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen); + } + else if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node { for (i=0; i> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr); + sprintf(argbuf,"{\"isPoS\":%d,\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%s\",\"p2shval\":\"%s\",\"wifval\":\"%s\",\"isPoS\":%u,\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",isPoS,chainname,symbol,magicstr,juint(valsobj,"port"),blocktime,pubstr,p2shstr,wifvalstr,juint(valsobj,"isPoS"),(nBits >> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr); free(blockstr); //printf("argbuf.(%s) hash.%s\n",argbuf,hashstr); return(cJSON_Parse(argbuf)); @@ -222,8 +224,8 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *valsobj) { - //printf("issue isPoS.%d\n",juint(valsobj,"isPoS")); - return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nbits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS"))); + printf("issue blocktime.%d\n",juint(valsobj,"blocktime")); + return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nBits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS"))); } struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj) @@ -245,8 +247,11 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo free(ptr); virt->chain->genesis_hex = clonestr(hexstr); virt->MAXPEERS = 0; + virt->virtualchain = 1; addr = &virt->internaladdr; iguana_initpeer(virt,addr,calc_ipbits("127.0.0.1")); + if ( addr->blockspace == 0 ) + addr->blockspace = calloc(1,IGUANA_MAXPACKETSIZE + 8192); if ( addr->RAWMEM.ptr == 0 ) iguana_meminit(&addr->RAWMEM,virt->symbol,0,IGUANA_MAXPACKETSIZE * 2,0); if ( addr->TXDATA.ptr == 0 ) @@ -352,6 +357,95 @@ char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void return(OS_filestr(&filesize,"genesis/list")); } +char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint8_t *serialized,int32_t datalen) +{ + char space[16384],*allocstr = 0; cJSON *retjson = cJSON_CreateObject(); + if ( datalen > 0 && basilisk_addhexstr(&allocstr,retjson,space,sizeof(space),serialized,datalen) != 0 ) + { + jaddstr(retjson,"CMD",CMD); + jaddstr(retjson,"type",type); + jaddstr(retjson,"coin",virt->symbol); + jaddnum(retjson,"longest",virt->longestchain); + jaddnum(retjson,"hwm",virt->blocks.hwmchain.height); + jaddbits256(retjson,"pubkey",virt->blocks.hwmchain.RO.hash2); + } + else jaddstr(retjson,"error","no data to send"); + if ( allocstr != 0 ) + free(allocstr); + return(jprint(retjson,1)); +} + +int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t i,n,num,height,len=0; struct iguana_block *block; + if ( (block= iguana_blockfind("geckohdr",virt,hash2)) != 0 ) + { + if ( (height= block->height) >= 0 ) + { + if ( (num= juint(valsobj,"num")) == 0 || num > virt->chain->bundlesize ) + num = virt->chain->bundlesize; + for (i=0; i 0 ) + len += n; + } + hash2 = iguana_blockhash(virt,height+i+1); + block = iguana_blockfind("geckohdri",virt,hash2); + } + return(len); + } + } + return(-1); +} + +int32_t basilisk_respond_geckogetblock(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t datalen = 0; + // set serialized + return(datalen); +} + +int32_t basilisk_respond_geckogettx(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t datalen = 0; + // set serialized + return(datalen); +} + +char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk) +{ + int32_t (*getfunc)(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2); + uint8_t *serialized; int32_t maxsize,len = 0; char *symbol,*type; struct iguana_info *virt; + if ( (type= jstr(valsobj,"type")) != 0 ) + { + if ( strcmp(type,"HDR") == 0 ) + getfunc = basilisk_respond_geckogetheaders; + else if ( strcmp(type,"BLK") == 0 ) + getfunc = basilisk_respond_geckogetblock; + else if ( strcmp(type,"GTX") == 0 ) + getfunc = basilisk_respond_geckogettx; + else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); + if ( (serialized= ((struct iguana_peer *)addr)->blockspace) == 0 ) + return(clonestr("{\"error\":\"peer has no blockspace\"}")); + maxsize = IGUANA_MAXPACKETSIZE; + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + datalen = (*getfunc)(myinfo,virt,serialized,maxsize,valsobj,hash2); + return(basilisk_standardreturn(CMD,type,virt,serialized,len)); + } else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); + } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); +} + +char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + return(gecko_headersarrived(myinfo,virt,addr,data,datalen,hash2)); + else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); +} + char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk) { bits256 checktxid; int32_t blocklen; uint32_t nBits; char *symbol,*blockstr,*txptrs[2],space[4096]; struct iguana_info *virt; cJSON *sendjson; struct iguana_block newblock; uint8_t *blockdata,*allocptr,blockspace[8192]; @@ -362,7 +456,7 @@ char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr newblock.height = virt->blocks.hwmchain.height + 1; newblock.RO.prev_block = virt->blocks.hwmchain.RO.prev_block; newblock.RO.version = GECKO_DEFAULTVERSION; - if ( bits256_cmp(txid,checktxid) == 0 && (nBits= gecko_nBits(virt,&newblock)) != 0 ) + if ( bits256_cmp(txid,checktxid) == 0 && (nBits= gecko_nBits(virt,&newblock,GECKO_DIFFITERS)) != 0 ) { newblock.RO.bits = nBits; txptrs[0] = basilisk_addhexstr(&txptrs[1],0,space,sizeof(space),data,datalen); // add mempool @@ -396,12 +490,12 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a if ( (symbol= jstr(valsobj,"coin")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) { hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); - nBits = gecko_nBits(virt,(struct iguana_block *)&virt->blocks.hwmchain); + nBits = gecko_nBits(virt,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS); if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits) == 0 ) { iguana_rwblock(symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&checkhash2,data,&msg,datalen); if ( bits256_cmp(hash2,checkhash2) == 0 ) - return(gecko_blockarrived(myinfo,virt,addr,data,datalen)); + return(gecko_blockarrived(myinfo,virt,addr,data,datalen,hash2)); else return(clonestr("{\"error\":\"block error with checkhash2\"}")); } else return(clonestr("{\"error\":\"block nonce didnt verify\"}")); } @@ -436,7 +530,7 @@ HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr) if ( (isPoS= juint(vals,"isPoS")) == 0 ) isPoS = 1; //printf("netmagic.%s\n",magicstr); - if ( (argjson= gecko_genesisjson(myinfo,btcd,isPoS,symbol,chainname,vals,magicstr)) != 0 ) + if ( (argjson= gecko_genesisjson(myinfo,btcd,isPoS,symbol,chainname,vals,magicstr,juint(vals,"blocktime"))) != 0 ) { argvals = gecko_genesisissue(symbol,chainname,chainstr,argjson); if ( btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0 ) @@ -488,8 +582,17 @@ HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr) HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr) { - return(clonestr("{\"error\":\"geckoblock is an internal function\"}")); - //return(basilisk_standardservice("BLK",myinfo,pubkey,vals,hexstr,1)); + return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoheaders,pubkey,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoget,pubkey,vals,hexstr) +{ + return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,pubkey,0)); } HASH_ARRAY_STRING(basilisk,geckogenesis,pubkey,vals,hexstr) diff --git a/gecko/gecko.h b/gecko/gecko.h index 449ea0965..8025a7ccd 100755 --- a/gecko/gecko.h +++ b/gecko/gecko.h @@ -20,13 +20,15 @@ #define GECKO_MAXBTCDGAP 18 #define GECKO_DEFAULTVERSION 1 -#define GECKO_DEFAULTDIFF 0x1fffffff -#define GECKO_DEFAULTDIFFSTR "1fffffff" +#define GECKO_EASIESTDIFF 0x1fffffff +#define GECKO_DEFAULTDIFF 0x1f00ffff +#define GECKO_DEFAULTDIFFSTR "1f00ffff" #define GECKO_FIRSTPOSSIBLEBTC 414000 #define GECKO_FIRSTPOSSIBLEBTCD 1100000 #define GECKO_MAXNAMELEN 64 #define GECKO_MAXMINERITERS 10000000 +#define GECKO_DIFFITERS 3 struct iguana_peer; @@ -48,11 +50,14 @@ char *basilisk_respond_hashstamps(struct supernet_info *myinfo,char *CMD,void *a char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); +char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk); +char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk); void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr); void gecko_seqresult(struct supernet_info *myinfo,char *retstr); int32_t gecko_sequpdate(char *symbol,uint32_t reftimestamp); -char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen); -char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen); +char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); +char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); +char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); #endif diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index 339d7512d..69b9dedb8 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -15,22 +15,125 @@ // included from gecko.c -char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen) +char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) { return(clonestr("{\"result\":\"gecko headers queued\"}")); } -char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen) +char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 txid) { - struct iguana_txblock txdata; int32_t n,len = -1; struct iguana_msghdr H; + return(clonestr("{\"result\":\"gecko headers queued\"}")); +} + +struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_block *block,int32_t origheight,int32_t depth) +{ + int32_t hdrsi,bundlei,i,iter,checkbundlei,height = origheight; bits256 zero; struct iguana_block *prev; struct iguana_bundle *bp = 0; + memset(zero.bytes,0,sizeof(zero)); + for (iter=0; iter<2; iter++) + { + prev = block; + height = block->height; + for (i=0; ichain->bundlesize); + hdrsi = (height / virt->chain->bundlesize); + if ( iter == 1 ) + { + if ( (bp= virt->bundles[hdrsi]) != 0 ) + { + bp->blocks[bundlei] = prev; + bp->hashes[bundlei] = prev->RO.hash2; + } + else + { + printf("cant find bundle for ht.%d\n",height); + return(0); + } + } + else if ( bundlei == 0 && virt->bundles[hdrsi] == 0 ) + iguana_bundlecreate(virt,&checkbundlei,height,prev->RO.hash2,zero,0); + prev = iguana_blockfind("geckoensure",virt,prev->RO.prev_block); + } + } + hdrsi = (block->height / virt->chain->bundlesize); + return(virt->bundles[hdrsi]); +} + +char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) +{ + struct iguana_txblock txdata; int32_t valid,adjacent,n,i,hdrsi,j,len = -1; struct iguana_peer *addr; struct iguana_block *block,*prev; struct iguana_bundle *bp; + memset(&txdata,0,sizeof(txdata)); if ( virt->TXMEM.ptr == 0 ) iguana_meminit(&virt->TXMEM,virt->name,0,IGUANA_MAXPACKETSIZE * 2,0); iguana_memreset(&virt->TXMEM); - memset(&txdata,0,sizeof(txdata)); + addr = &virt->internaladdr; if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen ) { - memset(&H,0,sizeof(H)); - iguana_gotblockM(virt,addr,&txdata,virt->TXMEM.ptr,&H,data,datalen); - return(clonestr("{\"result\":\"gecko block queued\"}")); - } else return(clonestr("{\"error\":\"gecko block didnt decode\"}")); + if ( bits256_cmp(hash2,txdata.zblock.RO.hash2) != 0 ) + { + printf("gecko_blockarrived: mismatched hash2\n"); + return(clonestr("{\"error\":\"gecko block hash2 mismatch\"}")); + } + txdata.zblock.RO.allocsize = sizeof(struct iguana_block); + if ( iguana_blockvalidate(virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 ) + { + char str[65]; printf("got block that doesnt validate? %s\n",bits256_str(str,txdata.zblock.RO.hash2)); + return(clonestr("{\"error\":\"gecko block didnt validate\"}")); + } + if ( (block= iguana_blockfind("geckoblock",virt,hash2)) == 0 ) + { + if ( (block= iguana_blockhashset("geckoblock",virt,-1,hash2,1)) == 0 ) + return(clonestr("{\"error\":\"gecko block couldnt be created\"}")); + } + iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata.zblock); + prev = block; + adjacent = -1; + for (i=0; ichain->bundlesize; i++) + { + if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 ) + return(clonestr("{\"error\":\"gecko block is orphan\"}")); + if ( i == 0 ) + adjacent = prev->height; + //printf("i.%d prevht.%d adjacent.%d hwm.%d\n",i,prev->height,adjacent,virt->blocks.hwmchain.height); + if ( prev->height >= 0 ) + { + block->height = adjacent + 1; + if ( block->height > virt->blocks.hwmchain.height ) // longest chain wins + { + //printf("new HWM %d adjacent.%d prev.%d i.%d\n",block->height,adjacent,prev->height,i); + block->mainchain = 1; + prev = block; + // probably should clear mainchain bits in old path + for (j=0; j<=i; j++) + { + if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 ) + return(clonestr("{\"error\":\"gecko block mainchain link error\"}")); + prev->mainchain = 1; + } + iguana_blockzcopy(virt->chain->zcash,(void *)&virt->blocks.hwmchain,block); + if ( gecko_ensurebundle(virt,block,block->height,i+1) == 0 ) + return(clonestr("{\"error\":\"gecko bundle couldnt be created\"}")); + if ( iguana_ramchain_data(virt,addr,&txdata,virt->TXMEM.ptr,txdata.zblock.RO.txn_count,data,datalen) >= 0 ) + { + block->fpipbits = (uint32_t)addr->ipbits; + block->RO.recvlen = datalen; + block->txvalid = 1; + hdrsi = block->height / virt->chain->bundlesize; + if ( (bp= virt->bundles[hdrsi]) != 0 ) + { + bp->numsaved++; + if ( (block->height % virt->chain->bundlesize) == 13 && hdrsi > 0 && (bp= virt->bundles[hdrsi - 1]) != 0 && bp->emitfinish == 0 && bp->numsaved >= bp->n ) + iguana_bundlefinalize(virt,bp,&virt->MEM,virt->MEMB); + } + //printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved); + return(clonestr("{\"result\":\"gecko block created\"}")); + } else return(clonestr("{\"error\":\"gecko error creating ramchain0\"}")); + } + } + } + } + return(clonestr("{\"error\":\"gecko block didnt decode\"}")); } + diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c index ede140a24..4a8d38d3e 100755 --- a/gecko/gecko_miner.c +++ b/gecko/gecko_miner.c @@ -25,19 +25,85 @@ int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int else return(0); } -uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *newblock) +/*uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag,int32_t targetspacing,int32_t targettimespan) { - uint32_t nBits = GECKO_DEFAULTDIFF; struct iguana_block *prev=0,*prev2=0; - if ( newblock->height >= 0 && (prev= iguana_blockfind("geckotx",virt,newblock->RO.prev_block)) != 0 && prev->height > 1 ) + // targetspacing NTARGETSPACING, mspacing NINTERVAL_MSPACING, pspacing NINTERVAL_PSPACING + bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 cmpval); + bits256 targetval; int32_t gap,mspacing,pspacing; + if ( hwmchain->height <= 2 || hwmchain->height <= 0 ) + return(hwmchain->RO.bits); + mspacing = (((targettimespan / targetspacing) - 1) * targetspacing); + pspacing = (((targettimespan / targetspacing) + 1) * targetspacing); + targetval = iguana_targetval(coin,hwmchain->height,PoSflag); + if ( prev != 0 ) + { + if ( prev2 != 0 && prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 ) + { + //if ( prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 ) skip check for compatiblity + { + if ( (gap= prev->RO.timestamp - prev2->RO.timestamp) < 0 ) + gap = targetspacing; + //printf("nBits.%08x gap.%d (%u - %u)\n",prev->RO.bits,gap,prev->RO.timestamp,prev2->RO.timestamp); + targetval = mpz_muldivcmp(bits256_from_compact(prev->RO.bits),mspacing + (gap << 1),pspacing,targetval); + } + } + } + return(bits256_to_compact(targetval)); +}*/ + +uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *block,int32_t n) +{ + uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval; + if ( virt->chain->estblocktime == 0 ) + return(GECKO_EASIESTDIFF); + for (i=0; iRO.prev_block)) == 0 || prev->height == 0 ) + { + i++; + break; + } + if ( i == 0 ) + { + endtime = prev->RO.timestamp; + nBits = prev->RO.bits; + } + starttime = prev->RO.timestamp; + block = prev; + } + if ( starttime != 0 && endtime > starttime && i > 1 ) + { + diff = (endtime - starttime); + est = virt->chain->estblocktime * i; + targetval = bits256_from_compact(nBits); + if ( diff > est ) + { + targetval = bits256_rshift(bits256_add(targetval,bits256_lshift(targetval))); + } + else if ( diff < est ) + { + targetval = bits256_rshift(bits256_add(targetval,bits256_rshift(targetval))); + } + //printf("diff.%d est.%d nBits.%08x <- %08x\n",endtime - starttime,virt->chain->estblocktime * i,bits256_to_compact(targetval),nBits); + nBits = bits256_to_compact(targetval); + } + if ( nBits > GECKO_EASIESTDIFF ) + { + printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF); + nBits = GECKO_EASIESTDIFF; + } + /*if ( newblock->height >= 0 && (prev= iguana_blockfind("geckotx",virt,newblock->RO.prev_block)) != 0 && prev->height > 1 ) { if ( (prev2= iguana_blockfind("prvatetx2",virt,prev->RO.prev_block)) != 0 && prev2->height >= 0 ) { nBits = iguana_targetbits(virt,newblock,prev,prev2,1,virt->chain->targetspacing,virt->chain->targettimespan); - if ( nBits > virt->chain->nBits ) - nBits = virt->chain->nBits; + if ( nBits > GECKO_EASIESTDIFF ) + { + printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF); + nBits = GECKO_EASIESTDIFF; + } } - else nBits = virt->chain->nBits; - } else printf("ht.%d prev.%p prevht.%d prev2.%p\n",newblock->height,prev,prev!=0?prev->height:-1,prev2); + } else printf("ht.%d prev.%p prevht.%d prev2.%p\n",newblock->height,prev,prev!=0?prev->height:-1,prev2);*/ return(nBits); } @@ -216,11 +282,11 @@ char **gecko_mempool(struct supernet_info *myinfo,struct iguana_info *virt,int64 return(0); } -void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr) +void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2) { uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr; if ( (peers= virt->peers) == 0 || (numranked= peers->numranked) == 0 ) - basilisk_blocksubmit(myinfo,virt,blockstr); + basilisk_blocksubmit(myinfo,virt,blockstr,hash2); else { if ( (data= get_dataptr(sizeof(struct iguana_msghdr),&allocptr,&len,space,sizeof(space),blockstr)) != 0 ) @@ -239,13 +305,14 @@ void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,cha void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr) { struct iguana_zblock newblock; uint32_t nBits,locktime=0; int64_t reward = 0; int32_t bundlei,txn_count; cJSON *item,*array,*coinbasetx=0; char *blockstr,**txptrs,*ptr,*space[256]; struct iguana_bundle *bp; - if ( virt->virtualchain == 0 || virt->bundles[virt->blocks.hwmchain.height / virt->chain->bundlesize] == 0 ) + if ( virt->virtualchain == 0 )//|| virt->bundles[virt->blocks.hwmchain.height / virt->chain->bundlesize] == 0 ) return; memset(&newblock,0,sizeof(newblock)); newblock.height = virt->blocks.hwmchain.height + 1; newblock.RO.prev_block = virt->blocks.hwmchain.RO.hash2; newblock.RO.version = GECKO_DEFAULTVERSION; - if ( (nBits= gecko_nBits(virt,(void *)&newblock)) != 0 ) + newblock.RO.allocsize = sizeof(struct iguana_block); + if ( (nBits= gecko_nBits(virt,(void *)&newblock,GECKO_DIFFITERS)) != 0 ) { newblock.RO.bits = nBits; //printf("mine.%s %s nBits.%x\n",virt->symbol,mineraddr,nBits); @@ -271,11 +338,11 @@ void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct ig iguana_hash2set(virt,"miner",bp,bundlei,newblock.RO.hash2); if ( iguana_bundlefind(virt,&bp,&bundlei,newblock.RO.hash2) == 0 ) printf("cant find ht.%d %s\n",newblock.height,bits256_str(str,newblock.RO.hash2)); - else printf("found bp.%p bundlei.%d\n",bp,bundlei); + //else printf("found bp.%p bundlei.%d\n",bp,bundlei); } - virt->blocks.hwmchain = newblock; - char str[65]; printf("%s mined.%x %s isPoS.%d numtx.%d ht.%d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),virt->chain->isPoS,newblock.RO.txn_count,newblock.height); - gecko_blocksubmit(myinfo,virt,blockstr); + //virt->blocks.hwmchain = newblock; + //char str[65]; printf("%s mined.%x %s %u ht.%d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height); + gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2); free(blockstr); } if ( txptrs != space ) diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 48b4db9a1..af4bbc96f 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -47,12 +47,21 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson) coin = mycalloc('C',1,sizeof(*coin)); coin->blockspacesize = IGUANA_MAXPACKETSIZE + 8192; coin->blockspace = calloc(1,coin->blockspacesize); - coin->peers = calloc(1,sizeof(*coin->peers)); - for (j=0; jpeers->active[j].usock = -1; - strcpy(coin->peers->active[j].coinname,name); - strcpy(coin->peers->active[j].symbol,symbol); + myinfo->allcoins_numvirts++; + coin->virtualchain = 1; + } + else + { + coin->chain = iguana_chainfind((char *)symbol,argjson,1); + coin->peers = calloc(1,sizeof(*coin->peers)); + for (j=0; jpeers->active[j].usock = -1; + strcpy(coin->peers->active[j].coinname,name); + strcpy(coin->peers->active[j].symbol,symbol); + } } if ( (coin->protocol= juint(argjson,"protocol")) == 0 ) coin->protocol = IGUANA_PROTOCOL_BITCOIN; @@ -61,11 +70,6 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson) secp256k1_rangeproof_context_initialize(coin->ctx); strcpy(coin->name,name); strcpy(coin->symbol,symbol); - if ( (privatechain= jstr(argjson,"privatechain")) != 0 && privatechain[0] != 0 ) - { - myinfo->allcoins_numvirts++; - coin->virtualchain = 1; - } else coin->chain = iguana_chainfind((char *)symbol,argjson,1); iguana_initcoin(coin,argjson); basilisk_functions(coin,coin->protocol); printf("ADD ALLCOINS.(%s) name.(%s) size %ld numvirts.%d\n",symbol,name,sizeof(*coin),myinfo->allcoins_numvirts); @@ -654,11 +658,26 @@ void iguana_helper(void *arg) void iguana_callcoinstart(struct iguana_info *coin) { - struct iguana_bundle *bp; int32_t bundlei; bits256 zero; + struct iguana_bundle *bp; int32_t bundlei; bits256 zero; char dirname[512],*symbol; iguana_rwiAddrind(coin,0,0,0); //for (i=0; ichain); i++) // printf("%02x",((uint8_t *)coin->chain)[i]); char str[65]; printf(" netmagic.%08x init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",*(uint32_t *)coin->chain->netmagic,coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND); + symbol = coin->symbol; + sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/purgeable/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + if ( coin->VALIDATEDIR[0] != 0 ) + { + sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname); + } + sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); iguana_coinstart(coin,coin->initialheight,coin->mapflags); coin->chain->minconfirms = coin->minconfirms; coin->started = coin; @@ -798,11 +817,12 @@ void iguana_nameset(char name[64],char *symbol,cJSON *json) 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 maxrequests,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512],name[64]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char name[64]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; iguana_nameset(name,symbol,json); if ( (coin= iguana_coinfind(symbol)) == 0 ) coin = iguana_coinadd(symbol,name,json); + //printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND); mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 32; maxval = IGUANA_MAXPENDBUNDLES; if ( coin->virtualchain == 0 ) @@ -865,21 +885,6 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->active = juint(json,"active"); if ( (coin->minconfirms = minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; - //printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND); - sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname); - sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/purgeable/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - if ( coin->VALIDATEDIR[0] != 0 ) - { - sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname); - } - sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); if ( coin->chain == 0 && (coin->chain= iguana_createchain(json)) == 0 ) { printf("cant initialize chain.(%s)\n",jstr(json,0)); diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 04ee6ebaa..0d513f12f 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -286,9 +286,24 @@ int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits2 return(len - sizeof(struct iguana_msghdr)); } +int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block) +{ + bits256 checkhash2; struct iguana_msgblock msgB; int32_t len = 0; + iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1); + if ( (len= iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr)],&msgB,(int32_t)(maxsize-sizeof(struct iguana_msghdr)))) < 0 ) + return(-1); + if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + { + char str[65],str2[65]; + printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",block->height,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); + return(-1); + } + return(len); +} + int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2) { - int32_t len=0,i,flag=0,height,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_msgblock msgB; bits256 checkhash2; struct iguana_bundle *bp; + int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_bundle *bp; if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1)) != 0 ) { bundlesize = coin->chain->bundlesize; @@ -300,15 +315,12 @@ int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32 { if ( (block= bp->blocks[i]) != 0 ) { - iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1); - len += iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr) + len],&msgB,(int32_t)(maxsize-len-sizeof(struct iguana_msghdr))); - flag++; - if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + if ( (n= iguana_headerget(coin,&serialized[len],maxsize-len,block)) < 0 ) { - char str[65],str2[65]; - printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",height+i,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); - return(-1); + printf("%s error getting header ht.%d\n",coin->symbol,block->height); + continue; } + len += n; } else printf("cant find block at ht.%d\n",height+i); } } diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 53792cca1..967cb56fc 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -217,12 +217,12 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo } if ( bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) { - char str[65],str2[65]; - printf("bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); + //char str[65],str2[65]; + //printf("B bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); iguana_blockunmark(coin,block,bp,bundlei,1); bp->blocks[bundlei] = 0; //if ( block->mainchain != 0 ) - // bp->hashes[bundlei] = block->RO.hash2; + // bp->hashes[bundlei] = block->RO.hash2; return(-1); } @@ -805,6 +805,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int if ( 0 && requiredflag != 0 ) printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(coin,&valid,block,1) < 0,bp->hdrsi,i); } + else printf("cant find (%s)\n",fname); } } else @@ -819,6 +820,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int } } } + printf("ready.%d\n",ready); return(ready); } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 8bb682685..4d4d0db35 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -287,6 +287,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) { extern char Userhome[]; char *path,conf[512],*hexstr,genesisblock[1024]; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; + printf("chainparams.(%s)\n",jprint(argjson,0)); if ( strcmp(chain->symbol,"NXT") != 0 ) { if ( strcmp(chain->symbol,"BTCD") == 0 ) @@ -294,7 +295,8 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) if ( (chain->minoutput= j64bits(argjson,"minoutput")) == 0 ) chain->minoutput = 10000; chain->minconfirms = juint(argjson,"minconfirms"); - chain->estblocktime = juint(argjson,"estblocktime"); + if ( (chain->estblocktime= juint(argjson,"estblocktime")) == 0 ) + chain->estblocktime = juint(argjson,"blocktime"); path = jstr(argjson,"path"); if ( jobj(argjson,"conf") == 0 ) conf[0] = 0; @@ -347,10 +349,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) if ( (hexstr= jstr(argjson,"wifval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->wiftype,1,hexstr); if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 ) - { decode_hex((uint8_t *)chain->netmagic,4,hexstr); - printf("NETMAGIC.(%s) -> %08x\n",hexstr,*(uint32_t *)chain->netmagic); - } if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->unitval,1,hexstr); if ( (hexstr= jstr(argjson,"alertpubkey")) != 0 && (strlen(hexstr)>>1) <= sizeof(chain->alertpubkey) ) @@ -371,8 +370,10 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) ((uint8_t *)&nBits)[1] = tmp[2]; ((uint8_t *)&nBits)[2] = tmp[1]; ((uint8_t *)&nBits)[3] = tmp[0]; - } - else nBits = 0x1e00ffff; + } else nBits = 0x1e00ffff; + chain->nBits = nBits; + chain->unitval = (nBits >> 24); + printf("NETMAGIC %08x unitval.%02x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,chain->nBits); chain->genesishash2 = iguana_chaingenesis(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,chain->genesishash2,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); memcpy(chain->genesis_hashdata,chain->genesishash2.bytes,32); char str[65]; init_hexbytes_noT(str,chain->genesis_hashdata,32); @@ -381,6 +382,17 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) } else { + if ( jstr(argjson,"nBits") != 0 ) + { + decode_hex((void *)&tmp,sizeof(tmp),jstr(argjson,"nBits")); + ((uint8_t *)&nBits)[0] = tmp[3]; + ((uint8_t *)&nBits)[1] = tmp[2]; + ((uint8_t *)&nBits)[2] = tmp[1]; + ((uint8_t *)&nBits)[3] = tmp[0]; + } else nBits = 0x1e00ffff; + chain->nBits = nBits; + chain->unitval = (nBits >> 24); + printf("NETMAGIC -> %08x unitval.%02x (%s) -> tmp.%08x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,jstr(argjson,"nBits"),*(uint32_t *)tmp,chain->nBits); if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) { uint8_t hexbuf[1024],*ptr,*data; int32_t datalen,hdrsize; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 00fe88792..f74adac36 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -104,7 +104,7 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) auxback = coin->chain->auxpow, coin->chain->auxpow = 0; iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,buf,&msg,sizeof(buf)); coin->chain->auxpow = auxback; - if ( coin->virtualchain != 0 || coin->MAXPEERS > 1 ) + if ( coin->virtualchain == 0 && coin->MAXPEERS > 1 ) { if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) { @@ -127,9 +127,10 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) ptr->mainchain = 1; ptr->height = 0; //coin->blocks.RO[0] = block.RO; - if ( (height= iguana_chainextend(coin,ptr)) == 0 ) + if ( coin->virtualchain != 0 || (height= iguana_chainextend(coin,ptr)) == 0 ) { iguana_blockzcopy(coin->chain->zcash,block,ptr); + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,ptr); printf("size.%d genesis block PoW %f ptr %f\n",block->RO.allocsize,block->PoW,ptr->PoW); coin->blocks.recvblocks = coin->blocks.issuedblocks = 1; } else printf("genesis block doesnt validate for %s ht.%d\n",coin->symbol,height); @@ -520,11 +521,14 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei int32_t bundlei = -2; static const bits256 zero; iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1); - _iguana_chainlink(coin,iguana_blockfind("genesis",coin,*(bits256 *)coin->chain->genesis_hashdata)); - if ( coin->blocks.hwmchain.height != 0 || memcmp(coin->blocks.hwmchain.RO.hash2.bytes,coin->chain->genesis_hashdata,sizeof(coin->chain->genesis_hashdata)) != 0 ) + if ( coin->virtualchain == 0 ) { - char str[65]; printf("%s genesis values mismatch hwmheight.%d %.15f %.15f %s\n",coin->name,coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW,coin->blocks.hwmchain.PoW,bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - getchar(); + _iguana_chainlink(coin,iguana_blockfind("genesis",coin,*(bits256 *)coin->chain->genesis_hashdata)); + if ( coin->blocks.hwmchain.height != 0 || memcmp(coin->blocks.hwmchain.RO.hash2.bytes,coin->chain->genesis_hashdata,sizeof(coin->chain->genesis_hashdata)) != 0 ) + { + char str[65]; printf("%s genesis values mismatch hwmheight.%d %.15f %.15f %s\n",coin->name,coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW,coin->blocks.hwmchain.PoW,bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + getchar(); + } } memset(&lastbundle,0,sizeof(lastbundle)); if ( coin->peers == 0 ) diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index b33d7fa53..cba3edf6c 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -799,7 +799,7 @@ char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) { - char hexstr[16384]; uint8_t databuf[8192]; cJSON *json; + char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; if ( message != 0 && message[0] != 0 ) { memset(hexstr,0,sizeof(hexstr)); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index a57720e08..35fcfc307 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -101,7 +101,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, bp = 0, bundlei = -2; if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) { - if ( 0 && dispflag != 0 ) + //if ( 0 && dispflag != 0 ) printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); } @@ -1050,7 +1050,8 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits #endif if ( (fp= fopen(fname,"wb")) == 0 ) printf("iguana_ramchain_save: couldnt create.(%s) errno.%d\n",fname,errno); - else coin->peers->numfiles++; + else if ( coin->peers != 0 ) + coin->peers->numfiles++; if ( fp != 0 ) { fpos = ftell(fp); @@ -2603,7 +2604,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { for (j=starti; j<=endi; j++) { - if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 ) + if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 && coin->peers != 0 ) coin->peers->numfiles -= OS_removefile(fname,0); else printf("error removing.(%s)\n",fname); } diff --git a/iguana/iguana_stake.c b/iguana/iguana_stake.c index a3ab90df8..fe36b9429 100644 --- a/iguana/iguana_stake.c +++ b/iguana/iguana_stake.c @@ -87,8 +87,7 @@ uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchai { if ( (gap= prev->RO.timestamp - prev2->RO.timestamp) < 0 ) gap = targetspacing; - // ppcoin: target change every block, retarget with exponential moving toward target spacing - //printf("MSPACING.%d gap.%d\n",NINTERVAL_MSPACING,gap); + //printf("nBits.%08x gap.%d (%u - %u)\n",prev->RO.bits,gap,prev->RO.timestamp,prev2->RO.timestamp); targetval = mpz_muldivcmp(bits256_from_compact(prev->RO.bits),mspacing + (gap << 1),pspacing,targetval); } } diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index 3eb558eab..a26ac244f 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -354,7 +354,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 jaddnum(json,"valid",block->valid); jaddnum(json,"txn_count",block->RO.txn_count); - jaddnum(json,"bits",block->RO.bits); + jaddnum(json,"nBits",block->RO.bits); serialized[0] = ((uint8_t *)&block->RO.bits)[3]; serialized[1] = ((uint8_t *)&block->RO.bits)[2]; serialized[2] = ((uint8_t *)&block->RO.bits)[1]; diff --git a/iguana/tests/new b/iguana/tests/new index 1e6312fc9..3d15a1c1d 100755 --- a/iguana/tests/new +++ b/iguana/tests/new @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newprivatechain\",\"vals\":{\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"blocktime\":0,\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index ff0e1a2f8..a480aad85 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -21,12 +21,15 @@ INT_AND_ARRAY(basilisk,result,basilisktag,vals); HASH_ARRAY_STRING(basilisk,geckogenesis,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckoheaders,pubkey,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckoget,pubkey,vals,hexstr); + HASH_ARRAY_STRING(basilisk,addrelay,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,dispatch,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,publish,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,subscribe,pubkey,vals,hexstr); -HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr); -HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,forward,pubkey,vals,hexstr); HASH_ARRAY_STRING(basilisk,mailbox,pubkey,vals,hexstr); diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index f778e50a0..aa8a797ce 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -486,7 +486,7 @@ void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_blo int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block); void basilisk_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr); int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); -int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr); +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2); struct supernet_info *SuperNET_MYINFO(char *passphrase); bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash); @@ -500,6 +500,8 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr); char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr); char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); +int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block); +int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB); #include "../includes/iguana_api.h"