jl777 7 years ago
parent
commit
ff2907f8a6
  1. 1
      iguana/exchanges/LP_include.h
  2. 39
      iguana/exchanges/LP_ordermatch.c
  3. 29
      iguana/exchanges/LP_rpc.c
  4. 57
      iguana/exchanges/LP_scan.c
  5. 23
      iguana/exchanges/LP_transaction.c
  6. 4
      iguana/exchanges/LP_utxo.c

1
iguana/exchanges/LP_include.h

@ -311,6 +311,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr);
uint16_t LP_randpeer(char *destip); uint16_t LP_randpeer(char *destip);
int32_t LP_butxo_findeither(bits256 txid,int32_t vout); int32_t LP_butxo_findeither(bits256 txid,int32_t vout);
cJSON *LP_listunspent(char *symbol,char *coinaddr); cJSON *LP_listunspent(char *symbol,char *coinaddr);
int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid);
#endif #endif

39
iguana/exchanges/LP_ordermatch.c

@ -454,26 +454,31 @@ int32_t LP_nearest_utxovalue(struct LP_address_utxo **utxos,int32_t n,uint64_t t
return(mini); return(mini);
} }
uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t desttxfee)
{
return(SATOSHIDEN * ((relvolume + dstr(desttxfee)) / price) + 2*txfee);
}
struct LP_utxoinfo *LP_address_utxopair(struct LP_utxoinfo *utxo,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double volume,double price,int32_t avoidflag,uint64_t desttxfee) struct LP_utxoinfo *LP_address_utxopair(struct LP_utxoinfo *utxo,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double volume,double price,int32_t avoidflag,uint64_t desttxfee)
{ {
struct LP_address *ap; uint64_t targetval; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2;
if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 )
{ {
if ( (m= LP_address_utxo_ptrs(utxos,max,ap,avoidflag)) > 1 ) if ( (m= LP_address_utxo_ptrs(utxos,max,ap,avoidflag)) > 1 )
{ {
targetval = SATOSHIDEN * ((volume + dstr(desttxfee)) / price) + 2*txfee; targetval = LP_basesatoshis(volume,price,txfee,desttxfee);
{ {
int32_t i; int32_t i;
for (i=0; i<m; i++) for (i=0; i<m; i++)
printf("%.8f ",dstr(utxos[i]->U.value)); printf("%.8f ",dstr(utxos[i]->U.value));
printf("targetval %.8f vol %.8f price %.8f txfee %.8f\n",dstr(targetval),volume,price,dstr(txfee)); printf("targetval %.8f vol %.8f price %.8f txfee %.8f\n",dstr(targetval),volume,price,dstr(txfee));
} }
if ( (mini= LP_nearest_utxovalue(utxos,m,targetval)) >= 0 && (double)utxos[mini]->U.value/targetval < LP_MINVOL ) if ( (mini= LP_nearest_utxovalue(utxos,m,targetval)) >= 0 && (double)utxos[mini]->U.value/targetval < LP_MINVOL-1 )
{ {
up = utxos[mini]; up = utxos[mini];
utxos[mini] = 0; utxos[mini] = 0;
targetval = (up->U.value / 8) * 9 + 2*txfee; targetval2 = (up->U.value / 8) * 9 + 2*txfee;
if ( (mini= LP_nearest_utxovalue(utxos,m,targetval)) >= 0 ) if ( (mini= LP_nearest_utxovalue(utxos,m,targetval2)) >= 0 )
{ {
if ( up != 0 && (up2= utxos[mini]) != 0 ) if ( up != 0 && (up2= utxos[mini]) != 0 )
{ {
@ -486,7 +491,7 @@ struct LP_utxoinfo *LP_address_utxopair(struct LP_utxoinfo *utxo,struct LP_addre
utxo->deposit.txid = up2->U.txid; utxo->deposit.txid = up2->U.txid;
utxo->deposit.vout = up2->U.vout; utxo->deposit.vout = up2->U.vout;
utxo->deposit.value = up2->U.value; utxo->deposit.value = up2->U.value;
utxo->S.satoshis = SATOSHIDEN * (volume / price); utxo->S.satoshis = targetval;
return(utxo); return(utxo);
} }
} }
@ -911,9 +916,9 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
return(jprint(bestitem,0)); return(jprint(bestitem,0));
} }
struct LP_utxoinfo *LP_buyutxo(struct LP_utxoinfo *space,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,double relvolume,char *gui) struct LP_utxoinfo *LP_buyutxo(struct LP_utxoinfo *space,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 pubkey; char *obookstr,coinaddr[64],str[65]; cJSON *orderbook,*asks,*item; int32_t i,n,numasks,max = 10000; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; bits256 pubkey; char *obookstr,coinaddr[64],str[65]; cJSON *orderbook,*asks,*item; int32_t i,n,numasks,max = 10000; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; struct iguana_info *basecoin; uint64_t basesatoshis; struct LP_utxoinfo *bestutxo = 0;
*ordermatchpricep = 0.; *ordermatchpricep = 0.;
*bestsatoshisp = *bestdestsatoshisp = 0; *bestsatoshisp = *bestdestsatoshisp = 0;
basecoin = LP_coinfind(base); basecoin = LP_coinfind(base);
@ -944,11 +949,11 @@ struct LP_utxoinfo *LP_buyutxo(struct LP_utxoinfo *space,double *ordermatchprice
n = LP_listunspent_both(base,coinaddr); n = LP_listunspent_both(base,coinaddr);
if ( n > 1 ) if ( n > 1 )
{ {
if ( (bestutxo= LP_address_utxopair(space,utxos,max,basecoin,coinaddr,txfee,dstr(autxo->S.satoshis),price,0,desttxfee)) != 0 ) basesatoshis = LP_basesatoshis(dstr(autxo->S.satoshis),price,txfee,desttxfee);
if ( (bestutxo= LP_address_utxopair(space,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis),price,0,desttxfee)) != 0 )
{ {
bestutxo->pubkey = pubp->pubkey; bestutxo->pubkey = pubp->pubkey;
safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui)); safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui));
//autxo->S.satoshis = bestutxo->S.satoshis * price - desttxfee;
*bestsatoshisp = bestutxo->S.satoshis; *bestsatoshisp = bestutxo->S.satoshis;
*ordermatchpricep = price; *ordermatchpricep = price;
*bestdestsatoshisp = autxo->S.satoshis; *bestdestsatoshisp = autxo->S.satoshis;
@ -980,7 +985,7 @@ struct LP_utxoinfo *LP_buyutxo(struct LP_utxoinfo *space,double *ordermatchprice
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) 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)
{ {
uint64_t desttxfee,txfee; int64_t bestsatoshis=0,bestdestsatoshis=0; struct LP_utxoinfo *autxo,_best,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; uint64_t desttxfee,txfee; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct LP_utxoinfo *autxo,_bestB,_bestA,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q;
printf("LP_autobuy %s/%s price %.8f vol %.8f\n",base,rel,maxprice,relvolume); printf("LP_autobuy %s/%s price %.8f vol %.8f\n",base,rel,maxprice,relvolume);
if ( duration <= 0 ) if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION; duration = LP_ORDERBOOK_DURATION;
@ -989,10 +994,16 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}")); return(clonestr("{\"error\":\"invalid parameter\"}"));
LP_txfees(&txfee,&desttxfee,base,rel); LP_txfees(&txfee,&desttxfee,base,rel);
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume + desttxfee)) == 0 ) memset(&_bestA,0,sizeof(_bestA));
memset(&_bestB,0,sizeof(_bestB));
destsatoshis = SATOSHIDEN * relvolume + desttxfee;
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
memset(&_best,0,sizeof(_best)); _bestA = *autxo;
if ( (bestutxo= LP_buyutxo(&_best,&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,relvolume,gui)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) autxo = &_bestA;
if ( destsatoshis < autxo->S.satoshis )
autxo->S.satoshis = destsatoshis;
if ( (bestutxo= LP_buyutxo(&_bestB,&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )
{ {
printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis));
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); return(clonestr("{\"error\":\"cant find ordermatch utxo\"}"));

29
iguana/exchanges/LP_rpc.c

@ -626,7 +626,7 @@ double LP_getestimatedrate(struct iguana_info *coin)
char *LP_sendrawtransaction(char *symbol,char *signedtx) char *LP_sendrawtransaction(char *symbol,char *signedtx)
{ {
cJSON *array; char *paramstr,*tmpstr,*retstr=0; int32_t n; cJSON *retjson; struct iguana_info *coin; cJSON *array,*errobj; char *paramstr,*tmpstr,*retstr=0; int32_t n,alreadyflag = 0; cJSON *retjson; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(0); return(0);
coin = LP_coinfind(symbol); coin = LP_coinfind(symbol);
@ -646,14 +646,27 @@ char *LP_sendrawtransaction(char *symbol,char *signedtx)
if ( (retjson= electrum_sendrawtransaction(symbol,coin->electrum,&retjson,signedtx)) != 0 ) if ( (retjson= electrum_sendrawtransaction(symbol,coin->electrum,&retjson,signedtx)) != 0 )
{ {
retstr = jprint(retjson,1); retstr = jprint(retjson,1);
printf("electrum sendrawtx.(%s) -> %s\n",signedtx,retstr); //electrum sendrawtx (the transaction was rejected by network rules.\n\ntransaction already in block chain)
n = (int32_t)strlen(retstr); if ( strstr(retstr,"already in block") != 0 )
if ( retstr[0] == '"' && retstr[n-1] == '"' ) alreadyflag = 1;
printf("electrum sendrawtx.(%s) -> %s already.%d\n",signedtx,retstr,alreadyflag);
if ( alreadyflag != 0 )
{ {
retstr[n-1] = 0; errobj = cJSON_CreateObject();
tmpstr = clonestr(retstr+1); jaddstr(errobj,"error","rejected");
free(retstr); jaddnum(errobj,"code",-27);
retstr = tmpstr; retstr = jprint(errobj,1);
}
else
{
n = (int32_t)strlen(retstr);
if ( retstr[0] == '"' && retstr[n-1] == '"' )
{
retstr[n-1] = 0;
tmpstr = clonestr(retstr+1);
free(retstr);
retstr = tmpstr;
}
} }
} }
} }

57
iguana/exchanges/LP_scan.c

@ -452,46 +452,53 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
expiration = (uint32_t)time(NULL) + duration; expiration = (uint32_t)time(NULL) + duration;
while ( 1 ) while ( 1 )
{ {
if ( coin->electrum == 0 ) if ( LP_gettx_presence(symbol,txid) != 0 )
{ numconfirms = 0;
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
}
else else
{ {
if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 ) if ( coin->electrum == 0 )
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
numconfirms = 0;
}
else
{ {
char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0)); if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 )
if ( (n= cJSON_GetArraySize(array)) > 0 )
{ {
for (i=0; i<n; i++) char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{ {
item = jitem(array,i); for (i=0; i<n; i++)
if ( bits256_cmp(txid,jbits256(item,"tx_hash")) == 0 )
{ {
char str[65]; printf("found %s %s in mempool\n",symbol,bits256_str(str,txid)); item = jitem(array,i);
numconfirms = 0; if ( bits256_cmp(txid,jbits256(item,"tx_hash")) == 0 )
break; {
char str[65]; printf("found %s %s in mempool\n",symbol,bits256_str(str,txid));
numconfirms = 0;
break;
}
} }
} }
free(array);
}
LP_listunspent_issue(coin->symbol,coinaddr);
struct LP_address_utxo *up;
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{
char str[65]; printf("address_utxofind found confirmed %s %s %s ht.%d vs %d\n",symbol,coinaddr,bits256_str(str,txid),up->U.height,coin->height);
if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 )
free_json(array);
if ( coin->height >= up->U.height )
numconfirms = (coin->height - up->U.height + 1);
} }
free(array);
}
LP_listunspent_issue(coin->symbol,coinaddr);
struct LP_address_utxo *up;
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{
char str[65]; printf("address_utxofind found confirmed %s %s %s ht.%d vs %d\n",symbol,coinaddr,bits256_str(str,txid),up->U.height,coin->height);
if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 )
free_json(array);
if ( coin->height >= up->U.height )
numconfirms = (coin->height - up->U.height + 1);
} }
} }
if ( time(NULL) > expiration || numconfirms >= 0 ) if ( time(NULL) > expiration || numconfirms >= 0 )
break; break;
usleep(500000); usleep(500000);
} }
if ( numconfirms <= 0 )
numconfirms = LP_numconfirms(symbol,coinaddr,txid,vout,1);
return(numconfirms); return(numconfirms);
} }

23
iguana/exchanges/LP_transaction.c

@ -19,13 +19,31 @@
// marketmaker // marketmaker
// //
int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid)
{
cJSON *txobj; bits256 txid; int32_t flag = 0;
if ( (txobj= LP_gettx(symbol,expectedtxid)) != 0 )
{
txid = jbits256(txobj,"txid");
if ( jobj(txobj,"error") == 0 && bits256_cmp(txid,expectedtxid) == 0 )
{
char str[65]; printf("%s already in gettx (%s)\n",bits256_str(str,txid),jprint(txobj,0));
flag = 1;
}
free_json(txobj);
}
return(flag);
}
bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid) bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid)
{ {
char *retstr; bits256 txid; cJSON *retjson,*errorobj; int32_t i,sentflag = 0; char *retstr; bits256 txid; cJSON *retjson,*errorobj; int32_t i,sentflag = 0;
memset(&txid,0,sizeof(txid)); memset(&txid,0,sizeof(txid));
for (i=0; i<1; i++) for (i=0; i<2; i++)
{ {
if ( (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 ) if ( sentflag == 0 && LP_gettx_presence(symbol,expectedtxid) != 0 )
sentflag = 1;
if ( sentflag == 0 && (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 )
{ {
if ( is_hexstr(retstr,0) == 64 ) if ( is_hexstr(retstr,0) == 64 )
{ {
@ -50,6 +68,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi
} }
if ( sentflag != 0 ) if ( sentflag != 0 )
break; break;
sleep(3);
} }
return(txid); return(txid);
} }

4
iguana/exchanges/LP_utxo.c

@ -542,7 +542,6 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool)
{ {
struct iguana_info *coin; int32_t ht,numconfirms = 100; struct iguana_info *coin; int32_t ht,numconfirms = 100;
//#ifndef BASILISK_DISABLEWAITTX
cJSON *txobj; cJSON *txobj;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1); return(-1);
@ -560,14 +559,13 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
else else
{ {
if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height ) if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height )
numconfirms = (LP_getheight(coin) - ht); numconfirms = (LP_getheight(coin) - ht + 1);
else if ( mempool != 0 ) else if ( mempool != 0 )
{ {
if (LP_waitmempool(symbol,coinaddr,txid,vout,30) >= 0 ) if (LP_waitmempool(symbol,coinaddr,txid,vout,30) >= 0 )
numconfirms = 0; numconfirms = 0;
} }
} }
//#endif
return(numconfirms); return(numconfirms);
} }

Loading…
Cancel
Save