diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c new file mode 100755 index 000000000..91016a9fa --- /dev/null +++ b/basilisk/basilisk.c @@ -0,0 +1,421 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +#include "../iguana/iguana777.h" + +char *basilisk_finish(struct basilisk_item *ptr,cJSON **argjsonp,int32_t besti) +{ + int32_t i; char *retstr = 0; + for (i=0; inumresults; i++) + { + if ( besti >= 0 && i != besti ) + { + if ( ptr->results[i] != 0 ) + free(ptr->results[i]); + if ( ptr->resultargs[i] != 0 ) + free_json(ptr->resultargs[i]); + } + else + { + retstr = ptr->results[i]; + if ( argjsonp != 0 ) + *argjsonp = ptr->resultargs[i]; + } + ptr->results[i] = 0; + ptr->resultargs[i] = 0; + } + ptr->finished = (uint32_t)time(NULL); + return(retstr); +} + +#include "basilisk_bitcoin.c" +#include "basilisk_nxt.c" +#include "basilisk_ether.c" +#include "basilisk_waves.c" +#include "basilisk_lisk.c" + +cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basilisktag,int32_t timeout) +{ + char *str,*buf; cJSON *retjson; + jaddnum(hexjson,"basilisktag",basilisktag); + str = jprint(hexjson,0); + buf = malloc(strlen(str)*2 + 1); + init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str)); + free(str); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"hexmsg",buf); + free(buf); + jaddstr(retjson,"agent","SuperNET"); + jaddstr(retjson,"method","DHT"); + jaddnum(retjson,"request",1); + jaddnum(retjson,"plaintext",1); + jaddbits256(retjson,"categoryhash",myinfo->basilisk_category); + jaddnum(retjson,"timeout",timeout); + return(retjson); +} + +int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t timeout,int32_t fanout,struct basilisk_item *ptr) +{ + int32_t i,j,k,l,r2,r,n; struct iguana_peer *addr; struct iguana_info *coin; char *reqstr; cJSON *tmpjson; + tmpjson = basilisk_json(myinfo,reqjson,ptr->basilisktag,timeout); + reqstr = jprint(tmpjson,1); + if ( fanout <= 0 ) + fanout = BASILISK_MINFANOUT; + else if ( fanout > BASILISK_MAXFANOUT ) + fanout = BASILISK_MAXFANOUT; + r2 = rand(); + for (l=n=0; lpeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) + { + ptr->submit = (uint32_t)time(NULL); + iguana_send_supernet(addr,reqstr,0); + if ( n++ > fanout ) + break; + } + } + } + } + free(reqstr); + 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) +{ + double expiration; struct basilisk_item *ptr; + ptr = calloc(1,sizeof(*ptr)); + if ( basilisktag == 0 ) + basilisktag = rand(); + ptr->basilisktag = basilisktag; + queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + if ( basilisk_submit(myinfo,hexjson,timeoutmillis,fanout,ptr) > 0 ) + { + if ( timeoutmillis >= 0 ) + { + expiration = OS_milliseconds() + ((timeoutmillis == 0) ? BASILISK_TIMEOUT : timeoutmillis); + while ( OS_milliseconds() < expiration && ptr->finished == 0 && ptr->numresults < minresults ) + usleep(timeoutmillis/100 + 1); + } + } + return(ptr); +} + +void basilisk_functions(struct iguana_info *coin) +{ + switch ( coin->protocol ) + { + case IGUANA_PROTOCOL_BITCOIN: + coin->basilisk_balances = basilisk_bitcoinbalances; + coin->basilisk_rawtx = basilisk_bitcoinrawtx; + coin->basilisk_value = basilisk_bitcoinvalue; + break; + /*case IGUANA_PROTOCOL_IOTA: + coin->basilisk_balances = basilisk_iotabalances; + coin->basilisk_rawtx = basilisk_iotarawtx; + break; + case IGUANA_PROTOCOL_NXT: + coin->basilisk_balances = basilisk_nxtbalances; + coin->basilisk_rawtx = basilisk_nxtrawtx; + break; + case IGUANA_PROTOCOL_ETHER: + coin->basilisk_balances = basilisk_etherbalances; + coin->basilisk_rawtx = basilisk_etherrawtx; + break; + case IGUANA_PROTOCOL_WAVES: + coin->basilisk_balances = basilisk_wavesbalances; + coin->basilisk_rawtx = basilisk_wavesrawtx; + break; + case IGUANA_PROTOCOL_LISK: + coin->basilisk_balances = basilisk_liskbalances; + coin->basilisk_rawtx = basilisk_liskrawtx; + break;*/ + } +} + +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) +{ + struct iguana_info *coin; char *rawtx=0; + *vinsp = 0; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin->basilisk_rawtx != 0 ) + rawtx = (*coin->basilisk_rawtx)(myinfo,coin,remoteaddr,basilisktag,vinsp,locktime,satoshis,changeaddr,txfee,addresses,minconf,spendscriptstr,timeout); + } + return(rawtx); +} + +int64_t basilisk_issuebalances(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,cJSON **argsp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeout) +{ + struct iguana_info *coin; int64_t balance = 0; + *argsp = 0; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin->basilisk_balances != 0 ) + balance = (*coin->basilisk_balances)(myinfo,coin,remoteaddr,basilisktag,argsp,lastheight,minconf,addresses,timeout); + } + return(balance); +} + +int64_t basilisk_issuevalue(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,cJSON **argsp,bits256 txid,int16_t vout,char *coinaddr,int32_t timeout) +{ + struct iguana_info *coin; int64_t value = 0; + *argsp = 0; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin->basilisk_value != 0 ) + value = (*coin->basilisk_value)(myinfo,coin,remoteaddr,basilisktag,txid,vout,coinaddr,timeout); + } + return(value); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +INT_ARRAY_STRING(basilisk,balances,lastheight,addresses,activecoin) +{ + /*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 ) + { +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 ) + { + //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)); + } + else if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 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\"}")); +} + +STRING_ARRAY_OBJ_STRING(basilisk,rawtx,changeaddr,addresses,vals,spendscriptstr) +{ + cJSON *argjson=0,*retjson,*hexjson,*valsobj; char *rawtx=0,*symbol=0; int64_t txfee,satoshis; uint32_t locktime,minconf,basilisktag; int32_t timeout; + //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 ) + { + minconf = juint(vals,"minconf"); + locktime = juint(vals,"locktime"); + if ( jobj(json,"timeout") != 0 ) + timeout = jint(json,"timeout"); + else timeout = jint(vals,"timeout"); + satoshis = j64bits(vals,"amount"); + txfee = j64bits(vals,"txfee"); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + OS_randombytes((uint8_t *)&basilisktag,sizeof(basilisktag)); + if ( (rawtx= basilisk_issuerawtx(myinfo,remoteaddr,basilisktag,symbol,&argjson,locktime,satoshis,spendscriptstr,changeaddr,txfee,minconf,addresses,timeout)) != 0 ) + { + //printf("return rawtx.(%s) remote.%p symbol.%s\n",rawtx,remoteaddr,symbol); + if ( remoteaddr != 0 && remoteaddr[0] != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + hexjson = cJSON_CreateObject(); + jaddstr(hexjson,"rawtx",rawtx); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","result"); + if ( argjson != 0 ) + jadd(hexjson,"args",argjson); + valsobj = cJSON_CreateObject(); + jaddstr(valsobj,"coin",symbol); + jadd(hexjson,"vals",valsobj); + retjson = basilisk_json(myinfo,hexjson,basilisktag,timeout); + free_json(hexjson); + } + else + { + jaddstr(retjson,"result",rawtx); + if ( argjson != 0 ) + jadd(retjson,"args",argjson); + } + free(rawtx); + } else jaddstr(retjson,"error","couldnt create rawtx"); + } + return(jprint(retjson,1)); +} + +INT_ARRAY_STRING(basilisk,result,basilisktag,argjson,hexmsg) +{ + struct basilisk_item *ptr = calloc(1,sizeof(*ptr) + strlen(hexmsg) + 1); + ptr->results[0] = clonestr(hexmsg); + ptr->basilisktag = basilisktag; + if ( argjson != 0 ) + ptr->resultargs[0] = jduplicate(argjson); + ptr->numresults = 1; + queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); + return(clonestr("{\"result\":\"queued basilisk 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 *method="",*agent="",*retstr = 0; int32_t i,j; cJSON *vins,*json,*valsobj; struct iguana_info *coin=0; struct iguana_peer *addr; + if ( (json= cJSON_Parse(ptr)) != 0 ) + { + printf("basilisk.(%s)\n",jprint(json,0)); + agent = jstr(json,"agent"); + method = jstr(json,"method"); + valsobj = jobj(json,"vals"); + if ( strcmp(agent,"basilisk") == 0 ) + { + if ( valsobj != 0 && jobj(valsobj,"coin") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"coin")); + else if ( jstr(json,"activecoin") != 0 ) + coin = iguana_coinfind(jstr(json,"activecoin")); + if ( coin != 0 ) + { + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) + { + if ( valsobj != 0 && strcmp(method,"rawtx") == 0 ) + { + uint64_t amount = j64bits(valsobj,"amount"); + uint64_t txfee = j64bits(valsobj,"txfee"); + int32_t minconf = juint(valsobj,"minconf"); + int32_t timeout = juint(valsobj,"timeout"); + uint32_t locktime = juint(valsobj,"locktime"); + retstr = basilisk_issuerawtx(myinfo,remoteaddr,0,coin->symbol,&vins,locktime,amount,jstr(json,"spendscriptstr"),jstr(json,"changeaddr"),txfee,minconf,jobj(json,"addresses"),timeout); + } + else if ( strcmp(method,"balances") == 0 ) + { + retstr = basilisk_balances(myinfo,coin,json,remoteaddr,juint(json,"lastheight"),jobj(json,"addresses"),jstr(json,"activecoin")); + } + 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 basilisk_result addr->supernet.%u to (%s)\n",addr->supernet,addr->ipaddr); + 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); + } + } + } + else + { + if ( strcmp(method,"result") == 0 ) + { + printf("got rawtx.(%s)\n",jstr(json,"hexmsg")); + return(basilisk_result(myinfo,coin,json,remoteaddr,juint(json,"basilisktag"),jobj(json,"args"),jstr(json,"hexmsg"))); + } + } + } + } + } + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) + 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); + while ( 1 ) + { + for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 ) + basilisk_bitcoinscan(coin,blockspace,&RAWMEM); + if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 ) + { + if ( ptr->finished == 0 ) + HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(ptr->basilisktag),ptr); + else free(ptr); + continue; + } + else if ( (ptr= queue_dequeue(&myinfo->basilisks.resultsQ,0)) != 0 ) + { + HASH_FIND(hh,myinfo->basilisks.issued,&ptr->basilisktag,sizeof(ptr->basilisktag),pending); + if ( pending != 0 ) + { + if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) + { + pending->results[n] = ptr->results[0]; + pending->resultargs[n] = ptr->resultargs[0]; + pending->numresults++; + } + } + free(ptr); + continue; + } + else + { + flag = 0; + HASH_ITER(hh,myinfo->basilisks.issued,ptr,tmp) + { + if ( ptr->finished != 0 ) + { + HASH_DELETE(hh,myinfo->basilisks.issued,ptr); + free(ptr); + flag++; + } + } + if ( flag == 0 ) + usleep(100000); + } + } +} + +void basilisks_init(struct supernet_info *myinfo) +{ + bits256 basiliskhash; + iguana_initQ(&myinfo->basilisks.submitQ,"submitQ"); + iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ"); + basiliskhash = calc_categoryhashes(0,"basilisk",0); + myinfo->basilisk_category = basiliskhash; + category_subscribe(myinfo,basiliskhash,GENESIS_PUBKEY); + category_processfunc(basiliskhash,GENESIS_PUBKEY,basilisk_hexmsg); + category_processfunc(basiliskhash,myinfo->myaddr.persistent,basilisk_hexmsg); + myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); +} diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h new file mode 100755 index 000000000..a4eca2639 --- /dev/null +++ b/basilisk/basilisk.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +#ifndef H_BASILISK_H +#define H_BASILISK_H + +#include "../iguana/iguana777.h" + +#define BASILISK_TIMEOUT 30000 +#define BASILISK_MINFANOUT 8 +#define BASILISK_MAXFANOUT 64 + +struct basilisk_value { bits256 txid; int64_t value; int16_t vout; char coinaddr[64]; }; + +struct basilisk_item +{ + struct queueitem DL; UT_hash_handle hh; + uint32_t submit,finished,basilisktag,numresults,numexact; + char *results[BASILISK_MAXFANOUT]; cJSON *resultargs[BASILISK_MAXFANOUT]; +}; + +struct basilisk_info +{ + queue_t resultsQ,submitQ; void *launched; //portable_mutex_t *mutex; + struct basilisk_item *issued; + 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); +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 new file mode 100755 index 000000000..98af380be --- /dev/null +++ b/basilisk/basilisk_bitcoin.c @@ -0,0 +1,487 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +#ifdef bitcoincancalculatebalances +int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr) +{ + char params[512],str[65]; char *curlstr; cJSON *txobj,*vouts,*item,*sobj,*addrs; int32_t j,m,n; int64_t value = 0; + sprintf(params,"[\"%s\", 1]",bits256_str(str,txid)); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + if ( (txobj= cJSON_Parse(curlstr)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) + { + for (j=0; jsymbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + { + if ( (curljson= cJSON_Parse(curlstr)) != 0 ) + { + if ( (height= juint(curljson,"blocks")) > lastheight ) + maxconf = height - lastheight; + free_json(curljson); + } + free(curlstr); + } + sprintf(params,"%d, %d, [\"%s\"]",minconf,maxconf,coinaddr); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) + { + if ( (array= cJSON_Parse(curlstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; isymbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + { + if ( (curljson= cJSON_Parse(curlstr)) != 0 ) + { + height = juint(curljson,"blocks"); + free_json(curljson); + } + free(curlstr); + } + loadheight = coin->blocks.hwmchain.height; + if ( loadheight == 0 ) + loadheight = 1; + while ( loadheight <= height )//&& coin->blocks.pending < 10 ) + { + flag = 0; + if ( (blockjson= bitcoin_blockjson(&h,coin->symbol,coin->chain->serverport,coin->chain->userpass,0,loadheight)) != 0 ) + { + blockspace = origblockspace; + msg = (void *)blockspace; + memset(msg,0,sizeof(*msg)); + msg->H.version = juint(blockjson,"version"); + msg->H.prev_block = jbits256(blockjson,"previousblockhash"); + msg->H.merkle_root = jbits256(blockjson,"merkleroot"); + msg->H.timestamp = juint(blockjson,"timestamp"); + if ( (bitstr= jstr(blockjson,"bits")) != 0 ) + { + decode_hex(revbits,sizeof(revbits),bitstr); + for (i=0; i<4; i++) + bitsbuf[i] = revbits[3 - i]; + memcpy(&msg->H.bits,bitsbuf,sizeof(msg->H.bits)); + } + msg->H.nonce = juint(blockjson,"nonce"); + datalen = 80; + if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 ) + { + msg->txn_count = numtxids; + if ( numtxids < 0xfd ) + blockspace[datalen++] = numtxids; + else + { + blockspace[datalen++] = 0xfd; + blockspace[datalen++] = numtxids & 0xff; + blockspace[datalen++] = numtxids >> 8; + } + starti = datalen; + for (i=0; isymbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + //printf("%s txid.%d\n",curlstr,i); + if ( (hexlen= is_hexstr(curlstr,0)) > 1 ) + { + hexlen >>= 1; + decode_hex(&blockspace[datalen],hexlen,curlstr); + datalen += hexlen; + } + free(curlstr); + } + } + num++; + coin->blocks.pending++; + if ( rawmem->ptr == 0 ) + iguana_meminit(rawmem,"basilisk",0,IGUANA_MAXPACKETSIZE*3,0); + else iguana_memreset(rawmem); + memset(&txdata,0,sizeof(txdata)); + memset(&H,0,sizeof(H)); + if ( (n= iguana_gentxarray(coin,rawmem,&txdata,&len,blockspace,datalen)) == datalen ) + { + len = n; + iguana_gotblockM(coin,0,&txdata,rawmem->ptr,&H,blockspace,datalen); + flag = 1; + //if ( (rand() % 1000) == 0 ) + printf("%s height.%-7d datalen.%-6d | HWM.%d\n",coin->symbol,h,datalen,coin->blocks.hwmchain.height); + } + else + { + printf(" parse error block.%d txn_count.%d, n.%d len.%d vs datalen.%d\n",loadheight,txdata.block.RO.txn_count,n,len,datalen); + } + } + free_json(blockjson); + } + if ( flag == 0 ) + break; + loadheight++; + } + if ( coin->blocks.pending > 0 ) + coin->blocks.pending--; + return(num); +} + +#endif + +int32_t basilisk_bitcoinavail(struct iguana_info *coin) +{ + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + return(1); + //else if ( coin->chain->serverport[0] != 0 ) + // return(1); + else return(0); +} + +int64_t basilisk_bitcoinbalances(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **arrayp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis) +{ + 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(); + if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) + { + if ( (n= cJSON_GetArraySize(addresses)) > 0 ) + { + for (i=0; iVALIDATENODE != 0 || coin->RELAYNODE != 0 ) + balancestr = iguana_balance(myinfo,coin,0,remoteaddr,coin->symbol,coinaddr,lastheight,minconf); + //else balancestr = bitcoin_balance(coin,coinaddr,lastheight,minconf); + if ( balancestr != 0 ) + { + if ( (result= cJSON_Parse(balancestr)) != 0 ) + { + if ( jobj(result,"balance") != 0 ) + { + item = cJSON_CreateObject(); + amount = SATOSHIDEN * jdouble(result,"balance"); + total += amount; + jaddnum(item,coinaddr,dstr(amount)); + jaddi(array,item); + } + free_json(result); + } + free(balancestr); + } + } + } + } + else + { + hexjson = cJSON_CreateObject(); + jaddnum(hexjson,"basilisktag",basilisktag); + jadd(hexjson,"addresses",jduplicate(addresses)); + jaddnum(hexjson,"minconf",minconf); + jaddnum(hexjson,"lastheight",lastheight); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","balances"); + 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 ( (retjson= cJSON_Parse(ptr->results[i])) != 0 ) + { + if ( (total= j64bits(retjson,"balance")) > most ) + { + most = total; + besti = i; + } + free_json(retjson); + } + } + retstr = basilisk_finish(ptr,arrayp,besti); + } + free_json(hexjson); + } + *arrayp = array; + return(most); +} + +int64_t basilisk_bitcoinvalue(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,bits256 txid,int32_t vout,char *coinaddr,int32_t timeoutmillis) +{ + int32_t i,height; struct basilisk_value *v; cJSON *hexjson; uint64_t value = 0; struct basilisk_item *ptr; + if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) + { + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + if ( iguana_unspentindfind(coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount) > 0 ) + return(value); + } //else return(bitcoin_value(coin,txid,vout,coinaddr)); + } + else + { + if ( (v= myinfo->basilisks.values) != 0 ) + { + for (i=0; ibasilisks.numvalues; i++,v++) + { + if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) + return(v->value); + } + } + hexjson = cJSON_CreateObject(); + jaddnum(hexjson,"basilisktag",basilisktag); + jaddstr(hexjson,"address",coinaddr); + jaddbits256(hexjson,"txid",txid); + jaddnum(hexjson,"vout",vout); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","value"); + if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) + { + v = &myinfo->basilisks.values[myinfo->basilisks.numvalues++]; + strcpy(v->coinaddr,coinaddr); + v->value = value; + v->txid = txid; + } + free_json(hexjson); + } + return(value); +} + +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 *rawtx,cJSON *vins) +{ + cJSON *txobj,*vouts,*vin,*sobj,*addrs; int64_t change=0,outputsum=0,inputsum=0,spentsatoshis=0,cost = -1; int32_t i,j,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],asmtype; struct vin_info V; char *scriptstr,str[65]; bits256 txid; + if ( coin != 0 ) + { + spendlen = (int32_t)strlen(spendscriptstr) >> 1; + decode_hex(script,spendlen,spendscriptstr); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace))) != 0 ) + { + if ( juint(txobj,"locktime") != locktime ) + { + printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime); + return(-1); + } + else if ( jobj(txobj,"error") == 0 && (vins= jarray(&n,txobj,"vin")) != 0 && cJSON_GetArraySize(vins) == msgtx.tx_in ) + { + numaddrs = cJSON_GetArraySize(addresses); + for (i=0; i> 1; + decode_hex(V.spendscript,V.spendlen,scriptstr); + asmtype = _iguana_calcrmd160(coin,&V); + if ( basilisk_bitcoinvalue(myinfo,coin,remoteaddr,0,msgtx.vins[i].prev_hash,msgtx.vins[i].prev_vout,V.coinaddr,10000) == V.amount ) + { + inputsum += V.amount; + for (j=0; jVALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + if ( txfee == 0 ) + txfee = coin->chain->txfee; + if ( (txobj= bitcoin_txcreate(coin,locktime)) != 0 ) + { + spendlen = (int32_t)strlen(spendscriptstr) >> 1; + decode_hex(buf,spendlen,spendscriptstr); + bitcoin_txoutput(coin,txobj,buf,spendlen,satoshis); + rawtx = iguana_calcrawtx(myinfo,coin,vinsp,txobj,satoshis,changeaddr,txfee,addresses,minconf); + } else printf("error creating txobj\n"); + } //else rawtx = bitcoin_calcrawtx(myinfo,coin,vinsp,satoshis,spendscriptstr,changeaddr,txfee,addresses,minconf,locktime); + if ( rawtx != 0 ) + { + if ( *vinsp != 0 ) + { + free_json(txobj); + //printf("return locally generated rawtx.(%s) vins.%p\n",rawtx,*vinsp); + return(rawtx); + } else free(rawtx); + } + } + if ( txobj != 0 ) + free_json(txobj); + 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 ) + { + 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,satoshis,txfee,addresses,spendscriptstr,changeaddr,ptr->results[i],ptr->resultargs[i])) >= 0 && (bestcost == 0 || cost < bestcost) ) + { + if ( retstr != 0 ) + ptr->numexact = 0; + retstr = ptr->results[i]; + bestcost = cost; + besti = i; + } + } + retstr = basilisk_finish(ptr,vinsp,besti); + } + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_ether.c b/basilisk/basilisk_ether.c new file mode 100755 index 000000000..98e6dd9c7 --- /dev/null +++ b/basilisk/basilisk_ether.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +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) +{ + 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,vinsp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_iota.c b/basilisk/basilisk_iota.c new file mode 100755 index 000000000..c239af0bb --- /dev/null +++ b/basilisk/basilisk_iota.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +char *basilisk_iotarawtx(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; + *argsjsonp = 0; + if ( addresses != 0 ) + { + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"basilisktag",basilisktag); + jaddstr(valsobj,"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,argsjsonp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_lisk.c b/basilisk/basilisk_lisk.c new file mode 100755 index 000000000..3ec822574 --- /dev/null +++ b/basilisk/basilisk_lisk.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +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) +{ + 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,vinsp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_nxt.c b/basilisk/basilisk_nxt.c new file mode 100755 index 000000000..ccb66b466 --- /dev/null +++ b/basilisk/basilisk_nxt.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +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) +{ + 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,vinsp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_waves.c b/basilisk/basilisk_waves.c new file mode 100755 index 000000000..65fbc1b2c --- /dev/null +++ b/basilisk/basilisk_waves.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +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) +{ + 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,vinsp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 98f58999f..a07a64af3 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -15,8 +15,7 @@ #include "OS_portable.h" -//#define USE_CURL -#ifdef USE_CURL +#ifdef LIQUIDITY_PROVIDER #ifdef _WIN32 #include #include @@ -199,7 +198,7 @@ try_again: free(s.ptr); return(0); } - else if ( numretries >= 2 ) + else if ( numretries >= 5 ) { printf("Maximum number of retries exceeded!\n"); free(s.ptr); diff --git a/crypto777/m_LP b/crypto777/m_LP new file mode 100755 index 000000000..bc3a4c1c2 --- /dev/null +++ b/crypto777/m_LP @@ -0,0 +1,4 @@ +git pull +rm *.o +gcc -c -DLIQUIDITY_PROVIDER -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl +rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index 732862871..585efe9c5 100755 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -73,21 +73,23 @@ struct supernet_address char NXTADDR[32],BTC[64],BTCD[64]; }; -struct rawtx_queue { struct queueitem DL; cJSON *vins; uint32_t rawtxtag; char rawtx[]; }; +struct supernet_info; +#include "../basilisk/basilisk.h" struct supernet_info { char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category,bitcoin_category; + bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category,basilisk_category; char secret[2048],NXTAPIURL[512],permanentfile[1024]; uint8_t *recvbuf[6]; struct supernet_address myaddr; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport; //struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active; - struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ,rawtxQ; + struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; + struct basilisk_info basilisks; int32_t numagents,numexchanges; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; struct iguana_waccount *wallet; void *ctx; @@ -194,6 +196,7 @@ int32_t SuperNET_MYINFOS(struct supernet_info **myinfos,int32_t max); FILE *myfopen(char *fname,char *mode); int32_t myfclose(FILE *fp); cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs); +char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr); #endif diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index a1c18628d..4fa9329f4 100755 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -202,77 +202,9 @@ char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag return(retstr); } -char *bitcoin_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) -{ - char *method="",*agent="",*retstr = 0; int32_t i,j; cJSON *json,*valsobj; struct iguana_info *coin=0; struct iguana_peer *addr; - if ( (json= cJSON_Parse(ptr)) != 0 ) - { - printf("bitcoinprocess.(%s)\n",jprint(json,0)); - agent = jstr(json,"agent"); - method = jstr(json,"method"); - valsobj = jobj(json,"vals"); - if ( strcmp(agent,"iguana") == 0 ) - { - if ( valsobj != 0 && jobj(valsobj,"coin") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"coin")); - else if ( jstr(json,"activecoin") != 0 ) - coin = iguana_coinfind(jstr(json,"activecoin")); - if ( coin != 0 ) - { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) - { - if ( valsobj != 0 && strcmp(method,"rawtx") == 0 ) - { - 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")); - } - if ( retstr == 0 ) - return(0); - printf("RELAY 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 rawtx_result addr->supernet.%u to (%s)\n",addr->supernet,addr->ipaddr); - 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); - } - } - } - else - { - if ( strcmp(method,"rawtx_result") == 0 ) - { - printf("got rawtx.(%s)\n",jstr(json,"rawtx")); - return(iguana_rawtx_result(myinfo,coin,json,remoteaddr,juint(json,"rawtxtag"),jobj(json,"vins"),jstr(json,"rawtx"))); - } - } - } - } - } - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) - printf("unhandled bitcoin_hexmsg.(%d) from %s (%s/%s)\n",len,remoteaddr,agent,method); - free_json(json); - return(retstr); -} - void category_init(struct supernet_info *myinfo) { - bits256 pangeahash,instantdexhash,bitcoinhash; + bits256 pangeahash,instantdexhash; category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY); pangeahash = calc_categoryhashes(0,"pangea",0); myinfo->pangea_category = pangeahash; @@ -285,9 +217,5 @@ void category_init(struct supernet_info *myinfo) category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); - bitcoinhash = calc_categoryhashes(0,"bitcoin",0); - myinfo->bitcoin_category = bitcoinhash; - category_subscribe(myinfo,bitcoinhash,GENESIS_PUBKEY); - category_processfunc(bitcoinhash,GENESIS_PUBKEY,bitcoin_hexmsg); - category_processfunc(bitcoinhash,myinfo->myaddr.persistent,bitcoin_hexmsg); -} + basilisks_init(myinfo); +} \ No newline at end of file diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 82d7b49ff..10451cf1d 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -158,22 +158,23 @@ int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin) return(0); } +#ifdef bitcoincancalulatebalances uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item) { - uint8_t addrtype; char *hexstr,*wifstr,coinaddr[64],args[128]; + char *hexstr,coinaddr[64]; memset(unspent,0,sizeof(*unspent)); if ( jstr(item,"address") != 0 ) { safecopy(coinaddr,jstr(item,"address"),sizeof(coinaddr)); bitcoin_addr2rmd160(&unspent->addrtype,unspent->rmd160,coinaddr); - sprintf(args,"[\"%s\"]",coinaddr); + /*sprintf(args,"[\"%s\"]",coinaddr); wifstr = bitcoind_RPC(0,coin->symbol,coin->chain->serverport,coin->chain->userpass,"dumpprivkey",args); if ( wifstr != 0 ) { bitcoin_wif2priv(&addrtype,&unspent->privkeys[0],wifstr); //printf("wifstr.(%s) -> %s\n",wifstr,bits256_str(str,unspent->privkeys[0])); free(wifstr); - } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr); + } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr);*/ } if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms <= 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) ) { @@ -191,15 +192,15 @@ uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *u return(unspent->value); } -struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account) +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address) { char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n; - if ( account != 0 && account[0] == 0 ) - account = 0; *numunspentsp = 0; if ( retstrp != 0 ) *retstrp = 0; - sprintf(params,"%.0f, 99999999",minconfirms); + if ( address == 0 ) + sprintf(params,"%.0f, 99999999",minconfirms); + else sprintf(params,"%.0f, 99999999, [\"%s\"]",minconfirms,address); if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) { printf("sss unspents.(%s)\n",retstr); @@ -211,7 +212,7 @@ struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct i unspents = calloc(*numunspentsp,sizeof(*unspents)); for (i=0; i<*numunspentsp; i++) { - value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,account,jitem(utxo,i)); + value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,0,jitem(utxo,i)); printf("i.%d n.%d value %.8f\n",i,n,dstr(value)); if ( value != 0 ) { @@ -267,13 +268,37 @@ struct bitcoin_unspent *iguana_bestfit(struct iguana_info *coin,struct bitcoin_u return(vin); } -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,char *account) +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf) { - int32_t i,mode,numunspents,maxinputs = 1024; struct bitcoin_unspent *ptr,*up; - struct bitcoin_unspent *ups; struct bitcoin_spend *spend; double balance; int64_t remains,smallest = 0; - if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,coin->chain->minconfirms,account)) == 0 ) + int32_t i,n,mode,maxinputs,numunspents,totalunspents = 0; struct bitcoin_unspent *ptr,*up,*ups=0,*u; + struct bitcoin_spend *spend; double balance; int64_t remains; + if ( (n= cJSON_GetArraySize(addresses)) > 0 ) + { + for (i=0; iinputs) * maxinputs); + if ( totalunspents == 0 ) + return(0); + maxinputs = totalunspents; + spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * totalunspents); spend->txfee = txfee; remains = txfee + amount; spend->satoshis = remains; @@ -281,38 +306,100 @@ struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana for (i=0; i=0; mode--) - if ( (up= iguana_bestfit(coin,ups,numunspents,remains,mode)) != 0 ) + if ( (up= iguana_bestfit(coin,ups,totalunspents,remains,mode)) != 0 ) break; if ( up != 0 ) { - if ( smallest == 0 || up->value < smallest ) - { - smallest = up->value; - memcpy(spend->change160,up->rmd160,sizeof(spend->change160)); - } spend->input_satoshis += up->value; spend->inputs[spend->numinputs++] = *up; + // todo: update a vins array if ( spend->input_satoshis >= spend->satoshis ) { - // numinputs 1 -> (1.00074485 - spend 0.41030880) = net 0.59043605 vs amount 0.40030880 change 0.40030880 -> txfee 0.01000000 vs chainfee 0.01000000 spend->change = (spend->input_satoshis - spend->satoshis) - txfee; printf("numinputs %d -> (%.8f - spend %.8f) = change %.8f -> txfee %.8f vs chainfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(spend->satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->satoshis),dstr(txfee)); break; } + memset(up,0,sizeof(*up)); remains -= up->value; } else break; } if ( spend->input_satoshis >= spend->satoshis ) { spend = realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs); + free(ups); return(spend); } else { free(spend); + free(ups); + return(0); + } +} + +cJSON *bitcoin_vout(uint64_t satoshis,char *paymentscriptstr) +{ + cJSON *item,*skey; + item = cJSON_CreateObject(); + jadd64bits(item,"satoshis",satoshis); + skey = cJSON_CreateObject(); + jaddstr(skey,"hex",paymentscriptstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); + jadd(item,"scriptPubkey",skey); + return(item); +} + +char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime) +{ + uint8_t addrtype,rmd160[20],script[512]; int32_t i,scriptlen; char *params,*rawtx=0; cJSON *item,*array,*vins=0,*vouts=0; struct bitcoin_spend *spend; char scriptstr[512],*voutstr; + *vinsp = 0; + if ( (spend= iguana_spendset(myinfo,coin,satoshis,txfee*2,addresses,minconf)) == 0 ) return(0); + if ( spend->input_satoshis >= satoshis+txfee*2 ) + { + vins = cJSON_CreateArray(); + for (i=0; inuminputs; i++) + { + item = cJSON_CreateObject(); + jaddbits256(item,"txid",spend->inputs[i].txid); + jaddnum(item,"vout",spend->inputs[i].vout); + jaddi(vins,item); + } + vouts = cJSON_CreateArray(); + jaddi(vouts,bitcoin_vout(satoshis,paymentscriptstr)); + if ( spend->change > 0 ) + { + if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) + { + free(spend); + printf("illegal destination address.(%s)\n",changeaddr); + return(0); + } + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + init_hexbytes_noT(scriptstr,script,scriptlen); + jaddi(vouts,bitcoin_vout(satoshis,scriptstr)); + } + bitcoin_addr2rmd160(&addrtype,rmd160,myinfo->myaddr.BTC); + scriptlen = bitcoin_standardspend(script,0,rmd160); + jaddi(vouts,bitcoin_vout(satoshis,scriptstr)); + voutstr = jprint(vouts,1); + voutstr[0] = '{', voutstr[strlen(voutstr)-1] = '}'; + array = cJSON_CreateArray(); + jaddi(array,jduplicate(vins)); + jaddi(array,cJSON_Parse(voutstr)), free(voutstr); + params = jprint(array,1); + rawtx = bitcoind_passthru(coin->name,coin->chain->serverport,coin->chain->userpass,"createrawtransaction",params); + free(params); } + *vinsp = vins; + free(spend); + // add sigtxid to vins + if ( locktime != 0 ) + printf("need to patch locktime\n"); + return(rawtx); } +#endif #define EXCHANGE_NAME "bitcoin" #define UPDATE bitcoin ## _price @@ -364,19 +451,19 @@ char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) { - double balance; char *retstr; int32_t i,numunspents,minconfirms; struct iguana_info *coin; - struct supernet_info *myinfo; struct bitcoin_unspent *unspents; cJSON *item,*retjson,*utxo; + double balance; int32_t i,minconfirms; struct iguana_info *coin; // char *retstr,numunspents; + struct supernet_info *myinfo; cJSON *retjson;// item,*utxo; //struct bitcoin_unspent *unspents; retjson = cJSON_CreateArray(); myinfo = SuperNET_accountfind(argjson); for (i=0; ichain->serverport[0] != 0 ) + if ( (coin= Coins[i]) != 0 )//&& coin->chain->serverport[0] != 0 ) { balance = 0.; minconfirms = juint(argjson,"minconfirms"); if ( minconfirms < coin->minconfirms ) minconfirms = coin->minconfirms; - if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) + /*if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) { item = cJSON_CreateObject(); jaddnum(retjson,"balance",balance); @@ -391,7 +478,7 @@ cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) } free(unspents); jadd(retjson,coin->symbol,item); - } + }*/ } } return(retjson); diff --git a/iguana/iguana.sources b/iguana/iguana.sources index f4fb60f62..fdaee759c 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,2 +1,2 @@ -SOURCES := SuperNET.c iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c secp256k1/src/secp256k1.c \ No newline at end of file +SOURCES := SuperNET.c iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../basilisk/basilisk.c secp256k1/src/secp256k1.c \ No newline at end of file diff --git a/iguana/iguana777.c b/iguana/iguana777.c index a077e8c86..9e710b1d4 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -691,7 +691,7 @@ void iguana_coinloop(void *arg) { if ( coin->MAXPEERS > IGUANA_MAXPEERS ) coin->MAXPEERS = IGUANA_MAXPEERS; - if ( coin->MAXPEERS < IGUANA_MINPEERS ) + if ( coin->MAXPEERS > 1 && coin->MAXPEERS < IGUANA_MINPEERS ) coin->MAXPEERS = IGUANA_MAXPEERS; #ifdef __PNACL__ if ( coin->MAXPEERS > 64 ) @@ -729,7 +729,7 @@ void iguana_coinloop(void *arg) } if ( coin->bindsock >= 0 ) { - if ( coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible ) + if ( coin->MAXPEERS > 1 && coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible ) { //fprintf(stderr,"possible\n"); if ( coin->peers.numranked > 0 && (now % 60) == 0 ) @@ -739,21 +739,21 @@ void iguana_coinloop(void *arg) } else { - if ( coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) + if ( coin->MAXPEERS > 1 && coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) { if ( coin->peers.numranked > 0 && (now % 60) == 0 ) iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } - if ( now > coin->peers.lastmetrics+10 ) + if ( coin->MAXPEERS > 1 && now > coin->peers.lastmetrics+10 ) { //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(myinfo,coin); // ranks peers } if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 || coin->MAXPEERS == 1 ) flag += iguana_processrecv(myinfo,coin); iguana_jsonQ(); } @@ -796,6 +796,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->myservices = services; coin->initialheight = initialheight; coin->mapflags = mapflags; + coin->protocol = IGUANA_PROTOCOL_BITCOIN; + basilisk_functions(coin); mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 8; maxval = IGUANA_MAXPENDBUNDLES; if ( (coin->txfee= jdouble(json,"txfee") * SATOSHIDEN) == 0 ) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index cc160922b..98e83babe 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -17,6 +17,7 @@ #define iguana777_net_h #include "../crypto777/OS_portable.h" #include "SuperNET.h" +#include "../basilisk/basilisk.h" #define SPARSECOUNT(x) ((x) << 1) @@ -96,6 +97,13 @@ struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpo #define IGUANA_SUBDIRDIVISOR 28000 +#define IGUANA_PROTOCOL_BITCOIN 'b' +#define IGUANA_PROTOCOL_NXT 'n' +#define IGUANA_PROTOCOL_ETHER 'e' +#define IGUANA_PROTOCOL_LISK 'l' +#define IGUANA_PROTOCOL_WAVES 'w' +#define IGUANA_PROTOCOL_IOTA 'i' + #ifdef __PNACL void PNACL_message(const char* format, ...); #endif @@ -337,7 +345,7 @@ struct iguana_blocks char coin[8]; struct iguanakv *db; struct iguana_block *hash; struct iguana_blockRO *RO; int32_t maxbits; - int32_t maxblocks,initblocks,hashblocks,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; + int32_t maxblocks,initblocks,hashblocks,pending,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; struct iguana_block hwmchain; }; @@ -489,8 +497,12 @@ struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[ struct iguana_info { - char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; + char name[64],symbol[8],protocol,statusstr[512],scriptsfname[2][512]; struct iguana_peers peers; struct iguana_peer internaladdr; + char *(*basilisk_rawtx)(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); + int64_t (*basilisk_balances)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **arrayp,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis); + int64_t (*basilisk_value)(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,bits256 txid,int32_t vout,char *coinaddr,int32_t timeoutmillis); + 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; @@ -825,7 +837,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf); cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extrapace,int32_t extralen); cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); @@ -841,7 +853,7 @@ int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uin char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); char *issue_startForging(struct supernet_info *myinfo,char *secret); -struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address); void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int64_t *unspents,int32_t *numunspentsp,int32_t maxunspents); long iguana_spentsfile(struct iguana_info *coin,int32_t n); @@ -991,7 +1003,6 @@ void instantdex_FSMinit(); void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf); char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey); -char *iguana_pollrawtx(queue_t *Q,cJSON **vinsp,uint32_t rawtxtag,double expiration); bits256 scrypt_blockhash(const void *input); bits256 iguana_calcblockhash(int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len); uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag); @@ -1000,6 +1011,9 @@ void instantdex_eventfree(struct bitcoin_eventitem *ptr); struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 txid); struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr); double iguana_txidstatus(struct iguana_info *coin,bits256 txid); +void basilisk_functions(struct iguana_info *coin); +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); +char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 48133948c..82dbbec9a 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -572,6 +572,8 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl } } block->mainchain = 1; + if ( coin->blocks.pending > 0 ) + coin->blocks.pending--; /*if ( block->serdata != 0 ) { printf(" call process_iguanablock2.%p ht.%d nbits.%08x\n",block->serdata,block->height,*(uint32_t *)&block->serdata[72]); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 301a1e81e..c950aa040 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1411,8 +1411,8 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) static FILE *logfp; if ( logfp == 0 ) logfp = fopen("debug.log","wb"); - if ( logfp != 0 ) - fprintf(logfp,"%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + //if ( logfp != 0 ) + printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); strcpy(coin->lastdispstr,str); //if ( (rand() % 100) == 0 ) // myallocated(0,0); diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index e3d94b419..f20656146 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -367,7 +367,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS void iguana_unspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { uint32_t spent_unspentind; char coinaddr[64]; int16_t spent_hdrsi; int32_t i,RTspentflag,num; - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->MAXPEERS == 1 || coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) { num = cJSON_GetArraySize(vins); for (i=0; ibitcoin_category); - jaddnum(retjson,"timeout",5000); - jaddstr(retjson,"hexmsg",buf); - free(buf); - return(retjson); -} - -char *iguana_pollrawtx(queue_t *Q,cJSON **vinsp,uint32_t rawtxtag,double expiration) -{ - struct rawtx_queue *ptr; char *rawtx; - while ( OS_milliseconds() < expiration ) - { - usleep(100000); - 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 if ( ptr->vins != 0 ) - free_json(ptr->vins); - free(ptr); - return(rawtx); - } - else - { - if ( ptr->vins != 0 ) - free_json(ptr->vins); - free(ptr); - } - } - } - return(0); -} - -char *iguana_request_andwait(struct supernet_info *myinfo,queue_t *Q,cJSON **vinsp,cJSON *reqjson,uint32_t rawtxtag,int32_t timeout) -{ - struct rawtx_queue *ptr; int32_t i,j,n; struct iguana_peer *addr; double expiration; struct iguana_info *coin; char *reqstr; cJSON *tmpjson; - if ( vinsp != 0 ) - *vinsp = 0; - tmpjson = iguana_requestjson(myinfo,reqjson); - reqstr = jprint(tmpjson,1); - while ( (ptr= queue_dequeue(Q,0)) != 0 ) - { - if ( ptr->vins != 0 ) - free_json(ptr->vins); - free(ptr); - } - expiration = OS_milliseconds() + ((timeout == 0) ? 15000 : timeout); - for (i=n=0; ipeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) - { - iguana_send_supernet(addr,reqstr,0); - if ( n++ > 8 ) - break; - } - } - } - } - return(iguana_pollrawtx(Q,vinsp,rawtxtag,expiration)); -} - -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,int32_t timeout) -{ - uint8_t buf[IGUANA_MAXSCRIPTSIZE]; int32_t spendlen; cJSON *hexjson,*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) ) - { - if ( (txobj= bitcoin_txcreate(coin,locktime)) != 0 ) - { - spendlen = (int32_t)strlen(spendscriptstr) >> 1; - decode_hex(buf,spendlen,spendscriptstr); - bitcoin_txoutput(coin,txobj,buf,spendlen,satoshis); - if ( (rawtx= iguana_calcrawtx(myinfo,coin,vinsp,txobj,satoshis,changeaddr,txfee,addresses,minconf)) != 0 ) - { - if ( *vinsp != 0 ) - { - free_json(txobj); - //printf("return rawtx.(%s) vins.%p\n",rawtx,*vinsp); - return(rawtx); - } else free(rawtx); - } - } - } - if ( txobj != 0 ) - free_json(txobj); - if ( addresses != 0 ) - { - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"changeaddr",changeaddr); - jaddstr(hexjson,"spendscriptstr",spendscriptstr); - jadd(hexjson,"addresses",jduplicate(addresses)); - valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"rawtxtag",rawtxtag); - jaddstr(valsobj,"coin",symbol); - jadd64bits(valsobj,"amount",satoshis); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - jadd(hexjson,"vals",valsobj); - jaddstr(hexjson,"agent","iguana"); - jaddstr(hexjson,"method","rawtx"); - //{\"agent\":\"iguana\",\"method\":\"rawtx\",\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"],\"vals\":{\"coin\":\"BTCD\",\"amount\":\"10000000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"} - if ( (retstr= iguana_request_andwait(myinfo,&myinfo->rawtxQ,vinsp,hexjson,rawtxtag,timeout)) == 0 ) - return(clonestr("{\"error\":\"timeout waiting for remote request\"}")); - else return(retstr); - } - return(0); -} - -char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,uint64_t txfee,char *comment,char *comment2,int32_t minconf,char *account) +char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *coinaddr,uint64_t satoshis,uint64_t txfee,char *comment,char *comment2,int32_t minconf,char *account) { uint8_t addrtype,spendscript[1024],rmd160[20]; int32_t completed; char spendscriptstr[4096],*rawtx=0,*signedtx = 0; bits256 signedtxid,senttxid; cJSON *retjson,*vins,*addresses; uint32_t spendlen,locktime = 0; struct iguana_waddress *waddr; //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y @@ -525,7 +396,7 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); spendlen = bitcoin_standardspend(spendscript,0,rmd160); init_hexbytes_noT(spendscriptstr,spendscript,spendlen); - if ( (rawtx= iguana_rawtxissue(myinfo,rand(),coin->symbol,&vins,locktime,satoshis,coin->changeaddr,txfee,addresses,minconf,spendscriptstr,60000)) != 0 ) + if ( (rawtx= basilisk_issuerawtx(myinfo,remoteaddr,0,coin->symbol,&vins,locktime,satoshis,spendscriptstr,coin->changeaddr,txfee,minconf,addresses,0)) != 0 ) { if ( (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,vins,rawtx,0)) != 0 ) { @@ -557,144 +428,9 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * return(clonestr("{\"error\":\"need address and amount\"}")); } -char *iguana_createrawtx(struct supernet_info *myinfo,uint32_t rawtxtag,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) -{ - char *rawtx=0; - *vinsp = 0; - if ( (rawtx= iguana_rawtxissue(myinfo,rawtxtag,symbol,vinsp,locktime,satoshis,changeaddr,txfee,addresses,minconf,spendscriptstr,timeout)) != 0 ) - { - /*if ( *vinsp != 0 && (coin= iguana_coinfind(symbol)) != 0 && (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,*vinsp,rawtx)) != 0 ) - { - iguana_unspentslock(myinfo,coin,*vinsp); - retjson = cJSON_CreateObject(); - jaddbits256(retjson,"result",signedtxid); - jaddstr(retjson,"signedtx",signedtx); - jadd(retjson,"complete",completed != 0 ? jtrue() : jfalse()); - free(rawtx); - free(signedtx); - return(jprint(retjson,1)); - }*/ - return(rawtx); - } - return(0); -} - #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -INT_ARRAY_STRING(iguana,balances,lastheight,addresses,activecoin) -{ - 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 ) - { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) - { - array = cJSON_CreateArray(); - if ( (n= cJSON_GetArraySize(addresses)) > 0 ) - { - for (i=0; irawtxQ,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\"}")); -} - -STRING_ARRAY_OBJ_STRING(iguana,rawtx,changeaddr,addresses,vals,spendscriptstr) -{ - 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 ) - { - minconf = juint(vals,"minconf"); - locktime = juint(vals,"locktime"); - satoshis = j64bits(vals,"amount"); - txfee = j64bits(vals,"txfee"); - if ( (rawtxtag= juint(vals,"rawtxtag")) == 0 ) - OS_randombytes((uint8_t *)&rawtxtag,sizeof(rawtxtag)); - if ( (rawtx= iguana_createrawtx(myinfo,rawtxtag,symbol,&vins,locktime,satoshis,spendscriptstr,changeaddr,txfee,minconf,addresses,juint(json,"timeout"))) != 0 ) - { - //printf("return rawtx.(%s) remote.%p symbol.%s\n",rawtx,remoteaddr,symbol); - if ( remoteaddr != 0 && remoteaddr[0] != 0 && (coin= iguana_coinfind(symbol)) != 0 ) - { - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"rawtx",rawtx); - jaddstr(hexjson,"agent","iguana"); - jaddstr(hexjson,"method","rawtx_result"); - jaddnum(hexjson,"rawtxtag",rawtxtag); - if ( vins != 0 ) - jadd(hexjson,"vins",vins); - valsobj = cJSON_CreateObject(); - jaddstr(valsobj,"coin",symbol); - jadd(hexjson,"vals",valsobj); - retjson = iguana_requestjson(myinfo,hexjson); - } - else - { - jaddstr(retjson,"result",rawtx); - jadd(retjson,"vins",vins); - } - free(rawtx); - } else jaddstr(retjson,"error","couldnt create rawtx"); - } - return(jprint(retjson,1)); -} - -//{"rawtx":"0100000011533957010252b9534fe0186625e3075606f9b547e223830af04b3fb9dab2aaadc7cad5300100000000ffffffff0280969800000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac700c023b000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000","agent":"iguana","method":"rawtx_result","vins":[{"txid":"30d5cac7adaab2dab93f4bf00a8323e247b5f9065607e3256618e04f53b95202","vout":1,"scriptPubKey":"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac"}],"tag":"17812456603326673661"} - -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); - if ( vins != 0 ) - ptr->vins = jduplicate(vins); - ptr->rawtxtag = rawtxtag; - queue_enqueue("rawtxQ",&myinfo->rawtxQ,&ptr->DL,0); - return(0); -} - STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees) { cJSON *retjson = cJSON_CreateObject(); bits256 txid; @@ -1390,7 +1126,7 @@ S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; //iguana_unspentset(myinfo,coin); - return(sendtoaddress(myinfo,coin,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)); + return(sendtoaddress(myinfo,coin,remoteaddr,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)); } SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2) @@ -1401,7 +1137,7 @@ SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comme return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; //iguana_unspentset(myinfo,coin); - return(sendtoaddress(myinfo,coin,toaddress,amount * SATOSHIDEN,coin->txfee,comment,comment2,minconf,fromaccount)); + return(sendtoaddress(myinfo,coin,remoteaddr,toaddress,amount * SATOSHIDEN,coin->txfee,comment,comment2,minconf,fromaccount)); } S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) @@ -1422,7 +1158,7 @@ S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) amount = jdouble(item,0); val = amount * SATOSHIDEN; printf("(%s %.8f) ",coinaddr,dstr(val)); - if ( (str= sendtoaddress(myinfo,coin,coinaddr,val,coin->txfee,comment,"",minconf,fromaccount)) != 0 ) + if ( (str= sendtoaddress(myinfo,coin,remoteaddr,coinaddr,val,coin->txfee,comment,"",minconf,fromaccount)) != 0 ) { free(str); } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index e1f800e32..9a0c28965 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1042,7 +1042,7 @@ int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,in printf("cant create.(%s)\n",fname); return(-1); } - if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + if ( coin->MAXPEERS == 1 || coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) { iguana_vinsfname(coin,0,fname,addr->addrind); if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 2983b9613..f431e03fd 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -1029,8 +1029,10 @@ void iguana_rpcloop(void *args) else myinfo->argport = 0; if ( jsonbuf == 0 ) jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); - while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) + if ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) { + //if ( coin->MAXPEERS == 1 ) + // break; //exit(-1); sleep(3); } diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index eb8513328..c9f17648e 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -101,7 +101,7 @@ int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvou return(len); } -cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) +cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 sigtxid) { char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); vout = vin->prev_vout; @@ -112,6 +112,8 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) { jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); jaddnum(json,"vout",vout); + if ( bits256_nonz(sigtxid) != 0 ) + jaddbits256(json,"sigtxid",sigtxid); if ( vin->scriptlen > 0 ) iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); if ( vin->spendlen > 0 ) @@ -293,14 +295,52 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3 return(json); } +bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr) +{ + int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; + dest = *msgtx; + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( hashtype != SIGHASH_ALL ) + { + printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); + return(sigtxid); + } + for (i=0; itx_in; i++) + { + if ( i == vini ) + { + dest.vins[i].vinscript = spendscript; + dest.vins[i].scriptlen = spendlen; + } + else + { + dest.vins[i].vinscript = (uint8_t *)""; + dest.vins[i].scriptlen = 0; + } + dest.vins[i].p2shlen = 0; + dest.vins[i].redeemscript = 0; + } + len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0); + if ( len > 0 ) + { + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + revsigtxid = bits256_doublesha256(0,serialized,len); + for (i=0; iversion),&msg->version); if ( json != 0 ) { jaddnum(json,"version",msg->version); array = cJSON_CreateArray(); + if ( rwflag == 0 ) + sigser = calloc(1,maxsize); } //printf("version.%d\n",msg->version); if ( coin->chain->hastimestamp != 0 ) @@ -340,10 +380,17 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 return(-1); } if ( array != 0 ) - jaddi(array,iguana_vinjson(coin,&msg->vins[i])); + { + if ( sigser != 0 ) + sigtxid = bitcoin_sigtxid(coin,sigser,maxsize,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr); + else memset(sigtxid.bytes,0,sizeof(sigtxid)); + jaddi(array,iguana_vinjson(coin,&msg->vins[i],sigtxid)); + } } if ( array != 0 ) { + if ( sigser != 0 ) + free(sigser); jadd(json,"vin",array); jaddnum(json,"numvins",msg->tx_in); array = cJSON_CreateArray(); @@ -511,6 +558,8 @@ char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bit cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen) { int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; uint8_t *serialized; cJSON *txobj; + if ( coin == 0 ) + return(0); txobj = cJSON_CreateObject(); if ( msgtx == 0 ) msgtx = &M; @@ -531,42 +580,6 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_ms return(txobj); } -bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr) -{ - int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; - dest = *msgtx; - memset(sigtxid.bytes,0,sizeof(sigtxid)); - if ( hashtype != SIGHASH_ALL ) - { - printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); - return(sigtxid); - } - for (i=0; itx_in; i++) - { - if ( i == vini ) - { - dest.vins[i].vinscript = spendscript; - dest.vins[i].scriptlen = spendlen; - } - else - { - dest.vins[i].vinscript = (uint8_t *)""; - dest.vins[i].scriptlen = 0; - } - dest.vins[i].p2shlen = 0; - dest.vins[i].redeemscript = 0; - } - len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0); - if ( len > 0 ) - { - len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); - revsigtxid = bits256_doublesha256(0,serialized,len); - for (i=0; iVALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) + if ( (coin->MAXPEERS > 1 && coin->VALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) { bp->validated = (uint32_t)time(NULL); return(bp->n); diff --git a/iguana/m_LP b/iguana/m_LP new file mode 100755 index 000000000..730decef6 --- /dev/null +++ b/iguana/m_LP @@ -0,0 +1,8 @@ +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm ../agents/iguana *.o +git pull +cd secp256k1; ./m_unix; cd .. +gcc -g -Wno-deprecated -c -O2 *.c #databases/iguana_DB.c +gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c +#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_LTC b/iguana/m_LTC new file mode 100755 index 000000000..47f27e5fd --- /dev/null +++ b/iguana/m_LTC @@ -0,0 +1 @@ +../agents/iguana "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"LTC\",\"active\":1,\"maxpeers\":1,\"services\":128,\"poll\":30,\"RELAY\":0,\"VALIDATE\":0}" diff --git a/iguana/m_unix b/iguana/m_unix index a6c65aa34..45e692e57 100755 --- a/iguana/m_unix +++ b/iguana/m_unix @@ -4,5 +4,5 @@ git pull cd secp256k1; ./m_unix; cd .. gcc -g -Wno-deprecated -c -O2 *.c #databases/iguana_DB.c gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c -#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm +#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm diff --git a/iguana/main.c b/iguana/main.c index 4a55d7f50..e38ce76cf 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1164,10 +1164,10 @@ void iguana_appletests(struct supernet_info *myinfo) //int32_t iguana_schnorr_test(void *ctx); //iguana_schnorr_test(myinfo->ctx); getchar(); - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) + if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":128,\"maxpeers\":1,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) + if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index c7bde392f..c247a2faf 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -14,6 +14,7 @@ ******************************************************************************/ #include "../exchanges/bitcoin.h" +#include "../../basilisk/basilisk.h" /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 https://bitcointalk.org/index.php?topic=1364951 Tier Nolan's approach is followed with the following changes: @@ -169,7 +170,7 @@ void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo,struct iguana_info *coin,uint32_t locktime,char *scriptstr,int64_t satoshis,int64_t txfee,int32_t minconf,int32_t myside) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; uint8_t pubkey33[33]; char coinaddr[64],wifstr[64]; char *rawtx,*signedtx,*retstr; bits256 signedtxid; uint32_t rawtxtag; int32_t flag,completed; cJSON *valsobj,*vins,*retjson=0,*privkey,*argjson,*addresses; + struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; uint8_t pubkey33[33]; char coinaddr[64],wifstr[64]; char *rawtx,*signedtx,*retstr; bits256 signedtxid; uint32_t basilisktag; int32_t flag,completed; cJSON *valsobj,*vins,*retjson=0,*privkey,*argjson,*addresses; if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 ) { printf("no change addr error\n"); @@ -193,12 +194,12 @@ struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo jadd64bits(valsobj,"amount",satoshis); jadd64bits(valsobj,"txfee",txfee); jaddnum(valsobj,"minconf",minconf); - rawtxtag = (uint32_t)rand(); - jaddnum(valsobj,"rawtxtag",rawtxtag); + basilisktag = (uint32_t)rand(); + jaddnum(valsobj,"basilisktag",basilisktag); jaddnum(valsobj,"locktime",locktime); argjson = cJSON_CreateObject(); - jaddnum(argjson,"timeout",60000); - if ( (retstr= iguana_rawtx(myinfo,coin,argjson,0,coin->changeaddr,addresses,valsobj,scriptstr)) != 0 ) + jaddnum(argjson,"timeout",30000); + if ( (retstr= basilisk_rawtx(myinfo,coin,argjson,0,coin->changeaddr,addresses,valsobj,scriptstr)) != 0 ) { printf("%s got.(%s)\n",str,retstr); flag = 0; @@ -207,15 +208,6 @@ struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo if ( (rawtx= jstr(retjson,"result")) != 0 && (vins= jobj(retjson,"vins")) != 0 ) flag = 1; } - if ( flag == 0 ) - { - vins = 0; - if ( (rawtx= iguana_pollrawtx(&myinfo->rawtxQ,&vins,rawtxtag,OS_milliseconds() + 60000)) != 0 ) - { - if ( vins != 0 ) - flag = 2; - } - } if ( flag != 0 && vins != 0 ) { //printf("vins.(%s)\n",jprint(vins,0)); diff --git a/iguana/tests/balances b/iguana/tests/balances index 0583f8f62..469771abc 100755 --- a/iguana/tests/balances +++ b/iguana/tests/balances @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"iguana\",\"method\":\"balances\",\"lastheight\":0,\"activecoin\":\"BTCD\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"lastheight\":0,\"activecoin\":\"BTCD\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"]}" diff --git a/iguana/tests/rawtx b/iguana/tests/rawtx index 6f5c925ee..f0ed44bf6 100755 --- a/iguana/tests/rawtx +++ b/iguana/tests/rawtx @@ -1 +1 @@ -curl --url "http://127.0.0.1:14632" --data "{\"timeout\":25000,\"agent\":\"iguana\",\"method\":\"rawtx\",\"changeaddr\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"vals\":{\"coin\":\"BTC\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}" +curl --url "http://127.0.0.1:14632" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"changeaddr\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"vals\":{\"coin\":\"BTC\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}" diff --git a/iguana/tests/rawtxB b/iguana/tests/rawtxB new file mode 100755 index 000000000..c0ed9efff --- /dev/null +++ b/iguana/tests/rawtxB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"],\"vals\":{\"coin\":\"BTCD\",\"amount\":\"20000\"},\"spendscriptstr\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 1381d30e8..bca95dde1 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -14,6 +14,10 @@ ******************************************************************************/ +INT_ARRAY_STRING(basilisk,balances,lastheight,addresses,activecoin); +STRING_ARRAY_OBJ_STRING(basilisk,rawtx,changeaddr,addresses,vals,spendscriptstr); +INT_ARRAY_STRING(basilisk,result,basilisktag,argjson,hexmsg); + ZERO_ARGS(bitcoinrpc,getinfo); ZERO_ARGS(bitcoinrpc,getblockcount); ZERO_ARGS(bitcoinrpc,getbestblockhash); @@ -83,10 +87,6 @@ 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); - STRING_ARG(iguana,initfastfind,activecoin); STRING_ARG(iguana,peers,activecoin); STRING_AND_INT(iguana,maxpeers,activecoin,max);