From 8c49b49f05f294ccb51ef89c65e09dacf620c29f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 28 May 2016 14:33:08 -0500 Subject: [PATCH] test --- basilisk/basilisk.c | 372 ++++++++++++++++++++++------------ basilisk/basilisk.h | 10 +- basilisk/basilisk_bitcoin.c | 304 ++++++++++++++------------- basilisk/basilisk_ether.c | 26 +-- basilisk/basilisk_lisk.c | 26 +-- basilisk/basilisk_nxt.c | 26 +-- basilisk/basilisk_waves.c | 26 +-- iguana/iguana777.h | 6 +- includes/iguana_apideclares.h | 4 +- 9 files changed, 425 insertions(+), 375 deletions(-) diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 4495e6c4a..e8ab62329 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -15,7 +15,7 @@ #include "../iguana/iguana777.h" -char *basilisk_finish(struct basilisk_item *ptr,int32_t besti) +char *basilisk_finish(struct basilisk_item *ptr,int32_t besti,char *errstr) { int32_t i; char *retstr = 0; for (i=0; inumresults; i++) @@ -24,10 +24,12 @@ char *basilisk_finish(struct basilisk_item *ptr,int32_t besti) { if ( ptr->results[i] != 0 ) free(ptr->results[i]); - } - else retstr = ptr->results[i]; + } else retstr = ptr->results[i]; ptr->results[i] = 0; } + if ( retstr == 0 ) + retstr = clonestr(errstr); + ptr->retstr = retstr; ptr->finished = (uint32_t)time(NULL); return(retstr); } @@ -52,7 +54,18 @@ cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basili return(retjson); } -cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,char *retstr) +char *basilisk_results(uint32_t basilisktag,cJSON *valsobj) +{ + cJSON *resultobj = cJSON_CreateObject(); + jadd(resultobj,"vals",valsobj); + jaddstr(resultobj,"agent","basilisk"); + jaddstr(resultobj,"method","result"); + jaddnum(resultobj,"plaintext",1); + jaddnum(resultobj,"basilisktag",basilisktag); + return(jprint(resultobj,1)); +} + +/*cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,char *retstr) { cJSON *hexjson=0,*retjson=0; if ( retstr != 0 ) @@ -72,7 +85,7 @@ cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remo retjson = cJSON_Parse(retstr); } return(retjson); -} +}*/ #include "basilisk_bitcoin.c" #include "basilisk_nxt.c" @@ -115,23 +128,33 @@ int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t time return(n); } -struct basilisk_item *basilisk_issue(struct supernet_info *myinfo,cJSON *hexjson,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag) +struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,char *methodstr,char *symbol,cJSON *vals,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag) { - double expiration; struct basilisk_item *ptr; - ptr = calloc(1,sizeof(*ptr)); + double expiration; struct basilisk_item *ptr; cJSON *hexjson; if ( basilisktag == 0 ) basilisktag = rand(); + hexjson = cJSON_CreateObject(); + jaddstr(hexjson,"agent","basilisk"); + jaddnum(hexjson,"basilisktag",basilisktag); + jaddstr(hexjson,"method",methodstr); + jaddstr(hexjson,"activecoin",symbol); + if ( vals != 0 ) + jadd(hexjson,"vals",jduplicate(vals)); + printf("issue.(%s)\n",jprint(hexjson,0)); + ptr = calloc(1,sizeof(*ptr)); ptr->basilisktag = basilisktag; + ptr->numrequired = minresults; queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); if ( basilisk_submit(myinfo,hexjson,timeoutmillis,fanout,ptr) > 0 ) { - if ( timeoutmillis >= 0 ) + if ( timeoutmillis > 0 ) { expiration = OS_milliseconds() + ((timeoutmillis == 0) ? BASILISK_TIMEOUT : timeoutmillis); - while ( OS_milliseconds() < expiration && ptr->finished == 0 && ptr->numresults < minresults ) + while ( OS_milliseconds() < expiration && ptr->finished == 0 && ptr->numresults < ptr->numrequired ) usleep(timeoutmillis/100 + 1); } } + free_json(hexjson); return(ptr); } @@ -142,7 +165,9 @@ void basilisk_functions(struct iguana_info *coin) case IGUANA_PROTOCOL_BITCOIN: coin->basilisk_balances = basilisk_bitcoinbalances; coin->basilisk_rawtx = basilisk_bitcoinrawtx; + coin->basilisk_rawtxmetric = basilisk_bitcoin_rawtxmetric; coin->basilisk_value = basilisk_bitcoinvalue; + coin->basilisk_valuemetric = basilisk_bitcoin_valuemetric; break; /*case IGUANA_PROTOCOL_IOTA: coin->basilisk_balances = basilisk_iotabalances; @@ -167,70 +192,164 @@ void basilisk_functions(struct iguana_info *coin) } } -char *basilisk_issuecmd(basilisk_func func,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) +int32_t basilisk_besti(struct basilisk_item *ptr) { - struct iguana_info *coin; char *retstr=0; - if ( basilisktag == 0 ) - OS_randombytes((uint8_t *)&basilisktag,sizeof(basilisktag)); - if ( (coin= iguana_coinfind(symbol)) != 0 ) + int32_t i,besti = -1; double metric,bestmetric; + if ( ptr->metricdir > 0 ) + bestmetric = -1.; + else if ( ptr->metricdir < 0 ) + bestmetric = 1.; + else bestmetric = 0.; + for (i=0; inumresults; i++) { - if ( func != 0 ) + if ( (metric= ptr->metrics[i]) != 0. ) { - if ( (retstr= (*func)(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + if ( (ptr->metricdir < 0 && (bestmetric > 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric == 0.) ) { - //retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr); - //free(retstr); - //retstr = jprint(retjson,1); - printf("issue ret.(%s)\n",retstr); + bestmetric = metric; + besti = i; } } } - return(retstr); + if ( besti >= 0 ) + { + for (i=0; inumresults; i++) + if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) + ptr->numexact++; + } + return(besti); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -INT_ARRAY_STRING(basilisk,balances,lastheight,addresses,activecoin) +char *basilisk_block(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,struct basilisk_item *Lptr,struct basilisk_item *ptr) { - /*uint64_t amount,total = 0; cJSON *item,*result,*array,*retjson,*hexjson; int32_t i,n,minconf=0; char *retstr,*balancestr,*coinaddr; - retjson = cJSON_CreateObject(); - if ( activecoin != 0 && activecoin[0] != 0 && (coin= iguana_coinfind(activecoin)) != 0 ) + int32_t besti,i,j,numvalid; char *retstr = 0,*errstr; struct iguana_peer *addr; + if ( ptr == Lptr ) { -xxx - jadd(retjson,"balances",array); - jaddnum(retjson,"total",dstr(total)); - if ( lastheight != 0 ) - jaddnum(retjson,"lastheight",lastheight); - if ( remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) + if ( (retstr= Lptr->retstr) == 0 ) + retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); + } + else + { + if ( ptr->numrequired == 0 ) + ptr->numrequired = 1; + while ( OS_milliseconds() < ptr->expiration ) + { + if ( (numvalid= ptr->numresults) >= ptr->numrequired ) { - //printf("remote req.(%s)\n",jprint(retjson,0)); - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"rawtx",jprint(retjson,1)); - jaddstr(hexjson,"agent","iguana"); - jaddstr(hexjson,"method","rawtx_result"); - jaddstr(hexjson,"activecoin",activecoin); - jaddnum(hexjson,"basilisktag",lastheight); - retjson = iguana_json(myinfo,hexjson); - } else jaddstr(retjson,"result","success"); - return(jprint(retjson,1)); + for (i=numvalid=0; inumresults; i++) + { + if ( ptr->metrics[i] != 0. ) + numvalid++; + } + } + if ( numvalid < ptr->numrequired ) + { + usleep(10000); + continue; + } + if ( ptr->uniqueflag == 0 && ptr->numexact <= (ptr->numresults >> 1) ) + besti = -1, errstr = "{\"error\":\"basilisk non-consensus results\"}"; + else besti = basilisk_besti(ptr), errstr = "{\"error\":\"basilisk no valid results\"}"; + if ( (retstr= basilisk_finish(ptr,besti,errstr)) != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) + { + for (j=0; jpeers.active[i]) != 0 && addr->usock >= 0 ) + { + if ( addr->supernet != 0 && strcmp(addr->ipaddr,remoteaddr) == 0 ) + { + printf("send back.%d basilisk_result addr->supernet.%u to (%s).%d\n",(int32_t)strlen(retstr),addr->supernet,addr->ipaddr,addr->A.port); + iguana_send_supernet(addr,retstr,0); + return(retstr); + } + } + if ( 0 && addr->ipbits != 0 ) + printf("i.%d (%s) vs (%s) %s\n",i,addr->ipaddr,remoteaddr,coin->symbol); + } + } + } } - else if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) + retstr = basilisk_finish(ptr,-1,"{\"error\":\"basilisk timeout\"}"); + } + return(retstr); +} + +struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) +{ + struct iguana_info *coin; struct basilisk_item *ptr; + memset(Lptr,0,sizeof(*Lptr)); + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( func != 0 ) { - if ( (retstr= basilisk_request_andwait(myinfo,&myinfo->basiliskQ,0,json,lastheight,juint(json,"timeout"))) == 0 ) - return(clonestr("{\"error\":\"timeout waiting for remote request\"}")); - else return(retstr); - } else return(clonestr("{\"error\":\"invalid remoterequest when not relaynode\"}")); - } else */return(clonestr("{\"error\":\"invalid request for inactive coin\"}")); + if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + if ( (ptr->metricfunc= metricfunc) != 0 ) + ptr->vals = jduplicate(vals); + strcpy(ptr->symbol,symbol); + ptr->expiration = OS_milliseconds() + timeoutmillis; + return(ptr); + } + else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); + return(Lptr); } -INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) +char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) { - cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n,timeoutmillis; + if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) + { + if ( *basilisktagp == 0 ) + *basilisktagp = rand(); + if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) + *timeoutmillisp = BASILISK_TIMEOUT; + return(0); + } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); +} + +char *basilisk_standardcmd(struct supernet_info *myinfo,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) +{ + char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; + if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) + { + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + return(basilisk_block(myinfo,coin,remoteaddr,&Lptr,ptr)); + else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); + } else return(clonestr("{\"error\":\"couldnt get coin\"}")); + } else return(retstr); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin) +{ + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + return(basilisk_standardcmd(myinfo,activecoin,remoteaddr,basilisktag,vals,coin->basilisk_balances,coin->basilisk_balancesmetric)); + else return(clonestr("{\"error\":\"cant find missing coin\"}")); +} + +INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin) +{ + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + return(basilisk_standardcmd(myinfo,activecoin,remoteaddr,basilisktag,vals,coin->basilisk_value,coin->basilisk_valuemetric)); + else return(clonestr("{\"error\":\"cant find missing coin\"}")); +} + +char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) +{ + cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; + *timeoutmillisp = -1; changeaddr = jstr(vals,"changeaddr"); spendscriptstr = jstr(vals,"spendscript"); addresses = jarray(&n,vals,"addresses"); - timeoutmillis = jint(vals,"timeout"); if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); else @@ -239,53 +358,49 @@ INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) if ( strcmp(jstri(addresses,i),changeaddr) == 0 ) return(clonestr("{\"error\":\"changeaddr cant be in addresses[]\"}")); } - if ( spendscriptstr != 0 && spendscriptstr[0] != 0 && activecoin != 0 && activecoin[0] != 0 ) - { - return(basilisk_issuecmd(coin->basilisk_rawtx,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)); - } - return(clonestr("{\"error\":\"missing activecoin or spendscript\"}")); + if ( spendscriptstr != 0 && spendscriptstr[0] != 0 ) + return(basilisk_check(timeoutmillisp,basilisktagp,symbol,vals)); + else return(clonestr("{\"error\":\"missing spendscript\"}")); } -INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin) +INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) { - int32_t timeoutmillis; - if ( activecoin != 0 && activecoin[0] != 0 && vals != 0 ) + char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; + if ( (retstr= basilisk_checkrawtx(&timeoutmillis,(uint32_t *)&basilisktag,activecoin,vals)) == 0 ) { - timeoutmillis = jint(vals,"timeout"); - return(basilisk_issuecmd(coin->basilisk_value,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)); - } - return(clonestr("{\"error\":\"missing activecoin\"}")); + if ( (ptr= basilisk_issuecmd(&Lptr,coin->basilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + { + if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) + ptr->numrequired = 1; + ptr->uniqueflag = 1; + return(basilisk_block(myinfo,coin,remoteaddr,&Lptr,ptr)); + } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); + } else return(retstr); } INT_AND_ARRAY(basilisk,result,basilisktag,vals) { - struct basilisk_item *ptr; char *hexmsg=0; - if ( vals != 0 && (hexmsg= jstr(vals,"hexmsg")) != 0 ) + struct basilisk_item *ptr; + if ( vals != 0 ) { ptr = calloc(1,sizeof(*ptr)); - ptr->results[0] = jprint(vals,0); + ptr->retstr = jprint(vals,0); ptr->basilisktag = basilisktag; - ptr->numresults = 1; - //printf("Q results hexmsg.(%s) args.(%s)\n",hexmsg,jprint(args,0)); + printf("Q results vals.(%s)\n",ptr->retstr); queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); return(clonestr("{\"result\":\"queued basilisk return\"}")); - } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),hexmsg); + } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),vals); return(clonestr("{\"error\":\"no hexmsg to return\"}")); } - #include "../includes/iguana_apiundefs.h" - -char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) +char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) // incoming { - char *method="",*agent="",*retstr = 0,*tmpstr,*hexmsg; int32_t i,j,n,timeoutmillis; cJSON *array,*json,*valsobj; struct iguana_info *coin=0; struct iguana_peer *addr; uint32_t basilisktag; + char *method="",*agent="",*retstr = 0,*tmpstr,*hexmsg; int32_t n; cJSON *array,*json,*valsobj; struct iguana_info *coin=0; uint32_t basilisktag; array = 0; if ( (json= cJSON_Parse(ptr)) != 0 ) { printf("basilisk.(%s)\n",jprint(json,0)); - //basilisk.({"basilisktag":2955372280,"agent":"basilisk","method":"rawtx","vals":{"changeaddr":"1FNhoaBYzf7safMBjoCsJYgxtah3K95sep","addresses":["1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE"],"timeout":5000,"amount":"20000","spendscript":"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac"},"basilisktag":2955372280}) - // basilisk.({"agent":"basilisk","method":"rawtx","activecoin":"BTC","basilisktag":1398466607}) - agent = jstr(json,"agent"); method = jstr(json,"method"); if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"DHT") == 0 && (hexmsg= jstr(json,"hexmsg")) != 0 ) @@ -294,6 +409,7 @@ char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,voi tmpstr = calloc(1,n + 1); decode_hex((void *)tmpstr,n,hexmsg); free_json(json); + printf("NESTED.(%s)\n",tmpstr); if ( (json= cJSON_Parse(tmpstr)) == 0 ) { printf("couldnt parse decoded hexmsg.(%s)\n",tmpstr); @@ -307,9 +423,7 @@ char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,voi basilisktag = juint(json,"basilisktag"); if ( strcmp(agent,"basilisk") == 0 && (valsobj= jobj(json,"vals")) != 0 ) { - if ( jobj(json,"timeout") != 0 ) - timeoutmillis = jint(json,"timeout"); - if ( valsobj != 0 && jobj(valsobj,"coin") != 0 ) + if ( jobj(valsobj,"coin") != 0 ) coin = iguana_coinfind(jstr(valsobj,"coin")); else if ( jstr(json,"activecoin") != 0 ) coin = iguana_coinfind(jstr(json,"activecoin")); @@ -318,68 +432,39 @@ char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,voi if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) { if ( strcmp(method,"rawtx") == 0 ) - { - retstr = basilisk_issuecmd(coin->basilisk_rawtx,myinfo,remoteaddr,basilisktag,coin->symbol,timeoutmillis,valsobj); - } + retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); else if ( strcmp(method,"balances") == 0 ) - { - retstr = basilisk_issuecmd(coin->basilisk_balances,myinfo,remoteaddr,basilisktag,coin->symbol,timeoutmillis,valsobj); - } + retstr = basilisk_balances(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); else if ( strcmp(method,"value") == 0 ) - { - retstr = basilisk_issuecmd(coin->basilisk_value,myinfo,remoteaddr,basilisktag,coin->symbol,timeoutmillis,valsobj); - } - if ( retstr == 0 ) - return(0); - //printf("basilisk will return.(%s)\n",retstr); - for (j=0; jpeers.active[i]) != 0 && addr->usock >= 0 ) - { - if ( addr->supernet != 0 && strcmp(addr->ipaddr,remoteaddr) == 0 ) - { - printf("send back.%d basilisk_result addr->supernet.%u to (%s).%d\n",(int32_t)strlen(retstr),addr->supernet,addr->ipaddr,addr->A.port); - iguana_send_supernet(addr,retstr,0); - free_json(json); - return(retstr); - } - } - if ( 0 && addr->ipbits != 0 ) - printf("i.%d (%s) vs (%s) %s\n",i,addr->ipaddr,remoteaddr,coin->symbol); - } - } + retstr = basilisk_value(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + if ( retstr != 0 ) + free(retstr); + // should automatically send to remote requester } else { if ( strcmp(method,"result") == 0 ) - { - //printf("got rawtx.(%s)\n",jstr(valsobj,"hexmsg")); - return(basilisk_result(myinfo,coin,json,remoteaddr,basilisktag,valsobj)); - } + return(basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj)); } } } + free_json(json); } printf("unhandled bitcoin_hexmsg.(%d) from %s (%s/%s)\n",len,remoteaddr,agent,method); - free_json(json); return(retstr); } void basilisks_loop(void *arg) { - struct basilisk_item *ptr,*tmp,*pending; int32_t i,flag,n; struct supernet_info *myinfo = arg; - uint8_t *blockspace; struct OS_memspace RAWMEM; struct iguana_info *coin; - memset(&RAWMEM,0,sizeof(RAWMEM)); - blockspace = calloc(1,IGUANA_MAXPACKETSIZE); + basilisk_metricfunc metricfunc; struct basilisk_item *ptr,*tmp,*pending; int32_t i,flag,n; struct supernet_info *myinfo = arg; + //uint8_t *blockspace; struct OS_memspace RAWMEM; + //memset(&RAWMEM,0,sizeof(RAWMEM)); + //blockspace = calloc(1,IGUANA_MAXPACKETSIZE); while ( 1 ) { - for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) - basilisk_bitcoinscan(coin,blockspace,&RAWMEM); + //for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) + // basilisk_bitcoinscan(coin,blockspace,&RAWMEM); if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 ) { if ( ptr->finished == 0 ) @@ -394,8 +479,11 @@ void basilisks_loop(void *arg) { if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) { - pending->results[n] = ptr->results[0]; + pending->results[n] = ptr->retstr; pending->numresults++; + if ( (metricfunc= ptr->metricfunc) == 0 ) + pending->metrics[n] = n + 1; + else pending->metrics[n] = (*metricfunc)(myinfo,pending,pending->results[n]); } } free(ptr); @@ -404,14 +492,36 @@ void basilisks_loop(void *arg) else { flag = 0; - HASH_ITER(hh,myinfo->basilisks.issued,ptr,tmp) + HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) { - if ( ptr->finished != 0 ) + if ( pending->finished != 0 && pending->parent == 0 ) { - HASH_DELETE(hh,myinfo->basilisks.issued,ptr); - free(ptr); + HASH_DELETE(hh,myinfo->basilisks.issued,pending); + if ( pending->vals != 0 ) + free_json(pending->vals); + if ( pending->dependents != 0 ) + free(pending->dependents); + free(pending); flag++; } + else if ( OS_milliseconds() > pending->expiration ) + { + pending->finished = (uint32_t)time(NULL); + pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); + for (i=0; inumresults; i++) + if ( (metricfunc= pending->metricfunc) != 0 ) + pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); + } + else + { + for (i=0; inumresults; i++) + if ( pending->metrics[i] == 0. ) + { + if ( (metricfunc= pending->metricfunc) != 0 ) + pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); + flag++; + } + } } if ( flag == 0 ) usleep(100000); diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index 07e4228ea..714d9b873 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -26,9 +26,10 @@ struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vou struct basilisk_item { - struct queueitem DL; UT_hash_handle hh; - uint32_t submit,finished,basilisktag,numresults,numexact; - char *results[BASILISK_MAXFANOUT]; + struct queueitem DL; UT_hash_handle hh; struct basilisk_item *parent; void *dependents; + uint32_t submit,finished,basilisktag,numresults,numexact,uniqueflag,numrequired; + char symbol[32]; double expiration; cJSON *vals; int32_t metricdir; void *metricfunc; + char *retstr,*results[BASILISK_MAXFANOUT]; double metrics[BASILISK_MAXFANOUT]; }; struct basilisk_info @@ -38,8 +39,7 @@ struct basilisk_info struct basilisk_value values[8192]; int32_t numvalues; }; -struct basilisk_item *basilisk_issue(struct supernet_info *myinfo,cJSON *hexjson,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag); +struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,char *methodstr,char *symbol,cJSON *vals,int32_t timeoutmillis,int32_t fanout,int32_t minresults,uint32_t basilisktag); void basilisks_init(struct supernet_info *myinfo); -char *basilisk_issuerawtx(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *spendscriptstr,char *changeaddr,int64_t txfee,int32_t minconf,cJSON *addresses,int32_t timeout); #endif diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 4ed909e1f..669ff339e 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -13,6 +13,14 @@ * * ******************************************************************************/ +struct bitcoin_rawtxdependents +{ + int64_t spentsatoshis,outputsum,cost,change; + int32_t numptrs,numresults; + char **results,*coinaddrs; + struct basilisk_item *ptrs[]; +}; + #ifdef bitcoincancalculatebalances int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr) { @@ -75,7 +83,6 @@ char *bitcoin_balance(struct iguana_info *coin,char *coinaddr,int32_t lastheight jaddnum(retjson,"balance",dstr(balance)); return(jprint(retjson,1)); } -#else char *basilisk_bitcoinblockhashstr(char *coinstr,char *serverport,char *userpass,int32_t height) { @@ -149,23 +156,6 @@ int32_t basilisk_blockheight(struct iguana_info *coin,bits256 hash2) return(height); } -/*bits256 basilisk_blockhash(struct iguana_info *coin,bits256 prevhash2) -{ - char *blockhashstr; bits256 hash2; int32_t height; - memset(hash2.bytes,0,sizeof(hash2)); - if ( (height= basilisk_blockheight(coin,prevhash2)) >= 0 ) - { - printf("blockhash.%d\n",height); - if ( (blockhashstr= bitcoin_blockhashstr(coin->symbol,coin->chain->serverport,coin->chain->userpass,height+1)) != 0 ) - { - printf("got (%s)\n",blockhashstr); - hash2 = bits256_conv(blockhashstr); - free(blockhashstr); - } - } - return(hash2); -}*/ - cJSON *bitcoin_blockjson(int32_t *heightp,char *coinstr,char *serverport,char *userpass,char *blockhashstr,int32_t height) { cJSON *json = 0; int32_t flag = 0; char buf[1024],*blocktxt = 0; @@ -298,7 +288,6 @@ int32_t basilisk_bitcoinscan(struct iguana_info *coin,uint8_t origblockspace[IGU coin->blocks.pending--; return(num); } - #endif int32_t basilisk_bitcoinavail(struct iguana_info *coin) @@ -310,7 +299,7 @@ int32_t basilisk_bitcoinavail(struct iguana_info *coin) else return(0); } -char *basilisk_bitcoinbalances(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals) +void *basilisk_bitcoinbalances(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals) { /* cJSON *array=0,*result,*item,*retjson,*hexjson; int32_t i,n,besti=-1; char *coinaddr,*balancestr=0,*retstr=0; int64_t total=0,amount,most=0; struct basilisk_item *ptr; array = cJSON_CreateArray(); @@ -390,69 +379,142 @@ char *basilisk_valuestr(struct iguana_info *coin,char *coinaddr,uint64_t value,i return(jprint(retjson,1)); } -char *basilisk_bitcoinvalue(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals) +double basilisk_bitcoin_valuemetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) +{ + struct basilisk_value *v; cJSON *resultarg; int32_t ind; + if ( (ind= myinfo->basilisks.numvalues) >= sizeof(myinfo->basilisks.values)/sizeof(*myinfo->basilisks.values) ) + ind = (rand() % (sizeof(myinfo->basilisks.values)/sizeof(*myinfo->basilisks.values))); + else myinfo->basilisks.numvalues++; + v = &myinfo->basilisks.values[ind]; + if ( (resultarg= cJSON_Parse(resultstr)) != 0 ) + { + safecopy(v->coinaddr,jstr(resultarg,"address"),sizeof(v->coinaddr)); + v->value = j64bits(resultarg,"value"); + v->txid = jbits256(resultarg,"txid"); + v->vout = jint(resultarg,"vout"); + v->height = jint(resultarg,"height"); + } + return(ind + 1); +} + +void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { - int32_t i,height,vout; char *coinaddr,*retstr=0; struct basilisk_value *v; cJSON *hexjson,*resultarg; uint64_t value = 0; struct basilisk_item *ptr; bits256 txid; - txid = jbits256(vals,"txid"); - vout = jint(vals,"vout"); - coinaddr = jstr(vals,"address"); + int32_t i,height,vout; char *coinaddr; struct basilisk_value *v; uint64_t value = 0; bits256 txid; + txid = jbits256(valsobj,"txid"); + vout = jint(valsobj,"vout"); + coinaddr = jstr(valsobj,"address"); if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 && coinaddr != 0 && coinaddr[0] != 0 ) { if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) { - printf("local check\n"); if ( iguana_unspentindfind(coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount) > 0 ) - return(basilisk_valuestr(coin,coinaddr,value,height,txid,vout)); + { + Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout); + return(Lptr); + } } //else return(bitcoin_value(coin,txid,vout,coinaddr)); - printf("have local, but lite node\n"); } - else + printf("Scan basilisks values\n"); + if ( (v= myinfo->basilisks.values) != 0 ) { - printf("Scan basilisks values\n"); - if ( (v= myinfo->basilisks.values) != 0 ) + for (i=0; ibasilisks.numvalues; i++,v++) { - for (i=0; ibasilisks.numvalues; i++,v++) + if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) { - if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) - return(basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout)); + Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout); + return(Lptr); } } - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","value"); - if ( vals != 0 ) - jadd(hexjson,"vals",jduplicate(vals)); - printf("issue.(%s)\n",jprint(hexjson,0)); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) + } + return(basilisk_issueremote(myinfo,"value",coin->symbol,valsobj,0,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag)); +} + +double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents) +{ + int32_t i,j,numaddrs,notfinished = 0; cJSON *childjson,*addresses; struct basilisk_item *child; double metric = 0.; char *childstr,*coinaddr; int64_t inputsum,value,txfee; + for (i=0; inumptrs; i++) + { + if ( (child= dependents->ptrs[i]) != 0 ) + { + if ( ptr->finished != 0 ) + child->finished = (uint32_t)time(NULL); + else if ( child->finished == 0 ) + notfinished++; + } + } + if ( notfinished != 0 ) + { + if ( ptr->finished != 0 ) { - v = &myinfo->basilisks.values[myinfo->basilisks.numvalues++]; - if ( (resultarg= cJSON_Parse(ptr->results[0])) != 0 ) + if ( ptr->metricdir < 0 ) + return(1.); + else return(-1.); + } else return(0.); + } + else if ( ptr->vals != 0 ) + { + txfee = j64bits(ptr->vals,"txfee"); + addresses = jarray(&numaddrs,ptr->vals,"addresses"); + for (inputsum=i=0; inumptrs; i++) + { + if ( (child= dependents->ptrs[i]) != 0 && (childstr= child->retstr) != 0 && (coinaddr= &dependents->coinaddrs[64*i]) != 0 ) { - safecopy(v->coinaddr,jstr(resultarg,"address"),sizeof(v->coinaddr)); - v->value = j64bits(resultarg,"value"); - v->txid = jbits256(resultarg,"txid"); - v->vout = jint(resultarg,"vout"); - v->height = jint(resultarg,"height"); + if ( (childjson= cJSON_Parse(childstr)) != 0 ) + { + if ( (value= j64bits(childjson,"value")) != 0 ) + { + inputsum += value; + for (j=0; jretstr = 0; } - basilisk_finish(ptr,-1); - retstr = basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout); } - free_json(hexjson); - } - return(retstr); + if ( (inputsum - dependents->outputsum) != txfee ) + { + printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(dependents->outputsum),dstr(inputsum)-dstr(dependents->outputsum),dstr(txfee)); + return(1001.); // error + } + return(dstr(dependents->cost)); + } else return(666.); // no vals?? } -int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t locktime,int64_t satoshis,int64_t txfee,cJSON *addresses,char *spendscriptstr,char *changeaddr,char *resultstr) +double basilisk_bitcoin_rawtxmetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) { - cJSON *txobj,*vouts,*vin,*sobj,*addrs,*vretjson,*vins,*argvals,*resultsobj; int64_t value,change=0,outputsum=0,inputsum=0,spentsatoshis=0,cost = -1; int32_t i,j,m,numaddrs,vout,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],asmtype; struct vin_info V; char *scriptstr,str[65],*vret,*rawtx; bits256 txid; - if ( coin != 0 ) + cJSON *txobj,*vouts,*vin,*sobj,*addrs,*vins,*argvals,*resultsobj,*addresses; int64_t outputsum=0,amount=0,cost = -1; int32_t i,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],asmtype; struct vin_info V; char *scriptstr,*changeaddr,*coinaddr,*rawtx,*spendscriptstr; bits256 txid; struct iguana_info *coin; struct basilisk_item Lsubptr,*child; struct bitcoin_rawtxdependents *dependents=0; double metric; uint32_t locktime; + if ( (coin= iguana_coinfind(ptr->symbol)) != 0 ) { + if ( (dependents= ptr->dependents) != 0 ) + { + if ( (metric= basilisk_bitcoin_rawtxmetric_dependents(myinfo,coin,ptr,dependents)) != 0. ) + { + for (i=0; inumptrs; i++) + if ( (child= dependents->ptrs[i]) != 0 ) + child->parent = 0; + } + return(metric); + } if ( (resultsobj= cJSON_Parse(resultstr)) == 0 || (vins= jobj(resultsobj,"vins")) != 0 || (rawtx= jstr(resultsobj,"rawtx")) != 0 ) { if ( resultsobj != 0 ) free_json(resultsobj); - return(0); + return(1.); // error } + spendscriptstr = jstr(ptr->vals,"spendscript"); + changeaddr = jstr(ptr->vals,"changeaddr"); + locktime = juint(ptr->vals,"locktime"); + amount = j64bits(ptr->vals,"amount"); + addresses = jarray(&numaddrs,ptr->vals,"addresses"); spendlen = (int32_t)strlen(spendscriptstr) >> 1; decode_hex(script,spendlen,spendscriptstr); if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace))) != 0 ) @@ -461,11 +523,15 @@ int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info * if ( juint(txobj,"locktime") != locktime ) { printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime); - return(-1); + return(2.); // error } else if ( jobj(txobj,"error") == 0 && cJSON_GetArraySize(vins) == msgtx.tx_in ) { - numaddrs = cJSON_GetArraySize(addresses); + dependents = calloc(1,sizeof(*dependents) + msgtx.tx_in*(sizeof(*dependents->results) + sizeof(*dependents->ptrs) + 64)); + dependents->results = (void *)&dependents->ptrs[msgtx.tx_in]; + dependents->coinaddrs = (void *)&dependents->results[msgtx.tx_in]; + dependents->numptrs = msgtx.tx_in; + ptr->dependents = dependents; for (i=0; i> 1; decode_hex(V.spendscript,V.spendlen,scriptstr); asmtype = _iguana_calcrmd160(coin,&V); + coinaddr = &dependents->coinaddrs[64 * i]; //if ( asmtype == IGUANA_SCRIPT_76A988AC || asmtype == IGUANA_SCRIPT_AC || asmtype == IGUANA_SCRIPT_76AC || asmtype == IGUANA_SCRIPT_P2SH ) - bitcoin_address(V.coinaddr,coin->chain->pubtype,V.rmd160,20); - argvals = cJSON_CreateObject(); - txid = jbits256(argvals,"txid"); - vout = jint(argvals,"vout"); - if ( (vret= basilisk_bitcoinvalue(myinfo,coin,remoteaddr,0,10000,argvals)) != 0 ) + bitcoin_address(coinaddr,coin->chain->pubtype,V.rmd160,20); + if ( (argvals= cJSON_CreateObject()) != 0 ) { - if ( (vretjson= cJSON_Parse(vret)) != 0 ) + jaddbits256(argvals,"txid",jbits256(vin,"txid")); + jaddnum(argvals,"vout",jint(vin,"vout")); + if ( (dependents->ptrs[i]= basilisk_bitcoinvalue(&Lsubptr,myinfo,coin,0,rand(),(ptr->expiration - OS_milliseconds()) * .777,argvals)) != 0 ) { - if ( (value= j64bits(vretjson,"value")) != 0 ) + if ( dependents->ptrs[i] == &Lsubptr ) { - inputsum += value; - for (j=0; jresults[i] = Lsubptr.retstr; + dependents->ptrs[i] = 0; + } else dependents->ptrs[i]->parent = ptr; } - free(vret); - } - else - { - printf("spend of invalid %s unspent.(%s).%d\n",V.coinaddr,bits256_str(str,msgtx.vins[i].prev_hash),msgtx.vins[i].prev_vout); - free_json(txobj); - return(-1); - } - if ( argvals != 0 ) free_json(argvals); + } } else printf("cant find spend info.(%s)\n",jprint(vin,0)); } if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n == msgtx.tx_out ) @@ -519,7 +567,7 @@ int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info * outputsum += msgtx.vouts[i].value; if ( spendlen == msgtx.vouts[i].pk_scriptlen && memcmp(script,msgtx.vouts[i].pk_script,spendlen) == 0 ) { - spentsatoshis = msgtx.vouts[i].value; + dependents->spentsatoshis = msgtx.vouts[i].value; continue; } else @@ -528,7 +576,7 @@ int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info * { if ( m == 1 && strcmp(jstri(addrs,0),changeaddr) == 0 ) { - change = msgtx.vouts[i].value; + dependents->change = msgtx.vouts[i].value; printf("verify it is normal spend for %s\n",changeaddr); continue; } @@ -541,22 +589,23 @@ int64_t basilisk_bitcointxcost(struct supernet_info *myinfo,struct iguana_info * free_json(txobj); } } - if ( spentsatoshis != satoshis ) + if ( dependents->spentsatoshis != amount ) { - printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(spentsatoshis),dstr(satoshis),dstr(change)); - return(-1); + printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(dependents->spentsatoshis),dstr(amount),dstr(dependents->change)); + return(1000.); // error } - if ( (inputsum - outputsum) != txfee ) + if ( (dependents->outputsum= outputsum) <= 0 ) { - printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(outputsum),dstr(inputsum)-dstr(outputsum),dstr(txfee)); - return(-1); + printf("illegal outputsum %.8f\n",dstr(outputsum)); + return(1001.); // error } - return(cost); + dependents->cost = cost; + return(0.); } -char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) +void *basilisk_bitcoinrawtx(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { - uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t i,minconf,spendlen,besti=-1; cJSON *hexjson,*resultobj,*vins,*addresses,*txobj = 0; uint32_t locktime; char *spendscriptstr,*changeaddr,*retstr=0,*rawtx = 0; int64_t amount,txfee,cost,bestcost=-1; struct basilisk_item *ptr; + uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t minconf,spendlen; cJSON *vins,*addresses,*txobj = 0; uint32_t locktime; char *spendscriptstr,*changeaddr,*rawtx = 0; int64_t amount,txfee; vins = 0; changeaddr = jstr(valsobj,"changeaddr"); spendscriptstr = jstr(valsobj,"spendscript"); @@ -569,7 +618,10 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi if ( (txfee= j64bits(valsobj,"txfee")) == 0 ) txfee = 10000; if ( changeaddr == 0 || changeaddr[0] == 0 || spendscriptstr == 0 || spendscriptstr[0] == 0 || amount == 0 || addresses == 0 ) - return(clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}")); + { + Lptr->retstr = clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}"); + return(Lptr); + } if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) { if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) @@ -580,57 +632,31 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi decode_hex(buf,spendlen,spendscriptstr); bitcoin_txoutput(coin,txobj,buf,spendlen,amount); rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf); - } else printf("error creating txobj\n"); + } + else + { + Lptr->retstr = clonestr("{\"error\":\"couldnt create rawtx locally\"}"); + return(Lptr); + } } //else rawtx = bitcoin_calcrawtx(myinfo,coin,vinsp,satoshis,spendscriptstr,changeaddr,txfee,addresses,minconf,locktime); if ( rawtx != 0 ) { if ( vins != 0 ) { free_json(txobj); - resultobj = cJSON_CreateObject(); valsobj = cJSON_CreateObject(); - jaddstr(valsobj,"rawtx",rawtx), free(rawtx); jadd(valsobj,"vins",vins); - jadd(resultobj,"vals",valsobj); - jaddstr(resultobj,"agent","basilisk"); - jaddstr(resultobj,"method","result"); - jaddnum(resultobj,"plaintext",1); - //retstr = jprint(basilisk_resultsjson(myinfo,coin->symbol,remoteaddr,basilisktag,timeoutmillis,jprint(resultobj,1)),1); - return(jprint(resultobj,1)); + jaddstr(valsobj,"rawtx",rawtx); + free(rawtx); + Lptr->retstr = jprint(valsobj,1); + return(Lptr); } else free(rawtx); - } + } // fall through to remote } if ( txobj != 0 ) free_json(txobj), txobj = 0; if ( vins != 0 ) free_json(vins), vins = 0; - if ( addresses != 0 ) - { - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","rawtx"); - jaddstr(hexjson,"activecoin",coin->symbol); - jadd(hexjson,"vals",jduplicate(valsobj)); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - { - for (i=0; inumresults; i++) - { - if ( ptr->results[i] == 0 ) - continue; - if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 ) - ptr->numexact++; - if ( (cost= basilisk_bitcointxcost(myinfo,coin,remoteaddr,locktime,amount,txfee,addresses,spendscriptstr,changeaddr,ptr->results[i])) >= 0 && (bestcost == 0 || cost < bestcost) ) - { - if ( retstr != 0 ) - ptr->numexact = 0; - retstr = ptr->results[i]; - bestcost = cost; - besti = i; - } - } - retstr = basilisk_finish(ptr,besti); - } - free_json(hexjson); - } - return(retstr); + return(basilisk_issueremote(myinfo,"rawtx",coin->symbol,valsobj,0,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag)); } + diff --git a/basilisk/basilisk_ether.c b/basilisk/basilisk_ether.c index 609971bf0..e22d11e78 100755 --- a/basilisk/basilisk_ether.c +++ b/basilisk/basilisk_ether.c @@ -13,29 +13,7 @@ * * ******************************************************************************/ -char *basilisk_etherrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +struct basilisk_item *basilisk_etherrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) { - cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr; - *vinsp = 0; - if ( addresses != 0 ) - { - valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"basilisktag",basilisktag); - jaddstr(valsobj,"coin",coin->symbol); - jadd64bits(valsobj,"amount",satoshis); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"changeaddr",changeaddr); - jaddstr(hexjson,"spendscriptstr",spendscriptstr); - jadd(hexjson,"addresses",jduplicate(addresses)); - jadd(hexjson,"vals",valsobj); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","rawtx"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - retstr = basilisk_finish(ptr,0); - free_json(hexjson); - } - return(retstr); + return(0); } diff --git a/basilisk/basilisk_lisk.c b/basilisk/basilisk_lisk.c index 7e1e435c7..ee0d8b0a3 100755 --- a/basilisk/basilisk_lisk.c +++ b/basilisk/basilisk_lisk.c @@ -13,29 +13,7 @@ * * ******************************************************************************/ -char *basilisk_liskrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +struct basilisk_item *basilisk_liskrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) { - cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr; - *vinsp = 0; - if ( addresses != 0 ) - { - valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"basilisktag",basilisktag); - jaddstr(valsobj,"coin",coin->symbol); - jadd64bits(valsobj,"amount",satoshis); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"changeaddr",changeaddr); - jaddstr(hexjson,"spendscriptstr",spendscriptstr); - jadd(hexjson,"addresses",jduplicate(addresses)); - jadd(hexjson,"vals",valsobj); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","rawtx"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - retstr = basilisk_finish(ptr,0); - free_json(hexjson); - } - return(retstr); + return(0); } diff --git a/basilisk/basilisk_nxt.c b/basilisk/basilisk_nxt.c index c1bb606b5..9ccb39fb8 100755 --- a/basilisk/basilisk_nxt.c +++ b/basilisk/basilisk_nxt.c @@ -13,29 +13,7 @@ * * ******************************************************************************/ -char *basilisk_nxtrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +struct basilisk_item *basilisk_nxtrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) { - cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr; - *vinsp = 0; - if ( addresses != 0 ) - { - valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"basilisktag",basilisktag); - jaddstr(valsobj,"coin",coin->symbol); - jadd64bits(valsobj,"amount",satoshis); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"changeaddr",changeaddr); - jaddstr(hexjson,"spendscriptstr",spendscriptstr); - jadd(hexjson,"addresses",jduplicate(addresses)); - jadd(hexjson,"vals",valsobj); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","rawtx"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - retstr = basilisk_finish(ptr,0); - free_json(hexjson); - } - return(retstr); + return(0); } diff --git a/basilisk/basilisk_waves.c b/basilisk/basilisk_waves.c index d04419fc0..ae4ef0aaf 100755 --- a/basilisk/basilisk_waves.c +++ b/basilisk/basilisk_waves.c @@ -13,29 +13,7 @@ * * ******************************************************************************/ -char *basilisk_wavesrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +struct basilisk_item *basilisk_wavesrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) { - cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr; - *vinsp = 0; - if ( addresses != 0 ) - { - valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"basilisktag",basilisktag); - jaddstr(valsobj,"coin",coin->symbol); - jadd64bits(valsobj,"amount",satoshis); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"changeaddr",changeaddr); - jaddstr(hexjson,"spendscriptstr",spendscriptstr); - jadd(hexjson,"addresses",jduplicate(addresses)); - jadd(hexjson,"vals",valsobj); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","rawtx"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - retstr = basilisk_finish(ptr,0); - free_json(hexjson); - } - return(retstr); + return(0); } diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 8c28ea637..d595c58c5 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -495,14 +495,16 @@ struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t fir struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[IGUANA_MAXPEERS >> 3]; }; -typedef char *(*basilisk_func)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals); +typedef void *(*basilisk_func)(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals); +typedef double (*basilisk_metricfunc)(struct supernet_info *myinfo,struct basilisk_item *ptr,char *result); struct iguana_info { char name[64],symbol[8],protocol,statusstr[512],scriptsfname[2][512]; struct iguana_peers peers; struct iguana_peer internaladdr; basilisk_func basilisk_rawtx,basilisk_balances,basilisk_value; - + basilisk_metricfunc basilisk_rawtxmetric,basilisk_balancesmetric,basilisk_valuemetric; + uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index f101f21a0..6a06fbd1e 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -14,8 +14,8 @@ ******************************************************************************/ -INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin);//lastheight,addresses,activecoin); -INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin);//changeaddr,addresses,vals,spendscriptstr); +INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin); +INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin); INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin); INT_AND_ARRAY(basilisk,result,basilisktag,vals);