diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index f549526d9..312d97813 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -106,13 +106,13 @@ enable(coin)\n\ disable(coin)\n\ notarizations(coin)\n\ parselog()\n\ -statsdisp(starttime=0, endtime=0)\n\ +statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ getrawtransaction(coin, txid)\n\ inventory(coin)\n\ bestfit(rel, relvolume)\n\ lastnonce()\n\ -buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\ -sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\ +buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, pubkey="")\n\ +sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, pubkey="")\n\ withdraw(coin, outputs[])\n\ sendrawtransaction(coin, signedtx)\n\ swapstatus()\n\ @@ -278,7 +278,7 @@ stop()\n\ //* if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"))); + return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"))); } else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"sell") == 0 ) @@ -286,7 +286,7 @@ stop()\n\ //* if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"))); + return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"))); } else return(clonestr("{\"error\":\"no price set\"}")); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4e11914ec..0c5684d7b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -23,10 +23,11 @@ // select oldest utxo first // handles <-> pubkeys, deal with offline pubkeys, reputations, bonds etc. -// depth and trade to pubkey -// verify portfolio, pricearray, interest to KMD withdraw +// depth +// verify portfolio, pricearray, interest to KMD withdraw, pricebroadcast loop, trade to pubkey // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs +//statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ #include #include "LP_include.h" @@ -736,6 +737,26 @@ void LP_pubkeysloop(void *ctx) } } +void LP_price_broadcastloop(void *ctx) +{ + struct LP_priceinfo *basepp,*relpp; double price; int32_t baseind,relind; + sleep(30); + while ( 1 ) + { + for (baseind=0; baseindmyprices[relpp->ind]) > SMALLVAL) + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,price); + } + } + sleep(60); + } +} + void LP_privkeysloop(void *ctx) { sleep(20); @@ -1006,12 +1027,17 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)&myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)&myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + { + printf("error launching LP_swapsloop for port.%u\n",myport); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_price_broadcastloop,(void *)ctx) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); @@ -1077,10 +1103,10 @@ void LP_fromjs_iter() LP_nanomsg_recvs(ctx); LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock,LP_publicaddr,LP_RPCPORT); queue_loop(0); - if ( (LP_counter % 10) == 0 ) + if ( (LP_counter % 10) == 0 ) // 10 seconds { LP_coinsloop(0); - if ( (LP_counter % 100) == 0 ) + if ( (LP_counter % 100) == 0 ) // 100 seconds { LP_notify_pubkeys(ctx,LP_mypubsock); LP_privkey_updates(ctx,LP_mypubsock,0); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 748605348..13e39b9c8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -531,7 +531,7 @@ char *LP_connectedalice(cJSON *argjson) // alice int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) { - int32_t i,v,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol); + int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol); if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) ) { if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) @@ -543,8 +543,11 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) } else { + if ( strcmp(symbol,"BTC") == 0 ) + numconfs = 0; + else numconfs = 1; //printf("my coin electrum.%p\n",coin->electrum); - sprintf(buf,"[1, 99999999, [\"%s\"]]",coinaddr); + sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); if ( (array= bitcoin_json(coin,"listunspent",buf)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -761,7 +764,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma return(0); } -struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids) +struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) { bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; maxiters = 100; @@ -790,41 +793,36 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i price = jdouble(item,"price"); price *= 1.005; pubkey = jbits256(item,"pubkey"); + if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) + continue; //printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice); if ( LP_pricevalid(price) > 0 && price <= maxprice ) { - for (j=0; jtaddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); asatoshis = autxo->S.satoshis; - /*if ( basecoin->electrum != 0 ) - { - price *= 1.01; - *ordermatchpricep = price; - *bestsatoshisp = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); - *bestdestsatoshisp = asatoshis; - } - else*/ - { LP_listunspent_query(base,coinaddr); LP_listunspent_both(base,coinaddr,1); - for (j=0; jpubkey,gui)) != 0 ) { - if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,gui)) != 0 ) - { - printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); - break; - } - asatoshis = (asatoshis / 64) * 63; - } - if ( j < maxiters ) + printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); break; + } + asatoshis = (asatoshis / 64) * 63; } + if ( j < maxiters ) + break; } else printf("self trading or blacklisted peer\n"); } else @@ -847,7 +845,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i return(bestutxo); } -char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce) +char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey) { uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; basecoin = LP_coinfind(base); @@ -904,7 +902,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel } while ( 1 ) { - if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) { printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); return(clonestr("{\"error\":\"cant find ordermatch utxo, need to change relvolume to be closer to available\"}")); @@ -934,12 +932,13 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel if ( i == maxiters || qprice > maxprice ) { printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f, no acceptable quote for this pubkey\n",i,maxiters,dstr(qprice),dstr(maxprice)); - continue; + if ( bits256_nonz(destpubkey) == 0 ) + continue; + else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); } - break; + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration)); } - //printf("do quote.(%s)\n",jprint(LP_quotejson(&Q),1)); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration)); + return(clonestr("{\"error\":\"cant get here\"}")); } diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index dce7e3f99..16f1d65fe 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -484,7 +484,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,struct iguana_info *buy,struct iguana_info *sell,double relvolume,int32_t setbaserel,char *gui) { - char *retstr2; double bid,ask,maxprice; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; + char *retstr2; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; requestid = quoteid = 0; LP_myprice(&bid,&ask,buy->symbol,sell->symbol); maxprice = ask; @@ -504,7 +504,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str break; if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) { - if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 68125fbfa..167e08236 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -47,6 +47,13 @@ struct LP_cacheinfo uint32_t timestamp; } *LP_cacheinfos; +struct LP_priceinfo *LP_priceinfo(int32_t ind) +{ + if ( ind < 0 || ind >= LP_MAXPRICEINFOS ) + return(0); + else return(&LP_priceinfos[ind]); +} + char *LP_priceinfostr(int32_t ind) { if ( ind < 0 || ind >= LP_MAXPRICEINFOS ) @@ -875,30 +882,6 @@ uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance) return(KMDvalue); } -/*char *LP_pricestr(char *base,char *rel,double origprice) -{ - cJSON *retjson; double price = 0.; - if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 ) - { - price = LP_price(base,rel); - if ( origprice > SMALLVAL && origprice < price ) - price = origprice; - } - if ( LP_pricevalid(price) > 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"method","postprice"); - jaddbits256(retjson,"pubkey",G.LP_mypub25519); - jaddstr(retjson,"base",base); - jaddstr(retjson,"rel",rel); - jaddnum(retjson,"price",price); - jadd(retjson,"theoretical",LP_priceinfomatrix(0)); - jadd(retjson,"quotes",LP_priceinfomatrix(1)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"cant find baserel pair\"}")); -}*/ - void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) { LP_priceinfoupdate(base,rel,price); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index a039e6a70..991685332 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -477,7 +477,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) cJSON *LP_listunspent(char *symbol,char *coinaddr) { - char buf[128]; cJSON *retjson; struct iguana_info *coin; + char buf[128]; cJSON *retjson; int32_t numconfs; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); @@ -488,7 +488,10 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) { if ( LP_address_ismine(symbol,coinaddr) > 0 ) { - sprintf(buf,"[0, 99999999, [\"%s\"]]",coinaddr); + if ( strcmp(symbol,"BTC") == 0 ) + numconfs = 0; + else numconfs = 1; + sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); return(bitcoin_json(coin,"listunspent",buf)); } else return(LP_address_utxos(coin,coinaddr,0)); } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 61396e280..d369f5f24 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1882,6 +1882,31 @@ void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) return(clonestr("{\"result\":\"marked as spent\"}")); return(clonestr("{\"error\":\"cant find txid to check spent status\"}")); }*/ + + +/*char *LP_pricestr(char *base,char *rel,double origprice) + { + cJSON *retjson; double price = 0.; + if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 ) + { + price = LP_price(base,rel); + if ( origprice > SMALLVAL && origprice < price ) + price = origprice; + } + if ( LP_pricevalid(price) > 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"method","postprice"); + jaddbits256(retjson,"pubkey",G.LP_mypub25519); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"price",price); + jadd(retjson,"theoretical",LP_priceinfomatrix(0)); + jadd(retjson,"quotes",LP_priceinfomatrix(1)); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find baserel pair\"}")); + }*/ void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo) { struct _LP_utxoinfo u; struct iguana_info *coin; char str[65]; uint32_t now = (uint32_t)time(NULL); diff --git a/iguana/exchanges/setpassphrase b/iguana/exchanges/setpassphrase new file mode 100755 index 000000000..eec8bc5b1 --- /dev/null +++ b/iguana/exchanges/setpassphrase @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"passphrase\",\"passphrase\":\"put the passphrase here\",\"gui\":\"buildog\"}"