Browse Source

Merge pull request #498 from jl777/spvdex

fix vout encoding bug
etomic
jl777 7 years ago
committed by GitHub
parent
commit
59b67be15c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      iguana/exchanges/LP_commands.c
  2. 161
      iguana/exchanges/LP_ordermatch.c
  3. 14
      iguana/exchanges/LP_portfolio.c
  4. 2
      iguana/exchanges/LP_signatures.c
  5. 150
      iguana/exchanges/LP_statemachine.c
  6. 14
      iguana/exchanges/LP_tradebots.c
  7. 15
      iguana/exchanges/LP_transaction.c
  8. 20
      iguana/exchanges/LP_utxos.c

11
iguana/exchanges/LP_commands.c

@ -115,7 +115,6 @@ tradesarray(base, rel, starttime=<now>-timescale*1024, endtime=<now>, timescale=
pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
getrawtransaction(coin, txid)\n\
inventory(coin, reset=0, [passphrase=])\n\
bestfit(rel, relvolume)\n\
lastnonce()\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, destpubkey="")\n\
@ -385,13 +384,13 @@ zeroconf_claim(address, expiration=0)\n\
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 )
/*else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 )
{
double relvolume;
if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL )
return(LP_bestfit(rel,relvolume));
else return(clonestr("{\"error\":\"no relvolume set\"}"));
}
}*/
else if ( coin[0] != 0 )
{
if ( strcmp(method,"enable") == 0 )
@ -548,9 +547,11 @@ zeroconf_claim(address, expiration=0)\n\
jaddstr(retjson,"result","success");
jaddstr(retjson,"coin",coin);
jaddnum(retjson,"timestamp",time(NULL));
jadd(retjson,"alice",LP_inventory(coin));
jadd(retjson,"alice",cJSON_Parse("[]"));
//jadd(retjson,"alice",LP_inventory(coin));
//jadd(retjson,"bob",LP_inventory(coin,1));
LP_smartutxos_push(ptr);
//LP_smartutxos_push(ptr);
LP_address_utxo_reset(ptr);
return(jprint(retjson,1));
}
}

161
iguana/exchanges/LP_ordermatch.c

@ -496,7 +496,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(1,base,rel,zero,jprint(retjson,0));
LP_reserved_msg(0,base,rel,zero,jprint(retjson,0));
//LP_reserved_msg(0,base,rel,zero,jprint(retjson,0));
free_json(retjson);
retval = 0;
} else printf("error launching swaploop\n");
@ -751,7 +751,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag)
return(n);
}
char *LP_bestfit(char *rel,double relvolume)
/*char *LP_bestfit(char *rel,double relvolume)
{
struct LP_utxoinfo *autxo;
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 )
@ -759,7 +759,7 @@ char *LP_bestfit(char *rel,double relvolume)
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is close enough in size\"}"));
return(jprint(LP_utxojson(autxo),1));
}
}*/
int32_t LP_aliceonly(char *symbol)
{
@ -1005,7 +1005,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg));
LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg));
//LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg));
free(msg);
butxo->T.lasttime = (uint32_t)time(NULL);
return(retval);
@ -1024,113 +1024,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval);
}
#ifdef oldway
struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui)
{
uint64_t basesatoshis; struct LP_utxoinfo *bestutxo;
basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee);
//printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee));
if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 )
{
bestutxo->pubkey = pubkey;
safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui));
*bestsatoshisp = basesatoshis;
*ordermatchpricep = price;
*bestdestsatoshisp = asatoshis;
return(bestutxo);
}
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,bits256 destpubkey)
{
bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0;
maxiters = 100;
*ordermatchpricep = 0.;
*bestsatoshisp = *bestdestsatoshisp = 0;
basecoin = LP_coinfind(base);
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
if ( maxprice <= 0. || LP_priceinfofind(base) == 0 || basecoin == 0 )
return(0);
if ( basecoin->electrum == 0 )
max = 1000;
else max = LP_MAXDESIRED_UTXOS;
utxos = calloc(max,sizeof(*utxos));
LP_txfees(&txfee,&desttxfee,base,autxo->coin);
printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee));
if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 )
{
if ( (orderbook= cJSON_Parse(obookstr)) != 0 )
{
if ( (rawasks= jarray(&numasks,orderbook,"asks")) != 0 )
{
if ( (asks= LP_RTmetrics_sort(base,autxo->coin,rawasks,numasks,maxprice,dstr(autxo->S.satoshis))) == 0 )
asks = rawasks;
for (i=0; i<numasks; i++)
{
item = jitem(asks,i);
price = jdouble(item,"price");
//if ( price < maxprice && price > maxprice*0.8)
// price = price * 0.9 + 0.1 * maxprice;
//else price *= 1.005;
pubkey = jbits256(item,"pubkey");
if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 )
continue;
if ( LP_RTmetrics_blacklisted(pubkey) >= 0 )
continue;
//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis));
if ( LP_pricevalid(price) > 0 && price <= maxprice )
{
if ( bits256_nonz(destpubkey) == 0 )
{
for (j=0; j<numavoids; j++)
if ( bits256_cmp(pubkey,avoids[j]) == 0 )
break;
if ( j != numavoids )
continue;
}
if ( bits256_cmp(pubkey,G.LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
{
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
asatoshis = autxo->S.satoshis;
//LP_listunspent_query(base,coinaddr);
for (j=0; j<maxiters; j++)
{
if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,maxprice*.999,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 )
break;
} else printf("self trading or blacklisted peer\n");
}
else
{
if ( i == 0 )
printf("too expensive maxprice %.8f vs %.8f\n",maxprice,price);
break;
}
}
if ( asks != 0 && asks != rawasks )
free_json(asks);
}
free_json(orderbook);
}
free(obookstr);
}
free(utxos);
if ( *ordermatchpricep == 0. || *bestdestsatoshisp == 0 )
return(0);
int32_t changed;
LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep);
return(bestutxo);
}
#endif
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; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
@ -1173,8 +1066,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
else maxprice *= 1.001;
memset(pubkeys,0,sizeof(pubkeys));
LP_txfees(&txfee,&desttxfee,base,rel);
destsatoshis = SATOSHIDEN * relvolume;
//LP_address_utxo_reset(relcoin);
destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee;
memset(&A,0,sizeof(A));
LP_address_utxo_reset(relcoin);
if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) == 0 )
@ -1208,49 +1100,6 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
int32_t changed;
LP_mypriceset(&changed,autxo->coin,base,1. / maxprice);
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
#ifdef oldway
//LP_RTmetrics_update(base,rel);
while ( 1 )
{
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\"}"));
}
pubkeys[numpubs++] = bestutxo->pubkey;
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,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,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
maxiters = 200;
qprice = 1. / SMALLVAL;
for (i=0; i<maxiters; i++)
{
if ( (qprice= LP_quote_validate(autxo,0,&Q,0)) <= SMALLVAL )
{
printf("quote validate error %.0f\n",qprice);
return(clonestr("{\"error\":\"quote validate error\"}"));
}
if ( qprice/ordermatchprice < 1.+SMALLVAL )
{
//printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice);
if ( strcmp("BTC",Q.destcoin) == 0 || strcmp("BTC",Q.srccoin) == 0 )
Q.satoshis *= 0.999;
else Q.satoshis *= 0.9999;
} else break;
}
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));
if ( bits256_nonz(destpubkey) == 0 )
continue;
else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}"));
}
printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
}
return(clonestr("{\"error\":\"cant get here\"}"));
#endif
}

14
iguana/exchanges/LP_portfolio.c

@ -63,7 +63,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
}
free_json(array);
}
if ( (array= LP_inventory(symbol)) != 0 )
/*if ( (array= LP_inventory(symbol)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
@ -75,8 +75,9 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
}
}
free_json(array);
}
}*/
*valuep = valuesum;
satoshisum = valuesum;
return(satoshisum);
}
@ -489,7 +490,8 @@ 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; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2;
char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol);
requestid = quoteid = 0;
LP_myprice(&bid,&ask,buy->symbol,sell->symbol);
maxprice = ask;
@ -507,7 +509,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
{
if ( relvolume < dstr(LP_MIN_TXFEE) )
break;
if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 )
//if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 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,1)) != 0 )
@ -531,7 +534,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
for (i=0; i<100; i++)
{
relvolume *= .99;
if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 )
//if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
{
printf("i.%d relvolume %.8f from %.8f\n",i,relvolume,sell->relvolume);
break;

2
iguana/exchanges/LP_signatures.c

@ -723,7 +723,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
memset(&zero,0,sizeof(zero));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg));
LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg));
//LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg));
free(msg);
/*portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 )

150
iguana/exchanges/LP_statemachine.c

@ -3089,6 +3089,156 @@ if ( (0) )
portable_mutex_unlock(&ep->pendingQ.mutex);*/
//printf("%p SENT.(%s) to %s:%u\n",sitem,sitem->str,ep->ipaddr,ep->port);
#ifdef oldway
struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui)
{
uint64_t basesatoshis; struct LP_utxoinfo *bestutxo;
basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee);
//printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee));
if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 )
{
bestutxo->pubkey = pubkey;
safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui));
*bestsatoshisp = basesatoshis;
*ordermatchpricep = price;
*bestdestsatoshisp = asatoshis;
return(bestutxo);
}
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,bits256 destpubkey)
{
bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0;
maxiters = 100;
*ordermatchpricep = 0.;
*bestsatoshisp = *bestdestsatoshisp = 0;
basecoin = LP_coinfind(base);
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
if ( maxprice <= 0. || LP_priceinfofind(base) == 0 || basecoin == 0 )
return(0);
if ( basecoin->electrum == 0 )
max = 1000;
else max = LP_MAXDESIRED_UTXOS;
utxos = calloc(max,sizeof(*utxos));
LP_txfees(&txfee,&desttxfee,base,autxo->coin);
printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee));
if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 )
{
if ( (orderbook= cJSON_Parse(obookstr)) != 0 )
{
if ( (rawasks= jarray(&numasks,orderbook,"asks")) != 0 )
{
if ( (asks= LP_RTmetrics_sort(base,autxo->coin,rawasks,numasks,maxprice,dstr(autxo->S.satoshis))) == 0 )
asks = rawasks;
for (i=0; i<numasks; i++)
{
item = jitem(asks,i);
price = jdouble(item,"price");
//if ( price < maxprice && price > maxprice*0.8)
// price = price * 0.9 + 0.1 * maxprice;
//else price *= 1.005;
pubkey = jbits256(item,"pubkey");
if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 )
continue;
if ( LP_RTmetrics_blacklisted(pubkey) >= 0 )
continue;
//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis));
if ( LP_pricevalid(price) > 0 && price <= maxprice )
{
if ( bits256_nonz(destpubkey) == 0 )
{
for (j=0; j<numavoids; j++)
if ( bits256_cmp(pubkey,avoids[j]) == 0 )
break;
if ( j != numavoids )
continue;
}
if ( bits256_cmp(pubkey,G.LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
{
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
asatoshis = autxo->S.satoshis;
//LP_listunspent_query(base,coinaddr);
for (j=0; j<maxiters; j++)
{
if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,maxprice*.999,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 )
break;
} else printf("self trading or blacklisted peer\n");
}
else
{
if ( i == 0 )
printf("too expensive maxprice %.8f vs %.8f\n",maxprice,price);
break;
}
}
if ( asks != 0 && asks != rawasks )
free_json(asks);
}
free_json(orderbook);
}
free(obookstr);
}
free(utxos);
if ( *ordermatchpricep == 0. || *bestdestsatoshisp == 0 )
return(0);
int32_t changed;
LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep);
return(bestutxo);
}
#endif
#ifdef oldway
//LP_RTmetrics_update(base,rel);
while ( 1 )
{
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\"}"));
}
pubkeys[numpubs++] = bestutxo->pubkey;
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,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,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
maxiters = 200;
qprice = 1. / SMALLVAL;
for (i=0; i<maxiters; i++)
{
if ( (qprice= LP_quote_validate(autxo,0,&Q,0)) <= SMALLVAL )
{
printf("quote validate error %.0f\n",qprice);
return(clonestr("{\"error\":\"quote validate error\"}"));
}
if ( qprice/ordermatchprice < 1.+SMALLVAL )
{
//printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice);
if ( strcmp("BTC",Q.destcoin) == 0 || strcmp("BTC",Q.srccoin) == 0 )
Q.satoshis *= 0.999;
else Q.satoshis *= 0.9999;
} else break;
}
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));
if ( bits256_nonz(destpubkey) == 0 )
continue;
else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}"));
}
printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
}
return(clonestr("{\"error\":\"cant get here\"}"));
#endif
char *LP_ordermatch(char *base,int64_t txfee,double maxprice,double maxvolume,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration)
{
struct LP_quoteinfo Q; int64_t bestsatoshis=0,bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo;

14
iguana/exchanges/LP_tradebots.c

@ -455,12 +455,12 @@ char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson)
char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume)
{
struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin;
struct LP_tradebot *bot; char *retstr; double shortfall; cJSON *retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin;
basecoin = LP_coinfind(base);
relcoin = LP_coinfind(rel);
if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 )
return(clonestr("{\"error\":\"one or more coins inactive\"}"));
if ( (array= LP_inventory(rel)) != 0 )
/*if ( (array= LP_inventory(rel)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
@ -471,7 +471,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
}
}
free_json(array);
}
}*/
if ( (retstr= LP_orderbook(base,rel,0)) != 0 )
free(retstr);
txfee = LP_txfeecalc(relcoin,0,0);
@ -481,8 +481,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
else balance = LP_RTsmartbalance(relcoin);
sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*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 ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) )
//if ( dstr(abalance) < relvolume && balance > sum+2*txfee )
//if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) )
if ( balance < sum+2*txfee )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","not enough funds");
@ -493,7 +493,7 @@ 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);
if ( balance > sum+2*txfee )
/*if ( balance > sum+2*txfee )
{
char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item;
outputjson = cJSON_CreateObject();
@ -518,7 +518,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
free(withdrawstr);
}
free_json(outputjson);
}
}*/
return(jprint(retjson,1));
}
printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume);

15
iguana/exchanges/LP_transaction.c

@ -1210,13 +1210,8 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
}
//if ( bits256_nonz(utxotxid) == 0 )
{
if ( (ap= LP_address_utxo_reset(coin)) == 0 )
return(0);
}
//else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 )
// return(0);
memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 )
{
@ -1247,11 +1242,6 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,1,timestamp);
jdelete(txobj,"vin");
jadd(txobj,"vin",jduplicate(vins));
if ( change < 6000 )
{
adjust = change / numvouts;
change = 0;
}
printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts);
for (i=0; i<numvouts; i++)
{
@ -1281,6 +1271,11 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
}
if ( change < 6000 )
{
//adjust = change / numvouts; adjust messes up vout encoding!
change = 0;
}
if ( change != 0 )
txobj = bitcoin_txoutput(txobj,script,scriptlen,change);
if ( (rawtxbytes= bitcoin_json2hex(coin->isPoS,&txid,txobj,V)) != 0 )

20
iguana/exchanges/LP_utxos.c

@ -194,7 +194,7 @@ void LP_availableset(struct LP_utxoinfo *utxo)
}
}
}
*/
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{
@ -327,16 +327,6 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t
return(0);
}
txfee = LP_txfeecalc(coin,0,0);
/*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding
{
if ( value2 > 2*txfee )
tmpsatoshis = (((value2 - 2*txfee) / 9) << 3);
else
{
printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee));
return(0);
}
} else tmpsatoshis = (satoshis - txfee);*/
char str[65],str2[65],dispflag = 0;//(iambob == 0);
if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 )
{
@ -527,7 +517,7 @@ cJSON *LP_inventory(char *symbol)
printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0);
}
return(array);
}
}*/
int32_t LP_maxvalue(uint64_t *values,int32_t n)
{
@ -582,7 +572,7 @@ int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t
int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub)
{
int32_t enable_utxos = 0;
char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval;
char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo;
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
//printf("coin not active\n");
@ -682,7 +672,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
{
value = values[i];
values[i] = 0, used++;
portable_mutex_lock(&LP_UTXOmutex);
/*portable_mutex_lock(&LP_UTXOmutex);
if ( iambob != 0 )
{
if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 )
@ -696,7 +686,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
{
}
}
portable_mutex_unlock(&LP_UTXOmutex);
portable_mutex_unlock(&LP_UTXOmutex);*/
total += value;
} // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0));
} //else printf("nothing near i.%d\n",i);

Loading…
Cancel
Save