diff --git a/.gitignore b/.gitignore index ba6f0a1f2..89d21bd7a 100755 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,27 @@ iguana/help.json iguana/index7778.html *.json + +iguana/DB/KMD/utxo.dat + +iguana/unparsed.txt + +iguana/unparsed.txt + +iguana/unparsed.txt + +iguana/DB/SWAPS/.tmpmarker + +iguana/DB/SWAPS/list + +iguana/DB/SWAPS/15974209-4014252807 + +iguana/iguana777.o-0cc60f50 + +iguana/DB/SWAPS/667293271-3414303895 + +iguana/DB/SWAPS/667293271-3414303895.swap + +iguana/DB/SWAPS/548227681-1452262678.swap + +iguana/DB/SWAPS/548227681-1452262678 diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index e4760e040..8610f2d66 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -482,6 +482,7 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) #include "basilisk_ether.c" #include "basilisk_waves.c" #include "basilisk_lisk.c" +#include "smartaddress.c" #include "basilisk_MSG.c" #include "tradebots_marketmaker.c" @@ -953,6 +954,435 @@ void basilisks_init(struct supernet_info *myinfo) #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +TWO_STRINGS(tradebot,gensvm,base,rel) +{ +#ifdef _WIN + return(clonestr("{\"error\":\"windows doesnt support SVM\"}")); +#else + int32_t numfeatures = 317*61; + struct tradebot_arbpair *pair; + if ( base[0] != 0 && rel[0] != 0 && (pair= tradebots_arbpair_find(base,rel)) != 0 && pair->fp != 0 ) + { + tradebots_calcanswers(pair); + ocas_gen(pair->refc,numfeatures,0,(int32_t)(ftell(pair->fp) / sizeof(pair->rawfeatures))); + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"cant find arbpair\"}")); +#endif +} + +ZERO_ARGS(tradebot,openliquidity) +{ + int32_t i; cJSON *array = cJSON_CreateArray(); + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + if ( myinfo->linfos[i].base[0] != 0 ) + jaddi(array,linfo_json(&myinfo->linfos[i])); + } + return(jprint(array,1)); +} + +ZERO_ARGS(tradebot,allbalances) +{ + int32_t i,n; double value,pending; char *base; cJSON *item,*balances = cJSON_CreateObject(); + if ( myinfo->liquidity_currencies == 0 ) + myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); + if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) + { + for (i=0; iliquidity_currencies,i); + value = tradebot_balance(myinfo,base); + pending = tradebot_pending(myinfo,base); + item = cJSON_CreateObject(); + jaddnum(item,"value",value); + jaddnum(item,"pending",pending); + jadd(balances,base,item); + } + } + return(jprint(balances,1)); +} + +ZERO_ARGS(tradebot,anchor) +{ + FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; + if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) + { + if ( jobj(anchor,"error") == 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) + retval = 0; + fclose(fp); + } + } + } + free(anchorstr); + } + if ( retval == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); +} + +ZERO_ARGS(tradebot,portfolio) +{ + char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; + if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (current= cJSON_Parse(currentstr)) != 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) + { + anchor = cJSON_Parse(anchorstr); + free(anchorstr); + } + if ( anchor == 0 ) + anchor = cJSON_Parse("{}"); + portfolio = tradebot_balancesdiff(myinfo,current,anchor); + free_json(current); + } + free(currentstr); + } + if ( portfolio == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(jprint(portfolio,1)); +} + +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) +{ + static bits256 zero; char *targetcoin; int32_t i,n; + if ( currencies != 0 && vals != 0 ) + { + // init things so automatically updates refli.bid and refli.ask + // volume range with margin + // currency percentage value in BTC? target distribution, max percentage, min percentage` + // min price to sell, max price to buy, max volume + n = cJSON_GetArraySize(currencies); + for (i=0; imyaddr.persistent); + if ( (msgid= juint(vals,"msgid")) == 0 ) + { + msgid = (uint32_t)time(NULL); + jdelete(vals,"msgid"); + jaddnum(vals,"msgid",msgid); + } + if ( myinfo->NOTARY.RELAYID >= 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + { + channel = juint(vals,"channel"); + width = juint(vals,"width"); + retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(vals,"srchash"),jbits256(vals,"desthash"),width); + //printf("getmessage.(%s)\n",retstr); + return(retstr); + } + //printf("getmessage not relay.%d dexsock.%d subsock.%d\n",myinfo->NOTARY.RELAYID,myinfo->dexsock,myinfo->subsock); + return(basilisk_standardservice("MSG",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +{ + int32_t keylen,datalen,allocsize = 65536; uint8_t key[BASILISK_KEYSIZE],*space,*space2,*data,*ptr = 0; char *retstr=0; + space = calloc(1,allocsize); + space2 = calloc(1,allocsize); + data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,&space[BASILISK_KEYSIZE],allocsize-BASILISK_KEYSIZE,hexstr); + if ( myinfo->subsock >= 0 || myinfo->dexsock >= 0 || (myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0) ) + { + keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); + if ( data != 0 ) + { + retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); + } else printf("no get_dataptr\n"); + if ( retstr != 0 ) + free(retstr); + } //else printf("not notary.%d relayid.%d\n",myinfo->IAMNOTARY,myinfo->NOTARY.RELAYID); + if ( vals != 0 && juint(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); + if ( BASILISK_KEYSIZE+datalen < allocsize ) + { + memcpy(space2,key,BASILISK_KEYSIZE); + if ( data != 0 && datalen != 0 ) + memcpy(&space2[BASILISK_KEYSIZE],data,datalen); + dex_reqsend(myinfo,"DEX",space2,datalen+BASILISK_KEYSIZE,1,""); + } else printf("sendmessage space too small error for %d\n",datalen); + free(space); + free(space2); + if ( ptr != 0 ) + free(ptr); + return(basilisk_standardservice("OUT",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) +{ + char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; + if ( vals == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + txid = jbits256(vals,"txid"); + vout = jint(vals,"vout"); + if ( coin != 0 ) + { + if ( coin->FULLNODE < 0 ) + { + if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) + { + if ( (coinaddr= jstr(txoutjson,"address")) != 0 && (value= SATOSHIDEN*jdouble(txoutjson,"value")) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"amount",dstr(value)); + height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,0,coin); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",coin->symbol); + } + else + { + free_json(txoutjson); + return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); + } + free_json(txoutjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"null return from gettxout\"}")); + } + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = OS_milliseconds() + 10000; + return(retstr); + } + } + if ( myinfo->reqsock >= 0 ) + { + if ( (retstr= _dex_getrawtransaction(myinfo,symbol,txid)) != 0 ) + { + if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("TX.(%s)\n",jprint(txoutjson,0)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) + { + //printf("txjson.(%s)\n",jprint(txjson,0)); + if ( (value= jdouble(txjson,"value") * SATOSHIDEN) != 0 ) + { + if ( (sobj= jobj(txjson,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 && (coinaddr= jstri(addrs,0)) != 0 ) + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + if ( (infostr= _dex_getinfo(myinfo,symbol)) != 0 ) + { + if ( (info= cJSON_Parse(infostr)) != 0 ) + { + if ( (height= jint(info,"blocks")) > 0 ) + { + height -= jint(txoutjson,"confirmations"); + jaddnum(retjson,"height",height); + } + free_json(info); + } + free(infostr); + } + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",symbol); + free(retstr); + free_json(txoutjson); + return(jprint(retjson,1)); + } + } + free_json(txoutjson); + return(jprint(retjson,1)); + } + return(retstr); + } + } + return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; + if ( vals == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",MIN(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( coin != 0 ) + { + //if ( juint(vals,"burn") == 0 ) + // jaddnum(vals,"burn",0.0001); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals,0)) != 0 ) + { + printf("rawtx.(%s)\n",retstr); + if ( (amount= j64bits(vals,"satoshis")) == 0 ) + amount = jdouble(vals,"value") * SATOSHIDEN; + if ( (txfee= j64bits(vals,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + retval = -1; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + for (i=0; iFULLNODE >= 0 ) + return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); + else + { + safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + myinfo->jumblr_depositkey = curve25519(privkey,curve25519_basepoint9()); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + if ( coin->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coin,wifstr); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coinbtc->chain->wiftype); + if ( coinbtc->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coinbtc,wifstr); + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + } + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + myinfo->jumblr_pubkey = curve25519(privkey,curve25519_basepoint9()); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + return(jprint(retjson,1)); + } +} + +ZERO_ARGS(jumblr,status) +{ + cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; struct iguana_info *coinbtc; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; + if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 ) + { + jumblr_opidsupdate(myinfo,coin); + retjson = cJSON_CreateObject(); + step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; + jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + received = jumblr_receivedby(myinfo,coin,KMDaddr); + deposited = jumblr_balance(myinfo,coin,KMDaddr); + jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + finished = jumblr_receivedby(myinfo,coin,KMDaddr); + jumblred = jumblr_balance(myinfo,coin,KMDaddr); + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( strlen(ptr->src) >= 40 ) + { + if ( strlen(ptr->dest) >= 40 ) + step_z2z += ptr->amount; + else step_z2t += ptr->amount; + } else step_t2z += ptr->amount; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"deposits",dstr(deposited)); + jaddnum(retjson,"t_to_z",dstr(step_t2z)); + jaddnum(retjson,"z_to_z",dstr(step_z2z)); + jaddnum(retjson,"z_to_t",dstr(step_z2t)); + maxval = MAX(step_t2z,MAX(step_z2z,step_z2t)); + minval = MIN(step_t2z,MIN(step_z2z,step_z2t)); + if ( maxval > minval ) + { + pending = (maxval - minval); + if ( pending < finished*.1 ) + pending = 0; + } + jaddnum(retjson,"pending",dstr(pending)); + jaddnum(retjson,"jumbled",dstr(jumblred)); + jaddnum(retjson,"received",dstr(received)); + jaddnum(retjson,"finished",dstr(finished)); + return(jprint(retjson,1)); + } + else + { + printf("(%s) (%s) %d\n",coin->symbol,myinfo->jumblr_passphrase,coin->FULLNODE); + return(clonestr("{\"error\":\"jumblr status no passphrase or no native komodod\"}")); + } +} + HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) { char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; @@ -1085,9 +1515,16 @@ int32_t utxocmp(cJSON *utxo,cJSON *utxo2) else return(-1); } +ZERO_ARGS(basilisk,cancelrefresh) +{ + myinfo->cancelrefresh = 1; + return(clonestr("{\"result\":\"refresh cancel started\"}")); +} + TWO_STRINGS(basilisk,refresh,symbol,address) { cJSON *array=0,*array2=0,*array3,*item,*item2; char *retstr; int32_t i,j,n,m,vout; bits256 txid; + myinfo->cancelrefresh = 0; if ( symbol != 0 && iguana_isnotarychain(symbol) >= 0 && address != 0 && address[0] != 0 ) { if ( (retstr= _dex_listunspent(myinfo,symbol,address)) != 0 ) @@ -1110,6 +1547,8 @@ TWO_STRINGS(basilisk,refresh,symbol,address) //printf("MERGE %s and %s\n",jprint(array,0),jprint(array2,0)); for (j=0; jcancelrefresh != 0 ) + break; item2 = jitem(array2,j); for (i=0; icancelrefresh != 0 ) + break; item = jitem(array,i); txid = jbits256(item,"txid"); vout = jint(item,"vout"); @@ -1151,9 +1592,11 @@ TWO_STRINGS(basilisk,refresh,symbol,address) } } free_json(array); + myinfo->cancelrefresh = 0; return(jprint(array3,1)); } else return(clonestr("[]")); } + myinfo->cancelrefresh = 0; return(clonestr("{\"error\":\"invalid coin or address specified\"}")); } @@ -1175,5 +1618,242 @@ STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) //int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timelocked,char *destaddr,bits256 txid,int32_t vout) +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); +} + +ZERO_ARGS(InstantDEX,allcoins) +{ + struct iguana_info *tmp; cJSON *native,*notarychains,*basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); + full = cJSON_CreateArray(); + native = cJSON_CreateArray(); + basilisk = cJSON_CreateArray(); + virtual = cJSON_CreateArray(); + notarychains = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->FULLNODE < 0 ) + jaddistr(native,coin->symbol); + //else if ( coin->virtualchain != 0 ) + // jaddistr(virtual,coin->symbol); + else if ( coin->FULLNODE > 0 )//|| coin->VALIDATENODE > 0 ) + jaddistr(full,coin->symbol); + //else if ( coin->notarychain >= 0 ) + // jaddistr(notarychains,coin->symbol); + else jaddistr(basilisk,coin->symbol); + } + jadd(retjson,"native",native); + jadd(retjson,"basilisk",basilisk); + jadd(retjson,"full",full); + //jadd(retjson,"virtual",virtual); + //jadd(retjson,"notarychains",notarychains); + return(jprint(retjson,1)); +} + +STRING_ARG(InstantDEX,available,source) +{ + uint64_t total = 0; int32_t i,n=0; char coinaddr[64]; cJSON *item,*unspents,*retjson = 0; + if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) + { + if ( myinfo->expiration != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( (unspents= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) + { + //printf("available.(%s)\n",jprint(unspents,0)); + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; i %.8f\n",jprint(item,0),dstr(total)); + } + } + free_json(unspents); + } + retjson = cJSON_CreateObject(); + jaddnum(retjson,"result",dstr(total)); + printf(" n.%d total %.8f (%s)\n",n,dstr(total),jprint(retjson,0)); + return(jprint(retjson,1)); + } + printf("InstantDEX_available: need to unlock wallet\n"); + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } + printf("InstantDEX_available: %s is not active\n",source!=0?source:""); + return(clonestr("{\"error\":\"specified coin is not active\"}")); +} + +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) +{ + uint8_t serialized[512]; bits256 privkey; char buf[512],BTCaddr[64],KMDaddr[64]; struct basilisk_request R; int32_t jumblr,iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; + myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; + jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN * SATOSHIDEN); + if ( jobj(vals,"desthash") == 0 ) + jaddbits256(vals,"desthash",hash); + jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); + jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); + jaddnum(vals,"timestamp",time(NULL)); + if ( (jumblr= jint(vals,"usejumblr")) != 0 ) + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); + else privkey = myinfo->persistent_priv; + hash = curve25519(privkey,curve25519_basepoint9()); + if ( jobj(vals,"srchash") == 0 ) + jaddbits256(vals,"srchash",hash); + printf("service.(%s)\n",jprint(vals,0)); + memset(&R,0,sizeof(R)); + if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) + { + iambob = bitcoin_coinptrs(hash,&bobcoin,&alicecoin,R.src,R.dest,privkey,GENESIS_PUBKEY); + if ( (optionhours= jint(vals,"optionhours")) != 0 ) + { + printf("iambob.%d optionhours.%d R.requestid.%u vs calc %u, q.%u\n",iambob,R.optionhours,R.requestid,basilisk_requestid(&R),R.quoteid); + if ( iambob != 0 && optionhours > 0 ) + { + sprintf(buf,"{\"error\":\"illegal call option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + else if ( iambob == 0 && optionhours < 0 ) + { + sprintf(buf,"{\"error\":\"illegal put option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + } + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // R.relaybits = myinfo->myaddr.myipbits; + if ( (reqjson= basilisk_requestjson(&R)) != 0 ) + free_json(reqjson); + datalen = basilisk_rwDEXquote(1,serialized,&R); + //int32_t i; for (i=0; i 0 ) + { + uint32_t msgid;//,crc=0,crcs[2],numiters = 0; uint8_t buf[4096]; + memset(hash.bytes,0,sizeof(hash)); + msgid = (uint32_t)time(NULL); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + basilisk_channelsend(myinfo,hash,hash,DEX_channel,msgid,serialized,datalen,60); + sleep(3); + /*while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) + { + //printf("didnt get back what was sent\n"); + sleep(3); + basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); + numiters++; + }*/ + //if ( crc != 0 )//basilisk_channelsend(myinfo,R.srchash,R.desthash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) + return(clonestr("{\"result\":\"DEX message sent\"}")); + //else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); + } + return(clonestr("{\"error\":\"DEX message not sent\"}")); +} + +INT_ARG(InstantDEX,automatched,requestid) +{ + // return quoteid + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + return(clonestr("{\"result\":\"automatched not yet\"}")); +} + +int32_t InstantDEX_incoming_func(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + //int32_t i; + //for (i=0; iDEXpoll) + 2*drift; + if ( width < (drift+1) ) + width = 2*drift+1; + else if ( width > 64 ) + width = 64; + myinfo->DEXpoll = now; + retjson = cJSON_CreateObject(); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + msgid = (uint32_t)time(NULL) + drift; + if ( (retarray= basilisk_channelget(myinfo,zero,myinfo->myaddr.persistent,DEX_channel,msgid,width)) != 0 ) + { + //printf("GOT.(%s)\n",jprint(retarray,0)); + if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) + { + jaddstr(retjson,"result","success"); + } else jaddstr(retjson,"error","cant process InstantDEX retarray"); + jadd(retjson,"responses",retarray); + } + else + { + jaddstr(retjson,"error","cant do InstantDEX channelget"); + printf("error channelget\n"); + } + return(jprint(retjson,1)); +} + +/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) + { + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",(uint32_t)requestid); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } + }*/ + +TWO_INTS(InstantDEX,accept,requestid,quoteid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + if ( myinfo->IAMLP != 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + return(basilisk_respond_accept(myinfo,myinfo->persistent_priv,requestid,quoteid,&myinfo->DEXaccept)); + else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddnum(vals,"requestid",(uint32_t)requestid); + retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +ZERO_ARGS(InstantDEX,init) +{ + basilisk_swaps_init(myinfo); + return(clonestr("{\"result\":\"success\"}")); +} #include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index 45bbdd6b2..b15b9032f 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -16,7 +16,7 @@ #ifndef H_BASILISK_H #define H_BASILISK_H -//#define BASILISK_DISABLESENDTX +#define BASILISK_DISABLESENDTX #define BASILISK_DISABLEWAITTX #include "../iguana/iguana777.h" @@ -37,13 +37,16 @@ #define INSTANTDEX_INSURANCEDIV 777 #define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" #define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +struct basilisk_swap; + struct basilisk_rawtxinfo { - char destaddr[64]; + char destaddr[64],coinstr[16]; bits256 txid,signedtxid,actualtxid; uint64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; @@ -57,8 +60,9 @@ struct basilisk_rawtx struct iguana_msgtx msgtx; struct basilisk_rawtxinfo I; struct iguana_info *coin; + char vinstr[8192]; cJSON *vins; - uint8_t *txbytes,spendscript[512],redeemscript[1024],extraspace[1024]; + uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096]; }; struct basilisk_swapinfo @@ -67,27 +71,16 @@ struct basilisk_swapinfo char bobstr[64],alicestr[64]; bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; - int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent; + int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad; uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; - int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; uint8_t secretAm[20],secretBn[20]; uint8_t secretAm256[32],secretBn256[32]; }; -struct basilisk_swap -{ - struct supernet_info *myinfo; struct iguana_info *bobcoin,*alicecoin; - void (*balancingtrade)(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob); - struct basilisk_swapinfo I; - struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; - bits256 privkeys[INSTANTDEX_DECKSIZE]; - uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; - uint8_t verifybuf[65536]; -}; - struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vout; char coinaddr[64]; }; struct basilisk_item @@ -135,7 +128,7 @@ int32_t basilisk_update(char *symbol,uint32_t reftimestamp); void basilisk_seqresult(struct supernet_info *myinfo,char *retstr); struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj); void basilisk_alicepayment(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn); -void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33); +void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33,int32_t jumblrflag); void basilisk_setmyid(struct supernet_info *myinfo); int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp); cJSON *basilisk_requestjson(struct basilisk_request *rp); diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 607d32099..5ec6fcaed 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -229,15 +229,17 @@ int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits2 return(-1); } -char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *_rp,uint32_t statebits,int32_t optionduration) +char *basilisk_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *_rp,uint32_t statebits,int32_t optionduration) { - cJSON *retjson; struct basilisk_request *rp=0; int32_t i; + cJSON *retjson; bits256 tmpprivkey; struct basilisk_request *rp=0; int32_t i,srcmatch,destmatch; if ( _rp->requestid == myinfo->lastdexrequestid ) { //printf("filter duplicate r%u\n",_rp->requestid); return(clonestr("{\"error\":\"filter duplicate requestid\"}")); } - if ( (bits256_cmp(_rp->srchash,myinfo->myaddr.persistent) == 0 || bits256_cmp(_rp->desthash,myinfo->myaddr.persistent) == 0) ) + srcmatch = smartaddress_pubkey(myinfo,&tmpprivkey,_rp->srchash) >= 0; + destmatch = smartaddress_pubkey(myinfo,&tmpprivkey,_rp->desthash) >= 0; + if ( srcmatch != 0 || destmatch != 0 ) { for (i=0; inumswaps; i++) if ( myinfo->swaps[i]->I.req.requestid == _rp->requestid ) @@ -251,12 +253,11 @@ char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *_rp,u *rp = *_rp; printf("START thread to complete %u/%u for (%s %.8f) <-> (%s %.8f) q.%u\n",rp->requestid,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount),rp->quoteid); myinfo->lastdexrequestid = rp->requestid; - if ( basilisk_thread_start(myinfo,rp,statebits,optionduration) != 0 ) + if ( basilisk_thread_start(myinfo,privkey,rp,statebits,optionduration,0) != 0 ) { basilisk_request_enqueue(myinfo,rp); return(clonestr("{\"result\":\"started atomic swap thread\"}")); - } - else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}")); + } else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}")); } else { @@ -275,8 +276,8 @@ char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *_rp,u void basilisk_requests_poll(struct supernet_info *myinfo) { static uint32_t lastpoll; - char *retstr; uint8_t data[32768]; cJSON *outerarray,*retjson; uint32_t msgid,channel; int32_t datalen,i,n; struct basilisk_request issueR; double hwm = 0.; - if ( time(NULL) < lastpoll+3 ) + char *retstr; uint8_t data[32768]; cJSON *outerarray,*retjson; uint32_t msgid,channel; int32_t datalen,i,n; struct basilisk_request issueR; bits256 privkey; double hwm = 0.; + if ( myinfo->IAMNOTARY != 0 || time(NULL) < lastpoll+20 || (myinfo->IAMLP == 0 && myinfo->DEXactive < time(NULL)) ) return; lastpoll = (uint32_t)time(NULL); memset(&issueR,0,sizeof(issueR)); @@ -299,42 +300,15 @@ void basilisk_requests_poll(struct supernet_info *myinfo) channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); if ( hwm > 0. ) { - //printf("hwm %f\n",hwm); - //for (i=0; iDEXaccept = issueR; - /*issueR.quoteid = basilisk_quoteid(&issueR); - datalen = basilisk_rwDEXquote(1,data,&issueR); - msgid = (uint32_t)time(NULL); - keylen = basilisk_messagekey(key,0,msgid,issueR.srchash,issueR.desthash); - if ( (retstr= basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,BASILISK_DEXDURATION)) != 0 ) - free(retstr);*/ - if ( bits256_cmp(myinfo->myaddr.persistent,issueR.srchash) == 0 ) // my request + if ( smartaddress_pubkey(myinfo,&privkey,issueR.srchash) >= 0 ) { + printf("matched dex_smartpubkey\n"); dex_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid)); // 60 dpow_nanomsg_update(myinfo); dex_updateclient(myinfo); - if ( (retstr= basilisk_start(myinfo,&issueR,1,issueR.optionhours * 3600)) != 0 ) - free(retstr); - /*if ( (retstr= InstantDEX_accept(myinfo,0,0,0,issueR.requestid,issueR.quoteid)) != 0 ) + if ( (retstr= basilisk_start(myinfo,privkey,&issueR,1,issueR.optionhours * 3600)) != 0 ) free(retstr); - printf("my req hwm %f -> %u\n",hwm,issueR.requestid); - basilisk_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid),60); - numiters = crc = 0; - while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid),crcs)) == 0 ) - { - printf("didnt get back what was sent\n"); - sleep(3); - basilisk_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid),60); - numiters++; - } - if ( crc != 0 ) - { - printf("crc.%08x -> basilisk_starta\n",crc); - if ( (retstr= basilisk_start(myinfo,&issueR,1,issueR.optionhours * 3600)) != 0 ) - free(retstr); - } // else printf("couldnt accept offer\n");*/ } else if ( issueR.requestid != myinfo->lastdexrequestid )//if ( issueR.quoteid == 0 ) { @@ -346,24 +320,8 @@ void basilisk_requests_poll(struct supernet_info *myinfo) dex_channelsend(myinfo,issueR.desthash,issueR.srchash,channel,msgid,data,datalen); //INSTANTDEX_LOCKTIME*2 dpow_nanomsg_update(myinfo); dex_updateclient(myinfo); - if ( (retstr= basilisk_start(myinfo,&issueR,0,issueR.optionhours * 3600)) != 0 ) + if ( (retstr= basilisk_start(myinfo,myinfo->persistent_priv,&issueR,0,issueR.optionhours * 3600)) != 0 ) free(retstr); - /*crcs[0] = crcs[1] = 0; - numiters = 0; - basilisk_channelsend(myinfo,issueR.desthash,issueR.srchash,channel,msgid,data,datalen,INSTANTDEX_LOCKTIME*2); - while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),issueR.desthash,issueR.srchash,channel,msgid,data,datalen,crcs)) == 0 ) - { - //printf("didnt get back what was sent\n"); - sleep(3); - basilisk_channelsend(myinfo,issueR.desthash,issueR.srchash,channel,msgid,data,datalen,INSTANTDEX_LOCKTIME*2); - numiters++; - } - if ( crc != 0 ) - { - printf("crc.%08x -> basilisk_start\n",crc); - if ( (retstr= basilisk_start(myinfo,&issueR,0,issueR.optionhours * 3600)) != 0 ) - free(retstr); - }*/ } //else printf("basilisk_requests_poll unexpected hwm issueR\n"); } } @@ -489,7 +447,7 @@ char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32 return(jprint(retjson,1)); } -char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,uint32_t quoteid,struct basilisk_request *refrp) +char *basilisk_respond_accept(struct supernet_info *myinfo,bits256 privkey,uint32_t requestid,uint32_t quoteid,struct basilisk_request *refrp) { int32_t i,num=0; char *retstr=0; struct basilisk_request *requests,*rp; uint8_t space[4096]; portable_mutex_lock(&myinfo->DEX_reqmutex); @@ -501,7 +459,7 @@ char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,ui if ( rp->requestid == requestid && rp->quoteid == quoteid ) { printf("start from accept\n"); - retstr = basilisk_start(myinfo,rp,1,0); + retstr = basilisk_start(myinfo,privkey,rp,1,0); break; } } @@ -513,51 +471,6 @@ char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,ui retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}"); return(retstr); } - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) -{ - double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); - aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"aveprice",aveprice); - jaddnum(retjson,"avebid",retvals[0]); - jaddnum(retjson,"bidvol",retvals[1]); - jaddnum(retjson,"aveask",retvals[2]); - jaddnum(retjson,"askvol",retvals[3]); - return(jprint(retjson,1)); -} - -ZERO_ARGS(InstantDEX,allcoins) -{ - struct iguana_info *tmp; cJSON *native,*notarychains,*basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); - full = cJSON_CreateArray(); - native = cJSON_CreateArray(); - basilisk = cJSON_CreateArray(); - virtual = cJSON_CreateArray(); - notarychains = cJSON_CreateArray(); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->FULLNODE < 0 ) - jaddistr(native,coin->symbol); - //else if ( coin->virtualchain != 0 ) - // jaddistr(virtual,coin->symbol); - else if ( coin->FULLNODE > 0 )//|| coin->VALIDATENODE > 0 ) - jaddistr(full,coin->symbol); - //else if ( coin->notarychain >= 0 ) - // jaddistr(notarychains,coin->symbol); - else jaddistr(basilisk,coin->symbol); - } - jadd(retjson,"native",native); - jadd(retjson,"basilisk",basilisk); - jadd(retjson,"full",full); - //jadd(retjson,"virtual",virtual); - //jadd(retjson,"notarychains",notarychains); - return(jprint(retjson,1)); -} - cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { cJSON *unspents=0,*array=0; char *retstr; @@ -570,7 +483,7 @@ cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,c } else if ( coin->FULLNODE == 0 ) { - if ( (retstr= _dex_listunspent(myinfo,coin->symbol,coinaddr)) != 0 ) + if ( (retstr= dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)) != 0 ) { unspents = cJSON_Parse(retstr); free(retstr); @@ -600,191 +513,3 @@ char *basilisk_sendrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(retstr); } -STRING_ARG(InstantDEX,available,source) -{ - uint64_t total = 0; int32_t i,n=0; char coinaddr[64]; cJSON *item,*unspents,*retjson = 0; - if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) - { - if ( myinfo->expiration != 0 ) - { - bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); - if ( (unspents= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) - { - //printf("available.(%s)\n",jprint(unspents,0)); - if ( (n= cJSON_GetArraySize(unspents)) > 0 ) - { - for (i=0; i %.8f\n",jprint(item,0),dstr(total)); - } - } - free_json(unspents); - } - retjson = cJSON_CreateObject(); - jaddnum(retjson,"result",dstr(total)); - printf(" n.%d total %.8f (%s)\n",n,dstr(total),jprint(retjson,0)); - return(jprint(retjson,1)); - } - printf("InstantDEX_available: need to unlock wallet\n"); - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - } - printf("InstantDEX_available: %s is not active\n",source!=0?source:""); - return(clonestr("{\"error\":\"specified coin is not active\"}")); -} - -HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) -{ - uint8_t serialized[512]; char buf[512]; struct basilisk_request R; int32_t iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; - myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; - jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN); - if ( jobj(vals,"srchash") == 0 ) - jaddbits256(vals,"srchash",myinfo->myaddr.persistent); - if ( jobj(vals,"desthash") == 0 ) - jaddbits256(vals,"desthash",hash); - jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); - jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); - jaddnum(vals,"timestamp",time(NULL)); - hash = myinfo->myaddr.persistent; - printf("service.(%s)\n",jprint(vals,0)); - memset(&R,0,sizeof(R)); - if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) - { - iambob = bitcoin_coinptrs(myinfo,&bobcoin,&alicecoin,R.src,R.dest,myinfo->myaddr.persistent,GENESIS_PUBKEY); - if ( (optionhours= jint(vals,"optionhours")) != 0 ) - { - printf("iambob.%d optionhours.%d R.requestid.%u vs calc %u, q.%u\n",iambob,R.optionhours,R.requestid,basilisk_requestid(&R),R.quoteid); - if ( iambob != 0 && optionhours > 0 ) - { - sprintf(buf,"{\"error\":\"illegal call option request hours.%d when iambob.%d\"}",optionhours,iambob); - printf("ERROR.(%s)\n",buf); - return(clonestr(buf)); - } - else if ( iambob == 0 && optionhours < 0 ) - { - sprintf(buf,"{\"error\":\"illegal put option request hours.%d when iambob.%d\"}",optionhours,iambob); - printf("ERROR.(%s)\n",buf); - return(clonestr(buf)); - } - } - //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) - // R.relaybits = myinfo->myaddr.myipbits; - if ( (reqjson= basilisk_requestjson(&R)) != 0 ) - free_json(reqjson); - datalen = basilisk_rwDEXquote(1,serialized,&R); - //int32_t i; for (i=0; i 0 ) - { - uint32_t msgid,crc=0,crcs[2],numiters = 0; uint8_t buf[4096]; - memset(hash.bytes,0,sizeof(hash)); - msgid = (uint32_t)time(NULL); - DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); - sleep(3); - while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) - { - //printf("didnt get back what was sent\n"); - sleep(3); - basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); - numiters++; - } - if ( crc != 0 )//basilisk_channelsend(myinfo,R.srchash,R.desthash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) - return(clonestr("{\"result\":\"DEX message sent\"}")); - else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); - } - return(clonestr("{\"error\":\"DEX message not sent\"}")); -} - -INT_ARG(InstantDEX,automatched,requestid) -{ - // return quoteid - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - return(clonestr("{\"result\":\"automatched not yet\"}")); -} - -int32_t InstantDEX_incoming_func(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) -{ - //int32_t i; - //for (i=0; iDEXpoll) + 2*drift; - if ( width < (drift+1) ) - width = 2*drift+1; - else if ( width > 64 ) - width = 64; - myinfo->DEXpoll = now; - retjson = cJSON_CreateObject(); - DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - msgid = (uint32_t)time(NULL) + drift; - if ( (retarray= basilisk_channelget(myinfo,zero,myinfo->myaddr.persistent,DEX_channel,msgid,width)) != 0 ) - { - //printf("GOT.(%s)\n",jprint(retarray,0)); - if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) - { - jaddstr(retjson,"result","success"); - } else jaddstr(retjson,"error","cant process InstantDEX retarray"); - jadd(retjson,"responses",retarray); - } - else - { - jaddstr(retjson,"error","cant do InstantDEX channelget"); - printf("error channelget\n"); - } - return(jprint(retjson,1)); -} - -/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - //if ( myinfo->IAMLP != 0 ) - // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); - //else - { - vals = cJSON_CreateObject(); - jaddnum(vals,"requestid",(uint32_t)requestid); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddbits256(vals,"hash",myinfo->myaddr.persistent); - retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); - } -}*/ - -TWO_INTS(InstantDEX,accept,requestid,quoteid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - if ( myinfo->IAMLP != 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) - return(basilisk_respond_accept(myinfo,requestid,quoteid,&myinfo->DEXaccept)); - else - { - vals = cJSON_CreateObject(); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddnum(vals,"requestid",(uint32_t)requestid); - retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); - } -} -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index e80e37f73..6619c4db0 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -98,12 +98,16 @@ char *basilisk_iterate_MSG(struct supernet_info *myinfo,uint32_t channel,uint32_ // char str[65],str2[65]; printf("MSGiterate (%s) -> (%s)\n",bits256_str(str,srchash),bits256_str(str2,desthash)); array = cJSON_CreateArray(); portable_mutex_lock(&myinfo->messagemutex); - //printf("iterate_MSG allflag.%d width.%d channel.%d msgid.%d src.%llx -> %llx\n",allflag,origwidth,channel,msgid,(long long)srchash.txid,(long long)desthash.txid); + printf("iterate_MSG width.%d channel.%d msgid.%d src.%llx -> %llx\n",origwidth,channel,msgid,(long long)srchash.txid,(long long)desthash.txid); for (i=0; ikey,msg->keylen)) != 0 ) + { + jaddbits256(msgjson,"src",srchash); + jaddbits256(msgjson,"dest",desthash); jaddi(array,msgjson); + } } } if ( now > msg->expiration+60 ) @@ -217,7 +237,11 @@ char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int3 HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg); QUEUEITEMS++; portable_mutex_unlock(&myinfo->messagemutex); -//printf("add message keylen.%d [%d]\n",msg->keylen,datalen); + { + bits256 srchash,desthash; uint32_t channel,msgid; + basilisk_messagekeyread(key,&channel,&msgid,&srchash,&desthash); + //printf("add message keylen.%d [%d] msgid.%x channel.%x\n",msg->keylen,datalen,msgid,channel); + } //if ( myinfo->NOTARY.RELAYID >= 0 ) // dpow_handler(myinfo,msg); if ( sendping != 0 ) @@ -259,66 +283,41 @@ char *basilisk_respond_MSG(struct supernet_info *myinfo,char *CMD,void *addr,cha return(retstr); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) +cJSON *dpow_getmessage(struct supernet_info *myinfo,char *jsonstr) { - uint32_t msgid,width,channel; char *retstr; - if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"srchash")) == 0 ) - jaddbits256(vals,"srchash",hash); - if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"desthash")) == 0 ) - jaddbits256(vals,"desthash",myinfo->myaddr.persistent); - if ( (msgid= juint(vals,"msgid")) == 0 ) + cJSON *valsobj,*retjson = 0; char *retstr; + if ( (valsobj= cJSON_Parse(jsonstr)) != 0 ) { - msgid = (uint32_t)time(NULL); - jdelete(vals,"msgid"); - jaddnum(vals,"msgid",msgid); - } - if ( myinfo->NOTARY.RELAYID >= 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) - { - channel = juint(vals,"channel"); - width = juint(vals,"width"); - retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(vals,"srchash"),jbits256(vals,"desthash"),width); - //printf("getmessage.(%s)\n",retstr); - return(retstr); + retstr = basilisk_iterate_MSG(myinfo,juint(valsobj,"channel"),juint(valsobj,"msgid"),jbits256(valsobj,"srchash"),jbits256(valsobj,"desthash"),juint(valsobj,"width")); + retjson = cJSON_Parse(retstr); + free(retstr); } - //printf("getmessage not relay.%d dexsock.%d subsock.%d\n",myinfo->NOTARY.RELAYID,myinfo->dexsock,myinfo->subsock); - return(basilisk_standardservice("MSG",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,1)); + return(retjson); } -HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +cJSON *dpow_addmessage(struct supernet_info *myinfo,char *jsonstr) { - int32_t keylen,datalen,allocsize = 65536; uint8_t key[BASILISK_KEYSIZE],*space,*space2,*data,*ptr = 0; char *retstr=0; - space = calloc(1,allocsize); - space2 = calloc(1,allocsize); - data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,&space[BASILISK_KEYSIZE],allocsize-BASILISK_KEYSIZE,hexstr); - if ( myinfo->subsock >= 0 || myinfo->dexsock >= 0 || (myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0) ) + cJSON *vals,*retjson=0; char *retstr=0,*datastr; int32_t datalen,keylen; uint8_t *data=0,key[BASILISK_KEYSIZE]; + if ( (vals= cJSON_Parse(jsonstr)) != 0 ) { keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); - if ( data != 0 ) + if ( (datastr= jstr(vals,"data")) != 0 ) { - retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); - } else printf("no get_dataptr\n"); + datalen = (int32_t)strlen(datastr) >> 1; + data = malloc(datalen); + decode_hex(data,datalen,datastr); + if ( (retstr= basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration"))) != 0 ) + retjson = cJSON_Parse(retstr); + } if ( retstr != 0 ) free(retstr); - } //else printf("not notary.%d relayid.%d\n",myinfo->IAMNOTARY,myinfo->NOTARY.RELAYID); - if ( vals != 0 && juint(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); - if ( BASILISK_KEYSIZE+datalen < allocsize ) - { - memcpy(space2,key,BASILISK_KEYSIZE); - if ( data != 0 && datalen != 0 ) - memcpy(&space2[BASILISK_KEYSIZE],data,datalen); - dex_reqsend(myinfo,"DEX",space2,datalen+BASILISK_KEYSIZE,1,""); - } else printf("sendmessage space too small error for %d\n",datalen); - free(space); - free(space2); - if ( ptr != 0 ) - free(ptr); - return(basilisk_standardservice("OUT",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,0)); + if ( data != 0 ) + free(data); + } + if ( retjson == 0 ) + retjson = cJSON_Parse("{\"error\":\"couldnt add message\"}"); + return(retjson); } -#include "../includes/iguana_apiundefs.h" int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration) { @@ -384,9 +383,16 @@ cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 srchash,bits256 jaddnum(valsobj,"numrequired",1); jaddbits256(valsobj,"srchash",srchash); jaddbits256(valsobj,"desthash",desthash); - if ( (retstr= basilisk_getmessage(myinfo,0,0,0,desthash,valsobj,0)) != 0 ) + if ( myinfo->IAMNOTARY != 0 ) + retstr = basilisk_getmessage(myinfo,0,0,0,desthash,valsobj,0); + else + { + //char str[65],str2[65]; + retstr = _dex_getmessage(myinfo,jprint(valsobj,0)); + //printf("channel.%u msgid.%u gotmessage.(%d) %s %s %s\n",channel,msgid,(int32_t)strlen(retstr),strlen(retstr) < 100 ? retstr : "(too long)",bits256_str(str,srchash),bits256_str(str2,desthash)); + } + if ( retstr != 0 ) { - //printf("channel.%u msgid.%u gotmessage.(%d)\n",channel,msgid,(int32_t)strlen(retstr)); if ( (retarray= cJSON_Parse(retstr)) != 0 ) { if ( is_cJSON_Array(retarray) == 0 ) diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index e42ab5146..b779027bb 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -567,12 +567,12 @@ int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,ch coin->estimatedfee = iguana_getestimatedfee(myinfo,coin); if ( signedtx != 0 ) { - txfee = coin->estimatedfee * (strlen(signedtx) + numvins); + txfee = coin->estimatedfee * (strlen(signedtx)/2 + numvins); free(signedtx); } else if ( rawtx != 0 ) { - txfee = coin->estimatedfee * (strlen(rawtx) + numvins * 110); + txfee = coin->estimatedfee * (strlen(rawtx)/2 + numvins * 110); free(rawtx); } return(txfee); @@ -585,7 +585,7 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi if ( signedtxidp != 0 ) memset(signedtxidp,0,sizeof(*signedtxidp)); bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); - txfee = 10 * (coin->txfee + duplicates*coin->txfee/5); + txfee = (coin->txfee + duplicates*coin->txfee*2); if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) { if ( duplicates <= 0 ) @@ -769,7 +769,7 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi addresses = iguana_getaddressesbyaccount(myinfo,coin,"*"); jadd(valsobj,"addresses",addresses); } - //printf("use addresses.(%s)\n",jprint(addresses,0)); + printf("use addresses.(%s)\n",jprint(addresses,0)); //printf("(%s) vals.(%s) change.(%s) spend.%s\n",coin->symbol,jprint(valsobj,0),changeaddr,spendscriptstr); if ( changeaddr == 0 || changeaddr[0] == 0 || spendscriptstr == 0 || spendscriptstr[0] == 0 ) return(clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}")); @@ -798,7 +798,13 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi } else oplen = datachain_opreturnscript(coin,buf,opreturn,oplen); } rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr,V,0); - //printf("generated.(%s) vins.(%s)\n",rawtx!=0?rawtx:"",vins!=0?jprint(vins,0):""); + if ( txfee == 0 ) + { + txfee = iguana_esttxfee(myinfo,coin,rawtx,0,vins != 0 ? cJSON_GetArraySize(vins): 0); + rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr,V,0); + printf("new txfee %.8f\n",dstr(txfee)); + } + printf("generated.(%s) vins.(%s)\n",rawtx!=0?rawtx:"",vins!=0?jprint(vins,0):""); } if ( rawtx != 0 ) { @@ -1043,175 +1049,6 @@ cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exch } #endif - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) -{ - char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; - if ( vals == 0 ) - return(clonestr("{\"error\":\"null valsobj\"}")); - //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) - // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - txid = jbits256(vals,"txid"); - vout = jint(vals,"vout"); - if ( coin != 0 ) - { - if ( coin->FULLNODE < 0 ) - { - if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) - { - if ( (coinaddr= jstr(txoutjson,"address")) != 0 && (value= SATOSHIDEN*jdouble(txoutjson,"value")) != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"address",coinaddr); - jadd64bits(retjson,"satoshis",value); - jaddnum(retjson,"value",dstr(value)); - jaddnum(retjson,"amount",dstr(value)); - height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,0,coin); - jaddnum(retjson,"height",height); - jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); - jaddbits256(retjson,"txid",txid); - jaddnum(retjson,"vout",vout); - jaddstr(retjson,"coin",coin->symbol); - } - else - { - free_json(txoutjson); - return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); - } - free_json(txoutjson); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"null return from gettxout\"}")); - } - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - retstr = ptr->retstr, ptr->retstr = 0; - ptr->finished = OS_milliseconds() + 10000; - return(retstr); - } - } - if ( myinfo->reqsock >= 0 ) - { - if ( (retstr= _dex_getrawtransaction(myinfo,symbol,txid)) != 0 ) - { - if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) - { - //printf("TX.(%s)\n",jprint(txoutjson,0)); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); - if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) - { - //printf("txjson.(%s)\n",jprint(txjson,0)); - if ( (value= jdouble(txjson,"value") * SATOSHIDEN) != 0 ) - { - if ( (sobj= jobj(txjson,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 && (coinaddr= jstri(addrs,0)) != 0 ) - jaddstr(retjson,"address",coinaddr); - jadd64bits(retjson,"satoshis",value); - jaddnum(retjson,"value",dstr(value)); - if ( (infostr= _dex_getinfo(myinfo,symbol)) != 0 ) - { - if ( (info= cJSON_Parse(infostr)) != 0 ) - { - if ( (height= jint(info,"blocks")) > 0 ) - { - height -= jint(txoutjson,"confirmations"); - jaddnum(retjson,"height",height); - } - free_json(info); - } - free(infostr); - } - jaddbits256(retjson,"txid",txid); - jaddnum(retjson,"vout",vout); - jaddstr(retjson,"coin",symbol); - free(retstr); - free_json(txoutjson); - return(jprint(retjson,1)); - } - } - free_json(txoutjson); - return(jprint(retjson,1)); - } - return(retstr); - } - } - return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) -{ - char *retstr=0,*symbol; uint32_t basilisktag; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; - if ( vals == 0 ) - return(clonestr("{\"error\":\"null valsobj\"}")); - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"numrequired") == 0 ) - jaddnum(vals,"numrequired",MIN(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - if ( coin != 0 ) - { - //if ( juint(vals,"burn") == 0 ) - // jaddnum(vals,"burn",0.0001); - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals,0)) != 0 ) - { - printf("rawtx.(%s)\n",retstr); - if ( (amount= j64bits(vals,"satoshis")) == 0 ) - amount = jdouble(vals,"value") * SATOSHIDEN; - if ( (txfee= j64bits(vals,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; - retval = -1; - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(retarray) != 0 ) - { - for (i=0; iI.actualtxid); jaddnum(argjson,"vout",0); jaddstr(argjson,"coin",rawtx->coin->symbol); - if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,myinfo->myaddr.persistent,argjson,0)) != 0 ) + if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 ) { //char str[65]; printf("%s %s valstr.(%s)\n",rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr); if ( (valuearray= cJSON_Parse(valstr)) != 0 ) @@ -310,15 +317,10 @@ bits256 basilisk_swap_broadcast(char *name,struct supernet_info *myinfo,struct b return(txid); } -int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) +int32_t _basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,uint32_t timestamp,uint32_t locktime,uint32_t sequenceid,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) { - char *rawtxbytes=0,*signedtx=0,hexstr[999],wifstr[128]; cJSON *txobj,*vins,*item,*sobj,*privkeys; int32_t needsig=1,retval = -1; uint32_t timestamp,sequenceid=0xffffffff; struct vin_info *V; uint32_t locktime=0; - V = calloc(16,sizeof(*V)); - timestamp = swap->I.started; - if ( dest == &swap->aliceclaim ) - locktime = swap->bobdeposit.I.locktime + 1, sequenceid = 0; - else if ( dest == &swap->bobreclaim ) - locktime = swap->bobpayment.I.locktime + 1, sequenceid = 0; + char *rawtxbytes=0,*signedtx=0,hexstr[999],wifstr[128]; cJSON *txobj,*vins,*item,*sobj,*privkeys; int32_t needsig=1,retval = -1; struct vin_info *V; + V = calloc(256,sizeof(*V)); V[0].signers[0].privkey = privkey; bitcoin_pubkey33(myinfo->ctx,V[0].signers[0].pubkey,privkey); privkeys = cJSON_CreateArray(); @@ -350,6 +352,7 @@ int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct b needsig = 0; #endif } + //printf("rawtx B\n"); if ( bits256_nonz(rawtx->I.actualtxid) != 0 ) jaddbits256(item,"txid",rawtx->I.actualtxid); else jaddbits256(item,"txid",rawtx->I.signedtxid); @@ -369,17 +372,19 @@ int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct b jaddi(vins,item); jdelete(txobj,"vin"); jadd(txobj,"vin",vins); - //printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->locktime,dest->locktime,rawtx->name,hexstr,dest->name,dest->suppress_pubkeys); + //printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->I.locktime,dest->I.locktime,rawtx->name,hexstr,dest->name,dest->I.suppress_pubkeys); txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->I.spendlen,dest->I.amount); if ( (rawtxbytes= bitcoin_json2hex(myinfo,rawtx->coin,&dest->I.txid,txobj,V)) != 0 ) { + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); if ( needsig == 0 ) signedtx = rawtxbytes; if ( signedtx != 0 || (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&dest->I.signedtxid,&dest->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) { dest->I.datalen = (int32_t)strlen(signedtx) >> 1; - dest->txbytes = calloc(1,dest->I.datalen); - decode_hex(dest->txbytes,dest->I.datalen,signedtx); + if ( dest->I.datalen <= sizeof(dest->txbytes) ) + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",dest->I.datalen,(int32_t)sizeof(dest->txbytes)); if ( signedtx != rawtxbytes ) free(signedtx); if ( dest->I.completed != 0 ) @@ -390,12 +395,172 @@ int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct b } else printf("error making rawtx\n"); free_json(privkeys); free_json(txobj); + free(V); + return(retval); +} + +int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) +{ + uint32_t timestamp,locktime=0,sequenceid = 0xffffffff; + timestamp = swap->I.started; + if ( dest == &swap->aliceclaim ) + locktime = swap->bobdeposit.I.locktime + 1, sequenceid = 0; + else if ( dest == &swap->bobreclaim ) + locktime = swap->bobpayment.I.locktime + 1, sequenceid = 0; + return(_basilisk_rawtx_sign(myinfo,height,timestamp,locktime,sequenceid,dest,rawtx,privkey,privkey2,userdata,userdatalen,ignore_cltverr)); +} + +cJSON *basilisk_privkeyarray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) +{ + cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; + privkeyarray = cJSON_CreateArray(); + //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i= 0 ) + { + iguana_txidcategory(myinfo,coin,account,coinaddr,txid,vout); + if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + if ( len < (sizeof(script) << 1) ) + { + decode_hex(script,len,hexstr); + if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) + bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); + } + } + if ( coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); + jaddistr(privkeyarray,waddr->wifstr); + } + else if ( smartaddress(myinfo,&privkey,coinaddr) >= 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeyarray,wifstr); + } + else printf("cant find (%s) in wallet\n",coinaddr); + } else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); + } else printf("invalid txid/vout %d of %d\n",i,n); + } + } + return(privkeyarray); +} + +int32_t basilisk_rawtx_return(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V) +{ + char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1; + if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + { + privkeyarray = basilisk_privkeyarray(myinfo,rawtx->coin,vins); + if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 ) + { + if ( lockinputs != 0 ) + { + //printf("lockinputs\n"); + iguana_RTunspentslock(myinfo,rawtx->coin,vins); + if ( (n= cJSON_GetArraySize(vins)) != 0 ) + { + bits256 txid; int32_t vout; + for (i=0; iI.datalen = (int32_t)strlen(signedtx) >> 1; + //rawtx->txbytes = calloc(1,rawtx->I.datalen); + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx); + free(signedtx); + retval = 0; + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + free_json(privkeyarray); + } + return(retval); +} + +int32_t basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay) +{ + char *retstr,*jsonstr,scriptstr[1024],coinaddr[64]; uint32_t basilisktag; int32_t flag,i,n,retval = -1; cJSON *addresses,*valsobj,*retarray=0; struct vin_info *V; + //bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( rawtx->coin->changeaddr[0] == 0 ) + { + bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->chain->pubtype,pubkey33,33); + printf("set change address.(%s)\n",rawtx->coin->changeaddr); + } + //if ( strcmp(rawtx->coin->symbol,"BTC") == 0 ) + // txfee = 0; + init_hexbytes_noT(scriptstr,script,scriptlen); + basilisktag = (uint32_t)rand(); + valsobj = cJSON_CreateObject(); + jaddstr(valsobj,"coin",rawtx->coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); + jadd64bits(valsobj,"satoshis",rawtx->I.amount); + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + jaddnum(valsobj,"timestamp",swapstarted+delay); + addresses = cJSON_CreateArray(); + bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,pubkey33,33); + jaddistr(addresses,coinaddr); + jadd(valsobj,"addresses",addresses); + rawtx->I.locktime = locktime; + //printf("%s locktime.%u\n",rawtx->name,locktime); + V = calloc(256,sizeof(*V)); + if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V)) != 0 ) + { + //printf("%s %s basilisk_bitcoinrawtx.(%s)\n",rawtx->name,str,retstr); + flag = 0; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + n = cJSON_GetArraySize(retarray); + for (i=0; icoin->longestchain,rawtx,jitem(retarray,i),lockinputs,V)) == 0 ) + { + rawtx->vins = jduplicate(jobj(jitem(retarray,i),"vins")); + jsonstr = jprint(rawtx->vins,0); + safecopy(rawtx->vinstr,jsonstr,sizeof(rawtx->vinstr)); + free(jsonstr); + break; + } + } + } + else + { + retval = basilisk_rawtx_return(myinfo,rawtx->coin->longestchain,rawtx,retarray,lockinputs,V); + rawtx->vins = jduplicate(jobj(retarray,"vins")); + jsonstr = jprint(rawtx->vins,0); + safecopy(rawtx->vinstr,jsonstr,sizeof(rawtx->vinstr)); + free(jsonstr); + } + free(retarray); + } else printf("error parsing.(%s)\n",retstr); + free(retstr); + } else printf("error creating %s feetx\n",iambob != 0 ? "BOB" : "ALICE"); + free_json(valsobj); + free(V); return(retval); } struct basilisk_rawtx *basilisk_swapdata_rawtx(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) { - if ( rawtx->txbytes != 0 && rawtx->I.datalen <= maxlen ) + if ( rawtx->I.datalen != 0 && rawtx->I.datalen <= maxlen ) { memcpy(data,rawtx->txbytes,rawtx->I.datalen); return(rawtx); @@ -407,14 +572,15 @@ int32_t basilisk_verify_otherfee(struct supernet_info *myinfo,void *ptr,uint8_t { struct basilisk_swap *swap = ptr; // add verification and broadcast - swap->otherfee.txbytes = calloc(1,datalen); + //swap->otherfee.txbytes = calloc(1,datalen); memcpy(swap->otherfee.txbytes,data,datalen); + swap->otherfee.I.datalen = datalen; swap->otherfee.I.actualtxid = swap->otherfee.I.signedtxid = bits256_doublesha256(0,data,datalen); basilisk_txlog(myinfo,swap,&swap->otherfee,-1); return(0); } -int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) +int32_t basilisk_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { int32_t datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr; datalen = recvbuf[0]; @@ -426,9 +592,9 @@ int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,struct basilisk_ if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen); //printf("recvlen.%d datalen.%d redeemlen.%d\n",recvlen,datalen,rawtx->redeemlen); - if ( rawtx->txbytes == 0 ) + if ( rawtx->I.datalen == 0 ) { - rawtx->txbytes = calloc(1,datalen); + //rawtx->txbytes = calloc(1,datalen); memcpy(rawtx->txbytes,data,datalen); rawtx->I.datalen = datalen; } @@ -457,7 +623,8 @@ int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,struct basilisk_ { decode_hex(rawtx->spendscript,hexlen,hexstr); rawtx->I.spendlen = hexlen; - basilisk_txlog(myinfo,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment + if ( swap != 0 ) + basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment retval = 0; } } else printf("%s ERROR.(%s)\n",rawtx->name,jprint(txobj,0)); @@ -467,7 +634,7 @@ int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,struct basilisk_ return(retval); } -int32_t basilisk_swapuserdata(struct basilisk_swap *swap,uint8_t *userdata,bits256 privkey,int32_t ifpath,bits256 signpriv,uint8_t *redeemscript,int32_t redeemlen) +int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,bits256 signpriv,uint8_t *redeemscript,int32_t redeemlen) { int32_t i,len = 0; #ifdef DISABLE_CHECKSIG @@ -495,10 +662,10 @@ int32_t basilisk_swapuserdata(struct basilisk_swap *swap,uint8_t *userdata,bits2 int32_t basilisk_verify_bobdeposit(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; struct basilisk_swap *swap = ptr; - if ( basilisk_rawtx_spendscript(myinfo,swap,swap->bobcoin->blocks.hwmchain.height,&swap->bobdeposit,0,data,datalen,0) == 0 ) + if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) { - len = basilisk_swapuserdata(swap,userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) { for (i=0; ibobdeposit.I.datalen; i++) printf("%02x",swap->bobdeposit.txbytes[i]); @@ -517,8 +684,8 @@ int32_t basilisk_verify_bobdeposit(struct supernet_info *myinfo,void *ptr,uint8_ int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t delay) { uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; - len = basilisk_swapuserdata(swap,userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0)) == 0 ) + len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0)) == 0 ) { for (i=0; ibobrefund.I.datalen; i++) printf("%02x",swap->bobrefund.txbytes[i]); @@ -540,8 +707,8 @@ int32_t basilisk_bobpayment_reclaim(struct supernet_info *myinfo,struct basilisk { uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; printf("basilisk_bobpayment_reclaim\n"); - len = basilisk_swapuserdata(swap,userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1)) == 0 ) + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1)) == 0 ) { for (i=0; ibobreclaim.I.datalen; i++) printf("%02x",swap->bobreclaim.txbytes[i]); @@ -556,13 +723,13 @@ int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t * { uint8_t userdata[512]; int32_t i,retval,len = 0; bits256 revAm; struct basilisk_swap *swap = ptr; memset(revAm.bytes,0,sizeof(revAm)); - if ( basilisk_rawtx_spendscript(myinfo,swap,swap->bobcoin->blocks.hwmchain.height,&swap->bobpayment,0,data,datalen,0) == 0 ) + if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) { for (i=0; i<32; i++) revAm.bytes[i] = swap->I.privAm.bytes[31-i]; - len = basilisk_swapuserdata(swap,userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - char str[65]; printf("bobpaid.(%s)\n",bits256_str(str,swap->I.privAm)); - if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) + len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + char str[65],str2[65]; printf("bobpaid.(%s) (%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) { for (i=0; ibobpayment.I.datalen; i++) printf("%02x",swap->bobpayment.txbytes[i]); @@ -578,27 +745,125 @@ int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t * return(-1); } +void basilisk_alicepayment(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) +{ + alicepayment->I.spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->chain->p2shtype,pubAm,pubBn); + basilisk_rawtx_gen("alicepayment",myinfo,swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,coin->chain->txfee,1,0); +} + int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *dest) { int32_t i,retval; - //printf("alicepayment_spend\n"); + printf("alicepayment_spend\n"); swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin->chain->p2shtype,swap->I.pubAm,swap->I.pubBn); - if ( (retval= basilisk_rawtx_sign(myinfo,swap->alicecoin->blocks.hwmchain.height,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1)) == 0 ) + printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->alicecoin->longestchain,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1)) == 0 ) { for (i=0; iI.datalen; i++) printf("%02x",dest->txbytes[i]); printf(" <- msigspend\n\n"); - swap->I.bobspent = 1; + if ( dest == &swap->bobspend ) + swap->I.bobspent = 1; basilisk_txlog(myinfo,swap,dest,0); // bobspend or alicereclaim return(retval); } return(-1); } +int32_t basilisk_bobpayment_spendclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 privAm,bits256 myprivs0,uint8_t *data,int32_t datalen,int32_t jumblrflag) +{ + bits256 revAm; uint8_t userdata[512]; int32_t i,len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; + basilisk_rawtx_setparms("bobpayment",quoteid,src,bobcoin,numconfirms,0,amount,3,0,jumblrflag); + dest->I.suppress_pubkeys = 1; + basilisk_rawtx_gen("bobpayment",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); + if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) + { + memset(revAm.bytes,0,sizeof(revAm)); + for (i=0; i<32; i++) + revAm.bytes[i] = privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,0,myprivs0,src->redeemscript,src->I.redeemlen); + if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,1)) == 0 ) + { + } + } + return(retval); +} + +int32_t basilisk_bobpayment_reclaimclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs1,uint8_t *data,int32_t datalen,int32_t jumblrflag) +{ + bits256 zero; uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; + basilisk_rawtx_setparms("bobpayment",quoteid,src,bobcoin,numconfirms,0,amount,3,0,jumblrflag); + dest->I.suppress_pubkeys = 1; + basilisk_rawtx_gen("bobpayment",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); + if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + len = basilisk_swapuserdata(userdata,zero,1,myprivs1,src->redeemscript,src->I.redeemlen); + if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs1,0,userdata,len,1)) == 0 ) + { + } + } + return(retval); +} + +int32_t basilisk_bobdeposit_refundclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs0,bits256 privBn,uint8_t *data,int32_t datalen,int32_t jumblrflag) +{ + uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; + basilisk_rawtx_setparms("bobdeposit",quoteid,src,bobcoin,numconfirms,0,amount,4,0,jumblrflag); + dest->I.suppress_pubkeys = 1; + basilisk_rawtx_gen("bobdeposit",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); + if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) + { + len = basilisk_swapuserdata(userdata,privBn,0,myprivs0,src->redeemscript,src->I.redeemlen); + if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,0)) == 0 ) + { + } + } + return(retval); +} + +int32_t basilisk_bobdeposit_claimclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs0,uint8_t *data,int32_t datalen,int32_t jumblrflag) +{ + bits256 zero; uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; + basilisk_rawtx_setparms("bobdeposit",quoteid,src,bobcoin,numconfirms,0,amount,4,0,jumblrflag); + dest->I.suppress_pubkeys = 1; + basilisk_rawtx_gen("bobdeposit",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); + if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + len = basilisk_swapuserdata(userdata,zero,1,myprivs0,src->redeemscript,src->I.redeemlen); + if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,1)) == 0 ) + { + } + } + return(retval); +} + +//basilisk_alicepayment_clone(myinfo,&dest,&src,swapstarted,changepubkey33,alicecoin,quoteid,amount,privAm,pubAm,privBn,pubBn); + +int32_t basilisk_alicepayment_spendclone(struct supernet_info *myinfo,struct iguana_info *alicecoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 privAm,bits256 privBn,int32_t jumblrflag) +{ + uint8_t pubAm33[33],pubBn33[33]; bits256 pubAm,pubBn; int32_t retval,numconfirms = 0; uint32_t sequenceid = 0xffffffff; + bitcoin_pubkey33(myinfo->ctx,pubAm33,privAm); + memcpy(pubAm.bytes,pubAm33+1,32); + bitcoin_pubkey33(myinfo->ctx,pubBn33,privBn); + memcpy(pubBn.bytes,pubBn33+1,32); + memset(src,0,sizeof(*src)); + memset(dest,0,sizeof(*dest)); + basilisk_rawtx_setparms("alicepayment",quoteid,src,alicecoin,numconfirms,0,amount,2,0,jumblrflag); + src->I.spendlen = basilisk_alicescript(src->redeemscript,&src->I.redeemlen,src->spendscript,0,src->I.destaddr,alicecoin->chain->p2shtype,pubAm,pubBn); + basilisk_rawtx_gen("alicepayment",myinfo,swapstarted,changepubkey33,0,1,src,src->I.locktime,src->spendscript,src->I.spendlen,alicecoin->chain->txfee,1,0); + if ( (retval= _basilisk_rawtx_sign(myinfo,alicecoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,privAm,&privBn,0,0,1)) == 0 ) + { + + } + return(retval); +} + int32_t basilisk_verify_alicepaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { struct basilisk_swap *swap = ptr; - if ( basilisk_rawtx_spendscript(myinfo,swap,swap->alicecoin->blocks.hwmchain.height,&swap->alicepayment,0,data,datalen,0) == 0 ) + if ( basilisk_rawtx_spendscript(swap,swap->alicecoin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) return(0); else return(-1); } @@ -624,140 +889,6 @@ int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *s return(0); } -cJSON *basilisk_privkeyarray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) -{ - cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid; - privkeyarray = cJSON_CreateArray(); - //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); - if ( (n= cJSON_GetArraySize(vins)) > 0 ) - { - for (i=0; i= 0 ) - { - iguana_txidcategory(myinfo,coin,account,coinaddr,txid,vout); - if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) - { - len = (int32_t)strlen(hexstr) >> 1; - if ( len < (sizeof(script) << 1) ) - { - decode_hex(script,len,hexstr); - if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) - bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); - } - } - if ( coinaddr[0] != 0 ) - { - if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) - { - bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); - jaddistr(privkeyarray,waddr->wifstr); - } else printf("cant find (%s) in wallet\n",coinaddr); - } else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); - } else printf("invalid txid/vout %d of %d\n",i,n); - } - } - return(privkeyarray); -} - -int32_t basilisk_rawtx_return(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V) -{ - char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1; - if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) - { - privkeyarray = basilisk_privkeyarray(myinfo,rawtx->coin,vins); - if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 ) - { - if ( lockinputs != 0 ) - { - //printf("lockinputs\n"); - iguana_RTunspentslock(myinfo,rawtx->coin,vins); - if ( (n= cJSON_GetArraySize(vins)) != 0 ) - { - bits256 txid; int32_t vout; - for (i=0; iI.datalen = (int32_t)strlen(signedtx) >> 1; - rawtx->txbytes = calloc(1,rawtx->I.datalen); - decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); - printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx); - free(signedtx); - retval = 0; - } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll - free_json(privkeyarray); - } - return(retval); -} - -int32_t basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay) -{ - char *retstr,scriptstr[1024],coinaddr[64]; uint32_t basilisktag; int32_t flag,i,n,retval = -1; cJSON *addresses,*valsobj,*retarray=0; struct vin_info *V; - //bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); - if ( rawtx->coin->changeaddr[0] == 0 ) - { - bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); - printf("set change address.(%s)\n",rawtx->coin->changeaddr); - } - init_hexbytes_noT(scriptstr,script,scriptlen); - basilisktag = (uint32_t)rand(); - valsobj = cJSON_CreateObject(); - jaddstr(valsobj,"coin",rawtx->coin->symbol); - jaddstr(valsobj,"spendscript",scriptstr); - jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); - jadd64bits(valsobj,"satoshis",rawtx->I.amount); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - jaddnum(valsobj,"timeout",30000); - jaddnum(valsobj,"timestamp",swap->I.started+delay); - addresses = cJSON_CreateArray(); - bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); - jaddistr(addresses,coinaddr); - jadd(valsobj,"addresses",addresses); - rawtx->I.locktime = locktime; - //printf("%s locktime.%u\n",rawtx->name,locktime); - V = calloc(256,sizeof(*V)); - if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V)) != 0 ) - { - //printf("%s %s basilisk_bitcoinrawtx.(%s)\n",rawtx->name,str,retstr); - flag = 0; - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(retarray) != 0 ) - { - n = cJSON_GetArraySize(retarray); - for (i=0; icoin->blocks.hwmchain.height,rawtx,jitem(retarray,i),lockinputs,V)) == 0 ) - { - rawtx->vins = jobj(jitem(retarray,i),"vins"); - break; - } - } - } - else - { - retval = basilisk_rawtx_return(myinfo,rawtx->coin->blocks.hwmchain.height,rawtx,retarray,lockinputs,V); - rawtx->vins = jobj(retarray,"vins"); - } - free(retarray); - } else printf("error parsing.(%s)\n",retstr); - free(retstr); - } else printf("error creating %s feetx\n",iambob != 0 ? "BOB" : "ALICE"); - free_json(valsobj); - free(V); - return(retval); -} - int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) { int32_t i,j; //char str[65]; @@ -769,17 +900,17 @@ int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swa //for (i=0; ibobpayment.redeemlen; i++) // printf("%02x",swap->bobpayment.redeemscript[i]); //printf(" <- bobpayment.%d\n",i); - if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.txbytes == 0 ) + if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) { for (i=0; i<3; i++) { //if ( swap->bobpayment.txbytes != 0 && swap->bobpayment.I.spendlen != 0 ) // break; - basilisk_rawtx_gen("payment",myinfo,swap,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->chain->txfee,1,0); - if ( swap->bobpayment.txbytes == 0 || swap->bobpayment.I.spendlen == 0 ) + basilisk_rawtx_gen("payment",myinfo,swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->chain->txfee,1,0); + if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) { printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); - sleep(3); + sleep(DEX_SLEEP); } else { @@ -802,17 +933,17 @@ int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swa else { swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); - if ( genflag != 0 && (swap->bobdeposit.txbytes == 0 || swap->bobrefund.txbytes == 0) ) + if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) { for (i=0; i<3; i++) { //if ( swap->bobdeposit.txbytes != 0 && swap->bobdeposit.I.spendlen != 0 ) // break; - basilisk_rawtx_gen("deposit",myinfo,swap,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->chain->txfee,1,0); - if ( swap->bobdeposit.txbytes == 0 || swap->bobdeposit.I.spendlen == 0 ) + basilisk_rawtx_gen("deposit",myinfo,swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->chain->txfee,1,0); + if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) { printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); - sleep(3); + sleep(DEX_SLEEP); } else { @@ -879,28 +1010,193 @@ int32_t basilisk_process_swapverify(struct supernet_info *myinfo,void *ptr,int32 else return(0); } +void basilisk_swapgotdata(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit) +{ + int32_t i; struct basilisk_swapmessage *mp; + for (i=0; inummessages; i++) + if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) + return; + printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); + swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); + mp = &swap->messages[swap->nummessages++]; + mp->crc32 = crc32; + mp->srchash = srchash; + mp->desthash = desthash; + mp->msgbits = msgbits; + mp->quoteid = quoteid; + mp->data = malloc(datalen); + mp->datalen = datalen; + memcpy(mp->data,data,datalen); + if ( reinit == 0 && swap->fp != 0 ) + { + fwrite(mp,1,sizeof(*mp),swap->fp); + fwrite(data,1,datalen,swap->fp); + fflush(swap->fp); + } +} + +FILE *basilisk_swap_save(struct supernet_info *myinfo,struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) +{ + FILE *fp=0; char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname); + if ( 0 && (fp= fopen(fname,"rb+")) == 0 ) + { + if ( (fp= fopen(fname,"wb+")) != 0 ) + { + fwrite(privkey.bytes,1,sizeof(privkey),fp); + fwrite(rp,1,sizeof(*rp),fp); + fwrite(&statebits,1,sizeof(statebits),fp); + fwrite(&optionduration,1,sizeof(optionduration),fp); + fflush(fp); + } + } + else if ( reinit != 0 ) + { + } + return(fp); +} + +struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit); + +void basilisk_swaps_init(struct supernet_info *myinfo) +{ + char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) ) + { + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + printf("%s\n",fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed + { + memset(&M,0,sizeof(M)); + swapcompleted = 0; + for (iter=0; iter<2; iter++) + { + if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) && + fread(&R,1,sizeof(R),fp) == sizeof(R) && + fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) && + fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) ) + { + while ( fread(&M,1,sizeof(M),fp) == sizeof(M) ) + { + M.data = 0; + //printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen); + if ( M.datalen < 100000 ) + { + M.data = malloc(M.datalen); + fread(M.data,1,M.datalen,fp); + if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) + { + if ( iter == 1 ) + { + if ( swap == 0 ) + { + swap = basilisk_thread_start(myinfo,privkey,&R,statebits,optionduration,1); + swap->I.choosei = swap->I.otherchoosei = -1; + } + if ( swap != 0 ) + basilisk_swapgotdata(myinfo,swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); + } + } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + free(M.data), M.data = 0; + } + } + } + if ( swapcompleted != 0 ) + break; + rewind(fp); + } + } + } + } +} + +void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp); + int32_t basilisk_swapget(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen)) { - int32_t datalen; uint32_t crc; - if ( (crc= basilisk_crcrecv(myinfo,0,swap->verifybuf,sizeof(swap->verifybuf),&datalen,swap->I.otherhash,swap->I.myhash,swap->I.req.quoteid,msgbits)) != 0 ) + uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0; + while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 ) + { + swap->lasttime = (uint32_t)time(NULL); + memset(srchash.bytes,0,sizeof(srchash)); + memset(desthash.bytes,0,sizeof(desthash)); + //printf("gotmsg.[%d] crc.%x\n",size,crc32); + offset = 0; + for (i=0; i<32; i++) + srchash.bytes[i] = ptr[offset++]; + for (i=0; i<32; i++) + desthash.bytes[i] = ptr[offset++]; + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); + crc32 = calc_crc32(0,&ptr[offset],size-offset); + if ( size > offset ) + { + //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); + basilisk_swapgotdata(myinfo,swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + } + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; + } + //char str[65],str2[65]; + for (i=0; inummessages; i++) { - if ( datalen > 0 && datalen < maxlen ) + //printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash)); + if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 ) { - memcpy(data,swap->verifybuf,datalen); - return((*basilisk_verify_func)(myinfo,swap,data,datalen)); + if ( swap->messages[i].msgbits == msgbits ) + { + if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) + { + printf("nothing received for a while from Bob, try new sockets\n"); + if ( swap->pushsock >= 0 ) + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + basilisk_psockinit(myinfo,swap,0); + } + mp = &swap->messages[i]; + if ( msgbits != 0x80000000 ) + break; + } } } - return(-1); + if ( mp != 0 ) + retval = (*basilisk_verify_func)(myinfo,swap,mp->data,mp->datalen); + //printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash)); + return(retval); } uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) { - //if ( (rand() % 10) == 0 ) - // basilisk_channelsend(myinfo,swap->I.myhash,swap->I.otherhash,swap->I.req.quoteid,msgbits,data,datalen,INSTANTDEX_LOCKTIME*2); - //if ( basilisk_crcsend(myinfo,0,swap->verifybuf,sizeof(swap->verifybuf),swap->I.myhash,swap->I.otherhash,swap->I.req.quoteid,msgbits,data,datalen,crcs) != 0 ) - //return(nextbits); - dex_channelsend(myinfo,swap->I.myhash,swap->I.otherhash,swap->I.req.quoteid,msgbits,data,datalen); //INSTANTDEX_LOCKTIME*2 - return(0); + uint8_t *buf; int32_t sentbytes,offset=0,i; + buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2); + for (i=0; i<32; i++) + buf[offset++] = swap->I.myhash.bytes[i]; + for (i=0; i<32; i++) + buf[offset++] = swap->I.otherhash.bytes[i]; + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( datalen > 0 ) + memcpy(&buf[offset],data,datalen), offset += datalen; + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) + { + printf("sentbytes.%d vs offset.%d\n",sentbytes,offset); + if ( sentbytes < 0 ) + { + if ( swap->pushsock >= 0 ) + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + } + } + //else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data); + free(buf); + return(nextbits); } int32_t basilisk_priviextract(struct supernet_info *myinfo,struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) @@ -917,7 +1213,7 @@ int32_t basilisk_priviextract(struct supernet_info *myinfo,struct iguana_info *c if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) { *destp = privkey; - printf("found %s (%s)\n",name,bits256_str(str,privkey)); + printf("found privi %s (%s)\n",name,bits256_str(str,privkey)); return(0); } } @@ -929,11 +1225,11 @@ int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swa { if ( basilisk_priviextract(myinfo,swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 ) { - + printf("extracted privBn from blockchain\n"); } if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) { - if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.txbytes == 0 ) + if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) { char str[65]; printf("have privBn.%s\n",bits256_str(str,swap->I.privBn)); return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); @@ -948,7 +1244,7 @@ int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swa { } - if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.txbytes == 0 ) + if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) { char str[65]; printf("have privAm.%s\n",bits256_str(str,swap->I.privAm)); return(basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend)); @@ -956,15 +1252,15 @@ int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swa return(-1); } -bits256 instantdex_derivekeypair(struct supernet_info *myinfo,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) +bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) { bits256 sharedsecret; sharedsecret = curve25519_shared(privkey,orderhash); vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); - return(bitcoin_pubkey33(myinfo->ctx,pubkey,*newprivp)); + return(bitcoin_pubkey33(ctx,pubkey,*newprivp)); } -int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +int32_t instantdex_pubkeyargs(void *ctx,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) { char buf[3]; int32_t i,n,m,len=0; bits256 pubi,reveal; uint64_t txid; uint8_t secret160[20],pubkey[33]; sprintf(buf,"%c0",'A' - 0x02 + firstbyte); @@ -972,12 +1268,12 @@ int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct basilisk_swap { if ( swap->I.numpubs+2 >= numpubs ) return(numpubs); - printf(">>>>>> start generating %s\n",buf); + //fprintf(stderr,">>>>>> start generating %s\n",buf); } for (i=n=m=0; iname,name); rawtx->coin = coin; + strcpy(rawtx->I.coinstr,coin->symbol); rawtx->I.numconfirms = numconfirms; if ( (rawtx->I.amount= satoshis) < 10000 ) rawtx->I.amount = 10000; @@ -1032,9 +1329,12 @@ void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basi rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit if ( rawtx->I.vouttype == 0 ) { - if ( strcmp(coin->symbol,"BTC") == 0 && (swap->I.req.quoteid % 10) == 0 ) - decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); - else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); + if ( jumblrflag == 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) + decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); + } else decode_hex(rawtx->I.rmd160,20,JUMBLR_RMD160); bitcoin_address(rawtx->I.destaddr,rawtx->coin->chain->pubtype,rawtx->I.rmd160,20); } if ( pubkey33 != 0 ) @@ -1050,34 +1350,15 @@ void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basi } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); } -int32_t bitcoin_coinptrs(struct supernet_info *myinfo,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash) +int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash) { struct iguana_info *coin = iguana_coinfind(src); if ( coin == 0 || iguana_coinfind(dest) == 0 ) return(0); *bobcoinp = *alicecoinp = 0; - if ( strcmp("BTC",src) == 0 ) - { - *bobcoinp = iguana_coinfind(src); - *alicecoinp = iguana_coinfind(dest); - } - else if ( strcmp("BTC",dest) == 0 ) - { - *bobcoinp = iguana_coinfind(dest); - *alicecoinp = iguana_coinfind(src); - } - else if ( (coin= iguana_coinfind(src)) != 0 && coin->chain->havecltv != 0 ) - { - *bobcoinp = iguana_coinfind(src); - *alicecoinp = iguana_coinfind(dest); - } - else if ( (coin= iguana_coinfind(dest)) != 0 && coin->chain->havecltv != 0 ) - { - *bobcoinp = iguana_coinfind(dest); - *alicecoinp = iguana_coinfind(src); - } - else return(0); - if ( bits256_cmp(myinfo->myaddr.persistent,srchash) == 0 ) + *bobcoinp = iguana_coinfind(dest); + *alicecoinp = iguana_coinfind(src); + if ( bits256_cmp(pubkey,srchash) == 0 ) { if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) return(1); @@ -1085,7 +1366,7 @@ int32_t bitcoin_coinptrs(struct supernet_info *myinfo,struct iguana_info **bobco return(-1); else return(0); } - else if ( bits256_cmp(myinfo->myaddr.persistent,desthash) == 0 ) + else if ( bits256_cmp(pubkey,desthash) == 0 ) { if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) return(-1); @@ -1096,136 +1377,167 @@ int32_t bitcoin_coinptrs(struct supernet_info *myinfo,struct iguana_info **bobco return(0); } -struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t optionduration) +void basilisk_swap_saveupdate(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + FILE *fp; char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid); + if ( 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(&swap->I,1,sizeof(swap->I),fp); + /*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp); + fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp); + fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp); + fwrite(&swap->myfee,1,sizeof(swap->myfee),fp); + fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp); + fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp); + fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp); + fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp); + fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp); + fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp); + fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/ + fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp); + fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp); + fwrite(swap->deck,1,sizeof(swap->deck),fp); + fclose(fp); + } +} + +int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr) { - struct iguana_info *coin,*bobcoin,*alicecoin; uint8_t *alicepub33=0,*bobpub33=0; int32_t x = -1; - swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; - if ( optionduration < 0 ) - swap->I.putduration -= optionduration; - else if ( optionduration > 0 ) - swap->I.callduration += optionduration; - if ( strcmp("BTC",swap->I.req.src) == 0 ) + if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) ) { - swap->bobcoin = iguana_coinfind("BTC"); - swap->I.bobsatoshis = swap->I.req.srcamount; - swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); - swap->alicecoin = iguana_coinfind(swap->I.req.dest); - swap->I.alicesatoshis = swap->I.req.destamount; - swap->I.aliceconfirms = swap->I.bobconfirms * 3; + rawtx->coin = 0; + rawtx->vins = 0; + if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 ) + { + rawtx->coin = iguana_coinfind(rawtx->I.coinstr); + if ( rawtx->vinstr[0] != 0 ) + rawtx->vins = cJSON_Parse(rawtx->vinstr); + printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen); + return(0); + } } - else if ( strcmp("BTC",swap->I.req.dest) == 0 ) + return(-1); +} + +struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,int32_t reinit) +{ + FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag,x = -1; + if ( reinit != 0 ) { - swap->bobcoin = iguana_coinfind("BTC"); - swap->I.bobsatoshis = swap->I.req.destamount; - swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); - swap->alicecoin = iguana_coinfind(swap->I.req.src); - swap->I.alicesatoshis = swap->I.req.srcamount; - swap->I.aliceconfirms = swap->I.bobconfirms * 3; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid); + printf("reinit.(%s)\n",fname); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fread(&swap->I,1,sizeof(swap->I),fp); + if ( swap->bobcoin == 0 ) + swap->bobcoin = iguana_coinfind(swap->I.req.dest); + if ( swap->alicecoin == 0 ) + swap->alicecoin = iguana_coinfind(swap->I.req.src); + if ( swap->alicecoin != 0 && swap->bobcoin != 0 ) + { + /*basilisk_swap_loadtx(&swap->bobdeposit,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobpayment,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicepayment,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->myfee,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->otherfee,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->aliceclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicespend,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobreclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobspend,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobrefund,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicereclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol);*/ + } else printf("missing coins (%p %p)\n",swap->bobcoin,swap->alicecoin); + fread(swap->privkeys,1,sizeof(swap->privkeys),fp); + fread(swap->otherdeck,1,sizeof(swap->otherdeck),fp); + fread(swap->deck,1,sizeof(swap->deck),fp); + fclose(fp); + } else printf("cant find.(%s)\n",fname); } else { - if ( (coin= iguana_coinfind(swap->I.req.src)) != 0 ) + swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; + if ( optionduration < 0 ) + swap->I.putduration -= optionduration; + else if ( optionduration > 0 ) + swap->I.callduration += optionduration; + swap->I.bobsatoshis = swap->I.req.destamount; + swap->I.alicesatoshis = swap->I.req.srcamount; + if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) + swap->I.bobinsurance = 10000; + if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) + swap->I.aliceinsurance = 10000; + strcpy(swap->I.bobstr,swap->I.req.dest); + strcpy(swap->I.alicestr,swap->I.req.src); + swap->I.started = (uint32_t)time(NULL); + swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; + OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); + if ( swap->I.choosei < 0 ) + swap->I.choosei = -swap->I.choosei; + swap->I.choosei %= INSTANTDEX_DECKSIZE; + swap->I.otherchoosei = -1; + swap->I.myhash = pubkey25519; + if ( statebits != 0 ) { - if ( coin->chain->havecltv != 0 ) - { - swap->bobcoin = coin; - swap->I.bobsatoshis = swap->I.req.srcamount; - swap->alicecoin = iguana_coinfind(swap->I.req.dest); - swap->I.alicesatoshis = swap->I.req.destamount; - } - else if ( (coin= iguana_coinfind(swap->I.req.dest)) != 0 ) - { - if ( coin->chain->havecltv != 0 ) - { - swap->bobcoin = coin; - swap->I.bobsatoshis = swap->I.req.destamount; - swap->alicecoin = iguana_coinfind(swap->I.req.src); - swap->I.alicesatoshis = swap->I.req.srcamount; - } else printf("neither coin handles ctlv %s %s\n",swap->I.req.src,swap->I.req.dest); - } else printf("cant find src or dest coin.(%s %s)\n",swap->I.req.src,swap->I.req.dest); - } else printf("cant find src coin.(%s)\n",swap->I.req.src); + swap->I.iambob = 0; + swap->I.otherhash = swap->I.req.desthash; + } + else + { + swap->I.iambob = 1; + swap->I.otherhash = swap->I.req.srchash; + } + if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(myinfo->ctx,swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) + { + char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); + return(0); + } } + swap->bobcoin = iguana_coinfind(swap->I.req.dest); + swap->alicecoin = iguana_coinfind(swap->I.req.src); if ( swap->bobcoin == 0 || swap->alicecoin == 0 ) { printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,iguana_coinfind(swap->I.req.src),iguana_coinfind(swap->I.req.dest)); free(swap); return(0); } + swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); + swap->I.aliceconfirms = swap->I.bobconfirms * 3; if ( swap->I.bobconfirms == 0 ) swap->I.bobconfirms = swap->bobcoin->chain->minconfirms; if ( swap->I.aliceconfirms == 0 ) swap->I.aliceconfirms = swap->alicecoin->chain->minconfirms; - if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->I.bobinsurance = 10000; - if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->I.aliceinsurance = 10000; - strcpy(swap->I.bobstr,swap->bobcoin->symbol); - strcpy(swap->I.alicestr,swap->alicecoin->symbol); - swap->I.started = (uint32_t)time(NULL); - swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; - OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); - if ( swap->I.choosei < 0 ) - swap->I.choosei = -swap->I.choosei; - swap->I.choosei %= INSTANTDEX_DECKSIZE; - swap->I.otherchoosei = -1; - swap->I.myhash = myinfo->myaddr.persistent; - if ( bits256_cmp(swap->I.myhash,swap->I.req.srchash) == 0 ) - { - swap->I.otherhash = swap->I.req.desthash; - if ( strcmp(swap->I.req.src,swap->I.bobstr) == 0 ) - swap->I.iambob = 1; - } - else if ( bits256_cmp(swap->I.myhash,swap->I.req.desthash) == 0 ) - { - swap->I.otherhash = swap->I.req.srchash; - if ( strcmp(swap->I.req.dest,swap->I.bobstr) == 0 ) - swap->I.iambob = 1; - } - else - { - printf("neither src nor dest error\n"); - return(0); - } - if ( (bitcoin_coinptrs(myinfo,&bobcoin,&alicecoin,swap->I.req.src,swap->I.req.dest,swap->I.req.srchash,swap->I.req.desthash)+1)/2 != swap->I.iambob ) - { - printf("error iambob.%d != %d\n",swap->I.iambob,bitcoin_coinptrs(myinfo,&bobcoin,&alicecoin,swap->I.req.src,swap->I.req.dest,swap->I.req.srchash,swap->I.req.desthash)); - return(0); - } - if ( bits256_nonz(myinfo->persistent_priv) == 0 || (x= instantdex_pubkeyargs(myinfo,swap,2 + INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) - { - printf("couldnt generate privkeys %d\n",x); - return(0); - } + jumblrflag = (bits256_cmp(pubkey25519,myinfo->jumblr_pubkey) == 0 || bits256_cmp(pubkey25519,myinfo->jumblr_depositkey) == 0); if ( swap->I.iambob != 0 ) { - basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0); - basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0); - bobpub33 = myinfo->persistent_pubkey33; + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0); - basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0); - alicepub33 = myinfo->persistent_pubkey33; + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + alicepub33 = pubkey33; } - basilisk_rawtx_setparms("bobdeposit",myinfo,swap,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3) + swap->bobcoin->txfee,4,0); - basilisk_rawtx_setparms("bobrefund",myinfo,swap,&swap->bobrefund,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,bobpub33); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3) + swap->bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("aliceclaim",myinfo,swap,&swap->aliceclaim,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,alicepub33); + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",myinfo,swap,&swap->bobpayment,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin->txfee,3,0); - basilisk_rawtx_setparms("alicespend",myinfo,swap,&swap->alicespend,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("bobreclaim",myinfo,swap,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33); + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",myinfo,swap,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin->txfee,2,0); - basilisk_rawtx_setparms("bobspend",myinfo,swap,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("alicereclaim",myinfo,swap,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33); + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); swap->alicereclaim.I.suppress_pubkeys = 1; printf("IAMBOB.%d\n",swap->I.iambob); return(swap); @@ -1234,12 +1546,15 @@ struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,struct basil void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) { - if ( rawtx->txbytes != 0 ) - free(rawtx->txbytes), rawtx->txbytes = 0; + if ( rawtx->vins != 0 ) + free_json(rawtx->vins); + //if ( rawtx->txbytes != 0 ) + // free(rawtx->txbytes), rawtx->txbytes = 0; } void basilisk_swap_finished(struct supernet_info *myinfo,struct basilisk_swap *swap) { + int32_t i; swap->I.finished = (uint32_t)time(NULL); // save to permanent storage basilisk_rawtx_purge(&swap->bobdeposit); @@ -1247,11 +1562,17 @@ void basilisk_swap_finished(struct supernet_info *myinfo,struct basilisk_swap *s basilisk_rawtx_purge(&swap->alicepayment); basilisk_rawtx_purge(&swap->myfee); basilisk_rawtx_purge(&swap->otherfee); - basilisk_rawtx_purge(&swap->alicereclaim); + basilisk_rawtx_purge(&swap->aliceclaim); basilisk_rawtx_purge(&swap->alicespend); basilisk_rawtx_purge(&swap->bobreclaim); basilisk_rawtx_purge(&swap->bobspend); basilisk_rawtx_purge(&swap->bobrefund); + basilisk_rawtx_purge(&swap->alicereclaim); + for (i=0; inummessages; i++) + if ( swap->messages[i].data != 0 ) + free(swap->messages[i].data), swap->messages[i].data = 0; + free(swap->messages), swap->messages = 0; + swap->nummessages = 0; } void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap) @@ -1274,10 +1595,12 @@ void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap int32_t basilisk_verify_otherstatebits(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { - struct basilisk_swap *swap = ptr; + int32_t retval; struct basilisk_swap *swap = ptr; if ( datalen == sizeof(swap->I.otherstatebits) ) - return(iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits)); - else return(-1); + { + retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits); + return(retval); + } else return(-1); } int32_t basilisk_verify_choosei(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) @@ -1376,7 +1699,7 @@ int32_t basilisk_verify_privkeys(struct supernet_info *myinfo,void *ptr,uint8_t return(errs); } -uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits) +uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) { uint8_t sendbuf[32768]; int32_t sendlen; if ( basilisk_swapdata_rawtx(myinfo,swap,data,maxlen,rawtx) != 0 ) @@ -1400,11 +1723,17 @@ uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilis sendlen += rawtx->I.redeemlen; } //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); - return(basilisk_swapsend(myinfo,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs)); + if ( suppress_swapsend == 0 ) + return(basilisk_swapsend(myinfo,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs)); + else + { + printf("suppress swapsend %x\n",msgbits); + return(0); + } } } return(nextbits); - } else printf("error from basilisk_swapdata_rawtx %p len.%d\n",rawtx->txbytes,rawtx->I.datalen); + } else printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); return(0); } @@ -1412,7 +1741,7 @@ void basilisk_sendpubkeys(struct supernet_info *myinfo,struct basilisk_swap *swa { int32_t datalen; datalen = basilisk_swapdata_deck(myinfo,swap,data,maxlen); - //printf("send deck.%d\n",datalen); + printf("send deck.%d\n",datalen); swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x02,data,datalen,0x01,swap->I.crcs_mypub); } @@ -1430,7 +1759,7 @@ int32_t basilisk_checkdeck(struct supernet_info *myinfo,struct basilisk_swap *sw void basilisk_sendstate(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - int32_t datalen; + int32_t datalen=0; datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits); basilisk_swapsend(myinfo,swap,0x80000000,data,datalen,0,0); } @@ -1460,7 +1789,7 @@ void basilisk_sendchoosei(struct supernet_info *myinfo,struct basilisk_swap *swa void basilisk_waitchoosei(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - uint8_t pubkey33[33]; //char str[65],str2[65]; + uint8_t pubkey33[33]; char str[65],str2[65]; //printf("check otherchoosei\n"); if ( basilisk_swapget(myinfo,swap,0x08,data,maxlen,basilisk_verify_choosei) == 0 ) { @@ -1473,7 +1802,7 @@ void basilisk_waitchoosei(struct supernet_info *myinfo,struct basilisk_swap *swa revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn)); vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn)); swap->I.pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->I.privBn); - //printf("set privBn.%s %s\n",bits256_str(str,swap->privBn),bits256_str(str2,*(bits256 *)swap->secretBn256)); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); basilisk_bobscripts_set(myinfo,swap,1,1); } } @@ -1486,7 +1815,7 @@ void basilisk_waitchoosei(struct supernet_info *myinfo,struct basilisk_swap *swa revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm)); vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm)); swap->I.pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->I.privAm); - //printf("set privAm.%s %s\n",bits256_str(str,swap->privAm),bits256_str(str2,*(bits256 *)swap->secretAm256)); + char str[65],str2[65]; printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); //basilisk_bobscripts_set(myinfo,swap,0); } } @@ -1525,17 +1854,13 @@ void basilisk_sendmostprivs(struct supernet_info *myinfo,struct basilisk_swap *s swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x20,data,datalen,0x10,swap->I.crcs_myprivs); } -void basilisk_alicepayment(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) -{ - alicepayment->I.spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->chain->p2shtype,pubAm,pubBn); - basilisk_rawtx_gen("alicepayment",myinfo,swap,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,coin->chain->txfee,1,0); -} - int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { int32_t j,datalen,retval = 0; while ( ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) { + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); printf("D r%u/q%u swapstate.%x otherstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits); if ( (swap->I.statebits & 0x80) == 0 ) // wait for fee { @@ -1550,14 +1875,18 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) break; - sleep(3 + (swap->I.iambob == 0)*1); + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); basilisk_sendstate(myinfo,swap,data,maxlen); if ( (swap->I.otherstatebits & 0x80) == 0 ) - basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); + basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); } + basilisk_swap_saveupdate(myinfo,swap); while ( retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee { + basilisk_swap_saveupdate(myinfo,swap); + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); //if ( (rand() % 30) == 0 ) printf("E r%u/q%u swapstate.%x otherstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits); if ( swap->I.iambob != 0 ) @@ -1566,7 +1895,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap if ( (swap->I.statebits & 0x100) == 0 ) { printf("send bobdeposit\n"); - swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x200,data,maxlen,&swap->bobdeposit,0x100); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0); } // [BLOCKING: altfound] make sure altpayment is confirmed and send payment else if ( (swap->I.statebits & 0x1000) == 0 ) @@ -1575,12 +1904,12 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap if ( basilisk_swapget(myinfo,swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) { swap->I.statebits |= 0x1000; - printf("got alicepayment\n"); + printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); } } else if ( (swap->I.statebits & 0x2000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->alicepayment) >= swap->I.aliceconfirms ) + if ( basilisk_numconfirms(myinfo,swap,&swap->alicepayment) >= swap->I.aliceconfirms ) { swap->I.statebits |= 0x2000; printf("alicepayment confirmed\n"); @@ -1590,28 +1919,28 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap { basilisk_bobscripts_set(myinfo,swap,0,1); printf("send bobpayment\n"); - swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0); } // [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain - else if ( (swap->I.statebits & 0x40000) == 0 ) + else if ( (swap->I.statebits & 0xc0000) != 0xc0000 ) { if ( basilisk_swapget(myinfo,swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(myinfo,swap) == 0 ) // divulges privAm { - printf("got privi spend alicepayment\n"); + printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n"); basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 ) printf("Bob error spending alice payment\n"); else { tradebot_swap_balancingtrade(myinfo,swap,1); printf("Bob spends alicepayment\n"); swap->I.statebits |= 0x40000; - while ( basilisk_numconfirms(myinfo,&swap->bobspend) < swap->I.aliceconfirms ) + while ( basilisk_numconfirms(myinfo,swap,&swap->bobspend) < swap->I.aliceconfirms ) { printf("bobspend confirmed\n"); swap->I.statebits |= 0x80000; printf("Bob confirms spend of Alice's payment\n"); - sleep(10); + sleep(DEX_SLEEP); } retval = 1; } @@ -1622,14 +1951,14 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap // submit reclaim of payment printf("bob reclaims bobpayment\n"); swap->I.statebits |= (0x40000 | 0x80000); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobreclaim,0) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 ) printf("Bob error reclaiming own payment after alice timed out\n"); else { printf("Bob reclaimed own payment\n"); while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx? { - if ( basilisk_numconfirms(myinfo,&swap->bobreclaim) >= 1 ) + if ( basilisk_numconfirms(myinfo,swap,&swap->bobreclaim) >= 1 ) { printf("bobreclaim confirmed\n"); swap->I.statebits |= 0x100000; @@ -1657,7 +1986,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } else if ( (swap->I.statebits & 0x400) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->bobdeposit) >= swap->I.bobconfirms ) + if ( basilisk_numconfirms(myinfo,swap,&swap->bobdeposit) >= swap->I.bobconfirms ) { printf("bobdeposit confirmed\n"); swap->I.statebits |= 0x400; @@ -1666,7 +1995,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap else if ( (swap->I.statebits & 0x800) == 0 ) { printf("send alicepayment\n"); - swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x1000,data,maxlen,&swap->alicepayment,0x800); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0); } // [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim else if ( (swap->I.statebits & 0x8000) == 0 ) @@ -1681,7 +2010,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } else if ( (swap->I.statebits & 0x10000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->bobpayment) >= swap->I.bobconfirms ) + if ( basilisk_numconfirms(myinfo,swap,&swap->bobpayment) >= swap->I.bobconfirms ) { printf("bobpayment confirmed\n"); swap->I.statebits |= 0x10000; @@ -1690,17 +2019,17 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap else if ( (swap->I.statebits & 0x20000) == 0 ) { printf("alicespend bobpayment\n"); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000) != 0 && basilisk_numconfirms(myinfo,&swap->alicespend) > 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 && basilisk_numconfirms(myinfo,swap,&swap->alicespend) > 0 ) { for (j=datalen=0; j<32; j++) data[datalen++] = swap->I.privAm.bytes[j]; - printf("send privAm\n"); swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); + printf("send privAm %x\n",swap->I.statebits); } } else if ( (swap->I.statebits & 0x40000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->alicespend) >= swap->I.bobconfirms ) + if ( basilisk_numconfirms(myinfo,swap,&swap->alicespend) >= swap->I.bobconfirms ) { swap->I.statebits |= 0x40000; printf("Alice confirms spend of Bob's payment\n"); @@ -1710,7 +2039,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) { printf("Alice claims deposit\n"); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->aliceclaim,0) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 ) printf("Alice couldnt claim deposit\n"); else { @@ -1722,7 +2051,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap { printf("Alice reclaims her payment\n"); swap->I.statebits |= 0x40000000; - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicereclaim,0x40000000) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 ) printf("Alice error sending alicereclaim\n"); else { @@ -1733,7 +2062,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } if ( (rand() % 30) == 0 ) printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); - sleep(3 + (swap->I.iambob == 0)); + sleep(DEX_SLEEP + (swap->I.iambob == 0)); basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); } @@ -1753,10 +2082,90 @@ cJSON *swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) return(retjson); } +void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp) +{ + char keystr[64],databuf[1024],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1; + if ( swap->connected == 1 ) + return; + if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) + { + timeout = 100; + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + swap->pushsock = pushsock; + swap->subsock = subsock; + } + if ( swap->subsock < 0 || swap->pushsock < 0 ) + { + printf("error getting nn_sockets\n"); + return; + } + sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid); + if ( (retstr= _dex_kvsearch(myinfo,"KV",keystr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (datastr= jstr(retjson,"value")) != 0 ) + { + datalen = (int32_t)strlen(datastr) >> 1; + decode_hex((uint8_t *)databuf,datalen,datastr); + if ( (addrjson= cJSON_Parse(databuf)) != 0 ) + { + pushaddr = jstr(addrjson,"push"); + subaddr = jstr(addrjson,"sub"); + if ( pushaddr != 0 && subaddr != 0 ) + { + printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock); + if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 ) + swap->connected = 1; + } + free_json(addrjson); + } + } + free_json(retjson); + } + printf("KVsearch.(%s) connected.%d socks.(%d %d)\n",retstr,swap->connected,swap->pushsock,swap->subsock); + free(retstr); + } + if ( swap->connected == 0 && amlp != 0 ) + { + if ( (retstr= _dex_psock(myinfo,"{}")) != 0 ) + { + // {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"} + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + pushaddr = jstr(retjson,"pushaddr"); + subaddr = jstr(retjson,"subaddr"); + if ( pushaddr != 0 && subaddr != 0 ) + { + if ( nn_connect(pushsock,pushaddr) >= 0 && nn_connect(subsock,subaddr) >= 0 ) + { + swap->connected = 1; + sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\"}",pushaddr,subaddr); + datalen = (int32_t)strlen((char *)data) + 1; + printf("datalen.%d (%s)\n",datalen,(char *)data); + init_hexbytes_noT(databuf,data,datalen); + printf("%s -> %s\n",keystr,databuf); + if ( (retstr2= _dex_kvupdate(myinfo,"KV",keystr,databuf,1)) != 0 ) + { + printf("KVupdate.(%s)\n",retstr2); + free(retstr2); + } + } + } + free_json(retjson); + } + free(retstr); + } + } +} + void basilisk_swaploop(void *_swap) { uint8_t *data; uint32_t expiration; uint32_t channel; int32_t retval=0,i,j,datalen,maxlen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; - myinfo = swap->myinfo; + myinfo = swap->myinfoptr; fprintf(stderr,"start swap\n"); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); @@ -1765,22 +2174,31 @@ void basilisk_swaploop(void *_swap) channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); while ( (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) { - printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); - //basilisk_channelsend(myinfo,swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid),60); dex_channelsend(myinfo,swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60); - basilisk_sendstate(myinfo,swap,data,maxlen); - basilisk_sendpubkeys(myinfo,swap,data,maxlen); // send pubkeys - if ( basilisk_checkdeck(myinfo,swap,data,maxlen) == 0) // check for other deck 0x02 - basilisk_sendchoosei(myinfo,swap,data,maxlen); - basilisk_waitchoosei(myinfo,swap,data,maxlen); // wait for choosei 0x08 - if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) - break; - sleep(1); - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + if ( swap->connected != 0 ) + { + printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_sendpubkeys(myinfo,swap,data,maxlen); // send pubkeys + if ( basilisk_checkdeck(myinfo,swap,data,maxlen) == 0) // check for other deck 0x02 + basilisk_sendchoosei(myinfo,swap,data,maxlen); + basilisk_waitchoosei(myinfo,swap,data,maxlen); // wait for choosei 0x08 + if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) + break; + } + sleep(DEX_SLEEP); + } + if ( swap->connected == 0 ) + { + printf("couldnt establish connection\n"); + retval = -1; } - while ( (swap->I.statebits & 0x20) == 0 && time(NULL) < expiration ) + while ( retval == 0 && (swap->I.statebits & 0x20) == 0 && time(NULL) < expiration ) { + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_sendchoosei(myinfo,swap,data,maxlen); @@ -1790,24 +2208,25 @@ void basilisk_swaploop(void *_swap) swap->I.statebits |= 0x20; break; } - sleep(3 + (swap->I.iambob == 0)*1); - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); } + myinfo->DEXactive = swap->I.expiration; if ( time(NULL) >= expiration ) + { retval = -1; - myinfo->DEXactive = swap->I.expiration; + myinfo->DEXactive = 0; + } printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval); while ( retval == 0 && (swap->I.statebits & 0x40) == 0 ) // send fee { - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); - printf("sendstate.%x\n",swap->I.statebits); + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + //printf("sendstate.%x\n",swap->I.statebits); basilisk_sendstate(myinfo,swap,data,maxlen); - printf("swapget\n"); + //printf("swapget\n"); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); - printf("after swapget\n"); - if ( swap->myfee.txbytes == 0 ) + //printf("after swapget\n"); + if ( swap->myfee.I.datalen == 0 ) { /*for (i=0; i<20; i++) printf("%02x",swap->secretAm[i]); @@ -1845,7 +2264,7 @@ void basilisk_swaploop(void *_swap) printf("bobscripts set\n"); if ( basilisk_bobscripts_set(myinfo,swap,1,1) < 0 ) { - sleep(3); + sleep(DEX_SLEEP); printf("bobscripts set error\n"); continue; } @@ -1857,10 +2276,10 @@ void basilisk_swaploop(void *_swap) //if ( swap->alicepayment.txbytes != 0 && swap->alicepayment.I.spendlen != 0 ) // break; basilisk_alicepayment(myinfo,swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); - if ( swap->alicepayment.txbytes == 0 || swap->alicepayment.I.spendlen == 0 ) + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) { printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); - sleep(3); + sleep(DEX_SLEEP); } else { @@ -1875,17 +2294,17 @@ void basilisk_swaploop(void *_swap) } } printf("generate fee\n"); - if ( basilisk_rawtx_gen("myfee",myinfo,swap,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->chain->txfee,1,0) == 0 ) + if ( basilisk_rawtx_gen("myfee",myinfo,swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->chain->txfee,1,0) == 0 ) { printf("done generate fee\n"); - swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); iguana_unspents_mark(myinfo,swap->I.iambob!=0?swap->bobcoin:swap->alicecoin,swap->myfee.vins); basilisk_txlog(myinfo,swap,&swap->myfee,-1); for (i=0; imyfee.I.spendlen; i++) printf("%02x",swap->myfee.txbytes[i]); printf(" fee %p %x\n",swap->myfee.txbytes,swap->I.statebits); swap->I.statebits |= 0x40; - if ( swap->alicepayment.txbytes != 0 && swap->alicepayment.I.spendlen > 0 ) + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 ) break; } else @@ -1895,22 +2314,22 @@ void basilisk_swaploop(void *_swap) } } } - while ( basilisk_swapiteration(myinfo,swap,data,maxlen) == 0 ) + while ( retval == 0 && basilisk_swapiteration(myinfo,swap,data,maxlen) == 0 ) { - sleep(3); + sleep(DEX_SLEEP); basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_swap_saveupdate(myinfo,swap); if ( time(NULL) > swap->I.expiration ) break; - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); } - printf("end of atomic swap\n"); - if ( swap->I.iambob != 0 && swap->bobdeposit.txbytes != 0 ) + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 ) { + printf("BOB waiting for confirm\n"); + sleep(60); // wait for confirm/propagation of msig printf("BOB reclaims refund\n"); basilisk_bobdeposit_refund(myinfo,swap,0); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobrefund,0x40000000) == 0 ) // use secretBn + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn { printf("Bob submit error getting refund of deposit\n"); } @@ -1921,7 +2340,9 @@ void basilisk_swaploop(void *_swap) data[datalen++] = swap->I.privBn.bytes[j]; basilisk_swapsend(myinfo,swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv); } + basilisk_swap_saveupdate(myinfo,swap); } + printf("end of atomic swap\n"); if ( swapcompleted(myinfo,swap) > 0 ) // only if swap completed { if ( swap->I.iambob != 0 ) @@ -1933,9 +2354,10 @@ void basilisk_swaploop(void *_swap) free(data); } -struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration) +struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) { - int32_t i,m,n; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct basilisk_swap *swap = 0; + int32_t i,m,n; uint8_t pubkey33[33]; bits256 pubkey25519; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct basilisk_swap *swap = 0; + // statebits 1 -> client, 0 -> LP portable_mutex_lock(&myinfo->DEX_swapmutex); for (i=0; inumswaps; i++) if ( myinfo->swaps[i]->I.req.requestid == rp->requestid ) @@ -1945,54 +2367,90 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct } if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) ) { - printf("basilisk_thread_start request.%u statebits.%d\n",rp->requestid,statebits); swap = calloc(1,sizeof(*swap)); + swap->subsock = swap->pushsock = -1; vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp)); swap->I.req = *rp; - swap->myinfo = myinfo; + swap->myinfoptr = myinfo; + printf("basilisk_thread_start request.%u statebits.%d (%s/%s) reinit.%d\n",rp->requestid,statebits,rp->src,rp->dest,reinit); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + pubkey25519 = curve25519(privkey,curve25519_basepoint9()); + swap->persistent_pubkey = pubkey25519; + swap->persistent_privkey = privkey; + memcpy(swap->persistent_pubkey33,pubkey33,33); m = n = 0; - if ( bitcoin_swapinit(myinfo,swap,optionduration) != 0 ) + if ( bitcoin_swapinit(myinfo,privkey,pubkey33,pubkey25519,swap,optionduration,statebits,reinit) != 0 ) { - starttime = (uint32_t)time(NULL); - printf("statebits.%x m.%d n.%d\n",statebits,m,n); - while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+BASILISK_MSGDURATION ) + basilisk_psockinit(myinfo,swap,statebits == 0); + if ( reinit != 0 ) + { + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + { + + } + myinfo->swaps[myinfo->numswaps++] = swap; + } + else { - m = n = 0; - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); - sleep(3); - printf("waiting for offer to be accepted\n"); - channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - if ( (retarray= basilisk_channelget(myinfo,rp->srchash,rp->desthash,channel,0x4000000,30)) != 0 ) + starttime = (uint32_t)time(NULL); + printf("statebits.%x m.%d n.%d\n",statebits,m,n); + while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+BASILISK_MSGDURATION ) { - if ( is_cJSON_Array(retarray) != 0 && (n= cJSON_GetArraySize(retarray)) > 0 ) + m = n = 0; + sleep(DEX_SLEEP); + printf("waiting for offer to be accepted\n"); + channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + if ( (retarray= basilisk_channelget(myinfo,rp->srchash,rp->desthash,channel,0x4000000,30)) != 0 ) { - for (i=0; i 0 ) { - item = jitem(retarray,i); - if ( (msgobj= jarray(&n,item,"messages")) != 0 && n > 0 ) + for (i=0; i 0 ) + { + item = jitem(msgobj,0); + if ( jobj(item,"data") != 0 && jobj(item,"key") != 0 ) + m++; + else printf("(%s)\n",jprint(item,0)); + } //else printf("msgobj.%p m.%d n.%d\n",msgobj,m,n); + } + } + } else printf("no retarray\n"); + } + printf("LAUNCH check.%d m.%d\n",statebits,m); + if ( statebits != 0 || m > 0 )//n/2 ) + { + //for (i=0; iI.req); i++) + // fprintf(stderr,"%02x",((uint8_t *)&swap->I.req)[i]); + fprintf(stderr," M.%d N.%d launch.%d %d %p\n",m,n,myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps)),&swap->I.req); + if ( (swap->fp= basilisk_swap_save(myinfo,swap,privkey,rp,statebits,optionduration,reinit)) != 0 ) + { + if ( reinit == 0 ) + { + if ( myinfo->swapsfp == 0 ) + { + char fname[512]; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) == 0 ) + myinfo->swapsfp = fopen(fname,"wb+"); + else fseek(myinfo->swapsfp,0,SEEK_END); + } + if ( myinfo->swapsfp != 0 ) + { + fwrite(&rp->requestid,1,sizeof(rp->requestid),myinfo->swapsfp); + fwrite(&rp->quoteid,1,sizeof(rp->quoteid),myinfo->swapsfp); + fflush(myinfo->swapsfp); + } } } - } else printf("no retarray\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + { + + } + myinfo->swaps[myinfo->numswaps++] = swap; + } else printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d\n",rp->requestid,rp->quoteid,statebits,m,n); } - printf("LAUNCH check.%d m.%d\n",statebits,m); - if ( statebits != 0 || m > 0 )//n/2 ) - { - //for (i=0; iI.req); i++) - // fprintf(stderr,"%02x",((uint8_t *)&swap->I.req)[i]); - fprintf(stderr," M.%d N.%d launch.%d %d %p\n",m,n,myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps)),&swap->I.req); - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) - { - - } - myinfo->swaps[myinfo->numswaps++] = swap; - } else printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d\n",rp->requestid,rp->quoteid,statebits,m,n); } } portable_mutex_unlock(&myinfo->DEX_swapmutex); diff --git a/basilisk/basilisk_tradebot.c b/basilisk/basilisk_tradebot.c index 7940a4e94..5d16548dc 100755 --- a/basilisk/basilisk_tradebot.c +++ b/basilisk/basilisk_tradebot.c @@ -69,12 +69,12 @@ int32_t basilisk_txitem(struct supernet_info *myinfo,struct basilisk_swap *swap, decode_hex((void *)&rawtx->I,sizeof(rawtx->I),hexstr); if ( (hexstr= jstr(obj,"txbytes")) != 0 && strlen(hexstr) == rawtx->I.datalen*2 ) { - if ( rawtx->txbytes == 0 ) + /*if ( rawtx->txbytes == 0 ) { printf("free (%s) txbytes\n",name); free(rawtx->txbytes); } - rawtx->txbytes = calloc(1,rawtx->I.datalen); + rawtx->txbytes = calloc(1,rawtx->I.datalen);*/ decode_hex((void *)rawtx->txbytes,rawtx->I.datalen,hexstr); } printf("PROCESS.(%s)\n",jprint(obj,0)); @@ -92,6 +92,7 @@ cJSON *basilisk_swapobj(struct supernet_info *myinfo,struct basilisk_swap *swap) jaddnum(obj,"quoteid",swap->I.req.quoteid); jadd(obj,"req",basilisk_requestjson(&swap->I.req)); jaddstr(obj,"info",hexstr); + //printf("strlen(hexstr) swap->I %d vs %d\n",(int32_t)strlen(hexstr),(int32_t)sizeof(swap->I)*2); return(obj); } @@ -104,7 +105,7 @@ int32_t basilisk_swapconv(struct supernet_info *myinfo,struct basilisk_swap *swa if ( juint(obj,"requestid") == swap->I.req.requestid && juint(obj,"quoteid") == swap->I.req.quoteid ) return(0); printf("swapconv mismatched req/quote %d %d, %d %d\n",juint(obj,"requestid"),swap->I.req.requestid,juint(obj,"quoteid"),swap->I.req.quoteid); - } else printf("no info field in swap obj\n"); + } //else printf("no info field in swap obj.(%s) len.%d vs %d\n",jprint(obj,0),(int32_t)strlen(hexstr),(int32_t)sizeof(swap->I)*2); return(-1); } @@ -278,7 +279,7 @@ int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_req double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n) { - int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; int64_t balance=0,destamount,minamount = 0,maxamount = 0; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.; + int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; int64_t balance=0,destamount,minamount = 0,maxamount = 0; bits256 privkey; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.; memset(issueR,0,sizeof(*issueR)); minamount = list[0].minamount; //printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid); @@ -288,7 +289,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk return(0.); pendingid = active->I.req.quoteid; } - if ( bits256_cmp(myinfo->myaddr.persistent,list[0].srchash) == 0 ) // my request + if ( smartaddress_pubkey(myinfo,&privkey,list[0].srchash) >= 0 ) myrequest = 1; for (i=0; imyaddr.persistent,list[i].desthash) == 0 ) // my quoteid + if ( smartaddress_pubkey(myinfo,&privkey,list[i].desthash) >= 0 ) myrequest |= 2; havequoteflag++; if ( pendingid == 0 ) @@ -331,7 +332,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk if ( fabs(aveprice) < SMALLVAL ) return(0); //retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; - destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount; + destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount * SATOSHIDEN; printf("aveprice %f dest %.8f avebid %f bidvol %f, aveask %f askvol %f\n",aveprice,dstr(destamount),retvals[0],retvals[1],retvals[2],retvals[3]); if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) { diff --git a/basilisk/jumblr.c b/basilisk/jumblr.c index f61e07090..67b8c2306 100755 --- a/basilisk/jumblr.c +++ b/basilisk/jumblr.c @@ -63,6 +63,34 @@ struct jumblr_item *jumblr_opidadd(struct supernet_info *myinfo,struct iguana_in return(ptr); } +char *jumblr_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024]; + if ( coin->FULLNODE < 0 ) + { + sprintf(params,"[\"%s\"]",addr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",params)); + } else return(_dex_validateaddress(myinfo,coin->symbol,addr)); +} + +int32_t jumblr_ismine(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024],*retstr; cJSON *retjson,*obj; int32_t retval = -1; + sprintf(params,"[\"%s\"]",addr); + if ( (retstr= jumblr_validateaddress(myinfo,coin,addr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 ) + retval = 1; + else retval = 0; + free_json(retjson); + } + free(retstr); + } + return(retval); +} + char *jumblr_zgetnewaddress(struct supernet_info *myinfo,struct iguana_info *coin) { return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getnewaddress","")); @@ -165,17 +193,28 @@ int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,cha char *retstr; double val; cJSON *retjson; int32_t i,n; int64_t balance = 0; if ( jumblr_addresstype(myinfo,coin,addr) == 't' ) { - if ( (retstr= jumblr_listunspent(myinfo,coin,addr)) != 0 ) + if ( coin->FULLNODE < 0 && jumblr_ismine(myinfo,coin,addr) > 0 ) + { + if ( (retstr= jumblr_listunspent(myinfo,coin,addr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + for (i=0; isymbol,addr)) != 0 ) { + //printf("retstr.(%s)\n",retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (n= cJSON_GetArraySize(retjson)) > 0 ) - for (i=0; isrc,from,sizeof(ptr->src)); + } if ( (amounts= jarray(&n,params,"amounts")) != 0 ) { for (i=0; istatus == 0 ) { if ( (retstr= jumblr_zgetoperationstatus(myinfo,coin,ptr->opid)) != 0 ) @@ -248,6 +289,15 @@ void jumblr_opidupdate(struct supernet_info *myinfo,struct iguana_info *coin,str if ( strcmp(status,"success") == 0 ) { ptr->status = jumblr_itemset(ptr,item,status); + jumblr_privkey(myinfo,BTCaddr,KMDdeposit,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,KMDjumblr,""); + if ( (jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && strcmp(ptr->src,KMDdeposit) != 0) || (jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->src) == 't' && strcmp(ptr->dest,KMDjumblr) != 0) ) + { + printf("a non-jumblr t->z pruned\n"); + free(jumblr_zgetoperationresult(myinfo,coin,ptr->opid)); + ptr->status = -1; + } + } else if ( strcmp(status,"failed") == 0 ) { @@ -325,11 +375,46 @@ bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,char *KMDaddr, return(privkey); } +void jumblr_DEXcheck(struct supernet_info *myinfo,struct iguana_info *coinkmd,char *BTCaddr,char *KMDaddr,bits256 privkey) +{ + static double kmdprice,pending; static uint32_t lasttime; + double btcavail=0,minbtc,avebid,aveask,highbid,lowask,CMC_average,USD_average,changes[3]; struct iguana_info *coinbtc; cJSON *vals; bits256 hash; char *retstr; + coinbtc = iguana_coinfind("BTC"); + if ( kmdprice == 0. || time(NULL) > lasttime+60 ) + { + kmdprice = get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,"komodo","KMD","BTC",&USD_average); + lasttime = (uint32_t)time(NULL); + printf("KMD %.8f\n",kmdprice); + } + if ( kmdprice > SMALLVAL ) + { + minbtc = (kmdprice * 1.1) * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); + if ( coinbtc != 0 && (btcavail= dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))) > minbtc+pending ) + { + printf("BTC deposits %.8f, min %.8f\n",btcavail,minbtc); + vals = cJSON_CreateObject(); + jaddstr(vals,"source","BTC"); + //hash = curve25519(privkey,curve25519_basepoint9()); + jaddstr(vals,"dest","KMD"); + jaddnum(vals,"amount",btcavail*.3); + jaddnum(vals,"minprice",kmdprice*.95); + jaddnum(vals,"usejumblr",1); + memset(hash.bytes,0,sizeof(hash)); + pending = btcavail; + if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + // curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}" + } //else printf("btcavail %.8f pending %.8f\n",btcavail,pending); + } else printf("null kmdprice %.8f\n",kmdprice); +} + void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval) { - char BTCaddr[64],KMDaddr[64],*zaddr,*retstr; bits256 priv0; uint64_t amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint8_t r; - // if BTC has arrived in deposit address, invoke DEX -> KMD - // if BTC has arrived in destination address, invoke DEX -> BTC + //static uint32_t lasttime; + char BTCaddr[64],KMDaddr[64],*zaddr,*retstr; bits256 privkey; uint64_t amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint8_t r; fee = JUMBLR_INCR * JUMBLR_FEE; OS_randombytes(&r,sizeof(r)); //r = 0; @@ -339,7 +424,6 @@ void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int3 switch ( selector ) { case 0: // public -> z, need to importprivkey - priv0 = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); if ( (total= jumblr_balance(myinfo,coin,KMDaddr)) >= (JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))*SATOSHIDEN ) { if ( (r & 1) == 0 ) @@ -392,7 +476,7 @@ void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int3 { if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) { - priv0 = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); if ( (retstr= jumblr_sendz_to_t(myinfo,coin,ptr->dest,KMDaddr,dstr(total))) != 0 ) { printf("sendz_to_t.(%s)\n",retstr); @@ -408,75 +492,3 @@ void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int3 } } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -STRING_ARG(jumblr,setpassphrase,passphrase) -{ - cJSON *retjson; char KMDaddr[64],BTCaddr[64],wifstr[64]; bits256 privkey; - if ( passphrase == 0 || passphrase[0] == 0 || (coin= iguana_coinfind("KMD")) == 0 || coin->FULLNODE >= 0 ) - return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); - else - { - safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); - jumblr_importprivkey(myinfo,coin,wifstr); - jaddstr(retjson,"BTCdeposit","notyet"); - jaddstr(retjson,"KMDdeposit",KMDaddr); - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); - // jumblr_importprivkey(myinfo,coin,wifstr); dont mix jumbled funds with normal! - jaddstr(retjson,"BTCjumblr","notyet"); - jaddstr(retjson,"KMDjumblr",KMDaddr); - return(jprint(retjson,1)); - } -} - -ZERO_ARGS(jumblr,status) -{ - cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; - if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 ) - { - jumblr_opidsupdate(myinfo,coin); - retjson = cJSON_CreateObject(); - step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; - jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - jaddstr(retjson,"BTCdeposit","notyet"); - jaddstr(retjson,"KMDdeposit",KMDaddr); - received = jumblr_receivedby(myinfo,coin,KMDaddr); - deposited = jumblr_balance(myinfo,coin,KMDaddr); - jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - jaddstr(retjson,"BTCjumblr","notyet"); - jaddstr(retjson,"KMDjumblr",KMDaddr); - finished = jumblr_receivedby(myinfo,coin,KMDaddr); - jumblred = jumblr_balance(myinfo,coin,KMDaddr); - HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) - { - if ( strlen(ptr->src) >= 40 ) - { - if ( strlen(ptr->dest) >= 40 ) - step_z2z += ptr->amount; - else step_z2t += ptr->amount; - } else step_t2z += ptr->amount; - } - jaddstr(retjson,"result","success"); - jaddnum(retjson,"deposits",dstr(deposited)); - jaddnum(retjson,"t_to_z",dstr(step_t2z)); - jaddnum(retjson,"z_to_z",dstr(step_z2z)); - jaddnum(retjson,"z_to_t",dstr(step_z2t)); - maxval = MAX(step_t2z,MAX(step_z2z,step_z2t)); - minval = MIN(step_t2z,MIN(step_z2z,step_z2t)); - if ( maxval > minval ) - pending = (maxval - minval); - jaddnum(retjson,"pending",dstr(pending)); - jaddnum(retjson,"jumbled",dstr(jumblred)); - jaddnum(retjson,"received",dstr(received)); - jaddnum(retjson,"finished",dstr(finished)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/smartaddress.c b/basilisk/smartaddress.c new file mode 100755 index 000000000..ff9707b0c --- /dev/null +++ b/basilisk/smartaddress.c @@ -0,0 +1,90 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *BTCaddr,char *KMDaddr) +{ + struct smartaddress *ap; + int32_t i; + if ( myinfo->numsmartaddrs < sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs) ) + { + for (i=0; inumsmartaddrs; i++) + if ( bits256_cmp(myinfo->smartaddrs[i].privkey,privkey) == 0 ) + return(-1); + ap = &myinfo->smartaddrs[myinfo->numsmartaddrs++]; + ap->privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,ap->pubkey33,privkey); + calc_rmd160_sha256(ap->rmd160,ap->pubkey33,33); + ap->pubkey = curve25519(privkey,curve25519_basepoint9()); + char coinaddr[64]; uint8_t addrtype,rmd160[20]; + bitcoin_address(coinaddr,0,ap->pubkey33,33); + for (i=0; i<20; i++) + printf("%02x",ap->rmd160[i]); + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + printf(", "); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf (" <- rmd160 for %d %s vs %s\n",myinfo->numsmartaddrs,coinaddr,BTCaddr); + return(myinfo->numsmartaddrs); + } + printf("too many smartaddresses %d vs %d\n",myinfo->numsmartaddrs,(int32_t)(sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs))); + return(-1); +} + +int32_t smartaddress(struct supernet_info *myinfo,bits256 *privkeyp,char *coinaddr) +{ + int32_t i; uint8_t addrtype,rmd160[20]; + memset(privkeyp,0,sizeof(*privkeyp)); + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + for (i=0; inumsmartaddrs; i++) + if ( memcmp(myinfo->smartaddrs[i].rmd160,rmd160,20) == 0 ) + { + *privkeyp = myinfo->smartaddrs[i].privkey; + printf("MATCHED %s\n",coinaddr); + return(i); + } + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 smartaddress cant find (%s) of %d\n",coinaddr,myinfo->numsmartaddrs); + return(-1); +} + +int32_t smartaddress_pubkey(struct supernet_info *myinfo,bits256 *privkeyp,bits256 pubkey) +{ + int32_t i; + memset(privkeyp,0,sizeof(*privkeyp)); + for (i=0; inumsmartaddrs; i++) + if ( bits256_cmp(myinfo->smartaddrs[i].pubkey,pubkey) == 0 ) + { + *privkeyp = myinfo->smartaddrs[i].privkey; + return(i); + } + return(-1); +} + +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,bits256 *privkeyp,uint8_t *pubkey33) +{ + int32_t i; + memset(privkeyp,0,sizeof(*privkeyp)); + for (i=0; inumsmartaddrs; i++) + if ( memcmp(myinfo->smartaddrs[i].pubkey33,pubkey33,33) == 0 ) + { + *privkeyp = myinfo->smartaddrs[i].privkey; + return(i); + } + return(0); +} + diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c index cc38a2369..7e21127aa 100755 --- a/basilisk/tradebots_liquidity.c +++ b/basilisk/tradebots_liquidity.c @@ -110,7 +110,7 @@ int32_t tradebots_calcrawfeatures(struct tradebot_arbpair *pair) } if ( n > sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures) ) { - printf("n.%d too many for rawfeatures %ld\n",n,sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures)); + printf("n.%d too many for rawfeatures %d\n",n,(int32_t)(sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures))); exit(-1); } return(n); @@ -160,7 +160,7 @@ struct tradebot_arbpair *tradebots_arbpair_create(char *base,char *rel) pair->fp = OS_appendfile(fname); if ( (ftell(pair->fp) % sizeof(pair->rawfeatures)) != 0 ) { - printf("misalinged rawfeatures %ld %ld\n",ftell(pair->fp),(ftell(pair->fp) % sizeof(pair->rawfeatures))); + printf("misalinged rawfeatures %d %d\n",(uint32_t)ftell(pair->fp),(uint32_t)(ftell(pair->fp) % sizeof(pair->rawfeatures))); } fseek(pair->fp,(ftell(pair->fp) / sizeof(pair->rawfeatures)) * sizeof(pair->rawfeatures) - sizeof(pair->rawfeatures),SEEK_SET); if ( fread(pair->rawfeatures,1,sizeof(pair->rawfeatures),pair->fp) == sizeof(pair->rawfeatures) ) @@ -932,6 +932,8 @@ void _default_liquidity_command(struct supernet_info *myinfo,char *base,bits256 li.ask = jdouble(vals,"ask"); if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; + if ( strcmp(li.base,"KMD") == 0 && strcmp(li.rel,"BTC") == 0 && li.minvol > 100. ) + li.minvol = 100.; if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) li.maxvol = li.minvol; if ( (li.totalvol= jdouble(vals,"total")) < li.maxvol ) @@ -1129,6 +1131,8 @@ void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_s void tradebot_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) { + printf("balancing trade\n"); + return; if ( swap->balancingtrade == 0 ) _default_swap_balancingtrade(myinfo,swap,iambob); else (*swap->balancingtrade)(myinfo,swap,iambob); @@ -1203,35 +1207,3 @@ void tradebots_processprices(struct supernet_info *myinfo,struct exchange_info * } } } - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -TWO_STRINGS(tradebot,gensvm,base,rel) -{ -#ifdef _WIN - return(clonestr("{\"error\":\"windows doesnt support SVM\"}")); -#else - int32_t numfeatures = 317*61; - struct tradebot_arbpair *pair; - if ( base[0] != 0 && rel[0] != 0 && (pair= tradebots_arbpair_find(base,rel)) != 0 && pair->fp != 0 ) - { - tradebots_calcanswers(pair); - ocas_gen(pair->refc,numfeatures,0,(int32_t)(ftell(pair->fp) / sizeof(pair->rawfeatures))); - return(clonestr("{\"result\":\"success\"}")); - } else return(clonestr("{\"error\":\"cant find arbpair\"}")); -#endif -} - -ZERO_ARGS(tradebot,openliquidity) -{ - int32_t i; cJSON *array = cJSON_CreateArray(); - for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) - { - if ( myinfo->linfos[i].base[0] != 0 ) - jaddi(array,linfo_json(&myinfo->linfos[i])); - } - return(jprint(array,1)); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/tradebots_marketmaker.c b/basilisk/tradebots_marketmaker.c index 7d5d5ec61..575861fa6 100755 --- a/basilisk/tradebots_marketmaker.c +++ b/basilisk/tradebots_marketmaker.c @@ -106,97 +106,3 @@ double tradebot_pending(struct supernet_info *myinfo,char *base) return(pending); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -ZERO_ARGS(tradebot,allbalances) -{ - int32_t i,n; double value,pending; char *base; cJSON *item,*balances = cJSON_CreateObject(); - if ( myinfo->liquidity_currencies == 0 ) - myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); - if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) - { - for (i=0; iliquidity_currencies,i); - value = tradebot_balance(myinfo,base); - pending = tradebot_pending(myinfo,base); - item = cJSON_CreateObject(); - jaddnum(item,"value",value); - jaddnum(item,"pending",pending); - jadd(balances,base,item); - } - } - return(jprint(balances,1)); -} - -ZERO_ARGS(tradebot,anchor) -{ - FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; - if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) - { - if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) - { - if ( jobj(anchor,"error") == 0 ) - { - sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) - retval = 0; - fclose(fp); - } - } - } - free(anchorstr); - } - if ( retval == 0 ) - return(clonestr("{\"result\":\"success\"}")); - else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); -} - -ZERO_ARGS(tradebot,portfolio) -{ - char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; - if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) - { - if ( (current= cJSON_Parse(currentstr)) != 0 ) - { - sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) - { - anchor = cJSON_Parse(anchorstr); - free(anchorstr); - } - if ( anchor == 0 ) - anchor = cJSON_Parse("{}"); - portfolio = tradebot_balancesdiff(myinfo,current,anchor); - free_json(current); - } - free(currentstr); - } - if ( portfolio == 0 ) - return(clonestr("{\"result\":\"success\"}")); - else return(jprint(portfolio,1)); -} - -ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) -{ - static bits256 zero; char *targetcoin; int32_t i,n; - if ( currencies != 0 && vals != 0 ) - { - // init things so automatically updates refli.bid and refli.ask - // volume range with margin - // currency percentage value in BTC? target distribution, max percentage, min percentage` - // min price to sell, max price to buy, max volume - n = cJSON_GetArraySize(currencies); - for (i=0; iallocsize < sizeof(*sig) || sig->allocsize > IGUANA_MAXPACKETSIZE ) { diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index e9b8b8a51..80988fa5f 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -1164,7 +1164,7 @@ char *bittrex_orderbook(char *base,char *rel,int32_t maxdepth) double calc_theoretical(double weighted,double CMC_average,double changes[3]) { - double adjusted = 0.,theoretical = 0.; + double theoretical = 0.; //adjusted = 0., if ( weighted > SMALLVAL && CMC_average > SMALLVAL ) { theoretical = (weighted + CMC_average) * 0.5; @@ -1185,7 +1185,7 @@ double calc_theoretical(double weighted,double CMC_average,double changes[3]) if ( adjusted != 0. && theoretical != 0. ) theoretical = (theoretical + adjusted) * 0.5;*/ } - printf("adjusted %.8f theoretical %.8f (%.8f + wt %.8f)\n",adjusted,theoretical,CMC_average,weighted); + //printf("adjusted %.8f theoretical %.8f (%.8f + wt %.8f)\n",adjusted,theoretical,CMC_average,weighted); return(theoretical); } diff --git a/gecko/gecko.c b/gecko/gecko.c index 774139d3e..f8bdaeea3 100755 --- a/gecko/gecko.c +++ b/gecko/gecko.c @@ -273,9 +273,6 @@ char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *add } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx) { char *retstr = 0; struct iguana_info *virt,*btcd = iguana_coinfind("BTCD"); @@ -290,48 +287,5 @@ char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t return(retstr); } -HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr) -{ - struct iguana_info *btcd; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) - { - if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) - { - txid = bits256_doublesha256(0,data,datalen); - retstr = gecko_sendrawtransaction(myinfo,symbol,data,datalen,txid,vals,hexstr); - } else retstr = clonestr("{\"error\":\"no tx submitted\"}"); - if ( allocptr != 0 ) - free(allocptr); - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"couldnt create geckotx\"}"); - return(retstr); - } return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr) -{ - return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr) -{ - return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr) -{ - struct iguana_info *btcd,*virt; char *symbol; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) - { - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - basilisk_wait(myinfo,virt); - return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0)); - } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); - } - return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c index b44fc1b18..31cbe6869 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -22,7 +22,6 @@ #include "../includes/curve25519.h" #include "../includes/cJSON.h" - /* if ( 0 ) { @@ -421,52 +420,4 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) return(coinargs); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) -{ - char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - wallethash = wallet2priv = GENESIS_PRIVKEY; - if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) - wallethash = bits256_conv(pass); - if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) - wallet2priv = bits256_conv(fname2); - if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) - { - //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); - //obj = jduplicate(jobj(retjson,"payload")); - //jdelete(retjson,"payload"); - //jadd(retjson,"result",obj); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); -} - -THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) -{ - char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - argjson = jduplicate(json); - //printf("argjson.(%s)\n",jprint(argjson,0)); - jdelete(argjson,"agent"); - jdelete(argjson,"method"); - jdelete(argjson,"password"); - jdelete(argjson,"permanentfile"); - jdelete(argjson,"timestamp"); - jdelete(argjson,"tag"); - if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) - { - jaddstr(retjson,"result","success"); - jaddstr(retjson,"filename",destfname); - } else jaddstr(retjson,"error","couldnt encrypt json file"); - free_json(argjson); - return(jprint(retjson,1)); -} - - -#include "../includes/iguana_apiundefs.h" - diff --git a/iguana/dPoW.h b/iguana/dPoW.h index e6e8f9d80..b773104c8 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -23,7 +23,7 @@ //#define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1) #define DPOW_MODIND(bp,offset) (((((bp)->height / DPOW_CHECKPOINTFREQ) % (bp)->numnotaries) + (offset)) % (bp)->numnotaries) #define DPOW_VERSION 0x0781 -#define DPOW_UTXOSIZE 10000 +#define DPOW_UTXOSIZE 50000 #define DPOW_MINOUTPUT 6000 #define DPOW_DURATION 600 #define DPOW_RATIFYDURATION (3600 * 24) @@ -167,6 +167,9 @@ char *dpow_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin); cJSON *dpow_kvupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *key,char *value,int32_t flags); cJSON *dpow_kvsearch(struct supernet_info *myinfo,struct iguana_info *coin,char *key); void init_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin); +cJSON *dpow_getmessage(struct supernet_info *myinfo,char *jsonstr); +cJSON *dpow_addmessage(struct supernet_info *myinfo,char *jsonstr); +cJSON *dpow_psock(struct supernet_info *myinfo,char *jsonstr); char *_dex_getinfo(struct supernet_info *myinfo,char *symbol); char *_dex_getrawtransaction(struct supernet_info *myinfo,char *symbol,bits256 txid); @@ -178,6 +181,7 @@ char *_dex_gettxout(struct supernet_info *myinfo,char *symbol,bits256 txid,int32 char *_dex_gettxin(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout); char *_dex_importaddress(struct supernet_info *myinfo,char *symbol,char *address); char *_dex_validateaddress(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_getmessage(struct supernet_info *myinfo,char *jsonstr); char *_dex_listunspent(struct supernet_info *myinfo,char *symbol,char *address); char *_dex_listunspent2(struct supernet_info *myinfo,char *symbol,char *address); char *_dex_listspent(struct supernet_info *myinfo,char *symbol,char *address); @@ -189,6 +193,7 @@ int32_t _dex_getheight(struct supernet_info *myinfo,char *symbol); char *_dex_getnotaries(struct supernet_info *myinfo,char *symbol); char *_dex_kvupdate(struct supernet_info *myinfo,char *symbol,char *key,char *value,int32_t flags); char *_dex_kvsearch(struct supernet_info *myinfo,char *symbol,char *key); +char *_dex_psock(struct supernet_info *myinfo,char *jsonstr); int32_t komodo_notaries(char *symbol,uint8_t pubkeys[64][33],int32_t height); cJSON *dpow_checkaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address); diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index 4d563f9f1..18afb868b 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -126,8 +126,8 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct int32_t haveutxo,completed,minutxo,n; bits256 signedtxid; cJSON *addresses; char *rawtx,*sendtx; if ( strcmp("BTC",coin->symbol) == 0 ) { - minutxo = 499; - n = 50; + minutxo = 199; + n = 10; } else { diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 7cac5a7ea..cadc11faa 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -239,6 +239,105 @@ char *nanomsg_tcpname(struct supernet_info *myinfo,char *str,char *ipaddr,uint16 return(str); } +void dpow_psockloop(void *_ptr) +{ + int32_t i,nonz,size,sentbytes; uint32_t now; struct psock *ptr; void *buf; struct supernet_info *myinfo = _ptr; + while ( 1 ) + { + now = (uint32_t)time(NULL); + for (i=nonz=0; inumpsocks; i++) // change to nn_poll! + { + portable_mutex_lock(&myinfo->psockmutex); + if ( i < myinfo->numpsocks ) + { + ptr = &myinfo->PSOCKS[i]; + if ( (size= nn_recv(ptr->pullsock,&buf,NN_MSG,0)) > 0 ) + { + ptr->lasttime = now; + if ( (sentbytes= nn_send(ptr->pubsock,buf,size,0)) > 0 ) + { + //printf("PSOCKS[%d] of %d (%u %u) -> %d/%d bytes\n",i,myinfo->numpsocks,ptr->pushport,ptr->subport,size,sentbytes); + nonz++; + } + } + else if ( now > ptr->lasttime+PSOCK_IDLETIMEOUT ) + { + printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,myinfo->numpsocks,ptr->pushport,ptr->subport,now - ptr->lasttime); + nn_close(ptr->pullsock); + nn_close(ptr->pubsock); + if ( myinfo->numpsocks > 1 ) + { + myinfo->PSOCKS[i] = myinfo->PSOCKS[--myinfo->numpsocks]; + memset(&myinfo->PSOCKS[myinfo->numpsocks],0,sizeof(*ptr)); + } else myinfo->numpsocks = 0; + } + if ( buf != 0 ) + nn_freemsg(buf), buf = 0; + } + portable_mutex_unlock(&myinfo->psockmutex); + } + if ( nonz == 0 ) + usleep(100000); + } +} + +void dpow_psockadd(struct supernet_info *myinfo,int32_t pullsock,uint16_t pushport,int32_t pubsock,uint16_t subport) +{ + struct psock *ptr; + portable_mutex_lock(&myinfo->psockmutex); + myinfo->PSOCKS = realloc(myinfo->PSOCKS,sizeof(*myinfo->PSOCKS) * (myinfo->numpsocks + 1)); + ptr = &myinfo->PSOCKS[myinfo->numpsocks++]; + ptr->pullsock = pullsock; + ptr->pushport = pushport; + ptr->pubsock = pubsock; + ptr->subport = subport; + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_unlock(&myinfo->psockmutex); +} + +cJSON *dpow_psock(struct supernet_info *myinfo,char *jsonstr) +{ + char pushaddr[128],subaddr[128]; uint16_t i,pushport,subport; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; cJSON *retjson=0; + retjson = cJSON_CreateObject(); + pushport = myinfo->psockport++; + subport = myinfo->psockport++; + for (i=0; i<100; i++) + { + pullsock = pubsock = -1; + nanomsg_tcpname(myinfo,pushaddr,myinfo->ipaddr,pushport), pushport += 2; + nanomsg_tcpname(myinfo,subaddr,myinfo->ipaddr,subport), subport += 2; + if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) + { + if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 ) + { + timeout = 10; + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + maxsize = 1024 * 1024; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); + dpow_psockadd(myinfo,pullsock,pushport,pubsock,subport); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"pushaddr",pushaddr); + jaddstr(retjson,"subaddr",subaddr); + break; + } + if ( pullsock >= 0 ) + nn_close(pullsock); + if ( pubsock >= 0 ) + nn_close(pubsock); + } + if ( pushport < 1000 ) + pushport = 1001; + if ( subport < 1000 ) + subport = 1001; + } + if ( i == 100 ) + jaddstr(retjson,"error","cant find psock ports"); + return(retjson); +} + static int _increasing_ipbits(const void *a,const void *b) { #define uint32_a (*(uint32_t *)a) @@ -254,24 +353,24 @@ static int _increasing_ipbits(const void *a,const void *b) void dex_packet(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t size) { - char *retstr; int32_t datalen; struct iguana_info *coin; struct dex_request dexreq; + char *retstr; int32_t datalen; struct dex_request dexreq; //struct iguana_info *coin; //for (i=0; ihandler,size,calc_crc32(0,dexp->packet,dexp->datalen),(int32_t)(time(NULL)-dexp->timestamp),dexp->size,dexp->datalen); if ( strcmp(dexp->handler,"DEX") == 0 && dexp->datalen > BASILISK_KEYSIZE ) { + printf(" uniq.%s DEX_PACKET.[%d] crc.%x lag.%d (%d %d)\n",dexp->handler,size,calc_crc32(0,dexp->packet,dexp->datalen),(int32_t)(time(NULL)-dexp->timestamp),dexp->size,dexp->datalen); if ( (retstr= basilisk_respond_addmessage(myinfo,dexp->packet,BASILISK_KEYSIZE,&dexp->packet[BASILISK_KEYSIZE],dexp->datalen-BASILISK_KEYSIZE,0,BASILISK_DEXDURATION)) != 0 ) free(retstr); } else if ( strcmp(dexp->handler,"request") == 0 ) { datalen = dex_rwrequest(0,dexp->packet,&dexreq); - if ( myinfo->IAMNOTARY != 0 && dexreq.func == 'A' && (coin= iguana_coinfind(dexreq.name)) != 0 ) + /*if ( myinfo->IAMNOTARY != 0 && dexreq.func == 'A' && (coin= iguana_coinfind(dexreq.name)) != 0 ) { if ( (retstr= dpow_importaddress(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) free(retstr); printf("process broadcast importaddress.(%s) [%s]\n",(char *)&dexp->packet[datalen],dexreq.name); - } + }*/ } } @@ -306,7 +405,7 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 //prio = 8; //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio)); //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio)); - } + } if ( reqsock >= 0 ) { if ( myinfo->IAMNOTARY == 0 && subsock < 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) @@ -416,14 +515,14 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 printf("%d: subscribe connect (%s)\n",myinfo->numdexipbits,str); } } -//#ifndef __APPLE__ +#ifndef __APPLE__ if ( (rand() % 100) < 40 ) { nanomsg_tcpname(0,str,ipaddr,REP_SOCK); nn_connect(myinfo->reqsock,str); printf("%d: req connect (%s)\n",myinfo->numdexipbits,str); } -//#endif +#endif } } if ( freeptr != 0 ) @@ -620,7 +719,7 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d retstr = dpow_importaddress(myinfo,coin,(char *)&dexp->packet[datalen]); if ( retstr == 0 ) { - *broadcastflagp = 1; + //*broadcastflagp = 1; retstr = dpow_validateaddress(myinfo,coin,(char *)&dexp->packet[datalen]); } else @@ -644,6 +743,31 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d retstr = jprint(retjson,1); } } + else if ( dexreq.func == 'M' ) + { + if ( (retjson= dpow_getmessage(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'Z' ) + { + if ( (retjson= dpow_psock(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( 0 && dexreq.func == 'a' ) + { + if ( (retjson= dpow_addmessage(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + *broadcastflagp = 1; + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } else if ( dexreq.func == 'N' ) { uint8_t pubkeys[64][33]; char str[128]; int32_t numnotaries; cJSON *array,*item; @@ -993,6 +1117,35 @@ char *_dex_validateaddress(struct supernet_info *myinfo,char *symbol,char *addre return(_dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")); } +char *_dex_getmessage(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'M'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + +char *_dex_sendmessage(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'a'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + +char *_dex_psock(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + if ( jsonstr == 0 ) + jsonstr = "{}"; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'Z'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + char *_dex_listunspentarg(struct supernet_info *myinfo,char *symbol,char *address,uint8_t arg) { struct dex_request dexreq; char *retstr; @@ -1085,7 +1238,7 @@ int32_t dex_crc32find(struct supernet_info *myinfo,uint32_t crc32) int32_t dex_packetcheck(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t size) { - int32_t firstz=-1; uint32_t crc32; + uint32_t crc32; //int32_t firstz=-1; if ( dexp->version0 == (DEX_VERSION & 0xff) && dexp->version1 == ((DEX_VERSION >> 8) & 0xff) ) { if ( dexp->datalen == (size - sizeof(*dexp)) ) @@ -1093,7 +1246,7 @@ int32_t dex_packetcheck(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp crc32 = calc_crc32(0,dexp->packet,dexp->datalen);//(void *)((long)dexp + sizeof(dexp->crc32)),(int32_t)(size - sizeof(dexp->crc32))); if ( dexp->crc32 == crc32 )//&& (firstz= dex_crc32find(myinfo,crc32)) >= 0 ) return(0); - else printf("dexp %08x != %08x || firstz.%d < 0\n",dexp->crc32,crc32,firstz); + //else printf("dexp %08x != %08x || firstz.%d < 0\n",dexp->crc32,crc32,firstz); } else printf("datalen.%d != (%d - %ld)\n",dexp->datalen,size,sizeof(*dexp)); } return(-1); @@ -1102,6 +1255,7 @@ int32_t dex_packetcheck(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp int32_t dex_subsock_poll(struct supernet_info *myinfo) { int32_t size= -1; struct dex_nanomsghdr *dexp; void *freeptr; + return(0); //fprintf(stderr,"subsock.%d\n",myinfo->subsock); if ( myinfo->subsock >= 0 && (size= signed_nn_recv(&freeptr,myinfo->ctx,myinfo->notaries,myinfo->numnotaries,myinfo->subsock,&dexp)) >= 0 ) { @@ -1970,7 +2124,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) if ( dex_packetcheck(myinfo,dexp,size) == 0 ) { //printf("FROM BUS.%08x -> pub\n",dexp->crc32); - signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); dex_packet(myinfo,dexp,size); } //printf("GOT DEX bus PACKET.%d\n",size); @@ -1992,8 +2146,9 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) free(retstr); if ( broadcastflag != 0 ) { - //printf("BROADCAST dexp request.[%d]\n",size); + printf("BROADCAST dexp request.[%d]\n",size); signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); } } else @@ -2007,10 +2162,10 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) if ( dex_packetcheck(myinfo,dexp,size) == 0 ) { signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); - signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); //printf("REP.%08x -> dexbus and pub, t.%d lag.%d\n",dexp->crc32,dexp->timestamp,(int32_t)(time(NULL)-dexp->timestamp)); dex_packet(myinfo,dexp,size); - } else printf("failed dexpacketcheck\n"); + } //else printf("failed dexpacketcheck\n"); } //printf("GOT DEX rep PACKET.%d\n",size); //if ( freeptr != 0 ) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 2b4dee270..69502f02f 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -22,6 +22,7 @@ #include #include #include "OS_portable.h" +#define MAX(a,b) ((a) > (b) ? (a) : (b)) struct mmpending_order { @@ -501,15 +502,16 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double jaddnum(vals,"ask",ask); vol = bidvol > askvol ? askvol : bidvol; jaddnum(vals,"maxvol",vol); - jaddnum(vals,"minvol",vol * 0.1); + jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1); sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1)); + printf("(%s)\n",postdata); if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata)) != 0 ) { //printf("(%s) -> (%s)\n",postdata,retstr); free(retstr); } - spread_ratio = (ask - bid) / (bid + ask); + spread_ratio = .5 * ((ask - bid) / (bid + ask)); for (i=0; i SMALLVAL ) @@ -519,7 +521,7 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double jaddnum(vals,"bid",PAXPRICES[i] * (1. - spread_ratio)); jaddnum(vals,"ask",PAXPRICES[i] * (1. + spread_ratio)); jaddnum(vals,"maxvol",vol * PAXPRICES[i]); - jaddnum(vals,"minvol",vol * 0.1 * PAXPRICES[i]); + jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i]))); sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1)); if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata)) != 0 ) @@ -528,6 +530,7 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double free(retstr); } } +break; } } else printf("unsupported ask only for DEX %s/%s\n",base,rel); } @@ -561,7 +564,7 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel) { static uint32_t counter; - cJSON *fiatjson; double start_DEXbase,start_DEXrel,USD_average=0.,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,usdprice=0.,CMC_average=0.,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; + cJSON *fiatjson; double bid,ask,start_DEXbase,start_DEXrel,USD_average=0.,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,usdprice=0.,CMC_average=0.,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; incr = maxexposure * ratioincr; buyvol = sellvol = 0.; start_DEXbase = dex_balance(base,baseaddr); @@ -636,8 +639,11 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double mmask = 0.; } marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure); - printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f)\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel); - marketmaker_spread("DEX",base,rel,avebid - profitmargin*aveprice,incr,aveask + profitmargin*aveprice,incr,profitmargin*aveprice*0.5); + printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice); + if ( (aveask - avebid)/aveprice > 4*profitmargin ) + bid = highbid * (1 - 4*profitmargin), ask = lowask * (1 + 4*profitmargin); + else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice; + marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5); if ( (pendingbids + buyvol) > (pendingasks + sellvol) ) { bidincr *= (double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)); @@ -655,8 +661,8 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double askincr = (int32_t)askincr + 0.777; } //printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr); - marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); - sleep(60); + //marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); + sleep(6000); } } } @@ -707,7 +713,7 @@ int main(int argc, const char * argv[]) marketmaker(minask,maxbid,baseaddr,reladdr,start_base,start_rel,profitmargin,maxexposure,incrratio,exchange,name,base,rel); } free_json(addrjson); - } + } else printf("ERROR parsing.(%s)\n",retstr); free(retstr); } free_json(retjson); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 89d25f734..682d3da13 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -21,13 +21,17 @@ #define iguana777_net_h #if defined(_WIN32) || defined(_WIN64) +#ifndef WIN32 #define WIN32 #endif +#endif #if (defined(_WIN32) || defined(__WIN32__)) && \ !defined(WIN32) && !defined(__SYMBIAN32__) +#ifndef WIN32 #define WIN32 #endif +#endif #ifdef WIN32 #define __MINGW @@ -59,12 +63,14 @@ #include "../crypto777/nanosrc/nn.h" #include "../crypto777/nanosrc/bus.h" #include "../crypto777/nanosrc/pubsub.h" +#include "../crypto777/nanosrc/pipeline.h" #include "../crypto777/nanosrc/reqrep.h" #include "../crypto777/nanosrc/tcp.h" #else #include "/usr/local/include/nanomsg/nn.h" #include "/usr/local/include/nanomsg/bus.h" #include "/usr/local/include/nanomsg/pubsub.h" +#include "/usr/local/include/nanomsg/pipeline.h" #include "/usr/local/include/nanomsg/reqrep.h" #include "/usr/local/include/nanomsg/tcp.h" #endif @@ -88,8 +94,17 @@ struct supernet_address char NXTADDR[32],BTC[64],BTCD[64]; }; +struct smartaddress +{ + bits256 privkey,pubkey; + uint8_t pubkey33[33],rmd160[20]; +}; + struct pending_trade { UT_hash_handle hh; double basevolume,relvolume,dir; char base[32],rel[32]; }; +#define PSOCK_IDLETIMEOUT 600 +struct psock { uint32_t lasttime; int32_t pullsock,pubsock; uint16_t pushport,subport; }; + #define JUMBLR_DEPOSITPREFIX "deposit " struct jumblr_item { @@ -111,7 +126,7 @@ struct message_info { int32_t msgcount; bits256 refhash,msghashes[64]; uint32_t struct supernet_info { struct supernet_address myaddr; - bits256 persistent_priv,privkey; + bits256 persistent_priv,privkey,jumblr_pubkey,jumblr_depositkey; uint8_t persistent_pubkey33[33]; char ipaddr[64],NXTAPIURL[512],secret[4096],password[4096],rpcsymbol[64],handle[1024],permanentfile[1024],jumblr_passphrase[1024]; char *decryptstr; @@ -149,7 +164,33 @@ struct supernet_info uint8_t logs[256],exps[510]; struct message_info msgids[8192]; double *svmfeatures; + uint16_t psockport,numpsocks; struct psock *PSOCKS; portable_mutex_t psockmutex; uint8_t notaries[64][33]; int32_t numnotaries,DEXEXPLORER; + FILE *swapsfp; + struct smartaddress smartaddrs[64]; int32_t numsmartaddrs,cancelrefresh; +}; + +struct basilisk_swapmessage +{ + bits256 srchash,desthash; + uint32_t crc32,msgbits,quoteid,datalen; + uint8_t *data; +}; + +struct basilisk_swap +{ + struct supernet_info *myinfoptr; struct iguana_info *bobcoin,*alicecoin; + void (*balancingtrade)(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob); + int32_t subsock,pushsock,connected; uint32_t lasttime; + FILE *fp; + bits256 persistent_privkey,persistent_pubkey; + struct basilisk_swapinfo I; + struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; + bits256 privkeys[INSTANTDEX_DECKSIZE]; + struct basilisk_swapmessage *messages; int32_t nummessages; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536]; + }; #include "../includes/iguana_funcs.h" diff --git a/iguana/iguana_bitmap.c b/iguana/iguana_bitmap.c index ec1ce5484..89effe210 100755 --- a/iguana/iguana_bitmap.c +++ b/iguana/iguana_bitmap.c @@ -1162,42 +1162,3 @@ void iguana_bitmap(char *space,int32_t max,char *name) } } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -STRING_AND_TWOINTS(mouse,change,name,x,y) -{ - printf("mouse (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"changed\"}")); -} - -STRING_ARG(mouse,leave,name) -{ - printf("mouse (%s) leave\n",name); - return(clonestr("{\"result\":\"left\"}")); -} - -STRING_AND_TWOINTS(mouse,click,name,x,y) -{ - printf("mouse (%s) x.%d y.%d click\n",name,x,y); - return(clonestr("{\"result\":\"click\"}")); -} - -STRING_AND_INT(keyboard,key,name,c) -{ - printf(" KEY.(%s) c.%d (%c)\n",name,c,c); - return(clonestr("{\"result\":\"key\"}")); -} - -STRING_AND_TWOINTS(mouse,image,name,x,y) -{ - printf("mouse CREATE (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"opened\"}")); -} - -STRING_ARG(mouse,close,name) -{ - printf("mouse CLOSE (%s)\n",name); - return(clonestr("{\"result\":\"closed\"}")); -} -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 87a8ce798..b5749f8f5 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -486,7 +486,7 @@ void iguana_chaininit(struct supernet_info *myinfo,struct iguana_chain *chain,in if ( strcmp(chain->symbol,"BTC") == 0 ) { chain->unitval = 0x1d; - chain->txfee = 10000; + chain->txfee = 50000; chain->havecltv = 1; } else chain->txfee = 10000; diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index e7febc655..8002aa331 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -86,6 +86,7 @@ cJSON *SuperNET_helpjson() cJSON *array=0,*json,*agents; json = cJSON_CreateObject(); agents = cJSON_CreateArray(); +#ifndef WIN32 #define IGUANA_ARGS json,array,agents #define IGUANA_HELP0(agent,name) array = helpjson(IGUANA_ARGS,#agent,#name,0) #define IGUANA_HELP_S(agent,name,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#str,"string"))) @@ -191,7 +192,11 @@ cJSON *SuperNET_helpjson() #include "../includes/iguana_apideclares.h" +#undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" +#endif + if ( array != 0 ) jadd(json,"API",array); jadd(json,"agents",agents); @@ -493,422 +498,6 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) return(OS_filestr(&filesize,"index7778.html")); } -cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) -{ - cJSON *array,*json = cJSON_CreateObject(); - jaddstr(json,"ipaddr",addr->ipaddr); - if ( addr->supernet != 0 ) - jaddstr(json,"ipaddr",addr->ipaddr); - jaddstr(json,"supernet","yes"); - jaddnum(json,"protover",addr->protover); - jaddnum(json,"relay",addr->relayflag); - jaddnum(json,"height",addr->height); - jaddnum(json,"rank",addr->rank); - jaddnum(json,"usock",addr->usock); - if ( addr->dead != 0 ) - jaddnum(json,"dead",addr->dead); - jaddnum(json,"ready",addr->ready); - jaddnum(json,"recvblocks",addr->recvblocks); - jaddnum(json,"recvtotal",addr->recvtotal); - jaddnum(json,"lastcontact",addr->lastcontact); - if ( addr->numpings > 0 ) - jaddnum(json,"aveping",addr->pingsum/addr->numpings); - array = cJSON_CreateObject(); - jaddnum(array,"version",addr->msgcounts.version); - jaddnum(array,"verack",addr->msgcounts.verack); - jaddnum(array,"getaddr",addr->msgcounts.getaddr); - jaddnum(array,"addr",addr->msgcounts.addr); - jaddnum(array,"inv",addr->msgcounts.inv); - jaddnum(array,"getdata",addr->msgcounts.getdata); - jaddnum(array,"notfound",addr->msgcounts.notfound); - jaddnum(array,"getblocks",addr->msgcounts.getblocks); - jaddnum(array,"getheaders",addr->msgcounts.getheaders); - jaddnum(array,"headers",addr->msgcounts.headers); - jaddnum(array,"tx",addr->msgcounts.tx); - jaddnum(array,"block",addr->msgcounts.block); - jaddnum(array,"mempool",addr->msgcounts.mempool); - jaddnum(array,"ping",addr->msgcounts.ping); - jaddnum(array,"pong",addr->msgcounts.pong); - jaddnum(array,"reject",addr->msgcounts.reject); - jaddnum(array,"filterload",addr->msgcounts.filterload); - jaddnum(array,"filteradd",addr->msgcounts.filteradd); - jaddnum(array,"filterclear",addr->msgcounts.filterclear); - jaddnum(array,"merkleblock",addr->msgcounts.merkleblock); - jaddnum(array,"alert",addr->msgcounts.alert); - jadd(json,"msgcounts",array); - return(json); -} - -cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) -{ - cJSON *retjson,*array; int32_t i; struct iguana_peer *addr; - if ( coin == 0 || coin->peers == 0 ) - return(0); - array = cJSON_CreateArray(); - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( addr->usock >= 0 && addr->ipbits != 0 && addr->ipaddr[0] != 0 ) - { - if ( addronly != 0 ) - jaddistr(array,addr->ipaddr); - else jaddi(array,iguana_peerjson(coin,addr)); - } - } - if ( addronly == 0 ) - { - retjson = cJSON_CreateObject(); - jadd(retjson,"peers",array); - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(retjson); - } - else return(array); -} - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -STRING_ARG(iguana,peers,activecoin) -{ - if ( coin != 0 ) - return(jprint(iguana_peersjson(coin,0),1)); - else return(clonestr("{\"error\":\"peers needs coin\"}")); -} - -STRING_ARG(iguana,getconnectioncount,activecoin) -{ - int32_t i,num = 0; char buf[512]; - if ( coin != 0 && coin->peers != 0 ) - { - for (i=0; ipeers->active)/sizeof(*coin->peers->active); i++) - if ( coin->peers->active[i].usock >= 0 ) - num++; - sprintf(buf,"{\"result\":\"%d\"}",num); - return(clonestr(buf)); - } else return(clonestr("{\"error\":\"getconnectioncount needs coin\"}")); -} - -ZERO_ARGS(bitcoinrpc,getdifficulty) -{ - char buf[512]; - if ( coin != 0 ) - { - sprintf(buf,"{\"result\":\"success\",\"proof-of-work\":\"%.8f\",\"search-interval\": 0}",PoW_from_compact(coin->blocks.hwmchain.RO.bits,coin->chain->unitval)); - return(clonestr(buf)); - } else return(clonestr("{\"error\":\"getdifficulty needs coin\"}")); -} - -STRING_ARG(iguana,addcoin,newcoin) -{ - char *symbol,*seedip; int32_t retval; - if ( (symbol= newcoin) == 0 && coin != 0 ) - symbol = coin->symbol; - if ( symbol != 0 ) - { - if ( (seedip= jstr(json,"seedipaddr")) != 0 ) - safecopy(myinfo->seedipaddr,seedip,sizeof(myinfo->seedipaddr)); - printf(">> addcoin.%s seedipaddr.%s\n",symbol,myinfo->seedipaddr); -#ifdef __PNACL__ -// if ( strcmp(symbol,"BTC") == 0 ) -// return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); -#endif - if ( (retval= iguana_launchcoin(myinfo,symbol,json,0)) > 0 ) - { - if ( myinfo->rpcsymbol[0] == 0 ) - safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); - return(clonestr("{\"result\":\"coin added\"}")); - } - else if ( retval == 0 ) - return(clonestr("{\"result\":\"coin already there\"}")); - else return(clonestr("{\"error\":\"error adding coin\"}")); - } else return(clonestr("{\"error\":\"addcoin needs newcoin\"}")); -} - -STRING_ARG(iguana,startcoin,activecoin) -{ - if ( coin != 0 ) - { - coin->active = 1; - return(clonestr("{\"result\":\"coin started\"}")); - } else return(clonestr("{\"error\":\"startcoin needs coin\"}")); -} - -STRING_ARG(iguana,stopcoin,activecoin) -{ - if ( activecoin[0] != 0 ) - coin = iguana_coinfind(activecoin); - if ( coin != 0 ) - { - coin->active = 0; - //iguana_coinpurge(coin); - return(clonestr("{\"result\":\"coin stopped\"}")); - } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); -} - -STRING_ARG(iguana,pausecoin,activecoin) -{ - if ( coin != 0 ) - { - coin->active = 0; - return(clonestr("{\"result\":\"coin paused\"}")); - } else return(clonestr("{\"error\":\"pausecoin needs coin\"}")); -} - -TWO_STRINGS(iguana,addnode,activecoin,ipaddr) -{ - struct iguana_peer *addr; int32_t i,n; - if ( coin == 0 ) - coin = iguana_coinfind(activecoin); - if ( coin != 0 && strcmp(coin->symbol,"RELAY") == 0 ) - basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),GENESIS_PUBKEY); - printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) - { - //iguana_possible_peer(coin,ipaddr); - if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) - { - addr->supernet = 1; - if ( addr->usock >= 0 ) - { - if ( (n= coin->peers->numranked) != 0 ) - { - for (i=0; ipeers->ranked[i] ) - break; - } - if ( i == n ) - { - if ( i == IGUANA_MAXPEERS ) - i--; - else coin->peers->numranked = n+1; - coin->peers->ranked[i] = addr; - addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; - addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; - printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); - } else printf("(%s) is already peer.%d\n",ipaddr,i); - } - return(clonestr("{\"result\":\"peer was already connected\"}")); - } - if ( addr->pending == 0 ) - { - addr->pending = (uint32_t)time(NULL); - iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"result\":\"addnode connection was already pending\"}")); - } else return(clonestr("{\"result\":\"addnode cant find peer slot\"}")); - } - else if ( coin == 0 ) - return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); - else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); -} - -TWO_STRINGS(iguana,persistent,activecoin,ipaddr) -{ - int32_t i; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers->active[i].persistent_peer = juint(json,"interval")+3; - return(clonestr("{\"result\":\"node marked as persistent\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"persistent needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,removenode,activecoin,ipaddr) -{ - int32_t i; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers->active[i].rank = 0; - coin->peers->active[i].dead = (uint32_t)time(NULL); - return(clonestr("{\"result\":\"node marked as dead\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"removenode needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,oneshot,activecoin,ipaddr) -{ - if ( coin != 0 && ipaddr != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) -{ - int32_t i; struct iguana_peer *addr; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( strcmp(addr->ipaddr,ipaddr) == 0 ) - return(jprint(iguana_peerjson(coin,addr),1)); - } - return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); - } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); -} - -STRING_AND_INT(iguana,maxpeers,activecoin,max) -{ - cJSON *retjson; int32_t i; struct iguana_peer *addr; - if ( coin != 0 && coin->peers != 0 ) - { - retjson = cJSON_CreateObject(); - if ( max > IGUANA_MAXPEERS ) - max = IGUANA_MAXPEERS; - if ( max > coin->MAXPEERS ) - { - for (i=max; iMAXPEERS; i++) - if ( (addr= coin->peers->ranked[i]) != 0 ) - addr->dead = 1; - } - coin->MAXPEERS = max; - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"maxpeers needs coin\"}")); -} - -char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message),char *name,char *message,char *password) -{ - char hexstr[1025]; cJSON *json; - if ( message != 0 && password != 0 && message[0] != 0 && password[0] != 0 ) - { - memset(hexstr,0,sizeof(hexstr)); - (*hmacfunc)(hexstr,password,password==0?0:(int32_t)strlen(password),message); - json = cJSON_CreateObject(); - jaddstr(json,"result","hmac calculated"); - jaddstr(json,"message",message); - jaddstr(json,name,hexstr); - return(jprint(json,1)); - } else return(clonestr("{\"error\":\"hmac needs message and passphrase\"}")); -} - -char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) -{ - char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; - if ( message != 0 && message[0] != 0 ) - { - memset(hexstr,0,sizeof(hexstr)); - (*hashfunc)(hexstr,databuf,(uint8_t *)message,(int32_t)strlen(message)); - json = cJSON_CreateObject(); - jaddstr(json,"result","hash calculated"); - jaddstr(json,"message",message); - jaddstr(json,name,hexstr); - return(jprint(json,1)); - } else return(clonestr("{\"error\":\"hash needs message\"}")); -} - -TWO_HASHES(hash,curve25519_pair,element,scalar) -{ - cJSON *retjson = cJSON_CreateObject(); - jaddbits256(retjson,"result",curve25519(element,scalar)); - return(jprint(retjson,1)); -} - -STRING_ARG(hash,NXT,passphrase) { return(hash_dispatch(calc_NXTaddr,"NXT",passphrase)); } -STRING_ARG(hash,curve25519,pubkey) { return(hash_dispatch(calc_curve25519_str,"curve25519",pubkey)); } -STRING_ARG(hash,crc32,message) { return(hash_dispatch(calc_crc32str,"crc32",message)); } -STRING_ARG(hash,base64_encode,message) { return(hash_dispatch(calc_base64_encodestr,"base64_encode",message)); } -STRING_ARG(hash,base64_decode,message) { return(hash_dispatch(calc_base64_decodestr,"base64_decode",message)); } -STRING_ARG(hash,rmd160_sha256,message) { return(hash_dispatch(rmd160ofsha256,"rmd160_sha256",message)); } -STRING_ARG(hash,sha256_sha256,message) { return(hash_dispatch(sha256_sha256,"sha256_sha256",message)); } -STRING_ARG(hash,hex,message) { return(hash_dispatch(calc_hexstr,"hex",message)); } -STRING_ARG(hash,unhex,message) { return(hash_dispatch(calc_unhexstr,"unhex",message)); } - -STRING_ARG(hash,sha224,message) { return(hash_dispatch(calc_sha224,"sha224",message)); } -STRING_ARG(hash,sha256,message) { return(hash_dispatch(vcalc_sha256,"sha256",message)); } -STRING_ARG(hash,sha384,message) { return(hash_dispatch(calc_sha384,"sha384",message)); } -STRING_ARG(hash,sha512,message) { return(hash_dispatch(calc_sha512,"sha512",message)); } -STRING_ARG(hash,rmd128,message) { return(hash_dispatch(calc_rmd128,"rmd128",message)); } -STRING_ARG(hash,rmd160,message) { return(hash_dispatch(calc_rmd160,"rmd160",message)); } -STRING_ARG(hash,rmd256,message) { return(hash_dispatch(calc_rmd256,"rmd256",message)); } -STRING_ARG(hash,rmd320,message) { return(hash_dispatch(calc_rmd320,"rmd320",message)); } -STRING_ARG(hash,sha1,message) { return(hash_dispatch(calc_sha1,"sha1",message)); } -STRING_ARG(hash,md2,message) { return(hash_dispatch(calc_md2str,"md2",message)); } -STRING_ARG(hash,md4,message) { return(hash_dispatch(calc_md4str,"md4",message)); } -STRING_ARG(hash,md5,message) { return(hash_dispatch(calc_md5str,"md5",message)); } -STRING_ARG(hash,tiger192_3,message) { return(hash_dispatch(calc_tiger,"tiger",message)); } -STRING_ARG(hash,whirlpool,message) { return(hash_dispatch(calc_whirlpool,"whirlpool",message)); } -TWO_STRINGS(hmac,sha224,message,passphrase) { return(hmac_dispatch(hmac_sha224_str,"sha224",message,passphrase)); } -TWO_STRINGS(hmac,sha256,message,passphrase) { return(hmac_dispatch(hmac_sha256_str,"sha256",message,passphrase)); } -TWO_STRINGS(hmac,sha384,message,passphrase) { return(hmac_dispatch(hmac_sha384_str,"sha384",message,passphrase)); } -TWO_STRINGS(hmac,sha512,message,passphrase) { return(hmac_dispatch(hmac_sha512_str,"sha512",message,passphrase)); } -TWO_STRINGS(hmac,rmd128,message,passphrase) { return(hmac_dispatch(hmac_rmd128_str,"rmd128",message,passphrase)); } -TWO_STRINGS(hmac,rmd160,message,passphrase) { return(hmac_dispatch(hmac_rmd160_str,"rmd160",message,passphrase)); } -TWO_STRINGS(hmac,rmd256,message,passphrase) { return(hmac_dispatch(hmac_rmd256_str,"rmd256",message,passphrase)); } -TWO_STRINGS(hmac,rmd320,message,passphrase) { return(hmac_dispatch(hmac_rmd320_str,"rmd320",message,passphrase)); } -TWO_STRINGS(hmac,sha1,message,passphrase) { return(hmac_dispatch(hmac_sha1_str,"sha1",message,passphrase)); } -TWO_STRINGS(hmac,md2,message,passphrase) { return(hmac_dispatch(hmac_md2_str,"md2",message,passphrase)); } -TWO_STRINGS(hmac,md4,message,passphrase) { return(hmac_dispatch(hmac_md4_str,"md4",message,passphrase)); } -TWO_STRINGS(hmac,md5,message,passphrase) { return(hmac_dispatch(hmac_md5_str,"md5",message,passphrase)); } -TWO_STRINGS(hmac,tiger192_3,message,passphrase) { return(hmac_dispatch(hmac_tiger_str,"tiger",message,passphrase)); } -TWO_STRINGS(hmac,whirlpool,message,passphrase) { return(hmac_dispatch(hmac_whirlpool_str,"whirlpool",message,passphrase)); } - -STRING_ARG(SuperNET,bitcoinrpc,setcoin) -{ - char buf[1024]; - if ( setcoin != 0 && setcoin[0] != 0 ) - { - strcpy(myinfo->rpcsymbol,setcoin); - touppercase(myinfo->rpcsymbol); - printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); - if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json,0) < 0 ) - return(clonestr("{\"error\":\"error creating coin\"}")); - else - { - sprintf(buf,"{\"result\":\"success\",\"setcoin\":\"%s\"}",setcoin); - return(clonestr(buf)); - } - } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); -} - -ZERO_ARGS(SuperNET,help) -{ - cJSON *helpjson,*retjson; - if ( (helpjson= SuperNET_helpjson()) != 0 ) - { - retjson = cJSON_CreateObject(); - jadd(retjson,"result",helpjson); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"cant get helpjson\"}")); -} - -TWO_STRINGS(SuperNET,html,agentform,htmlfile) -{ - char *htmlstr; cJSON *retjson; int32_t max = 4*1024*1024; - if ( htmlfile == 0 || htmlfile[0] == 0 ) - htmlfile = "forms.html"; - //if ( (fp= fopen(htmlfile,"w")) == 0 ) - // printf("error opening htmlfile.(%s)\n",htmlfile); - htmlstr = malloc(max); - htmlstr = SuperNET_htmlstr(htmlfile,htmlstr,max,agentform); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",htmlstr); - free(htmlstr); - //if ( fp != 0 ) - // fclose(fp); - return(jprint(retjson,1)); -} - -#undef IGUANA_ARGS -#include "../includes/iguana_apiundefs.h" - char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr) { char *coinstr; struct iguana_info *coin = 0; @@ -1025,8 +614,9 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define STRING_ARRAY_OBJ_STRING IGUANA_DISPATCH_SAOS #include "../includes/iguana_apideclares.h" -//#undef IGUANA_ARGS +#undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" char errstr[512]; sprintf(errstr,"{\"error\":\"unsupported call\",\"agent\":\"%s\",\"method\":\"%s\"}",agentstr,method); diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index c9532e3c0..d4378efd6 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -373,7 +373,6 @@ THREE_STRINGS(iguana,passthru,asset,function,hex) else return(clonestr("{\"error\":\"assetchain not active, start in bitcoind mode\"}")); } - TWO_STRINGS(dex,send,hex,handler) { uint8_t data[8192]; int32_t datalen; char *retstr; @@ -615,7 +614,7 @@ HASH_AND_STRING_AND_INT(dex,gettxout,txid,symbol,vout) TWO_STRINGS(dex,listunspent,symbol,address) { - if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->IAMLP != 0 ) + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->blocktrail_apikey[0] != 0 ) { char url[1024],*retstr,*coinaddr,*script; int32_t i,n,vout; cJSON *retjson,*data,*item,*item3,*data3; bits256 txid; uint64_t val; sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); @@ -670,7 +669,7 @@ TWO_STRINGS(dex,listunspent,symbol,address) TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip) { - if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->IAMLP != 0 ) + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->blocktrail_apikey[0] != 0 ) { char url[1024],*retstr,*retstr2; cJSON *retjson,*retjson2,*retjson3,*data,*data2; int32_t i,n; sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/transactions?api_key=%s",address,myinfo->blocktrail_apikey); @@ -747,6 +746,16 @@ TWO_STRINGS(dex,validateaddress,symbol,address) return(_dex_validateaddress(myinfo,symbol,address)); } +STRING_ARG(dex,getmessage,argstr) +{ + return(_dex_getmessage(myinfo,argstr)); +} + +STRING_ARG(dex,psock,argstr) +{ + return(_dex_psock(myinfo,argstr)); +} + STRING_ARG(dex,getnotaries,symbol) { return(_dex_getnotaries(myinfo,symbol)); @@ -860,7 +869,7 @@ TWO_STRINGS(dex,getbalance,symbol,address) } if ( symbol != 0 && address != 0 ) { - if ( strcmp(symbol,"BTC") == 0 && myinfo->IAMLP != 0 ) + if ( strcmp(symbol,"BTC") == 0 && myinfo->blocktrail_apikey[0] != 0 ) { sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s?api_key=%s",address,myinfo->blocktrail_apikey); if ( (retstr= issue_curl(url)) != 0 ) diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 86f22cb3c..196c3a313 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -175,7 +175,7 @@ int32_t iguana_RTbestunspent(struct supernet_info *myinfo,struct iguana_info *co } if ( iguana_RTunspent_check(myinfo,coin,unspents[i]) != 0 ) { - printf("(%d u%d) %.8f already used\n",unspents[i].hdrsi,unspents[i].unspentind,dstr(atx_value)); + //printf("(%d u%d) %.8f already used\n",unspents[i].hdrsi,unspents[i].unspentind,dstr(atx_value)); continue; } if ( maxmode == 0 ) @@ -274,7 +274,7 @@ char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int memset(&msgtx,0,sizeof(msgtx)); if ( V == 0 ) V = calloc(numinputs,sizeof(*V)), flagV = 1; - //printf("SIGN.(%s) priv.(%s) %llx %llx\n",jprint(vins,0),jprint(privkeys,0),(long long)V->signers[0].privkey.txid,(long long)V->signers[1].privkey.txid); + //printf("SIGN.(%s) priv.(%s) %llx %llx V.%p\n",jprint(vins,0),jprint(privkeys,0),(long long)V->signers[0].privkey.txid,(long long)V->signers[1].privkey.txid,V); if ( V != 0 ) { if ( iguana_signrawtransaction(myinfo,coin,height,&msgtx,&signedtx,signedtxidp,V,numinputs,rawtx,vins,privkeys) > 0 ) @@ -1685,4 +1685,99 @@ THREE_INTS(iguana,splitfunds,satoshis,duplicates,sendflag) return(jprint(retjson,1)); } +P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) +{ + struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; + char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; + bits256 signedtxid; char *signedtx; + struct iguana_msgtx msgtx; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( (active= iguana_coinfind(activecoin)) == 0 ) + return(clonestr("{\"error\":\"activecoin isnt active\"}")); + if ( M > N || N > 3 ) + return(clonestr("{\"error\":\"illegal M or N\"}")); + memset(&V,0,sizeof(V)); + txobj = bitcoin_txcreate(active->symbol,active->chain->isPoS,0,coin->chain->normal_txversion,0); + if ( destaddress[0] != 0 && destamount > 0. ) + bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); + if ( destaddress2[0] != 0 && destamount2 > 0. ) + bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); + if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) + return(retstr); + if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) + return(retstr); + if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) + return(retstr); + V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; + V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); + spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); + if ( pubA[0] != 0 ) + { + decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); + pubkeyptrs[0] = pubkeys[0]; + } + if ( pubB[0] != 0 ) + { + decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); + pubkeyptrs[1] = pubkeys[1]; + } + if ( pubC[0] != 0 ) + { + decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); + pubkeyptrs[2] = pubkeys[2]; + } + bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N,0,0); + bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); + retjson = cJSON_CreateObject(); + if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) + { + jaddstr(retjson,"result","msigtx"); + if ( signedtx != 0 ) + jaddstr(retjson,"signedtx",signedtx), free(signedtx); + jaddbits256(retjson,"txid",signedtxid); + } else jaddstr(retjson,"error","couldnt sign tx"); + jaddstr(retjson,"msigaddr",msigaddr); + return(jprint(retjson,1)); +} + +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) +{ + char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; + retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); + if ( sighash == 0 || sighash[0] == 0 ) + sighash = "ALL"; + if ( strcmp(sighash,"ALL") != 0 ) + jaddstr(retjson,"error","only sighash all (ALL) supported for now"); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + V = calloc(numinputs,sizeof(*V)); + memset(&msgtx,0,sizeof(msgtx)); + if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) + { + if ( signedtx != 0 ) + { + jaddstr(retjson,"result",signedtx); + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); + free(signedtx); + } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); + } + else if ( complete == -2 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); + else if ( complete == -1 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); + free(V); + //for (i=0; isymbol); + if ( coin != 0 ) + jaddstr(json,"coin",coin->symbol); if ( userpass != 0 ) jaddstr(json,"userpass",userpass); if ( coin != 0 && coin->FULLNODE >= 0 && coin->chain->userpass[0] != 0 ) diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c index 2b8d9f21e..57e8181d1 100755 --- a/iguana/iguana_scripts.c +++ b/iguana/iguana_scripts.c @@ -487,7 +487,7 @@ char *iguana_scriptaddress(struct iguana_info *coin,char *coinaddr,uint8_t *scri int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) { - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t *p2shscript; + int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; *userdatap = 0; *userdatalenp = *pubkeysizep = *sigsizep = 0; @@ -559,7 +559,7 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); vp->type = IGUANA_SCRIPT_76A988AC; }*/ - vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); return(vp->spendlen); } diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 3ef8338c6..43afba477 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -1013,13 +1013,13 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign { flag++; numsigs++; - int32_t z; + /*int32_t z; for (z=0; zsigners[j].pubkey[z]); - printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d\n",vini,j,numsigs,vp->M); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d\n",vini,j,numsigs,vp->M);*/ } } if ( numsigs >= vp->M ) @@ -1344,71 +1344,9 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc return(0); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - - -P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) -{ - struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; - char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; - bits256 signedtxid; char *signedtx; - struct iguana_msgtx msgtx; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - if ( (active= iguana_coinfind(activecoin)) == 0 ) - return(clonestr("{\"error\":\"activecoin isnt active\"}")); - if ( M > N || N > 3 ) - return(clonestr("{\"error\":\"illegal M or N\"}")); - memset(&V,0,sizeof(V)); - txobj = bitcoin_txcreate(active->symbol,active->chain->isPoS,0,coin->chain->normal_txversion,0); - if ( destaddress[0] != 0 && destamount > 0. ) - bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); - if ( destaddress2[0] != 0 && destamount2 > 0. ) - bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); - if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) - return(retstr); - if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) - return(retstr); - if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) - return(retstr); - V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; - V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); - spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); - if ( pubA[0] != 0 ) - { - decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); - pubkeyptrs[0] = pubkeys[0]; - } - if ( pubB[0] != 0 ) - { - decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); - pubkeyptrs[1] = pubkeys[1]; - } - if ( pubC[0] != 0 ) - { - decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); - pubkeyptrs[2] = pubkeys[2]; - } - bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N,0,0); - bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); - retjson = cJSON_CreateObject(); - if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) - { - jaddstr(retjson,"result","msigtx"); - if ( signedtx != 0 ) - jaddstr(retjson,"signedtx",signedtx), free(signedtx); - jaddbits256(retjson,"txid",signedtxid); - } else jaddstr(retjson,"error","couldnt sign tx"); - jaddstr(retjson,"msigaddr",msigaddr); - return(jprint(retjson,1)); -} - int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) { - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 65536; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 65536; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) @@ -1420,33 +1358,17 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf extraspace = malloc(extralen); memset(msgtx,0,sizeof(*msgtx)); decode_hex(serialized,len,rawtx); + //printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); if ( (txobj= bitcoin_hex2json(coin,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 ) { - if ( (0) && vins != 0 ) - printf("txobj.(%s)\n",jprint(txobj,0)); - if ( jobj(txobj,"error") != 0 ) - { - printf("txobj.(%s)\n",jprint(txobj,0)); - } - if ( (0) && (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 ) // no guarantee of identical regen - { - if ( strcmp(rawtx,checkstr) != 0 ) - { - printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr); - //free_json(txobj); - //free(checkstr); - //free(serialized), free(serialized2), free(serialized3), free(serialized4); - //free(extraspace); - //return(-2); - } - free(checkstr); - } + //printf("back from bitcoin_hex2json\n"); } else fprintf(stderr,"no txobj from bitcoin_hex2json\n"); if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) { memset(msgtx,0,sizeof(*msgtx)); if ( iguana_rwmsgtx(coin,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,65536,vins,V->suppress_pubkeys) > 0 && numinputs == msgtx->tx_in ) { + //printf("back rwmsgtx vins.%p\n",msgtx->vins); memset(pubkeys,0,sizeof(pubkeys)); memset(privkeys,0,sizeof(privkeys)); if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) @@ -1463,6 +1385,7 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf iguana_ensure_privkey(myinfo,coin,privkey); } } + //printf("after privkeys tx_in.%d\n",msgtx->tx_in); for (i=0; itx_in; i++) { if ( msgtx->vins[i].p2shlen != 0 ) @@ -1473,18 +1396,13 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf sigsize = 0; flag = (msgtx->vins[i].vinscript[0] == 0); type = bitcoin_scriptget(coin,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0); - if ( flag != 0 && pubkeysize == 33 ) // jl777: need to generalize this - { - for (k=0; kvins[i].scriptlen); if ( msgtx->vins[i].redeemscript != 0 ) { //for (j=0; jvins[i].p2shlen; j++) // printf("%02x",msgtx->vins[i].redeemscript[j]); bitcoin_address(coinaddr,coin->chain->p2shtype,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen); - type = iguana_calcrmd160(coin,0,&mvin,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen,zero,0,01); + type = iguana_calcrmd160(coin,0,&mvin,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen,zero,0,0); for (j=0; jsuppress_pubkeys == 0 ) @@ -1517,7 +1435,7 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf } } } - printf("type.%d p2sh.[%d] -> %s M.%d N.%d\n",type,i,mvin.coinaddr,mvin.M,mvin.N); + //printf("type.%d p2sh.[%d] -> %s M.%d N.%d\n",type,i,mvin.coinaddr,mvin.M,mvin.N); } } if ( i < V->N ) @@ -1555,43 +1473,4 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(complete); } -STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) -{ - char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; - retjson = cJSON_CreateObject(); - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); - if ( sighash == 0 || sighash[0] == 0 ) - sighash = "ALL"; - if ( strcmp(sighash,"ALL") != 0 ) - jaddstr(retjson,"error","only sighash all (ALL) supported for now"); - if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) - { - V = calloc(numinputs,sizeof(*V)); - memset(&msgtx,0,sizeof(msgtx)); - if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) - { - if ( signedtx != 0 ) - { - jaddstr(retjson,"result",signedtx); - jadd(retjson,"complete",complete!=0?jtrue():jfalse()); - free(signedtx); - } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); - } - else if ( complete == -2 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); - else if ( complete == -1 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); - free(V); - //for (i=0; i= 0 ) { - printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,txid),vout); + //printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,txid),vout); coin->markedunspents[firstslot] = txid; coin->markedunspents[firstslot].ushorts[15] = vout; - if ( coin->utxofp == 0 ) + if ( (0) && coin->utxofp == 0 ) { sprintf(fname,"%s/%s/utxo.dat",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); if ( (coin->utxofp= fopen(fname,"rb+")) == 0 ) @@ -939,6 +939,7 @@ void iguana_unspents_mark(struct supernet_info *myinfo,struct iguana_info *coin, void iguana_unspents_markinit(struct supernet_info *myinfo,struct iguana_info *coin) { char *filestr,fname[1024]; FILE *fp; long filesize; bits256 filetxid; cJSON *array,*item; int32_t i,filevout,n,firstslot; +return; sprintf(fname,"%s/%s/utxo.dat",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); if ( (fp= fopen(fname,"rb")) != 0 ) { @@ -948,7 +949,7 @@ void iguana_unspents_markinit(struct supernet_info *myinfo,struct iguana_info *c { if ( firstslot >= 0 ) { - char str[65]; printf("%s slot.[%d] <- %s/v%d\n",fname,firstslot,bits256_str(str,filetxid),filevout); + //char str[65]; printf("%s slot.[%d] <- %s/v%d\n",fname,firstslot,bits256_str(str,filetxid),filevout); coin->markedunspents[firstslot] = filetxid; coin->markedunspents[firstslot].ushorts[15] = filevout; } @@ -974,7 +975,7 @@ void iguana_unspents_markinit(struct supernet_info *myinfo,struct iguana_info *c { if ( firstslot >= 0 ) { - char str[65]; printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,filetxid),filevout); + //char str[65]; printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,filetxid),filevout); coin->markedunspents[firstslot] = filetxid; coin->markedunspents[firstslot].ushorts[15] = filevout; } diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 65f5c0d56..90303ae80 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -1367,6 +1367,9 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) jumblr_importprivkey(myinfo,coin,wifstr); } } + if ( bits256_nonz(myinfo->persistent_priv) != 0 ) + smartaddress_add(myinfo,myinfo->persistent_priv,"",""); + //basilisk_unspents_update(myinfo,coin); return(retstr); } diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index 2feabf1cd..f3abf52d2 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -395,7 +395,7 @@ cJSON *kmd_listaddress(struct supernet_info *myinfo,struct iguana_info *coin,cha struct kmd_addresshh *addr; struct kmd_transactionhh *ptr=0,*spent,*prev=0; uint8_t type_rmd160[21]; int32_t i; char *retstr; cJSON *retjson; if ( array == 0 ) array = cJSON_CreateArray(); - printf("%s listaddress.(%s)\n",coin->symbol,coinaddr); + //printf("%s listaddress.(%s)\n",coin->symbol,coinaddr); if ( (retstr= bitcoinrpc_validateaddress(myinfo,coin,0,0,coinaddr)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -478,7 +478,7 @@ cJSON *kmd_listaddress(struct supernet_info *myinfo,struct iguana_info *coin,cha } ptr = prev; } - } else printf("no valid entry for (%s) %p %p\n",coinaddr,addr,ptr); + } //else printf("no valid entry for (%s) %p %p\n",coinaddr,addr,ptr); return(array); } @@ -641,7 +641,7 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) while ( loadheight < height-lag ) { flag = 0; - //if ( (loadheight % 10000) == 0 ) + if ( (loadheight % 10000) == 0 ) printf("loading %s ht.%d vs height.%d - lag.%d kmdheight.%d\n",coin->symbol,loadheight,height,lag,coin->kmd_height);//,jprint(kmd_getbalance(coin,"*"),1)); if ( (blockjson= kmd_blockjson(&h,coin->symbol,coin->chain->serverport,coin->chain->userpass,0,loadheight)) != 0 ) { diff --git a/iguana/main.c b/iguana/main.c index 986764423..fcde8209e 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -24,6 +24,7 @@ #include "../pnacl_main.h" #include "iguana777.h" + struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char *retjsonstr; char remoteaddr[64]; uint16_t port; char jsonstr[]; }; uint16_t SuperNET_API2num(char *agent,char *method) @@ -683,6 +684,7 @@ void iguana_ensuredirs() sprintf(dirname,"%s",GLOBAL_GENESISDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_CONFSDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/TRANSACTIONS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/purgeable",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_TMPDIR), OS_ensure_directory(dirname); @@ -747,16 +749,23 @@ void iguana_urlinit(struct supernet_info *myinfo,int32_t ismainnet,int32_t usess void jumblr_loop(void *ptr) { - struct iguana_info *coin; uint32_t t; struct supernet_info *myinfo = ptr; int32_t mult = 10; + struct iguana_info *coin; char BTCaddr[64],KMDaddr[64]; bits256 privkey; uint32_t t; struct supernet_info *myinfo = ptr; int32_t mult = 10; printf("JUMBLR loop\n"); while ( 1 ) { - t = (uint32_t)time(NULL); - if ( (coin= iguana_coinfind("KMD")) != 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 && (t % (120 * mult)) < 60 ) + if ( (coin= iguana_coinfind("KMD")) != 0 && coin->FULLNODE < 0 ) { - jumblr_iteration(myinfo,coin,(t % (360 * mult)) / (120 * mult),t % (120 * mult)); + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + // if BTC has arrived in deposit address, invoke DEX -> KMD + // if BTC has arrived in destination address, invoke DEX -> BTC + jumblr_DEXcheck(myinfo,coin,BTCaddr,KMDaddr,privkey); + t = (uint32_t)time(NULL); + if ( myinfo->jumblr_passphrase[0] != 0 && (t % (120 * mult)) < 60 ) + { + jumblr_iteration(myinfo,coin,(t % (360 * mult)) / (120 * mult),t % (120 * mult)); + } + //printf("t.%u %p.%d %s\n",t,coin,coin!=0?coin->FULLNODE:0,myinfo->jumblr_passphrase); } - //printf("t.%u %p.%d %s\n",t,coin,coin!=0?coin->FULLNODE:0,myinfo->jumblr_passphrase); sleep(55); } } @@ -778,6 +787,7 @@ void iguana_launchdaemons(struct supernet_info *myinfo) printf("launch mainloop\n"); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo); + OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo); mainloop(myinfo); } @@ -1017,6 +1027,434 @@ void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +STRING_ARG(iguana,initfastfind,activecoin) +{ + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + iguana_fastfindcreate(coin); + return(clonestr("{\"result\":\"fast find initialized\"}")); + } else return(clonestr("{\"error\":\"no coin to initialize\"}")); +} + +TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,minconfd) +{ + int32_t lastheight,minconf,maxconf=1<<30; cJSON *array,*retjson = cJSON_CreateObject(); + if ( activecoin != 0 && activecoin[0] != 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 ) + { + if ( (minconf= minconfd) <= 0 ) + minconf = 1; + lastheight = lastheightd; + jaddstr(retjson,"address",address); + if ( bitcoin_validaddress(coin,address) < 0 ) + { + jaddstr(retjson,"error","illegal address"); + return(jprint(retjson,1)); + } + jadd64bits(retjson,"RTbalance",iguana_RTbalance(coin,address)); + array = cJSON_CreateArray(); + jaddistr(array,address); + jadd(retjson,"unspents",iguana_RTlistunspent(myinfo,coin,array,minconf,maxconf,remoteaddr,1)); + free_json(array); + if ( lastheight > 0 ) + jaddnum(retjson,"RTheight",coin->RTheight); + } + return(jprint(retjson,1)); +} + +STRING_ARG(iguana,validate,activecoin) +{ + int32_t i,total,validated; struct iguana_bundle *bp; cJSON *retjson; + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + for (i=total=validated=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 ) + { + validated += iguana_bundlevalidate(myinfo,coin,bp,1); + total += bp->n; + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","validation run"); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"validated",validated); + jaddnum(retjson,"total",total); + jaddnum(retjson,"bundles",coin->bundlescount); + jaddnum(retjson,"accuracy",(double)validated/total); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no active coin\"}")); +} + +STRING_ARG(iguana,removecoin,activecoin) +{ + struct iguana_bundle *bp; int32_t i,height; char fname[1024]; + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + coin->active = 0; + coin->started = 0; + if ( (0) ) + { + for (i=0; isymbol,i), OS_removefile(fname,0); + sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); + } + sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); + sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); + for (i=0; ibundlescount; i++) + { + sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); + if ( (bp= coin->bundles[i]) != 0 ) + { + iguana_bundlepurgefiles(coin,bp); + iguana_bundleremove(coin,bp->hdrsi,1); + } + } + for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) + { + sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); + OS_remove_directory(fname); + } + sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); + } + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"no active coin\"}")); +} + +INT_ARG(bitcoinrpc,getblockhash,height) +{ + cJSON *retjson; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getblockhash(myinfo,coin->symbol,height)); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"result",iguana_blockhash(coin,height)); + return(jprint(retjson,1)); +} + +HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) +{ + char *blockstr,*datastr; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson; bits256 txid; int32_t len; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getblock(myinfo,coin->symbol,blockhash)); + retjson = cJSON_CreateObject(); + memset(&msg,0,sizeof(msg)); + if ( remoteonly == 0 && (block= iguana_blockfind("getblockRPC",coin,blockhash)) != 0 ) + { + if ( verbose != 0 ) + return(jprint(iguana_blockjson(myinfo,coin,block,1),1)); + else + { + if ( (len= iguana_peerblockrequest(myinfo,coin,coin->blockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) + { + datastr = malloc(len*2 + 1); + init_hexbytes_noT(datastr,coin->blockspace,len); + jaddstr(retjson,"result",datastr); + free(datastr); + return(jprint(retjson,1)); + } + jaddstr(retjson,"error","error getting rawblock"); + } + } + else if ( coin->APIblockstr != 0 ) + jaddstr(retjson,"error","already have pending request"); + else + { + memset(txid.bytes,0,sizeof(txid)); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) + { + jaddstr(retjson,"result",blockstr); + free(blockstr); + } else jaddstr(retjson,"error","cant find blockhash"); + } + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,getbestblockhash) +{ + cJSON *retjson; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getbestblockhash(myinfo,coin->symbol)); + retjson = cJSON_CreateObject(); + char str[65]; jaddstr(retjson,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,getblockcount) +{ + cJSON *retjson = cJSON_CreateObject(); + //printf("result %d\n",coin->blocks.hwmchain.height); + jaddnum(retjson,"result",coin->blocks.hwmchain.height); + return(jprint(retjson,1)); +} + +STRING_AND_INT(iguana,bundleaddresses,activecoin,height) +{ + struct iguana_info *ptr; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + return(iguana_bundleaddrs(ptr,height / coin->chain->bundlesize)); + else return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_AND_INT(iguana,PoSweights,activecoin,height) +{ + struct iguana_info *ptr; int32_t num,nonz,errs,bundleheight; struct iguana_pkhash *refP; uint64_t *weights,supply; cJSON *retjson; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + { + //for (bundleheight=coin->chain->bundlesize; bundleheightchain->bundlesize) + { + bundleheight = (height / ptr->chain->bundlesize) * ptr->chain->bundlesize; + if ( (weights= iguana_PoS_weights(myinfo,ptr,&refP,&supply,&num,&nonz,&errs,bundleheight)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",errs == 0 ? "success" : "error"); + jaddnum(retjson,"bundleheight",bundleheight); + jaddnum(retjson,"numaddresses",num); + jaddnum(retjson,"nonzero",nonz); + jaddnum(retjson,"errors",errs); + jaddnum(retjson,"supply",dstr(supply)); + free(weights); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_PoS_weights returned null\"}")); + } + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_ARG(iguana,stakers,activecoin) +{ + struct iguana_info *ptr; int32_t i,datalen,pkind,hdrsi; bits256 hash2; struct iguana_bundle *bp; cJSON *retjson,*array; struct iguana_pkhash *refP; struct iguana_ramchaindata *rdata; char coinaddr[64]; uint8_t refrmd160[20]; bits256 *sortbuf; + if ( (ptr= iguana_coinfind(activecoin)) != 0 && ptr->RTheight > ptr->chain->bundlesize ) + { + hdrsi = (ptr->RTheight / ptr->chain->bundlesize) - 1; + if ( (bp= ptr->bundles[hdrsi]) != 0 && bp->weights != 0 && (rdata= bp->ramchain.H.data) != 0 && bp->weights != 0 ) + { + sortbuf = calloc(bp->numweights,2 * sizeof(*sortbuf)); + for (i=datalen=0; inumweights; i++) + datalen += iguana_rwnum(1,&((uint8_t *)sortbuf)[datalen],sizeof(bp->weights[i]),(void *)&bp->weights[i]); + hash2 = bits256_doublesha256(0,(uint8_t *)sortbuf,datalen); + refP = RAMCHAIN_PTR(rdata,Poffset); + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + memset(refrmd160,0,sizeof(refrmd160)); + for (i=0; ichain->bundlesize; i++) + { + if ( (pkind= iguana_staker_sort(ptr,&hash2,refrmd160,refP,bp->weights,bp->numweights,sortbuf)) > 0 ) + { + bitcoin_address(coinaddr,ptr->chain->pubtype,refP[pkind].rmd160,sizeof(refP[pkind].rmd160)); + jaddistr(array,coinaddr); + } else jaddistr(array,"error"); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"stakers",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_stakers needs PoSweights and weights\"}")); + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_AND_INT(iguana,bundlehashes,activecoin,height) +{ + struct iguana_info *ptr; struct iguana_bundle *bp; int32_t i,hdrsi; cJSON *retjson,*array; struct iguana_ramchaindata *rdata; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + { + hdrsi = height / coin->chain->bundlesize; + if ( hdrsi < coin->bundlescount && hdrsi >= 0 && (bp= coin->bundles[hdrsi]) != 0 ) + { + if ( (rdata= bp->ramchain.H.data) != 0 ) + { + array = cJSON_CreateArray(); + for (i=0; ilhashes[i].txid); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"sha256",rdata->sha256); + jadd(retjson,"bundlehashes",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"ramchain not there\"}")); + } else return(clonestr("{\"error\":\"height is too big\"}")); + } else return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +// low priority RPC + +HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag) +{ + /*"transactions" : [ + { + "account" : "doc test", + "address" : "mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6", + "category" : "receive", + "amount" : 0.10000000, + "vout" : 0, + "confirmations" : 76478, + "blockhash" : "000000000017c84015f254498c62a7c884a51ccd75d4dd6dbdcb6434aa3bd44d", + "blockindex" : 1, + "blocktime" : 1399294967, + "txid" : "85a98fdf1529f7d5156483ad020a51b7f3340e47448cf932f470b72ff01a6821", + "walletconflicts" : [ + ], + "time" : 1399294967, + "timereceived" : 1418924714 + },*/ + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,gettxoutsetinfo) +{ + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,listaddressgroupings) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"error\":\"low priority RPC not implemented\"}")); +} + +SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +ZERO_ARGS(pax,start) +{ + void PAX_init(); + PAX_init(); + return(clonestr("{\"result\":\"PAX_init called\"}")); +} + +STRING_AND_TWOINTS(mouse,change,name,x,y) +{ + printf("mouse (%s) x.%d y.%d\n",name,x,y); + return(clonestr("{\"result\":\"changed\"}")); +} + +STRING_ARG(mouse,leave,name) +{ + printf("mouse (%s) leave\n",name); + return(clonestr("{\"result\":\"left\"}")); +} + +STRING_AND_TWOINTS(mouse,click,name,x,y) +{ + printf("mouse (%s) x.%d y.%d click\n",name,x,y); + return(clonestr("{\"result\":\"click\"}")); +} + +STRING_AND_INT(keyboard,key,name,c) +{ + printf(" KEY.(%s) c.%d (%c)\n",name,c,c); + return(clonestr("{\"result\":\"key\"}")); +} + +STRING_AND_TWOINTS(mouse,image,name,x,y) +{ + printf("mouse CREATE (%s) x.%d y.%d\n",name,x,y); + return(clonestr("{\"result\":\"opened\"}")); +} + +STRING_ARG(mouse,close,name) +{ + printf("mouse CLOSE (%s)\n",name); + return(clonestr("{\"result\":\"closed\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr) +{ + struct iguana_info *btcd; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) + { + txid = bits256_doublesha256(0,data,datalen); + retstr = gecko_sendrawtransaction(myinfo,symbol,data,datalen,txid,vals,hexstr); + } else retstr = clonestr("{\"error\":\"no tx submitted\"}"); + if ( allocptr != 0 ) + free(allocptr); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"couldnt create geckotx\"}"); + return(retstr); + } return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr) +{ + struct iguana_info *btcd,*virt; char *symbol; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + basilisk_wait(myinfo,virt); + return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0)); + } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); + } + return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); +} + +TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) +{ + char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + wallethash = wallet2priv = GENESIS_PRIVKEY; + if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) + wallethash = bits256_conv(pass); + if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) + wallet2priv = bits256_conv(fname2); + if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) + { + //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); + //obj = jduplicate(jobj(retjson,"payload")); + //jdelete(retjson,"payload"); + //jadd(retjson,"result",obj); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); +} + +THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) +{ + char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + argjson = jduplicate(json); + //printf("argjson.(%s)\n",jprint(argjson,0)); + jdelete(argjson,"agent"); + jdelete(argjson,"method"); + jdelete(argjson,"password"); + jdelete(argjson,"permanentfile"); + jdelete(argjson,"timestamp"); + jdelete(argjson,"tag"); + if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"filename",destfname); + } else jaddstr(retjson,"error","couldnt encrypt json file"); + free_json(argjson); + return(jprint(retjson,1)); +} + + STRING_ARG(SuperNET,addr2rmd160,address) { uint8_t addrtype,rmd160[20]; char rmdstr[41]; cJSON *retjson; @@ -1604,7 +2042,7 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) free(str); myinfo->expiration = (uint32_t)(time(NULL) + 3600); return(SuperNET_activehandle(IGUANA_CALLARGS)); - } else return(clonestr("{\"error\":\"need passphrase\"}")); + } else return(clonestr("{\"error\":\"need passphrase or wallet doesnt exist\"}")); return(SuperNET_activehandle(IGUANA_CALLARGS)); } @@ -1616,7 +2054,7 @@ void komodo_ICO_batch(cJSON *array,int32_t batchid) if ( (n= cJSON_GetArraySize(array)) > 0 ) { totalKMD = totalREVS = 0; - for (iter=3; iter<4; iter++) + for (iter=0; iter<1; iter++) for (i=0; irpcport = IGUANA_RPCPORT; myinfo->dpowsock = myinfo->dexsock = myinfo->pubsock = myinfo->subsock = myinfo->reqsock = myinfo->repsock = -1; dex_init(myinfo); + myinfo->psockport = 30000; if ( arg != 0 ) { if ( strcmp((char *)arg,"OStests") == 0 ) @@ -1768,6 +2207,7 @@ void iguana_main(void *arg) portable_mutex_init(&myinfo->pending_mutex); portable_mutex_init(&myinfo->dpowmutex); portable_mutex_init(&myinfo->notarymutex); + portable_mutex_init(&myinfo->psockmutex); #if LIQUIDITY_PROVIDER myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("nxtae"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bitcoin"),0); diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 7f4878d62..267f17ffd 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -13,316 +13,424 @@ * * ******************************************************************************/ +// deprecated #include "iguana777.h" + #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -STRING_ARG(iguana,initfastfind,activecoin) + +STRING_ARG(iguana,peers,activecoin) +{ + if ( coin != 0 ) + return(jprint(iguana_peersjson(coin,0),1)); + else return(clonestr("{\"error\":\"peers needs coin\"}")); +} + +STRING_ARG(iguana,getconnectioncount,activecoin) { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + int32_t i,num = 0; char buf[512]; + if ( coin != 0 && coin->peers != 0 ) { - iguana_fastfindcreate(coin); - return(clonestr("{\"result\":\"fast find initialized\"}")); - } else return(clonestr("{\"error\":\"no coin to initialize\"}")); + for (i=0; ipeers->active)/sizeof(*coin->peers->active); i++) + if ( coin->peers->active[i].usock >= 0 ) + num++; + sprintf(buf,"{\"result\":\"%d\"}",num); + return(clonestr(buf)); + } else return(clonestr("{\"error\":\"getconnectioncount needs coin\"}")); } -TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,minconfd) +ZERO_ARGS(bitcoinrpc,getdifficulty) { - int32_t lastheight,minconf,maxconf=1<<30; cJSON *array,*retjson = cJSON_CreateObject(); - if ( activecoin != 0 && activecoin[0] != 0 ) - coin = iguana_coinfind(activecoin); + char buf[512]; if ( coin != 0 ) { - if ( (minconf= minconfd) <= 0 ) - minconf = 1; - lastheight = lastheightd; - jaddstr(retjson,"address",address); - if ( bitcoin_validaddress(coin,address) < 0 ) + sprintf(buf,"{\"result\":\"success\",\"proof-of-work\":\"%.8f\",\"search-interval\": 0}",PoW_from_compact(coin->blocks.hwmchain.RO.bits,coin->chain->unitval)); + return(clonestr(buf)); + } else return(clonestr("{\"error\":\"getdifficulty needs coin\"}")); +} + +STRING_ARG(iguana,addcoin,newcoin) +{ + char *symbol,*seedip; int32_t retval; + if ( (symbol= newcoin) == 0 && coin != 0 ) + symbol = coin->symbol; + if ( symbol != 0 ) + { + if ( (seedip= jstr(json,"seedipaddr")) != 0 ) + safecopy(myinfo->seedipaddr,seedip,sizeof(myinfo->seedipaddr)); + printf(">> addcoin.%s seedipaddr.%s\n",symbol,myinfo->seedipaddr); +#ifdef __PNACL__ + // if ( strcmp(symbol,"BTC") == 0 ) + // return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); +#endif + if ( (retval= iguana_launchcoin(myinfo,symbol,json,0)) > 0 ) { - jaddstr(retjson,"error","illegal address"); - return(jprint(retjson,1)); + if ( myinfo->rpcsymbol[0] == 0 ) + safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); + return(clonestr("{\"result\":\"coin added\"}")); } - jadd64bits(retjson,"RTbalance",iguana_RTbalance(coin,address)); - array = cJSON_CreateArray(); - jaddistr(array,address); - jadd(retjson,"unspents",iguana_RTlistunspent(myinfo,coin,array,minconf,maxconf,remoteaddr,1)); - free_json(array); - if ( lastheight > 0 ) - jaddnum(retjson,"RTheight",coin->RTheight); - } - return(jprint(retjson,1)); + else if ( retval == 0 ) + return(clonestr("{\"result\":\"coin already there\"}")); + else return(clonestr("{\"error\":\"error adding coin\"}")); + } else return(clonestr("{\"error\":\"addcoin needs newcoin\"}")); } -STRING_ARG(iguana,validate,activecoin) +STRING_ARG(iguana,startcoin,activecoin) { - int32_t i,total,validated; struct iguana_bundle *bp; cJSON *retjson; - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + if ( coin != 0 ) { - for (i=total=validated=0; ibundlescount; i++) - if ( (bp= coin->bundles[i]) != 0 ) - { - validated += iguana_bundlevalidate(myinfo,coin,bp,1); - total += bp->n; - } - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","validation run"); - jaddstr(retjson,"coin",coin->symbol); - jaddnum(retjson,"validated",validated); - jaddnum(retjson,"total",total); - jaddnum(retjson,"bundles",coin->bundlescount); - jaddnum(retjson,"accuracy",(double)validated/total); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no active coin\"}")); + coin->active = 1; + return(clonestr("{\"result\":\"coin started\"}")); + } else return(clonestr("{\"error\":\"startcoin needs coin\"}")); +} + +STRING_ARG(iguana,stopcoin,activecoin) +{ + if ( activecoin[0] != 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 ) + { + coin->active = 0; + //iguana_coinpurge(coin); + return(clonestr("{\"result\":\"coin stopped\"}")); + } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); } -STRING_ARG(iguana,removecoin,activecoin) +STRING_ARG(iguana,pausecoin,activecoin) { - struct iguana_bundle *bp; int32_t i,height; char fname[1024]; - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + if ( coin != 0 ) { coin->active = 0; - coin->started = 0; - if ( (0) ) + return(clonestr("{\"result\":\"coin paused\"}")); + } else return(clonestr("{\"error\":\"pausecoin needs coin\"}")); +} + +TWO_STRINGS(iguana,addnode,activecoin,ipaddr) +{ + struct iguana_peer *addr; int32_t i,n; + if ( coin == 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 && strcmp(coin->symbol,"RELAY") == 0 ) + basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),GENESIS_PUBKEY); + printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) + { + //iguana_possible_peer(coin,ipaddr); + if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) { - for (i=0; isupernet = 1; + if ( addr->usock >= 0 ) { - sprintf(fname,"%s/%s/vouts/%04d.vouts",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); - sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); - } - sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); - sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); - for (i=0; ibundlescount; i++) - { - sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); - if ( (bp= coin->bundles[i]) != 0 ) + if ( (n= coin->peers->numranked) != 0 ) { - iguana_bundlepurgefiles(coin,bp); - iguana_bundleremove(coin,bp->hdrsi,1); + for (i=0; ipeers->ranked[i] ) + break; + } + if ( i == n ) + { + if ( i == IGUANA_MAXPEERS ) + i--; + else coin->peers->numranked = n+1; + coin->peers->ranked[i] = addr; + addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; + addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; + printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); + } else printf("(%s) is already peer.%d\n",ipaddr,i); } + return(clonestr("{\"result\":\"peer was already connected\"}")); } - for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) + if ( addr->pending == 0 ) { - sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); - OS_remove_directory(fname); - } - sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); - } - return(clonestr("{\"result\":\"success\"}")); + addr->pending = (uint32_t)time(NULL); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + return(clonestr("{\"result\":\"addnode submitted\"}")); + } else return(clonestr("{\"result\":\"addnode connection was already pending\"}")); + } else return(clonestr("{\"result\":\"addnode cant find peer slot\"}")); } - return(clonestr("{\"error\":\"no active coin\"}")); + else if ( coin == 0 ) + return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); + else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); } -INT_ARG(bitcoinrpc,getblockhash,height) +TWO_STRINGS(iguana,persistent,activecoin,ipaddr) { - cJSON *retjson; - if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) - return(_dex_getblockhash(myinfo,coin->symbol,height)); - retjson = cJSON_CreateObject(); - jaddbits256(retjson,"result",iguana_blockhash(coin,height)); - return(jprint(retjson,1)); + int32_t i; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) + { + for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) + { + coin->peers->active[i].persistent_peer = juint(json,"interval")+3; + return(clonestr("{\"result\":\"node marked as persistent\"}")); + } + } + return(clonestr("{\"result\":\"node wasnt active\"}")); + } else return(clonestr("{\"error\":\"persistent needs coin and ipaddr\"}")); } -HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) +TWO_STRINGS(iguana,removenode,activecoin,ipaddr) { - char *blockstr,*datastr; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson; bits256 txid; int32_t len; - if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) - return(_dex_getblock(myinfo,coin->symbol,blockhash)); - retjson = cJSON_CreateObject(); - memset(&msg,0,sizeof(msg)); - if ( remoteonly == 0 && (block= iguana_blockfind("getblockRPC",coin,blockhash)) != 0 ) + int32_t i; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { - if ( verbose != 0 ) - return(jprint(iguana_blockjson(myinfo,coin,block,1),1)); - else + for (i=0; iblockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) + if ( strcmp(coin->peers->active[i].ipaddr,ipaddr) == 0 ) { - datastr = malloc(len*2 + 1); - init_hexbytes_noT(datastr,coin->blockspace,len); - jaddstr(retjson,"result",datastr); - free(datastr); - return(jprint(retjson,1)); + coin->peers->active[i].rank = 0; + coin->peers->active[i].dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"node marked as dead\"}")); } - jaddstr(retjson,"error","error getting rawblock"); } - } - else if ( coin->APIblockstr != 0 ) - jaddstr(retjson,"error","already have pending request"); - else - { - memset(txid.bytes,0,sizeof(txid)); - if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) - { - jaddstr(retjson,"result",blockstr); - free(blockstr); - } else jaddstr(retjson,"error","cant find blockhash"); - } - return(jprint(retjson,1)); + return(clonestr("{\"result\":\"node wasnt active\"}")); + } else return(clonestr("{\"error\":\"removenode needs coin and ipaddr\"}")); } -ZERO_ARGS(bitcoinrpc,getbestblockhash) +TWO_STRINGS(iguana,oneshot,activecoin,ipaddr) { - cJSON *retjson; - if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) - return(_dex_getbestblockhash(myinfo,coin->symbol)); - retjson = cJSON_CreateObject(); - char str[65]; jaddstr(retjson,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(jprint(retjson,1)); + if ( coin != 0 && ipaddr != 0 ) + { + iguana_possible_peer(coin,ipaddr); + return(clonestr("{\"result\":\"addnode submitted\"}")); + } else return(clonestr("{\"error\":\"addnode needs coin and ipaddr\"}")); } -ZERO_ARGS(bitcoinrpc,getblockcount) +cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) { - cJSON *retjson = cJSON_CreateObject(); - //printf("result %d\n",coin->blocks.hwmchain.height); - jaddnum(retjson,"result",coin->blocks.hwmchain.height); - return(jprint(retjson,1)); + cJSON *array,*json = cJSON_CreateObject(); + jaddstr(json,"ipaddr",addr->ipaddr); + if ( addr->supernet != 0 ) + jaddstr(json,"ipaddr",addr->ipaddr); + jaddstr(json,"supernet","yes"); + jaddnum(json,"protover",addr->protover); + jaddnum(json,"relay",addr->relayflag); + jaddnum(json,"height",addr->height); + jaddnum(json,"rank",addr->rank); + jaddnum(json,"usock",addr->usock); + if ( addr->dead != 0 ) + jaddnum(json,"dead",addr->dead); + jaddnum(json,"ready",addr->ready); + jaddnum(json,"recvblocks",addr->recvblocks); + jaddnum(json,"recvtotal",addr->recvtotal); + jaddnum(json,"lastcontact",addr->lastcontact); + if ( addr->numpings > 0 ) + jaddnum(json,"aveping",addr->pingsum/addr->numpings); + array = cJSON_CreateObject(); + jaddnum(array,"version",addr->msgcounts.version); + jaddnum(array,"verack",addr->msgcounts.verack); + jaddnum(array,"getaddr",addr->msgcounts.getaddr); + jaddnum(array,"addr",addr->msgcounts.addr); + jaddnum(array,"inv",addr->msgcounts.inv); + jaddnum(array,"getdata",addr->msgcounts.getdata); + jaddnum(array,"notfound",addr->msgcounts.notfound); + jaddnum(array,"getblocks",addr->msgcounts.getblocks); + jaddnum(array,"getheaders",addr->msgcounts.getheaders); + jaddnum(array,"headers",addr->msgcounts.headers); + jaddnum(array,"tx",addr->msgcounts.tx); + jaddnum(array,"block",addr->msgcounts.block); + jaddnum(array,"mempool",addr->msgcounts.mempool); + jaddnum(array,"ping",addr->msgcounts.ping); + jaddnum(array,"pong",addr->msgcounts.pong); + jaddnum(array,"reject",addr->msgcounts.reject); + jaddnum(array,"filterload",addr->msgcounts.filterload); + jaddnum(array,"filteradd",addr->msgcounts.filteradd); + jaddnum(array,"filterclear",addr->msgcounts.filterclear); + jaddnum(array,"merkleblock",addr->msgcounts.merkleblock); + jaddnum(array,"alert",addr->msgcounts.alert); + jadd(json,"msgcounts",array); + return(json); } -STRING_AND_INT(iguana,bundleaddresses,activecoin,height) +cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) { - struct iguana_info *ptr; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) - return(iguana_bundleaddrs(ptr,height / coin->chain->bundlesize)); - else return(clonestr("{\"error\":\"activecoin is not active\"}")); + cJSON *retjson,*array; int32_t i; struct iguana_peer *addr; + if ( coin == 0 || coin->peers == 0 ) + return(0); + array = cJSON_CreateArray(); + for (i=0; iMAXPEERS; i++) + { + addr = &coin->peers->active[i]; + if ( addr->usock >= 0 && addr->ipbits != 0 && addr->ipaddr[0] != 0 ) + { + if ( addronly != 0 ) + jaddistr(array,addr->ipaddr); + else jaddi(array,iguana_peerjson(coin,addr)); + } + } + if ( addronly == 0 ) + { + retjson = cJSON_CreateObject(); + jadd(retjson,"peers",array); + jaddnum(retjson,"maxpeers",coin->MAXPEERS); + jaddstr(retjson,"coin",coin->symbol); + return(retjson); + } + else return(array); } -STRING_AND_INT(iguana,PoSweights,activecoin,height) +TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) { - struct iguana_info *ptr; int32_t num,nonz,errs,bundleheight; struct iguana_pkhash *refP; uint64_t *weights,supply; cJSON *retjson; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + int32_t i; struct iguana_peer *addr; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { - //for (bundleheight=coin->chain->bundlesize; bundleheightchain->bundlesize) + for (i=0; iMAXPEERS; i++) { - bundleheight = (height / ptr->chain->bundlesize) * ptr->chain->bundlesize; - if ( (weights= iguana_PoS_weights(myinfo,ptr,&refP,&supply,&num,&nonz,&errs,bundleheight)) != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",errs == 0 ? "success" : "error"); - jaddnum(retjson,"bundleheight",bundleheight); - jaddnum(retjson,"numaddresses",num); - jaddnum(retjson,"nonzero",nonz); - jaddnum(retjson,"errors",errs); - jaddnum(retjson,"supply",dstr(supply)); - free(weights); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"iguana_PoS_weights returned null\"}")); + addr = &coin->peers->active[i]; + if ( strcmp(addr->ipaddr,ipaddr) == 0 ) + return(jprint(iguana_peerjson(coin,addr),1)); } - } - return(clonestr("{\"error\":\"activecoin is not active\"}")); + return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); + } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); } -STRING_ARG(iguana,stakers,activecoin) +STRING_AND_INT(iguana,maxpeers,activecoin,max) { - struct iguana_info *ptr; int32_t i,datalen,pkind,hdrsi; bits256 hash2; struct iguana_bundle *bp; cJSON *retjson,*array; struct iguana_pkhash *refP; struct iguana_ramchaindata *rdata; char coinaddr[64]; uint8_t refrmd160[20]; bits256 *sortbuf; - if ( (ptr= iguana_coinfind(activecoin)) != 0 && ptr->RTheight > ptr->chain->bundlesize ) + cJSON *retjson; int32_t i; struct iguana_peer *addr; + if ( coin != 0 && coin->peers != 0 ) { - hdrsi = (ptr->RTheight / ptr->chain->bundlesize) - 1; - if ( (bp= ptr->bundles[hdrsi]) != 0 && bp->weights != 0 && (rdata= bp->ramchain.H.data) != 0 && bp->weights != 0 ) + retjson = cJSON_CreateObject(); + if ( max > IGUANA_MAXPEERS ) + max = IGUANA_MAXPEERS; + if ( max > coin->MAXPEERS ) { - sortbuf = calloc(bp->numweights,2 * sizeof(*sortbuf)); - for (i=datalen=0; inumweights; i++) - datalen += iguana_rwnum(1,&((uint8_t *)sortbuf)[datalen],sizeof(bp->weights[i]),(void *)&bp->weights[i]); - hash2 = bits256_doublesha256(0,(uint8_t *)sortbuf,datalen); - refP = RAMCHAIN_PTR(rdata,Poffset); - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - memset(refrmd160,0,sizeof(refrmd160)); - for (i=0; ichain->bundlesize; i++) - { - if ( (pkind= iguana_staker_sort(ptr,&hash2,refrmd160,refP,bp->weights,bp->numweights,sortbuf)) > 0 ) - { - bitcoin_address(coinaddr,ptr->chain->pubtype,refP[pkind].rmd160,sizeof(refP[pkind].rmd160)); - jaddistr(array,coinaddr); - } else jaddistr(array,"error"); - } - jaddstr(retjson,"result","success"); - jadd(retjson,"stakers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"iguana_stakers needs PoSweights and weights\"}")); - } - return(clonestr("{\"error\":\"activecoin is not active\"}")); + for (i=max; iMAXPEERS; i++) + if ( (addr= coin->peers->ranked[i]) != 0 ) + addr->dead = 1; + } + coin->MAXPEERS = max; + jaddnum(retjson,"maxpeers",coin->MAXPEERS); + jaddstr(retjson,"coin",coin->symbol); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"maxpeers needs coin\"}")); } -STRING_AND_INT(iguana,bundlehashes,activecoin,height) +char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message),char *name,char *message,char *password) { - struct iguana_info *ptr; struct iguana_bundle *bp; int32_t i,hdrsi; cJSON *retjson,*array; struct iguana_ramchaindata *rdata; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + char hexstr[1025]; cJSON *json; + if ( message != 0 && password != 0 && message[0] != 0 && password[0] != 0 ) { - hdrsi = height / coin->chain->bundlesize; - if ( hdrsi < coin->bundlescount && hdrsi >= 0 && (bp= coin->bundles[hdrsi]) != 0 ) - { - if ( (rdata= bp->ramchain.H.data) != 0 ) - { - array = cJSON_CreateArray(); - for (i=0; ilhashes[i].txid); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddbits256(retjson,"sha256",rdata->sha256); - jadd(retjson,"bundlehashes",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"ramchain not there\"}")); - } else return(clonestr("{\"error\":\"height is too big\"}")); - } else return(clonestr("{\"error\":\"activecoin is not active\"}")); + memset(hexstr,0,sizeof(hexstr)); + (*hmacfunc)(hexstr,password,password==0?0:(int32_t)strlen(password),message); + json = cJSON_CreateObject(); + jaddstr(json,"result","hmac calculated"); + jaddstr(json,"message",message); + jaddstr(json,name,hexstr); + return(jprint(json,1)); + } else return(clonestr("{\"error\":\"hmac needs message and passphrase\"}")); } -// low priority RPC +char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) +{ + char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; + if ( message != 0 && message[0] != 0 ) + { + memset(hexstr,0,sizeof(hexstr)); + (*hashfunc)(hexstr,databuf,(uint8_t *)message,(int32_t)strlen(message)); + json = cJSON_CreateObject(); + jaddstr(json,"result","hash calculated"); + jaddstr(json,"message",message); + jaddstr(json,name,hexstr); + return(jprint(json,1)); + } else return(clonestr("{\"error\":\"hash needs message\"}")); +} -HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag) +TWO_HASHES(hash,curve25519_pair,element,scalar) { - /*"transactions" : [ - { - "account" : "doc test", - "address" : "mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6", - "category" : "receive", - "amount" : 0.10000000, - "vout" : 0, - "confirmations" : 76478, - "blockhash" : "000000000017c84015f254498c62a7c884a51ccd75d4dd6dbdcb6434aa3bd44d", - "blockindex" : 1, - "blocktime" : 1399294967, - "txid" : "85a98fdf1529f7d5156483ad020a51b7f3340e47448cf932f470b72ff01a6821", - "walletconflicts" : [ - ], - "time" : 1399294967, - "timereceived" : 1418924714 - },*/ cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","low priority RPC not implemented"); + jaddbits256(retjson,"result",curve25519(element,scalar)); return(jprint(retjson,1)); } -ZERO_ARGS(bitcoinrpc,gettxoutsetinfo) +STRING_ARG(hash,NXT,passphrase) { return(hash_dispatch(calc_NXTaddr,"NXT",passphrase)); } +STRING_ARG(hash,curve25519,pubkey) { return(hash_dispatch(calc_curve25519_str,"curve25519",pubkey)); } +STRING_ARG(hash,crc32,message) { return(hash_dispatch(calc_crc32str,"crc32",message)); } +STRING_ARG(hash,base64_encode,message) { return(hash_dispatch(calc_base64_encodestr,"base64_encode",message)); } +STRING_ARG(hash,base64_decode,message) { return(hash_dispatch(calc_base64_decodestr,"base64_decode",message)); } +STRING_ARG(hash,rmd160_sha256,message) { return(hash_dispatch(rmd160ofsha256,"rmd160_sha256",message)); } +STRING_ARG(hash,sha256_sha256,message) { return(hash_dispatch(sha256_sha256,"sha256_sha256",message)); } +STRING_ARG(hash,hex,message) { return(hash_dispatch(calc_hexstr,"hex",message)); } +STRING_ARG(hash,unhex,message) { return(hash_dispatch(calc_unhexstr,"unhex",message)); } + +STRING_ARG(hash,sha224,message) { return(hash_dispatch(calc_sha224,"sha224",message)); } +STRING_ARG(hash,sha256,message) { return(hash_dispatch(vcalc_sha256,"sha256",message)); } +STRING_ARG(hash,sha384,message) { return(hash_dispatch(calc_sha384,"sha384",message)); } +STRING_ARG(hash,sha512,message) { return(hash_dispatch(calc_sha512,"sha512",message)); } +STRING_ARG(hash,rmd128,message) { return(hash_dispatch(calc_rmd128,"rmd128",message)); } +STRING_ARG(hash,rmd160,message) { return(hash_dispatch(calc_rmd160,"rmd160",message)); } +STRING_ARG(hash,rmd256,message) { return(hash_dispatch(calc_rmd256,"rmd256",message)); } +STRING_ARG(hash,rmd320,message) { return(hash_dispatch(calc_rmd320,"rmd320",message)); } +STRING_ARG(hash,sha1,message) { return(hash_dispatch(calc_sha1,"sha1",message)); } +STRING_ARG(hash,md2,message) { return(hash_dispatch(calc_md2str,"md2",message)); } +STRING_ARG(hash,md4,message) { return(hash_dispatch(calc_md4str,"md4",message)); } +STRING_ARG(hash,md5,message) { return(hash_dispatch(calc_md5str,"md5",message)); } +STRING_ARG(hash,tiger192_3,message) { return(hash_dispatch(calc_tiger,"tiger",message)); } +STRING_ARG(hash,whirlpool,message) { return(hash_dispatch(calc_whirlpool,"whirlpool",message)); } +TWO_STRINGS(hmac,sha224,message,passphrase) { return(hmac_dispatch(hmac_sha224_str,"sha224",message,passphrase)); } +TWO_STRINGS(hmac,sha256,message,passphrase) { return(hmac_dispatch(hmac_sha256_str,"sha256",message,passphrase)); } +TWO_STRINGS(hmac,sha384,message,passphrase) { return(hmac_dispatch(hmac_sha384_str,"sha384",message,passphrase)); } +TWO_STRINGS(hmac,sha512,message,passphrase) { return(hmac_dispatch(hmac_sha512_str,"sha512",message,passphrase)); } +TWO_STRINGS(hmac,rmd128,message,passphrase) { return(hmac_dispatch(hmac_rmd128_str,"rmd128",message,passphrase)); } +TWO_STRINGS(hmac,rmd160,message,passphrase) { return(hmac_dispatch(hmac_rmd160_str,"rmd160",message,passphrase)); } +TWO_STRINGS(hmac,rmd256,message,passphrase) { return(hmac_dispatch(hmac_rmd256_str,"rmd256",message,passphrase)); } +TWO_STRINGS(hmac,rmd320,message,passphrase) { return(hmac_dispatch(hmac_rmd320_str,"rmd320",message,passphrase)); } +TWO_STRINGS(hmac,sha1,message,passphrase) { return(hmac_dispatch(hmac_sha1_str,"sha1",message,passphrase)); } +TWO_STRINGS(hmac,md2,message,passphrase) { return(hmac_dispatch(hmac_md2_str,"md2",message,passphrase)); } +TWO_STRINGS(hmac,md4,message,passphrase) { return(hmac_dispatch(hmac_md4_str,"md4",message,passphrase)); } +TWO_STRINGS(hmac,md5,message,passphrase) { return(hmac_dispatch(hmac_md5_str,"md5",message,passphrase)); } +TWO_STRINGS(hmac,tiger192_3,message,passphrase) { return(hmac_dispatch(hmac_tiger_str,"tiger",message,passphrase)); } +TWO_STRINGS(hmac,whirlpool,message,passphrase) { return(hmac_dispatch(hmac_whirlpool_str,"whirlpool",message,passphrase)); } + +STRING_ARG(SuperNET,bitcoinrpc,setcoin) { - cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","low priority RPC not implemented"); - return(jprint(retjson,1)); + char buf[1024]; + if ( setcoin != 0 && setcoin[0] != 0 ) + { + strcpy(myinfo->rpcsymbol,setcoin); + touppercase(myinfo->rpcsymbol); + printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); + if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json,0) < 0 ) + return(clonestr("{\"error\":\"error creating coin\"}")); + else + { + sprintf(buf,"{\"result\":\"success\",\"setcoin\":\"%s\"}",setcoin); + return(clonestr(buf)); + } + } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); } -ZERO_ARGS(bitcoinrpc,listaddressgroupings) +ZERO_ARGS(SuperNET,help) { - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - return(clonestr("{\"error\":\"low priority RPC not implemented\"}")); + cJSON *helpjson,*retjson; + if ( (helpjson= SuperNET_helpjson()) != 0 ) + { + retjson = cJSON_CreateObject(); + jadd(retjson,"result",helpjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant get helpjson\"}")); } -SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) +TWO_STRINGS(SuperNET,html,agentform,htmlfile) { - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); + char *htmlstr; cJSON *retjson; int32_t max = 4*1024*1024; + if ( htmlfile == 0 || htmlfile[0] == 0 ) + htmlfile = "forms.html"; + //if ( (fp= fopen(htmlfile,"w")) == 0 ) + // printf("error opening htmlfile.(%s)\n",htmlfile); + htmlstr = malloc(max); + htmlstr = SuperNET_htmlstr(htmlfile,htmlstr,max,agentform); retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",htmlstr); + free(htmlstr); + //if ( fp != 0 ) + // fclose(fp); return(jprint(retjson,1)); } -ZERO_ARGS(pax,start) -{ - void PAX_init(); - PAX_init(); - return(clonestr("{\"result\":\"PAX_init called\"}")); -} #undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" diff --git a/iguana/tests/DEXinit b/iguana/tests/DEXinit new file mode 100755 index 000000000..63e43fe15 --- /dev/null +++ b/iguana/tests/DEXinit @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"init\"}" diff --git a/iguana/tests/KMD.batch12.listunspent b/iguana/tests/KMD.batch12.listunspent index b54d4d79c..11e9bfdd0 100755 --- a/iguana/tests/KMD.batch12.listunspent +++ b/iguana/tests/KMD.batch12.listunspent @@ -1,112 +1,112 @@ # RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 # RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDTjem9CP97XPXvet1sQBb428xrmSZJSsd\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDTjem9CP97XPXvet1sQBb428xrmSZJSsd\",\"symbol\":\"KMD\"}" echo "1568.45531762 <- expected amount RDTjem9CP97XPXvet1sQBb428xrmSZJSsd" # RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 73430.96919475 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" echo "73430.96919475 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" # RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE KMD 5689.04575312 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE\",\"symbol\":\"KMD\"}" echo "5689.04575312 <- expected amount RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE" # RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT KMD 17817.00058850 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT\",\"symbol\":\"KMD\"}" echo "17817.00058850 <- expected amount RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT" # RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" # RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 6963.60677351 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"KMD\"}" echo "6963.60677351 <- expected amount RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf" # RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 32042.52085087 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" echo "32042.52085087 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" # RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 2135.12309659 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" echo "2135.12309659 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" # RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic KMD 5533.00461690 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" echo "5533.00461690 <- expected amount RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic" # RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i KMD 50.26846585 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i\",\"symbol\":\"KMD\"}" echo "50.26846585 <- expected amount RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i" # RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7 KMD 1733.05190072 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7\",\"symbol\":\"KMD\"}" echo "1733.05190072 <- expected amount RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7" # RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 # RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y\",\"symbol\":\"KMD\"}" echo "11852.83167290 <- expected amount RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y" # RH9CANWQNvqSktmX39ruDfiNFimcToD2ur KMD 43125.33019700 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH9CANWQNvqSktmX39ruDfiNFimcToD2ur\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RH9CANWQNvqSktmX39ruDfiNFimcToD2ur\",\"symbol\":\"KMD\"}" echo "43125.33019700 <- expected amount RH9CANWQNvqSktmX39ruDfiNFimcToD2ur" # RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b KMD 36837.09249870 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b\",\"symbol\":\"KMD\"}" echo "36837.09249870 <- expected amount RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b" # RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 # RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8\",\"symbol\":\"KMD\"}" echo "3016.26045526 <- expected amount RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8" # RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb KMD 91240.39653929 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb\",\"symbol\":\"KMD\"}" echo "91240.39653929 <- expected amount RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb" # RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury KMD 2440.00507548 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury\",\"symbol\":\"KMD\"}" echo "2440.00507548 <- expected amount RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury" # RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 # RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX\",\"symbol\":\"KMD\"}" echo "3823.81289934 <- expected amount RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX" # RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2772.48246697 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" echo "2772.48246697 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" # RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" # RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 10316.17621736 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" echo "10316.17621736 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" # RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 29566.93551966 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" echo "29566.93551966 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" # RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX KMD 19365.33667225 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX\",\"symbol\":\"KMD\"}" echo "19365.33667225 <- expected amount RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX" # R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X KMD 55229.13842423 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X\",\"symbol\":\"KMD\"}" echo "55229.13842423 <- expected amount R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X" # RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB KMD 29049.45748125 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB\",\"symbol\":\"KMD\"}" echo "29049.45748125 <- expected amount RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB" # RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10066.89321267 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" echo "10066.89321267 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" # RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 2834.17657315 -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" echo "2834.17657315 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" diff --git a/iguana/tests/KMD.batch13 b/iguana/tests/KMD.batch13 new file mode 100755 index 000000000..f2764fafe --- /dev/null +++ b/iguana/tests/KMD.batch13 @@ -0,0 +1,146 @@ +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 341.29719958 +./komodo-cli sendtoaddress RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 341.29719958 +sleep 3 +echo "341.29719958 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 177091.93551966 +./komodo-cli sendtoaddress RD486qQaD85849AdDPH3Xy3iyppuvxDZYf 177091.93551966 +sleep 3 +echo "177091.93551966 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10744.59269420 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 10744.59269420 +sleep 3 +echo "10744.59269420 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 885.02977777 +./komodo-cli sendtoaddress RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ 885.02977777 +sleep 3 +echo "885.02977777 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 1517.32401692 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 1517.32401692 +sleep 3 +echo "1517.32401692 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP KMD 722.28571081 +./komodo-cli sendtoaddress RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP" + +# RS12srxPnksnwwaXrSXLjhu14hBknd26aR KMD 1859.16527880 +./komodo-cli sendtoaddress RS12srxPnksnwwaXrSXLjhu14hBknd26aR 1859.16527880 +sleep 3 +echo "1859.16527880 <- expected amount RS12srxPnksnwwaXrSXLjhu14hBknd26aR" + +# RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw KMD 748.59289950 +./komodo-cli sendtoaddress RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw 748.59289950 +sleep 3 +echo "748.59289950 <- expected amount RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw" + +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766, REVS 33.43442069 +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766 +./komodo-cli sendtoaddress RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy 1684.62281766 +sleep 3 +echo "1684.62281766 <- expected amount RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy" + +# RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc KMD 4850.29108411 +./komodo-cli sendtoaddress RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc 4850.29108411 +sleep 3 +echo "4850.29108411 <- expected amount RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc" + +# RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ KMD 935.39253089 +./komodo-cli sendtoaddress RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ 935.39253089 +sleep 3 +echo "935.39253089 <- expected amount RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ" + +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038, REVS 819.96000000 +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038 +./komodo-cli sendtoaddress RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 86638.13975038 +sleep 3 +echo "86638.13975038 <- expected amount RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4" + +# RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 KMD 50.26846585 +./komodo-cli sendtoaddress RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 50.26846585 +sleep 3 +echo "50.26846585 <- expected amount RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32" + +# RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS KMD 3873.26099750 +./komodo-cli sendtoaddress RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 212102.44577315 +./komodo-cli sendtoaddress RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT 212102.44577315 +sleep 3 +echo "212102.44577315 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ KMD 10486.02744190 +./komodo-cli sendtoaddress RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ 10486.02744190 +sleep 3 +echo "10486.02744190 <- expected amount RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do KMD 3389.10337281 +./komodo-cli sendtoaddress RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do 3389.10337281 +sleep 3 +echo "3389.10337281 <- expected amount RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do" + +# RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc KMD 774.65219950 +./komodo-cli sendtoaddress RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 190185.06275980 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 190185.06275980 +sleep 3 +echo "190185.06275980 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg KMD 9683.15249375 +./komodo-cli sendtoaddress RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg" + +# RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF KMD 8424.34266955 +./komodo-cli sendtoaddress RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF 8424.34266955 +sleep 3 +echo "8424.34266955 <- expected amount RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF" + +# R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M KMD 6007.48089910 +./komodo-cli sendtoaddress R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M 6007.48089910 +sleep 3 +echo "6007.48089910 <- expected amount R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M" + +# RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE KMD 534.11913087 +./komodo-cli sendtoaddress RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE 534.11913087 +sleep 3 +echo "534.11913087 <- expected amount RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 1.56326640 +./komodo-cli sendtoaddress RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 1.56326640 +sleep 3 +echo "1.56326640 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM KMD 678.12202237 +./komodo-cli sendtoaddress RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM 678.12202237 +sleep 3 +echo "678.12202237 <- expected amount RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM" + +# RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE KMD 4841.57624687 +./komodo-cli sendtoaddress RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 25665.79190427 +./komodo-cli sendtoaddress RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv 25665.79190427 +sleep 3 +echo "25665.79190427 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 6627.41635888 +./komodo-cli sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 6627.41635888 +sleep 3 +echo "6627.41635888 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" diff --git a/iguana/tests/KMD.batch13.listunspent b/iguana/tests/KMD.batch13.listunspent new file mode 100755 index 000000000..06796ec86 --- /dev/null +++ b/iguana/tests/KMD.batch13.listunspent @@ -0,0 +1,118 @@ +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 341.29719958 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2\",\"symbol\":\"KMD\"}" +echo "341.29719958 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 177091.93551966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD486qQaD85849AdDPH3Xy3iyppuvxDZYf\",\"symbol\":\"KMD\"}" +echo "177091.93551966 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10744.59269420 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "10744.59269420 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 885.02977777 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" +echo "885.02977777 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 1517.32401692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "1517.32401692 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP" + +# RS12srxPnksnwwaXrSXLjhu14hBknd26aR KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RS12srxPnksnwwaXrSXLjhu14hBknd26aR\",\"symbol\":\"KMD\"}" +echo "1859.16527880 <- expected amount RS12srxPnksnwwaXrSXLjhu14hBknd26aR" + +# RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw KMD 748.59289950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw\",\"symbol\":\"KMD\"}" +echo "748.59289950 <- expected amount RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw" + +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766, REVS 33.43442069 +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy\",\"symbol\":\"KMD\"}" +echo "1684.62281766 <- expected amount RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy" + +# RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc KMD 4850.29108411 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc\",\"symbol\":\"KMD\"}" +echo "4850.29108411 <- expected amount RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc" + +# RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ KMD 935.39253089 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ\",\"symbol\":\"KMD\"}" +echo "935.39253089 <- expected amount RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ" + +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038, REVS 819.96000000 +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4\",\"symbol\":\"KMD\"}" +echo "86638.13975038 <- expected amount RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4" + +# RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 KMD 50.26846585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32\",\"symbol\":\"KMD\"}" +echo "50.26846585 <- expected amount RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32" + +# RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 212102.44577315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" +echo "212102.44577315 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ KMD 10486.02744190 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ\",\"symbol\":\"KMD\"}" +echo "10486.02744190 <- expected amount RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do KMD 3389.10337281 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do\",\"symbol\":\"KMD\"}" +echo "3389.10337281 <- expected amount RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do" + +# RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc\",\"symbol\":\"KMD\"}" +echo "774.65219950 <- expected amount RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 190185.06275980 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "190185.06275980 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg" + +# RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF KMD 8424.34266955 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF\",\"symbol\":\"KMD\"}" +echo "8424.34266955 <- expected amount RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF" + +# R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M KMD 6007.48089910 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M\",\"symbol\":\"KMD\"}" +echo "6007.48089910 <- expected amount R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M" + +# RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE KMD 534.11913087 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE\",\"symbol\":\"KMD\"}" +echo "534.11913087 <- expected amount RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 1.56326640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" +echo "1.56326640 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM KMD 678.12202237 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM\",\"symbol\":\"KMD\"}" +echo "678.12202237 <- expected amount RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM" + +# RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 25665.79190427 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" +echo "25665.79190427 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 6627.41635888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "6627.41635888 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + diff --git a/iguana/tests/LPinit b/iguana/tests/LPinit index c7dfbb067..1905ec149 100755 --- a/iguana/tests/LPinit +++ b/iguana/tests/LPinit @@ -1,4 +1,5 @@ #!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"3809853923098test\",\"timeout\":86444}" curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\"}" -#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"KMD\",\"vals\":{\"profit\":0.01}}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"KMD\",\"vals\":{\"ask\":0.000077,\"bid\":0.000067,\"maxvol\":400,\"minvol\":100}}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}" diff --git a/iguana/tests/cancelrefresh b/iguana/tests/cancelrefresh new file mode 100755 index 000000000..35c27504d --- /dev/null +++ b/iguana/tests/cancelrefresh @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"cancelrefresh\"}" diff --git a/iguana/tests/dexgetbalance b/iguana/tests/dexgetbalance index 0e91dac58..71efdf9af 100755 --- a/iguana/tests/dexgetbalance +++ b/iguana/tests/dexgetbalance @@ -1,3 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"symbol\":\"KMD\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"symbol\":\"USD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexkvupdate b/iguana/tests/dexkvupdate index a98240995..a6792a142 100755 --- a/iguana/tests/dexkvupdate +++ b/iguana/tests/dexkvupdate @@ -1,3 +1,3 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"test\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KMD\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"test\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KV\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"test\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"testtest\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KV\"}" diff --git a/iguana/tests/dexpsock b/iguana/tests/dexpsock new file mode 100755 index 000000000..0a0e6fb16 --- /dev/null +++ b/iguana/tests/dexpsock @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"psock\"}" diff --git a/iguana/tests/loop b/iguana/tests/loop index b7e8cfa16..460d2c4db 100755 --- a/iguana/tests/loop +++ b/iguana/tests/loop @@ -1,7 +1,6 @@ #!/bin/bash while true do -./dexlistunspent ./dexgetinfo done diff --git a/iguana/tests/notlp b/iguana/tests/notlp new file mode 100755 index 000000000..b29c9dde7 --- /dev/null +++ b/iguana/tests/notlp @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"notlp\"}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 3f952e15a..955acffe0 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -13,6 +13,12 @@ * * ******************************************************************************/ +#ifdef _IGUANA_APIDEC_H_ +emit compiler error if recursively being included +#endif +#ifndef _IGUANA_APIDEC_H_ +#define _IGUANA_APIDEC_H_ + STRING_ARG(dpow,pending,fiat); ZERO_ARGS(dpow,notarychains); STRING_ARG(dpow,active,maskhex); @@ -49,6 +55,8 @@ HASH_AND_STRING_AND_INT(dex,gettxin,txid,symbol,vout); TWO_STRINGS(dex,listspent,symbol,address); TWO_STRINGS(dex,getbalance,symbol,address); STRING_ARG(dex,explorer,symbol); +STRING_ARG(dex,getmessage,argstr); +STRING_ARG(dex,psock,argstr); HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr); @@ -57,6 +65,7 @@ HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr); TWO_STRINGS(basilisk,refresh,symbol,address); +ZERO_ARGS(basilisk,cancelrefresh); STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore); HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr); @@ -214,6 +223,7 @@ STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap); ZERO_ARGS(InstantDEX,allexchanges); STRING_ARG(InstantDEX,allpairs,exchange); THREE_STRINGS(InstantDEX,supports,exchange,base,rel); +ZERO_ARGS(InstantDEX,init); //THREE_STRINGS(atomic,approve,myorderid,otherid,txname); //THREE_STRINGS(atomic,claim,myorderid,otherid,txname); @@ -354,3 +364,5 @@ TWO_STRINGS(hmac,md4,message,passphrase); TWO_STRINGS(hmac,md5,message,passphrase); TWO_STRINGS(hmac,tiger192_3,message,passphrase); TWO_STRINGS(hmac,whirlpool,message,passphrase); + +#endif diff --git a/includes/iguana_apiundefs.h b/includes/iguana_apiundefs.h index 0b793ee2d..88156175d 100755 --- a/includes/iguana_apiundefs.h +++ b/includes/iguana_apiundefs.h @@ -49,3 +49,5 @@ #undef IGUANA_ARGS #undef IGUANA_CALLARGS +#undef _IGUANA_APIDEC_H_ + diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index c6a2e3a3f..7496ccd4b 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -15,6 +15,10 @@ #ifndef H_IGUANAFUNCS_H #define H_IGUANAFUNCS_H +#define SIGHASH_ALL 1 + +cJSON *SuperNET_helpjson(); + // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin); @@ -316,6 +320,10 @@ int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int3 //cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); +cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv); +int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddress,uint64_t satoshis); +char *_setVsigner(struct iguana_info *coin,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr); + 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); @@ -596,6 +604,11 @@ void basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notar void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr); int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]); void basilisk_requests_poll(struct supernet_info *myinfo); +void dpow_psockloop(void *_ptr); +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *BTCaddr,char *KMDaddr); +int32_t smartaddress(struct supernet_info *myinfo,bits256 *privkeyp,char *coinaddr); +int32_t smartaddress_pubkey(struct supernet_info *myinfo,bits256 *privkeyp,bits256 pubkey); +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,bits256 *privkeyp,uint8_t *pubkey33); void iguana_RTreset(struct iguana_info *coin); void iguana_RTpurge(struct iguana_info *coin,int32_t lastheight); @@ -615,8 +628,10 @@ int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *ref bits256 mpz_div64(bits256 hash,uint64_t divval); void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin); void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval); +void jumblr_DEXcheck(struct supernet_info *myinfo,struct iguana_info *coinkmd,char *BTCaddr,char *KMDaddr,bits256 privkey); bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,char *KMDaddr,char *prefix); char *jumblr_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wifstr); +int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,char *signedtx,int32_t numvins); // ------------------------------------------------------[ Preparation ]---- // Initialise a gfshare context for producing shares