From 20d5b381bd3f098635970c999898d375b6958ddf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 18 Jun 2016 10:43:46 -0300 Subject: [PATCH] test --- basilisk/basilisk.c | 56 ++++++++++++------- crypto777/OS_portable.h | 1 + crypto777/iguana_utils.c | 5 ++ gecko/gecko.c | 112 +++++--------------------------------- gecko/gecko.h | 4 +- gecko/gecko_blocks.c | 54 +++++++++--------- gecko/gecko_headers.c | 101 ++++++++++++++++++++++++++++++++++ gecko/gecko_mempool.c | 78 ++++++++++++++++++++++++-- gecko/gecko_miner.c | 95 +++++++++++++++++++------------- iguana/iguana_chains.c | 2 + iguana/iguana_payments.c | 8 +-- iguana/iguana_rpc.c | 13 +++-- iguana/iguana_sign.c | 8 ++- iguana/main.c | 2 +- iguana/tests/creategtx | 2 + iguana/tests/decodegtx | 1 + iguana/tests/gtx | 1 + iguana/tests/vtx | 1 - includes/iguana_funcs.h | 2 +- includes/iguana_structs.h | 1 - 20 files changed, 341 insertions(+), 206 deletions(-) create mode 100755 gecko/gecko_headers.c create mode 100755 iguana/tests/creategtx create mode 100755 iguana/tests/decodegtx create mode 100755 iguana/tests/gtx delete mode 100755 iguana/tests/vtx diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 98b98a9b1..d23baf036 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -354,7 +354,7 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) { - int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag; struct basilisk_item *ptr; char buf[4096],*str = 0; + int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt; basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); if ( jobj(valsobj,"hash") != 0 ) jdelete(valsobj,"hash"); @@ -364,6 +364,15 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char minresults = 1; if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) timeoutmillis = BASILISK_TIMEOUT; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + jaddstr(valsobj,"coin",symbol); + jaddnum(valsobj,"longest",virt->longestchain); + jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); + } + } encryptflag = jint(valsobj,"encrypt"); delaymillis = jint(valsobj,"delay"); ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",valsobj,1,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); @@ -565,12 +574,7 @@ char *_basilisk_rawtx(struct supernet_info *myinfo,struct iguana_info *coin,stru char *_basilisk_result(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) { - char *retstr;//,*str = 0; //strbuf[4096], - //basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - retstr = basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj); - //if ( str != 0 ) - // free(str); - return(retstr); + return(basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj)); } char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) @@ -607,29 +611,30 @@ int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *ad len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myinfo->relaybits[i]); init_hexbytes_noT(hexstr,serialized,len); vals = cJSON_CreateObject(); - if ( (retstr= basilisk_standardservice("REL",myinfo,hash,vals,hexstr,1)) != 0 ) + if ( (retstr= basilisk_standardservice("REL",myinfo,hash,vals,hexstr,0)) != 0 ) free(retstr); free_json(vals); return(0); } else return(-1); } -int32_t basilisk_headers_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,bits256 *txids,int32_t num) +int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *hashes,int32_t num) { bits256 hash; uint8_t *serialized; int32_t i,len = 0; char *str=0,*retstr,*hexstr,*allocptr=0,space[8192]; bits256 txid; cJSON *vals; if ( virt != 0 && addr != 0 ) { memset(hash.bytes,0,sizeof(hash)); - serialized = (void *)txids; + serialized = (void *)hashes; for (i=0; isymbol); + if ( (retstr= basilisk_standardservice(CMD,myinfo,hash,vals,hexstr,0)) != 0 ) free(retstr); free_json(vals); if ( allocptr != 0 ) @@ -753,6 +758,8 @@ HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr) #include "../includes/iguana_apiundefs.h" +// set hwm, get headers, then blocks + 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; @@ -863,7 +870,7 @@ void basilisks_loop(void *arg) pending->finished = (uint32_t)time(NULL); if ( pending->retstr == 0 ) pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); - printf("timeout call metrics.%u lag %f - %f\n",pending->basilisktag,OS_milliseconds(),pending->expiration); + printf("timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); for (i=0; inumresults; i++) if ( (metricfunc= pending->metricfunc) != 0 ) pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); @@ -877,7 +884,7 @@ void basilisks_loop(void *arg) HASH_DELETE(hh,myinfo->basilisks.issued,pending); if ( pending->dependents != 0 ) free(pending->dependents); - printf("HASH_DELETE free ptr.%u\n",pending->basilisktag); + //printf("HASH_DELETE free ptr.%u\n",pending->basilisktag); for (i=0; inumresults; i++) if ( pending->results[i] != 0 ) free(pending->results[i]), pending->results[i] = 0; @@ -927,16 +934,13 @@ void basilisks_loop(void *arg) } if ( flag == 0 && myinfo->allcoins_numvirts > 0 ) { - char mineraddr[64]; maxmillis = (1000 / myinfo->allcoins_numvirts) + 1; //portable_mutex_lock(&Allcoins_mutex); HASH_ITER(hh,myinfo->allcoins,virt,hhtmp) { if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 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,myinfo->persistent_pubkey33); + gecko_iteration(myinfo,btcd,virt,maxmillis); flag++; } } @@ -981,9 +985,9 @@ void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) } } -void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) +void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) { - cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; + cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; static basilisk_servicefunc *basilisk_services[][2] = { { (void *)"RUN", &basilisk_respond_dispatch }, // higher level protocol handler, pass through @@ -1027,6 +1031,18 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender { if ( jobj(valsobj,"coin") != 0 ) coin = iguana_coinfind(jstr(valsobj,"coin")); + else if ( jobj(valsobj,"symbol") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"symbol")); + if ( coin != 0 ) + { + if ( (height= juint(valsobj,"hwm")) > 0 ) + { + if ( height > addr->height ) + addr->height = height; + if ( height > coin->longestchain ) + coin->longestchain = height; + } + } if ( strcmp(type,"RET") == 0 ) { if ( (retstr= _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen)) != 0 ) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index dac36c990..e18d65156 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -359,6 +359,7 @@ int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +bits256 bits256_ave(bits256 a,bits256 b); bits256 bits256_doublesha256(char *hashstr,uint8_t *data,int32_t datalen); char *bits256_str(char hexstr[65],bits256 x); char *bits256_lstr(char hexstr[65],bits256 x); diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index a253f722a..e18c127f0 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -124,6 +124,11 @@ bits256 bits256_lshift(bits256 x) return(x); } +bits256 bits256_ave(bits256 a,bits256 b) +{ + return(bits256_rshift(bits256_add(a,b))); +} + bits256 bits256_from_compact(uint32_t c) { diff --git a/gecko/gecko.c b/gecko/gecko.c index f089996d1..499376a2f 100755 --- a/gecko/gecko.c +++ b/gecko/gecko.c @@ -34,6 +34,7 @@ #include "../iguana/iguana777.h" #include "gecko_delayedPoW.c" +#include "gecko_headers.c" #include "gecko_mempool.c" #include "gecko_miner.c" #include "gecko_blocks.c" @@ -200,12 +201,14 @@ cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,c jaddnum(argvals,"services",129); jaddnum(argvals,"portp2p",port); } + if ( blocktime == 0 ) + blocktime = 1; jaddnum(argvals,"blocktime",blocktime); if ( blocktime != 0 ) { if ( blocktime == 0xffff ) targetspacing = 24 * 60 * 60; // one day - else targetspacing = 60; // one minute + else targetspacing = blocktime; // one minute jaddnum(argvals,"targetspacing",targetspacing); if ( (timespan= sqrt(604800 / targetspacing)) < 7 ) timespan = 7; @@ -228,7 +231,8 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i decode_hex(&buf[3-i],1,&nbitstr[i*2]); memcpy(&nBits,buf,sizeof(nBits)); } - blocktime = juint(valsobj,"blocktime"); + if ( (blocktime= juint(valsobj,"blocktime")) == 0 ) + blocktime = 1; if ( (pubstr= jstr(valsobj,"pubval")) == 0 ) pubstr = "00"; if ( (p2shstr= jstr(valsobj,"p2shval")) == 0 ) @@ -239,12 +243,12 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i memset(&genesis,0,sizeof(genesis)); genesis.RO.version = GECKO_DEFAULTVERSION; genesis.RO.bits = nBits; - if ( (blockstr= gecko_createblock(myinfo,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 ) + if ( (blockstr= gecko_createblock(myinfo,blocktime,0,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 ) { bits256_str(hashstr,genesis.RO.hash2); 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); + printf("argbuf.(%s) hash.%s\n",argbuf,hashstr); return(cJSON_Parse(argbuf)); } else return(cJSON_Parse("{\"error\":\"couldnt create block\"}")); } @@ -259,6 +263,7 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo { int32_t datalen,hdrsize,len=0; struct iguana_info *virt=0; char *hexstr; uint8_t hexbuf[1024],*ptr,*serialized; struct iguana_peer *addr; struct iguana_txblock txdata; portable_mutex_lock(&myinfo->gecko_mutex); + printf("symbol.%s chain.%s (%s)\n",symbol,chainname,jprint(valsobj,0)); if ( iguana_coinfind(symbol) == 0 && (hexstr= jstr(valsobj,"genesisblock")) != 0 && (virt= iguana_coinadd(symbol,chainname,valsobj)) != 0 ) { safecopy(virt->name,chainname,sizeof(virt->name)); @@ -267,7 +272,7 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo serialized = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,hexbuf,sizeof(hexbuf),hexstr); iguana_chaininit(virt->chain,1,valsobj); hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); - if ( gecko_blocknonce_verify(virt,serialized,hdrsize,virt->chain->nBits) == 0 ) + if ( gecko_blocknonce_verify(virt,serialized,hdrsize,virt->chain->nBits,0,0) >= 0 ) { virt->chain->genesishash2 = iguana_calcblockhash(symbol,virt->chain->hashalgo,serialized,hdrsize); memcpy(virt->chain->genesis_hashdata,virt->chain->genesishash2.bytes,sizeof(virt->chain->genesishash2)); @@ -315,7 +320,7 @@ char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void struct iguana_info *virt,*btcd; struct gecko_chain *chain; char fname[512],*symbol,*retstr,*chainstr,chainname[GECKO_MAXNAMELEN],*genesises; cJSON *chainjson,*retjson,*genesisjson; long filesize; FILE *fp; if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) { - printf("%s already exists\n",chainname); + //printf("%s already exists\n",chainname); return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); } if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (chainstr= jstr(valsobj,"chain")) != 0 ) @@ -383,7 +388,7 @@ int32_t gecko_genesises(struct supernet_info *myinfo,cJSON *array) { if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) { - printf("%s %s already exists\n",chainname,symbol); + //printf("%s %s already exists\n",chainname,symbol); continue; } if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) @@ -403,7 +408,7 @@ 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 *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint8_t *serialized,int32_t datalen,bits256 hash) { char space[16384],*allocstr = 0; cJSON *retjson = cJSON_CreateObject(); if ( datalen > 0 && basilisk_addhexstr(&allocstr,retjson,space,sizeof(space),serialized,datalen) != 0 ) @@ -413,7 +418,7 @@ char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint jaddstr(retjson,"coin",virt->symbol); jaddnum(retjson,"longest",virt->longestchain); jaddnum(retjson,"hwm",virt->blocks.hwmchain.height); - jaddbits256(retjson,"hash",virt->blocks.hwmchain.RO.hash2); + jaddbits256(retjson,"hash",hash); } else jaddstr(retjson,"error","no data to send"); if ( allocstr != 0 ) @@ -421,45 +426,6 @@ char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint 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; - // find block and 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; - // find txid and 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); @@ -479,59 +445,11 @@ char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *add 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)); + return(basilisk_standardreturn(CMD,type,virt,serialized,len,hash2)); } else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); } -char *basilisk_respond_mempool(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) -{ - char *symbol; struct iguana_info *virt; - if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) - return(gecko_mempoolarrived(myinfo,virt,_addr,data,datalen,hash)); - else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); -} - -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; char *symbol; struct iguana_info *virt; - if ( data != 0 && datalen != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) - { - checktxid = bits256_doublesha256(0,data,datalen); - if ( bits256_cmp(txid,checktxid) == 0 ) - return(gecko_txarrived(myinfo,virt,addr,data,datalen,txid)); - else return(clonestr("{\"error\":\"geckotx mismatched txid\"}")); - } - return(clonestr("{\"error\":\"no geckotx chain or missing tx data\"}")); -} - -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 hash2,int32_t from_basilisk) -{ - char *symbol; struct iguana_info *virt; bits256 checkhash2; int32_t hdrsize; uint32_t nBits; struct iguana_msgblock msg; - printf("got geckoblock len.%d from (%s) %s\n",datalen,remoteaddr!=0?remoteaddr:"",jprint(valsobj,0)); - 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,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,hash2)); - else return(clonestr("{\"error\":\"block error with checkhash2\"}")); - } else return(clonestr("{\"error\":\"block nonce didnt verify\"}")); - } - return(0); -} - #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" diff --git a/gecko/gecko.h b/gecko/gecko.h index 22cc02f49..1f905d188 100755 --- a/gecko/gecko.h +++ b/gecko/gecko.h @@ -28,7 +28,8 @@ #define GECKO_FIRSTPOSSIBLEBTCD 1100000 #define GECKO_MAXNAMELEN 64 #define GECKO_MAXMINERITERS 10000000 -#define GECKO_DIFFITERS 3 +#define GECKO_DIFFITERS 13 +#define GECKO_MAXFUTUREBLOCK 3 struct iguana_peer; @@ -79,5 +80,6 @@ char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt char *gecko_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx); struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct iguana_info *virt,int32_t *numotherp,uint32_t ipbits); +void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis); #endif diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index 77a513b47..64b498b70 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -15,35 +15,6 @@ // included from gecko.c -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_mempoolarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) -{ - int32_t i,j,numother,len = 0; struct gecko_mempool *otherpool; bits256 txid; - if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,(uint32_t)calc_ipbits(remoteaddr))) != 0 ) - { - if ( numother > 0 ) - { - for (i=0; inumtx; j++) - if ( bits256_cmp(txid,otherpool->txids[j]) == 0 ) - break; - if ( j == otherpool->numtx ) - { - otherpool->txids[otherpool->numtx++] = txid; - printf("if first time, submit request for txid\n"); - } - } - } - } - return(clonestr("{\"result\":\"gecko mempool queued\"}")); -} - void gecko_txidpurge(struct iguana_info *virt,bits256 txid) { struct gecko_mempool *pool; int32_t i,n; struct gecko_memtx *memtx; @@ -237,3 +208,28 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c return(clonestr("{\"error\":\"gecko block didnt decode\"}")); } +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 hash2,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; bits256 checkhash2; int32_t hdrsize; uint32_t prevtimestamp,nBits; struct iguana_msgblock msg; + printf("got geckoblock len.%d from (%s) %s\n",datalen,remoteaddr!=0?remoteaddr:"",jprint(valsobj,0)); + 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,&prevtimestamp,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS); + if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits,virt->blocks.hwmchain.RO.timestamp,prevtimestamp) == 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,hash2)); + else return(clonestr("{\"error\":\"block error with checkhash2\"}")); + } else return(clonestr("{\"error\":\"block nonce didnt verify\"}")); + } + return(0); +} + +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; + // find block and set serialized + return(datalen); +} diff --git a/gecko/gecko_headers.c b/gecko/gecko_headers.c new file mode 100755 index 000000000..c14e74369 --- /dev/null +++ b/gecko/gecko_headers.c @@ -0,0 +1,101 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c + +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); +} + +void gecko_headerupdate(struct iguana_info *virt,bits256 hash2,int32_t height) +{ + int32_t bundlei; struct iguana_bundle *bp; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + if ( (height % virt->chain->bundlesize) == 0 ) + bp = iguana_bundlecreate(virt,&bundlei,height,hash2,zero,0); + else if ( (bp= virt->bundles[height / virt->chain->bundlesize]) != 0 ) + iguana_bundlehash2add(virt,0,bp,height % virt->chain->bundlesize,hash2); +} + +char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 firsthash2) +{ + bits256 hash2; struct iguana_block *block; int32_t firstheight,i,len=0,n; + n = (int32_t)(datalen / sizeof(bits256)); + if ( (block= iguana_blockfind("geckohdrs",virt,firsthash2)) != 0 && (firstheight= block->height) >= 0 ) + { + gecko_headerupdate(virt,firsthash2,firstheight); + for (i=0; ibundles[hdrsi]) != 0 ) + { + vals = cJSON_CreateObject(); + memset(zero.bytes,0,sizeof(zero)); + jaddstr(vals,"coin",virt->symbol); + if ( (retstr= basilisk_standardservice("HDR",myinfo,bp->hashes[0],vals,0,0)) != 0 ) + free(retstr); + free_json(vals); + } else printf("dont have bundle needed\n"); +} + +void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis) +{ + char mineraddr[64]; int32_t hwmhdrsi,longesthdrsi; + hwmhdrsi = virt->blocks.hwmchain.height / virt->chain->bundlesize; + longesthdrsi = virt->longestchain / virt->chain->bundlesize; + if ( hwmhdrsi < longesthdrsi ) + gecko_requesthdrs(myinfo,virt,hwmhdrsi); + bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33); + //printf("mine.%s %s\n",virt->symbol,mineraddr); + gecko_miner(myinfo,btcd,virt,maxmillis,myinfo->persistent_pubkey33); +} diff --git a/gecko/gecko_mempool.c b/gecko/gecko_mempool.c index 9b8db2a7f..8873b9920 100755 --- a/gecko/gecko_mempool.c +++ b/gecko/gecko_mempool.c @@ -69,7 +69,7 @@ void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bi txids[num++] = txid; } if ( num > 0 ) - basilisk_headers_send(myinfo,virt,addr,txids,num); + basilisk_hashes_send(myinfo,virt,addr,"MEM",txids,num); } } } @@ -200,6 +200,22 @@ struct gecko_memtx *gecko_mempool_txadd(struct supernet_info *myinfo,struct igua return(memtx); } +struct gecko_mempool *gecko_mempool_alloc(int32_t otherflag) +{ + struct gecko_mempool *pool; + pool = calloc(1,sizeof(*pool)); + if ( otherflag == 0 ) + pool->txs = calloc(0xffff,sizeof(*pool->txs)); + return(pool); +} + +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; + // find txid and set serialized + return(datalen); +} + char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid) { struct gecko_mempool *pool; int64_t txfee,vinstotal,voutstotal; uint64_t hdrsi_unspentind,value; int32_t i,numvins,numvouts,txlen,spentheight,minconf,maxconf,unspentind,hdrsi; struct iguana_msgtx msg; char *rawtx; struct gecko_memtx *memtx; @@ -234,10 +250,7 @@ char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char if ( txlen <= 0 ) return(clonestr("{\"error\":\"couldnt decode gecko tx\"}")); if ( (pool= virt->mempool) == 0 ) - { - pool = virt->mempool = calloc(1,sizeof(*pool)); - pool->txs = calloc(0xffff,sizeof(*pool->txs)); - } + pool = virt->mempool = gecko_mempool_alloc(0); rawtx = calloc(1,datalen*2 + 1); init_hexbytes_noT(rawtx,serialized,datalen); if ( (memtx= gecko_mempool_txadd(myinfo,virt,rawtx,(uint32_t)calc_ipbits(remoteaddr))) != 0 ) @@ -249,15 +262,34 @@ char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char } pool->txs[pool->numtx++] = pool->txs[i]; pool->txs[i] = memtx; + char str[65]; printf("add tx.%s to mempool i.%d numtx.%d\n",bits256_str(str,memtx->txid),i,pool->numtx); for (i=0; inumtx; i++) pool->txids[i] = pool->txs[i]->txid; if ( myinfo->IAMRELAY != 0 ) gecko_mempool_sync(myinfo,virt,pool->txids,pool->numtx); } + else + { + free(rawtx); + return(clonestr("{\"error\":\"geckotx invalid\"}")); + } free(rawtx); return(clonestr("{\"result\":\"gecko tx queued\"}")); } +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; char *symbol; struct iguana_info *virt; + if ( data != 0 && datalen != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + checktxid = bits256_doublesha256(0,data,datalen); + if ( bits256_cmp(txid,checktxid) == 0 ) + return(gecko_txarrived(myinfo,virt,addr,data,datalen,txid)); + else return(clonestr("{\"error\":\"geckotx mismatched txid\"}")); + } + return(clonestr("{\"error\":\"no geckotx chain or missing tx data\"}")); +} + struct gecko_memtx **gecko_mempool_txptrs(struct supernet_info *myinfo,struct iguana_info *virt,int64_t *rewardp,int32_t *txn_countp,void **ptrp,void *space,int32_t max,int32_t height) { int32_t i,n; struct gecko_memtx **txptrs; struct gecko_mempool *pool; int64_t txfees = 0,reward = virt->chain->initialreward; @@ -269,7 +301,7 @@ struct gecko_memtx **gecko_mempool_txptrs(struct supernet_info *myinfo,struct ig *ptrp = 0; *txn_countp = 0; if ( (pool= virt->mempool) == 0 ) - pool = virt->mempool = calloc(1,sizeof(*pool)); + pool = virt->mempool = gecko_mempool_alloc(0); if ( pool->numtx*sizeof(char *) <= max ) txptrs = space; else @@ -287,7 +319,41 @@ struct gecko_memtx **gecko_mempool_txptrs(struct supernet_info *myinfo,struct ig } } *rewardp = (reward + txfees); + if ( n > 0 ) + printf("reward %.8f n.%d numtx.%d\n",dstr(*rewardp),n,pool->numtx); if ( (*txn_countp= n) != 0 ) return(txptrs); else return(0); } + +char *gecko_mempoolarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) +{ + int32_t i,j,numother,len = 0; struct gecko_mempool *otherpool; bits256 txid; + if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,(uint32_t)calc_ipbits(remoteaddr))) != 0 ) + { + if ( numother > 0 ) + { + for (i=0; inumtx; j++) + if ( bits256_cmp(txid,otherpool->txids[j]) == 0 ) + break; + if ( j == otherpool->numtx ) + { + otherpool->txids[otherpool->numtx++] = txid; + printf("if first time, submit request for txid\n"); + } + } + } + } + return(clonestr("{\"result\":\"gecko mempool queued\"}")); +} + +char *basilisk_respond_mempool(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + return(gecko_mempoolarrived(myinfo,virt,_addr,data,datalen,hash)); + else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); +} diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c index 50826ef26..53730b4eb 100755 --- a/gecko/gecko_miner.c +++ b/gecko/gecko_miner.c @@ -15,19 +15,39 @@ // included from gecko.c -int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int32_t datalen,uint32_t nBits) +uint32_t gecko_earliest_blocktime(int32_t estblocktime,uint32_t prevtimestamp) +{ + if ( prevtimestamp == 0 ) + prevtimestamp = (uint32_t)time(NULL); + return(prevtimestamp + ((estblocktime << 1) / 3)); +} + +int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int32_t datalen,uint32_t nBits,uint32_t timestamp,uint32_t prevtimestamp) { bits256 threshold,hash2; + //printf("time.%u prev.%u\n",timestamp,prevtimestamp); + if ( 1 && timestamp != 0 && prevtimestamp != 0 ) + { + if ( prevtimestamp != 0 && timestamp < gecko_earliest_blocktime(virt->chain->estblocktime,prevtimestamp) ) + return(-1); + if ( timestamp > time(NULL) + GECKO_MAXFUTUREBLOCK ) + return(-1); + } threshold = bits256_from_compact(nBits); hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,datalen); if ( bits256_cmp(threshold,hash2) > 0 ) - return(0); - else return(0); + { + printf("nonce worked crc.%d\n",calc_crc32(0,serialized,datalen)); + return(1); + } + printf("nonce failed crc.%d\n",calc_crc32(0,serialized,datalen)); + return(-1); } -uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *block,int32_t n) +uint32_t gecko_nBits(struct iguana_info *virt,uint32_t *prevtimestampp,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; + *prevtimestampp = 0; if ( virt->chain->estblocktime == 0 ) return(GECKO_EASIESTDIFF); for (i=0; iRO.timestamp; + *prevtimestampp = endtime = prev->RO.timestamp; nBits = prev->RO.bits; } starttime = prev->RO.timestamp; @@ -52,11 +72,11 @@ uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *block,int32_t targetval = bits256_from_compact(nBits); if ( diff > est ) { - targetval = bits256_rshift(bits256_add(targetval,bits256_lshift(targetval))); + targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_lshift(targetval))); } else if ( diff < est ) { - targetval = bits256_rshift(bits256_add(targetval,bits256_rshift(targetval))); + targetval = bits256_ave(targetval,bits256_ave(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); @@ -139,7 +159,7 @@ char *gecko_coinbasestr(struct supernet_info *myinfo,struct iguana_info *virt,bi char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,struct gecko_memtx **txptrs,int32_t txn_count,uint8_t *coinbase,int32_t coinbaselen,bits256 coinbasespend,double expiration,uint8_t *minerpubkey,int64_t blockreward) { - struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384]; int32_t i,n,len,totaltxlen=0; char *coinbasestr,*blockstr=0; bits256 *txids=0,txspace[256],threshold; struct gecko_memtx *memtx; + struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384]; int32_t i,n,len,totaltxlen=0; char *coinbasestr,str[65],str2[65],*blockstr=0; bits256 *txids=0,txspace[256],threshold; struct gecko_memtx *memtx; if ( (btcd= iguana_coinfind("BTCD")) == 0 ) { printf("basilisk needs BTCD\n"); @@ -158,6 +178,7 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt { totaltxlen += memtx->datalen; txids[i + 1] = memtx->txid; + printf("memtxid.%s\n",bits256_str(str,memtx->txid)); } } } @@ -165,6 +186,10 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt { newblock->RO.merkle_root = iguana_merkle(txids,txn_count + 1); newblock->RO.txn_count = (txn_count + 1); + if ( txn_count > 0 ) + { + printf("%s %s\n",bits256_str(str,txids[0]),bits256_str(str2,txids[1])); + } threshold = bits256_from_compact(newblock->RO.bits); if ( (newblock->RO.nonce= *noncep) == 0 ) { @@ -172,15 +197,30 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt { newblock->RO.nonce = rand(); n = iguana_serialize_block(virt->chain,&newblock->RO.hash2,serialized,newblock); - //char str[65]; printf("nonce.%08x %s\n",block->RO.nonce,bits256_str(str,block->RO.hash2)); + //char str[65]; printf("nonce.%08x %s\n",newblock->RO.nonce,bits256_str(str,newblock->RO.hash2)); if ( bits256_cmp(threshold,newblock->RO.hash2) > 0 ) + { + //printf("FOUND NONCE\n"); break; - if ( (i & 0xff) == 0xff && OS_milliseconds() > expiration ) - break; + } + if ( virt->blocks.hwmchain.RO.timestamp != 0 && (i & 0xff) == 0xff && OS_milliseconds() > expiration ) + { + //printf("time limit exceeded %u\n",virt->blocks.hwmchain.RO.timestamp); + free(coinbasestr); + if ( txids != txspace ) + free(txids); + return(0); + } } } *noncep = newblock->RO.nonce; n = iguana_serialize_block(virt->chain,&newblock->RO.hash2,serialized,newblock); + while ( 1 && time(NULL) <= newblock->RO.timestamp + GECKO_MAXFUTUREBLOCK ) + { + //printf("wait for block to be close enough to now: lag %ld\n",time(NULL) - newblock->RO.timestamp); + sleep(1); + } + //if ( gecko_blocknonce_verify(virt,serialized,n,newblock->RO.bits,newblock->RO.timestamp,virt->blocks.hwmchain.RO.timestamp) >= 0 ) if ( bits256_cmp(threshold,newblock->RO.hash2) > 0 ) { blockstr = calloc(1,strlen(coinbasestr) + (totaltxlen+n)*2 + 1); @@ -196,7 +236,7 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt len += memtx->datalen << 1; } } - } + } else printf("nonce failure\n"); free(coinbasestr); } if ( txids != txspace ) @@ -204,13 +244,13 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt return(blockstr); } -char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,struct gecko_memtx **txptrs,int32_t txn_count,int32_t maxmillis,uint8_t *minerpubkey,int64_t blockreward) +char *gecko_createblock(struct supernet_info *myinfo,int32_t estblocktime,uint32_t prevtimestamp,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,struct gecko_memtx **txptrs,int32_t txn_count,int32_t maxmillis,uint8_t *minerpubkey,int64_t blockreward) { bits256 btcdhash; uint8_t coinbase[512]; int32_t coinbaselen; uint32_t nonce; double expiration = OS_milliseconds() + maxmillis; //char str[65]; printf("create prev.(%s) %p\n",bits256_str(str,newblock->RO.prev_block),&newblock->RO.prev_block); if ( btcd != 0 ) { - newblock->RO.timestamp = (uint32_t)time(NULL); + newblock->RO.timestamp = gecko_earliest_blocktime(estblocktime,prevtimestamp); if ( (coinbaselen= gecko_delayedPoW(myinfo,btcd,isPoS,coinbase,&btcdhash,newblock->RO.timestamp,newblock->height)) < 0 ) { printf("error generating coinbase for height.%d\n",newblock->height); @@ -221,25 +261,6 @@ char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,in } else return(0); } -/*int32_t basilist_validateblock(cJSON *valsobj) - { - uint32_t now,timestamp; - now = (uint32_t)time(NULL); - if ( (timestamp= juint(valsobj,"timestamp")) < now-BASILISK_MAXBLOCKLAG || timestamp > now+BASILISK_MAXFUTUREBLOCK ) - return(-1); - if ( bits256_nonz(prevhash) == 0 ) - prevhash = coin->blocks.hwmchain.RO.hash2; - if ( (prevblock= iguana_blockfind("setfield",coin,prevhash)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash\"}")); - if ( (prev2= iguana_blockfind("setfield",coin,prevblock->RO.prev_block)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash2\"}")); - nonce = juint(valsobj,"nonce"); - nBits = iguana_targetbits(coin,&coin->blocks.hwmchain,prevblock,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan); - blocktx = basilisk_block(myinfo,coin,&block,1,timestamp,&nonce,prevhash,nBits,prevblock->height+1,0,0,data,datalen,btcdhash,jobj(valsobj,"coinbase")); - - return(0); - }*/ - cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valsobj,int32_t reusedaddrs) { cJSON *item,*array; char *coinaddr; uint64_t satoshis; uint8_t addrtype,pubkey33[33],rmd160[20],outputscript[512]; int32_t i,n,scriptlen; uint32_t locktime,txversion; struct iguana_waddress *waddr; struct iguana_waccount *wacct; @@ -297,7 +318,7 @@ 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,uint8_t *minerpubkey33) { - struct iguana_zblock newblock; uint32_t nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; struct gecko_memtx **txptrs; void *ptr; //struct iguana_bundle *bp; + struct iguana_zblock newblock; uint32_t prevtimestamp,nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; struct gecko_memtx **txptrs; void *ptr; //struct iguana_bundle *bp; if ( virt->virtualchain == 0 ) return; memset(&newblock,0,sizeof(newblock)); @@ -305,15 +326,15 @@ void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct ig newblock.RO.prev_block = virt->blocks.hwmchain.RO.hash2; newblock.RO.version = GECKO_DEFAULTVERSION; newblock.RO.allocsize = iguana_ROallocsize(virt); - if ( (nBits= gecko_nBits(virt,(void *)&newblock,GECKO_DIFFITERS)) != 0 ) + if ( (nBits= gecko_nBits(virt,&prevtimestamp,(void *)&newblock,GECKO_DIFFITERS)) != 0 ) { newblock.RO.bits = nBits; //printf("mine.%s nBits.%x ht.%d\n",virt->symbol,nBits,newblock.height); txptrs = gecko_mempool_txptrs(myinfo,virt,&reward,&txn_count,&ptr,space,(int32_t)(sizeof(space)/sizeof(*space)),newblock.height); //char str[65]; printf("HWM.%s %p\n",bits256_str(str,newblock.RO.prev_block),&newblock.RO.prev_block); - if ( (blockstr= gecko_createblock(myinfo,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 ) + if ( (blockstr= gecko_createblock(myinfo,virt->chain->estblocktime,prevtimestamp,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 ) { - char str[65]; printf("%s.%x %s %u %d %.8f\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward)); + char str[65]; printf("%s.%x %s %u %d %.8f %d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward),newblock.RO.txn_count); gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2); free(blockstr); } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index a38d758c5..0508f8cbe 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -297,6 +297,8 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) chain->minconfirms = juint(argjson,"minconfirms"); if ( (chain->estblocktime= juint(argjson,"estblocktime")) == 0 ) chain->estblocktime = juint(argjson,"blocktime"); + if ( chain->estblocktime == 0 ) + chain->estblocktime = 60; path = jstr(argjson,"path"); if ( jobj(argjson,"conf") == 0 ) conf[0] = 0; diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 31f57a78a..76209dd21 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -818,7 +818,7 @@ HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool) { - bits256 txid,signedtxid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; + bits256 signedtxid,txid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; retjson = cJSON_CreateObject(); inputsum = outputsum = numinputs = numoutputs = 0; if ( rawtx != 0 && rawtx[0] != 0 && coin != 0 ) @@ -826,7 +826,7 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin if ( (strlen(rawtx) & 1) != 0 ) return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); memset(msgtx,0,sizeof(*msgtx)); - if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,rawtx,extraspace,extralen,0)) != 0 ) + if ( (txobj= bitcoin_hex2json(coin,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0)) != 0 ) { //printf("txobj.(%s)\n",jprint(txobj,0)); if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) @@ -844,7 +844,6 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,checkstr,extraspace,extralen,0)) != 0 ) jadd(retjson,"checktx",txobj); free(checkstr); - free(extraspace); return(jprint(retjson,1)); } free(checkstr); @@ -882,6 +881,7 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin } if ( (complete= bitcoin_verifyvins(coin,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,1,0)) > 0 && signedtx != 0 ) { + msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(coin,log,j64bits(txobj,"locktime"),V,numinputs) < 0 ) { @@ -1018,7 +1018,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) { if ( strcmp(field,"data") == 0 ) { - if ( (hexstr= jstr(item,"data")) != 0 ) + if ( (hexstr= jstr(item,0)) != 0 ) { spendlen = (int32_t)strlen(hexstr) >> 1; offset = 0; diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index f86bd9907..4dff170c2 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -667,7 +667,7 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch cJSON *params[16],*array; struct iguana_info *tmp,*coin = 0; char symbol[16]; int32_t i,c,n; char *retstr = 0; symbol[0] = 0; memset(params,0,sizeof(params)); - printf("bitcoinRPC\n"); + //printf("bitcoinRPC\n"); if ( json != 0 ) { if ( port == myinfo->rpcport ) @@ -705,7 +705,7 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch coin = iguana_coinfind(symbol); if ( coin != 0 ) safecopy(symbol,coin->symbol,sizeof(symbol)); - printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); + //printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) ) { if ( (array= jarray(&n,json,"params")) == 0 ) @@ -809,7 +809,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) { data = &urlstr[totallen - datalen]; data[-1] = 0; - printf("post.(%s) (%c)\n",data,data[0]); + //printf("post.(%s) (%c)\n",data,data[0]); jaddstr(json,"POST",data); } } else break; @@ -1010,7 +1010,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz origargjson = argjson; if ( is_cJSON_Array(argjson) != 0 && cJSON_GetArraySize(argjson) == 1 ) argjson = jitem(argjson,0); - printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); + //printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); if ( jstr(argjson,"method") == 0 ) { printf("no method in request.(%s)\n",jprint(argjson,0)); @@ -1018,7 +1018,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz return(0); } retstr = SuperNET_JSON(myinfo,argjson,remoteaddr,port); - printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); + //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); free_json(origargjson); return(retstr); } @@ -1162,11 +1162,12 @@ void iguana_rpcloop(void *args) char *response,hdrs[1024]; if ( jsonflag != 0 || postflag != 0 ) { - response = malloc(strlen(retstr)+1024+1); + response = malloc(strlen(retstr)+1024+1+1); sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; strcat(response,hdrs); strcat(response,retstr); + strcat(response,"\n"); if ( retstr != space ) free(retstr); retstr = response; diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index ee68fe950..f1ed08e18 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -559,9 +559,9 @@ char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bit return(txbytes); } -cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *serialized) +cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized) { - int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; + int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; uint8_t *serialized; if ( coin == 0 || txbytes == 0 ) return(0); txobj = cJSON_CreateObject(); @@ -569,6 +569,8 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_ms msgtx = &M; memset(msgtx,0,sizeof(M)); len = (int32_t)strlen(txbytes) >> 1; + if ( (serialized= origserialized) == 0 ) + serialized = calloc(1,len); decode_hex(serialized,len,txbytes); vpnstr[0] = 0; memset(txidp,0,sizeof(*txidp)); @@ -579,6 +581,8 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_ms jaddstr(txobj,"error","couldnt decode transaction"); jaddstr(txobj,"coin",coin->symbol); } + if ( serialized != origserialized ) + free(serialized); return(txobj); } diff --git a/iguana/main.c b/iguana/main.c index 02e762d4a..f817d6407 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -156,7 +156,7 @@ char *iguana_JSON(char *jsonstr,uint16_t port) char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr,uint16_t port) { cJSON *json; char *agent,*method,*retstr = 0; - printf("SuperNET_jsonstr.(%s)\n",jsonstr); + //printf("SuperNET_jsonstr.(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { method = jstr(json,"method"); diff --git a/iguana/tests/creategtx b/iguana/tests/creategtx new file mode 100755 index 000000000..fedeb0764 --- /dev/null +++ b/iguana/tests/creategtx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"createrawtransaction\",\"params\":[[], {\"data\":\"deadbeef\"}] }" + diff --git a/iguana/tests/decodegtx b/iguana/tests/decodegtx new file mode 100755 index 000000000..c1209850f --- /dev/null +++ b/iguana/tests/decodegtx @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000c3e763570001000000000000000006056adeadbeef00000000\"]}" diff --git a/iguana/tests/gtx b/iguana/tests/gtx new file mode 100755 index 000000000..cc81e80df --- /dev/null +++ b/iguana/tests/gtx @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"geckotx\",\"vals\":{\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"},\"hexstr\":\"01000000c3e763570001000000000000000006056adeadbeef00000000\"}" diff --git a/iguana/tests/vtx b/iguana/tests/vtx deleted file mode 100755 index e790bfff8..000000000 --- a/iguana/tests/vtx +++ /dev/null @@ -1 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"privatetx\",\"vals\":{\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"},\"hexstr\":\"0011223344\"}" diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index f018ba3d1..32b376b46 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -518,7 +518,7 @@ int64_t *gecko_valueptr(struct gecko_memtx *memtx,int32_t vout); struct iguana_peer *iguana_peerfindipaddr(struct iguana_info *coin,char *ipaddr,int32_t needalive); struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbits,int32_t needalive); int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *addr); -int32_t basilisk_headers_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,bits256 *txids,int32_t num); +int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *txids,int32_t num); #include "../includes/iguana_api.h" diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index ef34b2e6f..1cd38fc28 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -317,7 +317,6 @@ 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; uint8_t *blockspace;//[IGUANA_MAXPACKETSIZE + 8192]; #ifdef IGUANA_PEERALLOC