From 334ea570a9c4ebe1d684f370bbfae4006100359f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 4 Jul 2017 14:12:26 +0300 Subject: [PATCH] Test --- iguana/exchanges/LP_commands.c | 12 +++- iguana/exchanges/LP_ordermatch.c | 120 +++++++++++++++++++++---------- iguana/exchanges/LP_utxos.c | 10 ++- iguana/exchanges/ordermatch | 3 + 4 files changed, 103 insertions(+), 42 deletions(-) create mode 100755 iguana/exchanges/ordermatch diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c0cc1e9a6..fe5c4c0e3 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -66,8 +66,9 @@ myprice(base, rel)\n\ enable(coin)\n\ disable(coin)\n\ inventory(coin)\n\ -autotrade(base, rel, price, relvolume, timeout=10, duration=3600)\n\ bestfit(rel, relvolume)\n\ +ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\ +autotrade(base, rel, price, relvolume, timeout=10, duration=3600)\n\ swapstatus()\n\ swapstatus(requestid, quoteid)\n\ public API:\n \ @@ -102,7 +103,7 @@ forwardhex(pubkey,hex)\n\ return(clonestr("{\"error\":\"authentication error\"}")); if ( base != 0 && rel != 0 ) { - double price; + double price,bid,ask; if ( LP_isdisabled(base,rel) != 0 ) return(clonestr("{\"error\":\"at least one of coins disabled\"}")); price = jdouble(argjson,"price"); @@ -117,7 +118,6 @@ forwardhex(pubkey,hex)\n\ } else if ( strcmp(method,"myprice") == 0 ) { - double bid,ask; if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) { retjson = cJSON_CreateObject(); @@ -128,6 +128,12 @@ forwardhex(pubkey,hex)\n\ return(jprint(retjson,1)); } else return(clonestr("{\"error\":\"no price set\"}")); } + else if ( strcmp(method,"ordermatch") == 0 ) + { + if ( price > SMALLVAL ) + return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration"))); + else return(clonestr("{\"error\":\"no price set\"}")); + } else if ( strcmp(method,"autotrade") == 0 ) { if ( price > SMALLVAL ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0732db908..30a69d6ec 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -560,34 +560,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -char *LP_bestfit(char *rel,double relvolume) -{ - struct LP_utxoinfo *autxo; cJSON *retjson; - if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) - return(clonestr("{\"error\":\"invalid parameter\"}")); - if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) - return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); - retjson = LP_utxojson(autxo); - return(jprint(retjson,1)); -} - -char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) +struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,int64_t txfee,int64_t desttxfee) { - int64_t satoshis,destsatoshis,desttxfee,txfee,bestdestsatoshis=0; bits256 txid,pubkey; char *obookstr,*retstr; cJSON *orderbook,*asks,*item,*bestitem=0; struct LP_utxoinfo *autxo,*butxo,*bestutxo = 0; int32_t i,vout,numasks,DEXselector=0; uint32_t expiration; double ordermatchprice,bestmetric,metric,bestprice=0.,vol,price; struct LP_quoteinfo Q; struct LP_pubkeyinfo *pubp; + int64_t satoshis,destsatoshis; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,vout,numasks; double bestmetric=0.,metric,vol,price,bestprice = 0.; struct LP_pubkeyinfo *pubp; + *ordermatchpricep = 0.; + *bestdestsatoshisp = 0; if ( duration <= 0 ) duration = LP_ORDERBOOK_DURATION; - if ( timeout <= 0 ) - timeout = LP_AUTOTRADE_TIMEOUT; - if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) - return(clonestr("{\"error\":\"invalid parameter\"}")); - if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) - return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); - bestmetric = ordermatchprice = 0.; - if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + if ( maxprice <= 0. || LP_priceinfofind(base) == 0 ) + return(0); + if ( (desttxfee= LP_getestimatedrate(autxo->coin) * LP_AVETXSIZE) < LP_MIN_TXFEE ) desttxfee = LP_MIN_TXFEE; if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) txfee = LP_MIN_TXFEE; - if ( (obookstr= LP_orderbook(base,rel,duration)) != 0 ) + if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) { if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) { @@ -624,8 +610,8 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi if ( bestmetric == 0. || metric < bestmetric ) { bestutxo = butxo; - ordermatchprice = price; - bestdestsatoshis = destsatoshis; + *ordermatchpricep = price; + *bestdestsatoshisp = destsatoshis; bestmetric = metric; printf("set best!\n"); } @@ -646,41 +632,75 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi } free(obookstr); } - if ( bestutxo == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) + return(0); + return(bestutxo); +} + +char *LP_bestfit(char *rel,double relvolume) +{ + struct LP_utxoinfo *autxo; + if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); + return(jprint(LP_utxojson(autxo),1)); +} + +char *LP_ordermatch(char *base,int64_t txfee,double maxprice,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) +{ + struct LP_quoteinfo Q; int64_t bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; + if ( desttxfee == 0 && (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + desttxfee = LP_MIN_TXFEE; + if ( txfee == 0 && (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + if ( (autxo= LP_utxopairfind(0,txid,vout,feetxid,feevout)) == 0 ) + return(clonestr("{\"error\":\"cant find alice utxopair\"}")); + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); - bestutxo->T.bestflag = (uint32_t)time(NULL); + return(jprint(LP_quotejson(&Q),1)); +} + +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) +{ + struct LP_utxoinfo *bobutxo,*aliceutxo; char *retstr; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; + if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 ) + return(clonestr("{\"error\":\"cant find alice utxopair\"}")); + if ( (bobutxo= LP_utxopairfind(1,qp->txid,qp->vout,qp->txid2,qp->vout2)) == 0 ) + return(clonestr("{\"error\":\"cant find bob utxopair\"}")); + bobutxo->T.bestflag = (uint32_t)time(NULL); if ( (retstr= LP_registerall(0)) != 0 ) free(retstr); - price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",&Q); - bestitem = LP_quotejson(&Q); + price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",qp); + bestitem = LP_quotejson(qp); if ( price > SMALLVAL ) { if ( price <= maxprice ) { - price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",&Q); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,base,Q.satoshis,Q.destcoin,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector); + price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",qp); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,bobutxo->coin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector); expiration = (uint32_t)time(NULL) + timeout; while ( time(NULL) < expiration ) { - if ( autxo->S.swap != 0 ) + if ( aliceutxo->S.swap != 0 ) break; sleep(1); } - if ( autxo->S.swap == 0 ) + if ( aliceutxo->S.swap == 0 ) { - if ( (pubp= LP_pubkeyadd(bestutxo->pubkey)) != 0 ) + if ( (pubp= LP_pubkeyadd(bobutxo->pubkey)) != 0 ) pubp->numerrors++; jaddstr(bestitem,"status","couldnt establish connection"); } else jaddstr(bestitem,"status","connected"); jaddnum(bestitem,"quotedprice",price); jaddnum(bestitem,"maxprice",maxprice); - jaddnum(bestitem,"requestid",Q.R.requestid); - jaddnum(bestitem,"quoteid",Q.R.quoteid); - printf("Alice r.%u q.%u\n",Q.R.requestid,Q.R.quoteid); + jaddnum(bestitem,"requestid",qp->R.requestid); + jaddnum(bestitem,"quoteid",qp->R.quoteid); + printf("Alice r.%u qp->%u\n",qp->R.requestid,qp->R.quoteid); } else { @@ -694,11 +714,35 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi jaddnum(bestitem,"maxprice",maxprice); jaddstr(bestitem,"status","no response to request"); } - if ( autxo->S.swap == 0 ) - LP_availableset(autxo); + if ( aliceutxo->S.swap == 0 ) + LP_availableset(aliceutxo); return(jprint(bestitem,0)); } +char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) +{ + int64_t desttxfee,txfee,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double ordermatchprice=0.; struct LP_quoteinfo Q; + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( timeout <= 0 ) + timeout = LP_AUTOTRADE_TIMEOUT; + if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); + if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + desttxfee = LP_MIN_TXFEE; + if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + return(LP_trade(ctx,myipaddr,mypubsock,profitmargin,&Q,maxprice,timeout,duration)); +} + diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index c3969161d..bd7055070 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -72,6 +72,14 @@ struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) return(utxo); } +struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && vout2 == utxo->deposit.vout && bits256_cmp(utxo->deposit.txid,txid2) == 0 ) + return(utxo); + else return(0); +} + struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) { struct LP_utxoinfo *utxo=0; @@ -342,7 +350,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) return(0); HASH_ITER(hh,LP_utxoinfos[0],utxo,tmp) { - char str[65]; printf("[%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); + //char str[65]; printf("[%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); if ( strcmp(symbol,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { if ( utxo->S.satoshis >= destsatoshis && (bestutxo == 0 || utxo->S.satoshis < bestutxo->S.satoshis) ) diff --git a/iguana/exchanges/ordermatch b/iguana/exchanges/ordermatch new file mode 100755 index 000000000..05d30ba7e --- /dev/null +++ b/iguana/exchanges/ordermatch @@ -0,0 +1,3 @@ +source userpass +#ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\ +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"ordermatch\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234,\"duration\":600,\"txfee\":0,\"desttxfee\":0,\"txid\":\"$1\",\"vout\":$2,\"feetxid\":\"$3\",\"feevout\":$4}"