diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1c58d9e58..2bd4547c2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -90,7 +90,7 @@ void LP_millistats_update(struct LP_millistats *mp) #include "LP_etomic.h" #endif -portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex; +portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex,LP_gtcmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -1110,6 +1110,7 @@ void LP_swapsloop(void *ctx) sleep(6); } } + LP_gtc_iteration(); } } @@ -1473,6 +1474,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_blockinit_mutex); portable_mutex_init(&LP_pendswap_mutex); portable_mutex_init(&LP_listmutex); + portable_mutex_init(&LP_gtcmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1696f99a8..99ee259c6 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -18,6 +18,15 @@ // LP_ordermatch.c // marketmaker // + +struct LP_gtcorder +{ + struct LP_gtcorder *next,*prev; + struct LP_quoteinfo Q; + double maxprice; + uint32_t cancelled,pending; +} *GTCorders; + struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; double LP_Alicemaxprice; bits256 LP_Alicedestpubkey,LP_bobs_reserved; @@ -567,10 +576,42 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double return(retval); } +void LP_gtc_iteration() +{ + struct LP_gtcorder *gtc,*tmp; struct LP_quoteinfo *qp; uint64_t destvalue,destvalue2; + if ( Alice_expiration != 0 ) + return; + DL_FOREACH_SAFE(GTCorders,gtc,tmp) + { + qp = >c->Q; + if ( gtc->cancelled == 0 && LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) + { + gtc->cancelled = (uint32_t)time(NULL); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-9997,gtc->uuidstr); + } + if ( gtc->cancelled != 0 ) + { + portable_mutex_lock(&LP_gtcmutex); + DL_DELETE(GTCorders,gtc); + free(gtc); + portable_mutex_unlock(&LP_gtcmutex); + } + else + { + if ( time(NULL) > gtc->pending+LP_AUTOTRADE_TIMEOUT*10 ) + { + LP_query(ctx,myipaddr,mypubsock,"request",qp); + LP_Alicequery = *qp, LP_Alicemaxprice = gtc->maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = qp->srchash; + char str[65]; printf("LP_gtc fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),gtc->maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc); + break; + } + } + } +} + char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey,char *uuidstr) { - double price; - price = 0.; + struct LP_gtcorder *gtc; memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); @@ -578,8 +619,20 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->tradeid = LP_rand(); qp->srchash = destpubkey; strncpy(qp->uuidstr,uuidstr,sizeof(qp->uuidstr)-1); + qp->timestamp = (uint32_t)time(NULL); + if ( qp->gtc != 0 ) + { + qp->uuidstr[0] = 'G'; + gtc = calloc(1,sizeof(*gtc)); + gtc->Q = *qp; + gtc->maxprice = maxprice; + gtc->pending = (uint32_t)time(NULL); + portable_mutex_lock(&LP_gtcmutex); + DL_APPEND(GTCorders,gtc); + portable_mutex_unlock(&LP_gtcmutex); + } LP_query(ctx,myipaddr,mypubsock,"request",qp); - LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; + LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = qp->srchash; char str[65]; printf("LP_trade fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc); return(LP_recent_swaps(0,uuidstr)); } @@ -628,16 +681,45 @@ char *LP_cancel_order(char *uuidstr) int32_t num = 0; cJSON *retjson; if ( uuidstr != 0 ) { - num = LP_trades_canceluuid(uuidstr); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numentries",num); - if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 ) + if ( uuidstr[0] == 'G' ) { - LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr); - LP_alicequery_clear(); - jaddstr(retjson,"status","uuid canceled"); - } else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); + struct LP_gtcorder *gtc,*tmp; + DL_FOREACH_SAFE(GTCorders,gtc,tmp) + { + if ( strcmp(gtc->uuidstr,uuidstr) == 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"cancelled",uuidstr); + jaddstr(retjson,"pending",gtc->pending); + if ( gtc->cancelled == 0 ) + { + gtc->cancelled = (uint32_t)time(NULL); + jaddstr(retjson,"status","uuid canceled"); + LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9997,gtc->uuidstr); + } + else + { + jaddstr(retjson,"status","uuid already canceled"); + LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9996,gtc->uuidstr); + } + } + } + return(clonestr("{\"error\":\"gtc uuid not found\"}")); + } + else + { + num = LP_trades_canceluuid(uuidstr); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numentries",num); + if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 ) + { + LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr); + LP_alicequery_clear(); + jaddstr(retjson,"status","uuid canceled"); + } else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); + } return(jprint(retjson,1)); } return(clonestr("{\"error\":\"uuid not cancellable\"}")); @@ -1668,7 +1750,6 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha } } int32_t changed; - Q.gtc = gtcflag; Q.fill = fillflag; LP_mypriceset(&changed,rel,base,1. / maxprice); LP_mypriceset(&changed,base,rel,0.); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 0e59fc626..b41a809fa 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1038,7 +1038,7 @@ cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t hei coin = LP_coinfind(symbol); if ( coin == 0 || coin->electrum != 0 ) { - printf("unexpected electrum path for %s\n",symbol); + //printf("unexpected electrum path for %s\n",symbol); return(0); } if ( blockhashstr == 0 )