Browse Source

Merge pull request #467 from jl777/spvdex

dICO release candidate - electrum speed improvements, bug fixes
etomic
jl777 8 years ago
committed by GitHub
parent
commit
1bef785475
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      iguana/exchanges/LP_include.h
  2. 23
      iguana/exchanges/LP_nativeDEX.c
  3. 114
      iguana/exchanges/LP_ordermatch.c
  4. 19
      iguana/exchanges/LP_remember.c
  5. 48
      iguana/exchanges/LP_rpc.c
  6. 2
      iguana/exchanges/LP_socket.c
  7. 10
      iguana/exchanges/LP_tradebots.c
  8. 2
      iguana/exchanges/LP_transaction.c
  9. 13
      iguana/exchanges/LP_utxo.c
  10. 2
      iguana/exchanges/LP_utxos.c
  11. 2
      iguana/exchanges/sell

5
iguana/exchanges/LP_include.h

@ -23,7 +23,7 @@
#define LP_MAJOR_VERSION "0"
#define LP_MINOR_VERSION "1"
#define LP_BUILD_NUMBER "14288"
#define LP_BUILD_NUMBER "14336"
#ifdef FROM_JS
#include <emscripten.h>
@ -238,7 +238,7 @@ struct LP_swap_remember
bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)];
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid;
int64_t values[sizeof(txnames)/sizeof(*txnames)];
uint32_t tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char src[64],dest[64],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)];
@ -443,6 +443,7 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina
int32_t LP_destaddr(char *destaddr,cJSON *item);
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration);
char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey);
uint32_t LP_heighttime(char *symbol,int32_t height);
uint64_t LP_unspents_load(char *symbol,char *addr);
int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid);

23
iguana/exchanges/LP_nativeDEX.c

@ -18,9 +18,10 @@
// LP_nativeDEX.c
// marketmaker
//
// immediate "request", actual auction
// alice waiting for bestprice
// regen inventory
// previously, it used to show amount, kmd equiv, perc
//there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation
// there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation
// bot safe to exit?
//
// BCH signing
@ -466,7 +467,7 @@ void utxosQ_loop(void *myipaddr)
void LP_coinsloop(void *_coins)
{
struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
if ( strcmp("BTC",coins) == 0 )
{
strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop");
@ -514,14 +515,23 @@ void LP_coinsloop(void *_coins)
{
if ( (backupep= ep->prev) == 0 )
backupep = ep;
//HASH_ITER(hh,coin->addresses,ap,atmp)
// skip cLP_address MNZ bXcSsYBiVKtTzYErqxvma4UsojZTEf5L6H
//printf("electrum %s\n",coin->symbol);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
{
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
free_json(retjson);
}
HASH_ITER(hh,coin->addresses,ap,atmp)
{
//printf("call unspent %s\n",ap->coinaddr);
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
free_json(retjson);
}
HASH_ITER(hh,coin->addresses,ap,atmp)
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
break;
if ( up->U.height > 0 && up->spendheight < 0 )
{
if ( up->SPV == 0 )
@ -813,12 +823,14 @@ void LP_reserved_msgs(void *ignore)
if ( num_Reserved_msgs[1] > 0 )
{
num_Reserved_msgs[1]--;
//printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]);
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]);
Reserved_msgs[1][num_Reserved_msgs[1]] = 0;
}
else if ( num_Reserved_msgs[0] > 0 )
{
num_Reserved_msgs[0]--;
//printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]);
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]);
Reserved_msgs[0][num_Reserved_msgs[0]] = 0;
}
@ -845,6 +857,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha
if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] )
{
max_Reserved_msgs[priority] = num_Reserved_msgs[priority];
if ( (max_Reserved_msgs[priority] % 100) == 0 )
printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]);
}
portable_mutex_unlock(&LP_reservedmutex);

114
iguana/exchanges/LP_ordermatch.c

@ -18,6 +18,35 @@
// LP_ordermatch.c
// marketmaker
//
struct LP_quoteinfo LP_Alicequery;
double LP_Alicemaxprice;
uint32_t Alice_expiration;
struct { uint64_t aliceid; double bestprice; } Bob_competition[512];
double LP_bob_competition(uint64_t aliceid,double price)
{
int32_t i,firsti = -1;
for (i=0; i<sizeof(Bob_competition)/sizeof(*Bob_competition); i++)
{
if ( Bob_competition[i].aliceid == aliceid )
{
if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) )
{
Bob_competition[i].bestprice = price;
//printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price);
}
return(Bob_competition[i].bestprice);
}
else if ( Bob_competition[i].aliceid == 0 )
firsti = i;
}
if ( firsti < 0 )
firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition)));
Bob_competition[firsti].aliceid = aliceid;
Bob_competition[firsti].bestprice = price;
//printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price);
return(price);
}
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen)
{
@ -115,7 +144,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
{
if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 )
{
char str[65]; printf("alice not eligible destsatoshis %.8f (%.8f %.8f) %s/v%d\n",dstr(qp->destsatoshis),dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->feetxid),qp->feevout);
char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
return(-3);
}
if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 )
@ -413,9 +442,6 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
return(retval);
}
struct LP_quoteinfo LP_Alicequery;
double LP_Alicemaxprice;
uint32_t Alice_expiration;
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)
{
struct LP_utxoinfo *aliceutxo; double price; //cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
@ -486,14 +512,6 @@ char *LP_connectedalice(cJSON *argjson) // alice
return(clonestr("{\"result\",\"update stats\"}"));
}
printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid);
/*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 )
{
printf("reject mismatched alice query\n");
return(clonestr("{\"error\",\"mismatched alice query\"}"));
}
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;*/
if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 )
{
printf("cant find autxo\n");
@ -502,6 +520,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
}
if ( autxo->S.swap != 0 )
{
printf("ignore duplicate swap\n");
LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0);
return(clonestr("{\"error\":\"ignore duplicate swap\"}"));
}
@ -518,7 +537,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
}
if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL )
{
//printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask);
printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask);
LP_availableset(autxo);
LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0);
return(clonestr("{\"error\":\"no price set\"}"));
@ -669,22 +688,26 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{
char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t value,value2; cJSON *retjson; double qprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t retval = -1,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid,value,value2; cJSON *retjson; double qprice,range,bestprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t r,retval = -1,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) )
{
// LP_checksig
LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
LP_tradecommand_log(argjson);
//printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid);
//printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis);
retval = 1;
autxo = &A;
butxo = &B;
memset(autxo,0,sizeof(*autxo));
memset(butxo,0,sizeof(*butxo));
LP_abutxo_set(autxo,butxo,&Q);
aliceid = j64bits(argjson,"aliceid");
qprice = jdouble(argjson,"price");
if ( strcmp(method,"reserved") == 0 )
{
bestprice = LP_bob_competition(aliceid,qprice);
//printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice);
if ( LP_Alicemaxprice == 0. )
return(retval);
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 )
@ -699,7 +722,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid));
return(retval);
}
else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 )
else if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 )
{
printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2));
return(retval);
@ -737,11 +760,14 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
return(retval);
}
if ( (coin= LP_coinfind(Q.srccoin)) == 0 || (price= LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin)) <= SMALLVAL || ask <= SMALLVAL )
price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin);
if ( (coin= LP_coinfind(Q.srccoin)) == 0 || price <= SMALLVAL || ask <= SMALLVAL )
{
//printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin);
return(retval);
}
price = ask;
//printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price);
if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 )
{
printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid));
@ -752,7 +778,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid));
return(retval);
}
price = ask;
if ( LP_aliceonly(Q.srccoin) > 0 )
{
printf("{\"error\":\"GAME can only be alice coin\"}\n");
@ -760,11 +785,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
if ( strcmp(method,"request") == 0 )
{
char str[65],str2[65];
//printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0));
char str[65];//,str2[65];
recalc = 0;
if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 )
if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 )
{
qprice = (double)Q.destsatoshis / Q.satoshis;
strcpy(Q.gui,G.gui);
strcpy(Q.coinaddr,coin->smartaddr);
strcpy(butxo->coinaddr,coin->smartaddr);
@ -776,16 +801,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL )
recalc = 1;
else
else if ( price < qprice )
{
char tmp[64];
price = (qprice * 0.5) + (0.5 * price);
if ( bits256_nonz(Q.txid) != 0 )
LP_utxos_remove(Q.txid,Q.vout);
else recalc = 1;
if ( bits256_nonz(Q.txid2) != 0 )
LP_utxos_remove(Q.txid2,Q.vout2);
else recalc = 1;
printf("price %.8f qprice %.8f\n",price,qprice);
if ( recalc == 0 )
{
value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout);
@ -793,13 +818,21 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
//printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2));
if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 )
recalc = 1;
}
else
{
if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout )
else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout )
recalc = 1;
}
}
} else return(retval);
if ( qprice > price )
{
r = (rand() % 100);
range = (qprice - price);
printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + (r*range)/100.,LP_bob_competition(aliceid,price));
price += (r * range) / 100.;
bestprice = LP_bob_competition(aliceid,price);
if ( price < bestprice+SMALLVAL )
return(retval);
} else return(retval);
//printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0));
if ( recalc != 0 )
{
LP_RTmetrics_update(Q.srccoin,Q.destcoin);
@ -808,7 +841,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash));
return(retval);
}
//printf("butxo.%p recalc path %p %s, %p %s, %.8f\n",butxo,LP_allocated(butxo->payment.txid,butxo->payment.vout),bits256_str(str,butxo->payment.txid),LP_allocated(butxo->deposit.txid,butxo->deposit.vout),bits256_str(str2,butxo->deposit.txid),LP_quote_validate(autxo,butxo,&Q,1));
LP_listunspent_both(Q.srccoin,Q.coinaddr,0);
if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 )
{
@ -819,8 +851,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
Q.vout = butxo->payment.vout;
Q.txid2 = butxo->deposit.txid;
Q.vout2 = butxo->deposit.vout;
butxo->S.satoshis = Q.satoshis;
printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis));
Q.satoshis = butxo->S.satoshis;
//printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis));
}
else
{
@ -851,9 +883,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("quote validate error %.0f\n",qprice);
return(-3);
}
if ( qprice < (price - 0.00000001) * 0.998 )
if ( qprice < (ask - 0.00000001) * 0.998 )
{
printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin);
printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998);
return(retval);
}
char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0));
@ -874,7 +906,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
jaddstr(retjson,"method","reserved");
msg = jprint(retjson,0);
butxo->T.lasttime = (uint32_t)time(NULL);
printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg);
printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg);
// LP_addsig
//msg2 = clonestr(msg);
LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg));
@ -1011,7 +1043,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
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,uint32_t tradeid)
{
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];
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,B,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100];
basecoin = LP_coinfind(base);
relcoin = LP_coinfind(rel);
if ( gui == 0 )
@ -1076,8 +1108,18 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value));
return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}"));
}
bestsatoshis = LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee);
memset(&B,0,sizeof(B));
strcpy(B.coin,base);
if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
int32_t changed;
LP_mypriceset(&changed,autxo->coin,base,1. / maxprice);
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid));
LP_RTmetrics_update(base,rel);
//return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid));
while ( 1 )
{
if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )

19
iguana/exchanges/LP_remember.c

@ -450,6 +450,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
{
cJSON *item,*array; int32_t i;
item = cJSON_CreateObject();
jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2);
jaddnum(item,"tradeid",rswap->tradeid);
jaddnum(item,"requestid",rswap->requestid);
jaddnum(item,"quoteid",rswap->quoteid);
@ -476,7 +477,10 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
jadd(item,"values",array);
jaddstr(item,"result","success");
if ( rswap->finishedflag != 0 )
{
jaddstr(item,"status","finished");
jaddnum(item,"finishtime",rswap->finishtime);
}
else jaddstr(item,"status","pending");
jaddbits256(item,"bobdeposit",rswap->txids[BASILISK_BOBDEPOSIT]);
jaddbits256(item,"alicepayment",rswap->txids[BASILISK_ALICEPAYMENT]);
@ -657,6 +661,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
{
if ( (fileobj= cJSON_Parse(fstr)) != 0 )
{
rswap->finishtime = juint(fileobj,"finishtime");
rswap->origfinishedflag = rswap->finishedflag = 1;
free_json(fileobj);
}
@ -1115,6 +1120,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( (fp= fopen(fname,"wb")) != 0 )
{
jaddstr(item,"method","tradestatus");
jaddnum(item,"finishtime",rswap.finishtime);
jaddstr(item,"gui",G.gui);
itemstr = jprint(item,0);
fprintf(fp,"%s\n",itemstr);
@ -1131,7 +1137,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
{
uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[16],BTCtotals[16],Btotal,Ktotal; int32_t i,j,count=0;
uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS],Btotal,Ktotal; int32_t i,j,count=0;
portable_mutex_lock(&LP_swaplistmutex);
memset(ridqids,0,sizeof(ridqids));
memset(KMDtotals,0,sizeof(KMDtotals));
@ -1223,8 +1229,13 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid)
{
char *liststr,*retstr = 0; cJSON *retjson,*array,*item; int32_t i,n;
if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 )
cJSON *item; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS];
memset(KMDtotals,0,sizeof(KMDtotals));
memset(BTCtotals,0,sizeof(BTCtotals));
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
return(jprint(item,1));
else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}"));
/*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 )
{
//printf("swapentry.(%s)\n",liststr);
if ( (retjson= cJSON_Parse(liststr)) != 0 )
@ -1246,7 +1257,7 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid)
}
free(liststr);
}
return(retstr);
return(retstr);*/
}
extern struct LP_quoteinfo LP_Alicequery;

48
iguana/exchanges/LP_rpc.c

@ -447,6 +447,23 @@ uint32_t LP_locktime(char *symbol,bits256 txid)
return(locktime);
}
/*uint32_t LP_txtime(char *symbol,bits256 txid)
{
struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0;
char str[65]; printf("LP_txtime (%s %s)\n",symbol,bits256_str(str,txid));
if ( (timestamp= LP_locktime(symbol,txid)) != 0 )
return(timestamp);
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
height = tx->height;
timestamp = LP_heighttime(symbol,height);
}
}
return(height);
}*/
cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value)
{
cJSON *retjson,*addresses,*sobj;
@ -1013,6 +1030,37 @@ cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr)
return(bitcoin_json(coin,"getblock",buf));
}
uint32_t LP_heighttime(char *symbol,int32_t height)
{
struct electrum_info *ep; uint32_t timestamp = 0; cJSON *retjson; char *blockhashstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin != 0 )
{
if ( (ep= coin->electrum) == 0 )
{
if ( (blockhashstr= LP_blockhashstr(symbol,height)) != 0 )
{
if ( (retjson= cJSON_Parse(blockhashstr)) != 0 )
{
printf("height.(%s)\n",jprint(retjson,0));
timestamp = juint(retjson,"time");
free_json(retjson);
}
free(blockhashstr);
}
}
else
{
if ( (retjson= electrum_getheader(coin->symbol,ep,&retjson,height)) != 0 )
{
printf("%s\n",jprint(retjson,0));
timestamp = juint(retjson,"timestamp");
free_json(retjson);
}
}
}
return(timestamp);
}
cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height)
{
cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin;

2
iguana/exchanges/LP_socket.c

@ -329,7 +329,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
tx->height = ht;
if ( ep != 0 && coin != 0 && tx->SPV == 0 )
{
if ( strcmp(coinaddr,coin->smartaddr) == 0 )
if ( 0 && strcmp(coinaddr,coin->smartaddr) == 0 )
tx->SPV = LP_merkleproof(coin,coin->smartaddr,ep,txid,tx->height);
//printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height);
}

10
iguana/exchanges/LP_tradebots.c

@ -476,13 +476,14 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
free(retstr);
txfee = LP_txfeecalc(relcoin,0,0);
txfees = 10 * txfee;
printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees));
if ( dstr(abalance) < relvolume + dstr(txfees) )
{
retjson = cJSON_CreateObject();
if ( relcoin->electrum != 0 )
balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr);
else balance = LP_RTsmartbalance(relcoin);
sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777);
printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum));
if ( dstr(abalance) < relvolume + dstr(txfees) && balance > sum+txfee )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","not enough funds");
jaddstr(retjson,"coin",rel);
jaddnum(retjson,"abalance",dstr(abalance));
@ -491,7 +492,6 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
jaddnum(retjson,"txfees",dstr(txfees));
shortfall = (relvolume + dstr(txfees)) - dstr(balance);
jaddnum(retjson,"shortfall",shortfall);
sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777);
if ( balance >= sum+txfee )
{
char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item;

2
iguana/exchanges/LP_transaction.c

@ -652,7 +652,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
satoshis = value - 3*txfee/4;
printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value));
}
else if ( value == satoshis && (double)txfee/value < 0.1 )
else if ( value == satoshis && (double)txfee/value < 0.25 )
{
satoshis = value - txfee;
printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee));

13
iguana/exchanges/LP_utxo.c

@ -64,7 +64,10 @@ struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap = 0;
if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 )
{
ap = _LP_addressadd(coin,coinaddr);
//printf("LP_address %s %s\n",coin->symbol,coinaddr);
}
return(ap);
}
@ -145,6 +148,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
//printf("LP_address_utxo_ptrs for (%s).(%s)\n",ap->coinaddr,coinaddr);
if ( strcmp(ap->coinaddr,coinaddr) != 0 )
printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr);
LP_listunspent_issue(coin->symbol,coin->smartaddr,2);
portable_mutex_lock(&LP_utxomutex);
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
@ -185,7 +189,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
continue;
}
}
if ( LP_allocated(up->U.txid,up->U.vout) == 0 && _LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0 )
if ( LP_allocated(up->U.txid,up->U.vout) == 0 && (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) )
{
utxos[n++] = up;
if ( n >= max )
@ -660,6 +664,11 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 )
numconfirms = 0;
else if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
numconfirms = jint(txobj,"confirmations");
free_json(txobj);
}
}
else
{
@ -847,7 +856,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
}
return(1);
}
} // else printf("no val2\n");
} else printf("no val2 %.8f < threshold %.8f\n",dstr(val),dstr(threshold));
}
/*char str2[65];
if ( val != 0 && val2 != 0 )

2
iguana/exchanges/LP_utxos.c

@ -549,12 +549,12 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
if ( coin->privkeydepth > 0 )
return(0);
coin->privkeydepth++;
LP_address(coin,coin->smartaddr);
//printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth);
if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
array = LP_listunspent(coin->symbol,coin->smartaddr);
//printf("unspent array %ld\n",strlen(jprint(array,0)));
LP_address(coin,coin->smartaddr);
if ( array != 0 )
{
txfee = LP_txfeecalc(coin,0,0);

2
iguana/exchanges/sell

@ -1,3 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",price\":0.0005}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",\"price\":0.0005}"

Loading…
Cancel
Save