diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index 647723455..41de42e30 100755 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -220,6 +220,10 @@ char *bitcoin_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void { retstr = iguana_rawtx(myinfo,coin,json,remoteaddr,jstr(json,"changeaddr"),jobj(json,"addresses"),valsobj,jstr(json,"spendscriptstr")); } + else if ( strcmp(method,"balances") == 0 ) + { + retstr = iguana_balances(myinfo,coin,json,remoteaddr,juint(json,"lastheight"),jobj(json,"addresses"),jstr(json,"activecoin")); + } for (j=0; jbitcoin_category); + jaddnum(retjson,"timeout",5000); + jaddstr(retjson,"hexmsg",buf); + free(buf); + return(retjson); +} + +char *iguana_request_andwait(queue_t *Q,cJSON **vinsp,char *reqstr,uint32_t rawtxtag) +{ + struct rawtx_queue *ptr; int32_t i,j,n; struct iguana_peer *addr; double expiration; struct iguana_info *coin; char *rawtx; + if ( vinsp != 0 ) + *vinsp = 0; + while ( (ptr= queue_dequeue(Q,0)) != 0 ) + { + free_json(ptr->vins); + free(ptr); + } + expiration = OS_milliseconds() + 3333; + for (i=n=0; ipeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) + { + iguana_send_supernet(addr,reqstr,0); + if ( n++ > 8 ) + break; + } + } + } + } + while ( OS_milliseconds() < expiration ) + { + if ( (ptr= queue_dequeue(Q,0)) != 0 ) + { + if ( rawtxtag == ptr->rawtxtag ) + { + rawtx = clonestr(ptr->rawtx); + //printf("got RAWTX.(%s)\n",rawtx); + if ( vinsp != 0 ) + *vinsp = ptr->vins; + else free_json(ptr->vins); + free(ptr); + return(rawtx); + } + else + { + free_json(ptr->vins); + free(ptr); + } + } + } + return(0); +} + char *iguana_rawtxissue(struct supernet_info *myinfo,uint32_t rawtxtag,char *symbol,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr) { - struct rawtx_queue *ptr; struct iguana_peer *addr; uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t i,j,spendlen,delay = 0; cJSON *hexjson,*reqjson,*valsobj,*txobj = 0; char *str,*rawtx = 0; double expiration; struct iguana_info *coin; + uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t spendlen; cJSON *hexjson,*reqjson,*valsobj,*txobj = 0; char *retstr,*rawtx = 0; struct iguana_info *coin; *vinsp = 0; if ( (coin= iguana_coinfind(symbol)) != 0 && (coin->VALIDATENODE != 0 || coin->RELAYNODE != 0) ) { @@ -393,11 +462,6 @@ char *iguana_rawtxissue(struct supernet_info *myinfo,uint32_t rawtxtag,char *sym } } } - while ( (ptr= queue_dequeue(&myinfo->rawtxQ,0)) != 0 ) - { - free_json(ptr->vins); - free(ptr); - } //printf("fall through case\n"); if ( txobj != 0 ) free_json(txobj); @@ -417,53 +481,11 @@ char *iguana_rawtxissue(struct supernet_info *myinfo,uint32_t rawtxtag,char *sym jadd(hexjson,"vals",valsobj); jaddstr(hexjson,"agent","iguana"); jaddstr(hexjson,"method","rawtx"); - str = jprint(hexjson,1); - init_hexbytes_noT((char *)buf,(uint8_t *)str,(int32_t)strlen(str)); - free(str); - reqjson = cJSON_CreateObject(); - jaddstr(reqjson,"agent","SuperNET"); - jaddstr(reqjson,"method","DHT"); - jaddnum(reqjson,"plaintext",1); - jaddbits256(reqjson,"categoryhash",myinfo->bitcoin_category); - jaddnum(reqjson,"request",1); - jaddnum(reqjson,"timeout",5000); - jaddstr(reqjson,"hexmsg",(char *)buf); + reqjson = iguana_requestjson(myinfo,hexjson); //{\"agent\":\"iguana\",\"method\":\"rawtx\",\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"],\"vals\":{\"coin\":\"BTCD\",\"amount\":\"10000000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"} - expiration = OS_milliseconds() + 3333; - for (i=0; ipeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) - { - iguana_send_supernet(addr,jprint(reqjson,0),delay); - } - } - } - } - free_json(reqjson); - while ( OS_milliseconds() < expiration ) - { - if ( (ptr= queue_dequeue(&myinfo->rawtxQ,0)) != 0 ) - { - if ( rawtxtag == ptr->rawtxtag ) - { - rawtx = clonestr(ptr->rawtx); - //printf("got RAWTX.(%s)\n",rawtx); - *vinsp = ptr->vins; - free(ptr); - return(rawtx); - } - else - { - free_json(ptr->vins); - free(ptr); - } - } - } - return(clonestr("{\"error\":\"timeout waiting for remote request\"}")); + if ( (retstr= iguana_request_andwait(&myinfo->rawtxQ,vinsp,jprint(reqjson,1),rawtxtag)) == 0 ) + return(clonestr("{\"error\":\"timeout waiting for remote request\"}")); + else return(retstr); } return(0); } @@ -543,9 +565,45 @@ char *iguana_createrawtx(struct supernet_info *myinfo,uint32_t rawtxtag,char *sy #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +INT_ARRAY_STRING(iguana,balances,lastheight,addresses,activecoin) +{ + uint8_t *rmdarray; uint64_t total = 0; cJSON *array,*retjson,*hexjson; int32_t numrmds=0,minconf=0,maxconf=0,numunspents = 0; char *retstr; + retjson = cJSON_CreateObject(); + if ( activecoin != 0 && activecoin[0] != 0 && (coin= iguana_coinfind(activecoin)) != 0 ) + { + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) + { + array = cJSON_CreateArray(); + rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,array,0); + total = iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,lastheight,0,&numunspents); + if ( rmdarray != 0 ) + free(rmdarray); + jadd(retjson,"balances",array); + if ( lastheight != 0 ) + jaddnum(retjson,"lastheight",lastheight); + if ( remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) + { + hexjson = cJSON_CreateObject(); + jaddstr(hexjson,"rawtx",jprint(retjson,1)); + jaddstr(hexjson,"agent","iguana"); + jaddstr(hexjson,"method","rawtx_result"); + jaddnum(hexjson,"rawtxtag",lastheight); + retjson = iguana_requestjson(myinfo,hexjson); + } else jaddstr(retjson,"result","success"); + return(jprint(retjson,1)); + } + else if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) + { + if ( (retstr= iguana_request_andwait(&myinfo->rawtxQ,0,jprint(json,1),lastheight)) == 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\"}")); +} + STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr) { - cJSON *vins=0,*retjson,*hexjson,*valsobj; char buf[2*IGUANA_MAXSCRIPTSIZE+8192],*str,*rawtx=0,*symbol=0; int64_t txfee,satoshis; uint32_t locktime,minconf,rawtxtag; + cJSON *vins=0,*retjson,*hexjson,*valsobj; char *rawtx=0,*symbol=0; int64_t txfee,satoshis; uint32_t locktime,minconf,rawtxtag; //printf("RAWTX changeaddr.%s (%s) remote.(%s)\n",changeaddr==0?"":changeaddr,jprint(json,0),remoteaddr); retjson = cJSON_CreateObject(); if ( spendscriptstr != 0 && spendscriptstr[0] != 0 && (symbol= jstr(vals,"coin")) != 0 ) @@ -571,17 +629,7 @@ STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr) valsobj = cJSON_CreateObject(); jaddstr(valsobj,"coin",symbol); jadd(hexjson,"vals",valsobj); - str = jprint(hexjson,1); - init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str)); - free(str); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","DHT"); - jaddnum(retjson,"request",1); - jaddnum(retjson,"plaintext",1); - jaddbits256(retjson,"categoryhash",myinfo->bitcoin_category); - jaddnum(retjson,"timeout",5000); - jaddstr(retjson,"hexmsg",buf); + retjson = iguana_requestjson(myinfo,hexjson); } else jaddstr(retjson,"result",rawtx); free(rawtx); } else jaddstr(retjson,"error","couldnt create rawtx"); @@ -596,7 +644,8 @@ INT_ARRAY_STRING(iguana,rawtx_result,rawtxtag,vins,rawtx) struct rawtx_queue *ptr = calloc(1,sizeof(*ptr) + strlen(rawtx) + 1); //printf("rawtx_result\n"); strcpy(ptr->rawtx,rawtx); - ptr->vins = jduplicate(vins); + if ( vins != 0 ) + ptr->vins = jduplicate(vins); ptr->rawtxtag = rawtxtag; queue_enqueue("rawtxQ",&myinfo->rawtxQ,&ptr->DL,0); return(0); diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index eaaf24266..256a07bfb 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -83,6 +83,7 @@ ZERO_ARGS(bitcoinrpc,gettxoutsetinfo); ZERO_ARGS(bitcoinrpc,getrawchangeaddress); SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); +INT_ARRAY_STRING(iguana,balances,lastheight,addresses,activecoin); STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr); INT_ARRAY_STRING(iguana,rawtx_result,rawtxtag,vins,rawtx);