Browse Source

Merge pull request #420 from jl777/spvdex

working limitbot
etomic
jl777 7 years ago
committed by GitHub
parent
commit
cd581113b7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      iguana/exchanges/LP_coins.c
  2. 4
      iguana/exchanges/LP_commands.c
  3. 34
      iguana/exchanges/LP_include.h
  4. 12
      iguana/exchanges/LP_nativeDEX.c
  5. 50
      iguana/exchanges/LP_ordermatch.c
  6. 2
      iguana/exchanges/LP_portfolio.c
  7. 36
      iguana/exchanges/LP_remember.c
  8. 6
      iguana/exchanges/LP_rpc.c
  9. 9
      iguana/exchanges/LP_signatures.c
  10. 88
      iguana/exchanges/LP_statemachine.c
  11. 22
      iguana/exchanges/LP_swap.c
  12. 229
      iguana/exchanges/LP_tradebots.c
  13. 20
      iguana/exchanges/LP_transaction.c
  14. 2
      iguana/exchanges/LP_utxo.c
  15. 28
      iguana/exchanges/LP_utxos.c
  16. 2
      iguana/exchanges/stats.c

2
iguana/exchanges/LP_coins.c

@ -198,7 +198,7 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
if ( coin->userpass[0] != 0 )
{
jaddnum(item,"height",LP_getheight(coin));
balance = LP_smartbalance(coin);
balance = LP_RTsmartbalance(coin);
jaddnum(item,"balance",dstr(balance));
jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance)));
}

4
iguana/exchanges/LP_commands.c

@ -300,7 +300,7 @@ bot_resume(botid)\n\
//*
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey")));
return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"),0));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"sell") == 0 )
@ -308,7 +308,7 @@ bot_resume(botid)\n\
//*
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey")));
return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"),0));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}

34
iguana/exchanges/LP_include.h

@ -206,6 +206,31 @@ struct basilisk_swapinfo
uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
};
#define BASILISK_ALICESPEND 0
#define BASILISK_BOBSPEND 1
#define BASILISK_BOBPAYMENT 2
#define BASILISK_ALICEPAYMENT 3
#define BASILISK_BOBDEPOSIT 4
#define BASILISK_OTHERFEE 5
#define BASILISK_MYFEE 6
#define BASILISK_BOBREFUND 7
#define BASILISK_BOBRECLAIM 8
#define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
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;
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)];
};
struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; char coinaddr[64]; };
struct LP_transaction
@ -291,7 +316,8 @@ struct LP_quoteinfo
struct basilisk_request R;
bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey;
uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid;
uint32_t timestamp,quotetime; int32_t vout,vout2,destvout,feevout,pair;
uint32_t timestamp,quotetime,tradeid;
int32_t vout,vout2,destvout,feevout,pair;
char srccoin[16],coinaddr[64],destcoin[16],destaddr[64],gui[64];
};
@ -302,7 +328,8 @@ struct basilisk_swap
void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxoinfo *utxo;
struct LP_endpoint N;
void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob);
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted;
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf;
uint32_t lasttime,aborted,tradeid;
FILE *fp;
bits256 persistent_privkey,persistent_pubkey;
struct basilisk_swapinfo I;
@ -356,12 +383,13 @@ uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int3
//void LP_utxo_clientpublish(struct LP_utxoinfo *utxo);
int32_t LP_coinbus(uint16_t coin_busport);
int32_t LP_nanomsg_recvs(void *ctx);
uint64_t LP_smartbalance(struct iguana_info *coin);
uint64_t LP_RTsmartbalance(struct iguana_info *coin);
int32_t LP_getheight(struct iguana_info *coin);
int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg);
struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen);
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr);
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr);

12
iguana/exchanges/LP_nativeDEX.c

@ -49,7 +49,7 @@ uint32_t LP_lastnonce,LP_counter;
int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1;
int32_t LP_showwif,IAMLP = 0;
int32_t LP_numfinished,LP_showwif,IAMLP = 0;
double LP_profitratio = 1.;
struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; };
@ -147,7 +147,7 @@ char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
{
printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen);
jsonstr = 0;
} else printf("decrypted (%s)\n",jsonstr);
} //else printf("decrypted (%s)\n",jsonstr);
}
} else printf("cipher.%d too big for %d\n",cipherlen,(int32_t)sizeof(decoded));
*recvlenp = recvlen;
@ -236,8 +236,8 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
else
{
memset(zero.bytes,0,sizeof(zero));
if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) )
printf("broadcast.(%s)\n",Broadcaststr);
/*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) )
printf("broadcast.(%s)\n",Broadcaststr);*/
LP_reserved_msg("","",zero,jprint(reqjson,0));
}
retstr = clonestr("{\"result\":\"success\"}");
@ -1028,9 +1028,9 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
printf("error launching LP_swapsloop for port.%u\n",myport);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,ctx) != 0 )
{
printf("error launching LP_tradebot_timeslices for port.%u\n",myport);
printf("error launching LP_tradebot_timeslices\n");
exit(-1);
}
int32_t nonz;

50
iguana/exchanges/LP_ordermatch.c

@ -78,7 +78,7 @@ int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp,struct LP_utxoinfo *autxo,
double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp,int32_t iambob)
{
double qprice=0.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0;
printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis));
//printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis));
if ( butxo != 0 )
{
if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 )
@ -163,7 +163,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
txfee = qp->txfee;
if ( desttxfee < qp->desttxfee )
desttxfee = qp->desttxfee;
printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee));
//printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee));
if ( qp->txfee < LP_REQUIRED_TXFEE*txfee || qp->desttxfee < LP_REQUIRED_TXFEE*desttxfee )
return(-14);
if ( butxo != 0 )
@ -399,7 +399,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
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)
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;
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 )
@ -409,9 +409,11 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
}
price = 0.;
qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout);
qp->tradeid = tradeid;
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout;
return(clonestr("{\"result\":\"success\"}"));
printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis));
return(LP_recent_swaps(0));
}
int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2)
@ -441,6 +443,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo
price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout);
if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice )
{
qp->tradeid = LP_Alicequery.tradeid;
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;
@ -456,7 +459,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
clonestr("{\"error\":\"cant parse quote\"}");
if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 )
return(clonestr("{\"result\",\"update stats\"}"));
printf("CONNECTED.(%s) numpending.%d\n",jprint(argjson,0),G.LP_pendingswaps);
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");
@ -504,6 +507,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-2*Q.txfee,Q.destcoin,Q.destsatoshis-2*Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q);
swap->tradeid = Q.tradeid;
swap->N.pair = pairsock;
autxo->S.swap = swap;
swap->utxo = autxo;
@ -595,7 +599,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-2*Q.txfee,Q.destcoin,Q.destsatoshis-2*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 %s aliceid.%llx\n",method,(long long)Q.aliceid);
retval = 1;
if ( strcmp(method,"reserved") == 0 )
{
@ -612,7 +616,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 )
{
printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
//printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( (retstr= LP_connectedalice(argjson)) != 0 )
free(retstr);
}
@ -625,11 +629,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin);
return(retval);
}
if ( coin->electrum != 0 )
/*if ( coin->electrum != 0 )
{
printf("electrum can only be for alice\n");
return(retval);
}
}*/
if ( LP_aliceonly(Q.srccoin) > 0 )
{
printf("{\"error\":\"GAME can only be alice coin\"}\n");
@ -783,10 +787,10 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
return(0);
if ( basecoin->electrum == 0 )
max = 1000;
else max = 20;
else max = 40;
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));
//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 )
@ -826,7 +830,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
{
if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,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));
//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;
@ -857,7 +861,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
return(bestutxo);
}
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)
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];
basecoin = LP_coinfind(base);
@ -904,11 +908,21 @@ 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 + 2*desttxfee;
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis)) == 0 )
destsatoshis = SATOSHIDEN * relvolume;
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 )
return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}"));
if ( destsatoshis < autxo->S.satoshis )
if ( destsatoshis - 2*desttxfee < autxo->S.satoshis )
{
destsatoshis -= 2*desttxfee;
autxo->S.satoshis = destsatoshis;
printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis));
}
else if ( autxo->S.satoshis - 2*desttxfee < destsatoshis )
{
autxo->S.satoshis -= 2*desttxfee;
destsatoshis = autxo->S.satoshis;
printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis));
}
if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT )
{
printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value));
@ -938,7 +952,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
}
if ( qprice/ordermatchprice < 1.+SMALLVAL )
{
printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice);
//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;
@ -951,7 +965,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
continue;
else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}"));
}
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid));
}
return(clonestr("{\"error\":\"cant get here\"}"));
}

2
iguana/exchanges/LP_portfolio.c

@ -495,7 +495,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
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)) != 0 )
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 )
{
if ( (retjson2= cJSON_Parse(retstr2)) != 0 )
{

36
iguana/exchanges/LP_remember.c

@ -93,7 +93,7 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
fprintf(fp,"{\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee);
fprintf(fp,"{\"tradeid\":%u,\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->tradeid,(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee);
if ( memcmp(zeroes,swap->I.secretAm,20) != 0 )
{
init_hexbytes_noT(secretAmstr,swap->I.secretAm,20);
@ -303,20 +303,6 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in
return(spendtxid);
}
#define BASILISK_ALICESPEND 0
#define BASILISK_BOBSPEND 1
#define BASILISK_BOBPAYMENT 2
#define BASILISK_ALICEPAYMENT 3
#define BASILISK_BOBDEPOSIT 4
#define BASILISK_OTHERFEE 5
#define BASILISK_MYFEE 6
#define BASILISK_BOBREFUND 7
#define BASILISK_BOBRECLAIM 8
#define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind)
{
switch ( ind )
@ -460,21 +446,11 @@ void LP_totals_update(int32_t iambob,char *alicecoin,char *bobcoin,int64_t *KMDt
}
}
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 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)];
};
cJSON *LP_swap_json(struct LP_swap_remember *rswap)
{
cJSON *item,*array; int32_t i;
item = cJSON_CreateObject();
jaddnum(item,"tradeid",rswap->tradeid);
jaddnum(item,"requestid",rswap->requestid);
jaddnum(item,"quoteid",rswap->quoteid);
jaddnum(item,"iambob",rswap->iambob);
@ -523,6 +499,7 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
if ( (item= cJSON_Parse(fstr)) != 0 )
{
rswap->iambob = jint(item,"iambob");
rswap->tradeid = juint(item,"tradeid");
rswap->aliceid = j64bits(item,"aliceid");
if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 )
decode_hex(rswap->secretAm,20,secretstr);
@ -1130,7 +1107,10 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 )
{
char fname[1024],*itemstr; FILE *fp;
printf("SWAP %u-%u finished!\n",requestid,quoteid);
LP_numfinished++;
printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished);
if ( rswap.tradeid != 0 )
LP_tradebot_finished(rswap.tradeid,rswap.requestid,rswap.quoteid);
sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
@ -1307,6 +1287,7 @@ char *LP_recent_swaps(int32_t limit)
item = cJSON_CreateObject();
jaddnum(item,"expiration",Alice_expiration);
jaddnum(item,"timeleft",Alice_expiration-time(NULL));
jaddnum(item,"tradeid",LP_Alicequery.tradeid);
jaddnum(item,"requestid",LP_Alicequery.R.requestid);
jaddnum(item,"quoteid",LP_Alicequery.R.quoteid);
jaddstr(item,"bob",LP_Alicequery.srccoin);
@ -1315,6 +1296,7 @@ char *LP_recent_swaps(int32_t limit)
jaddstr(item,"alice",LP_Alicequery.destcoin);
jaddstr(item,"rel",LP_Alicequery.destcoin);
jaddnum(item,"relvalue",dstr(LP_Alicequery.destsatoshis));
jaddnum(item,"aliceid",LP_aliceid_calc(LP_Alicequery.desttxid,LP_Alicequery.destvout,LP_Alicequery.feetxid,LP_Alicequery.feevout));
jadd(retjson,"pending",item);
} else Alice_expiration = 0;
return(jprint(retjson,1));

6
iguana/exchanges/LP_rpc.c

@ -397,7 +397,7 @@ int32_t LP_getheight(struct iguana_info *coin)
return(height);
}
uint64_t LP_smartbalance(struct iguana_info *coin)
uint64_t LP_RTsmartbalance(struct iguana_info *coin)
{
cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value;
valuesum = 0;
@ -694,7 +694,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
}
else if ( IAMLP == 0 )
{
printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
//printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
LP_listunspent_query(coin->symbol,coin->smartaddr);
if ( fullflag != 0 )
{
@ -862,7 +862,7 @@ char *LP_sendrawtransaction(char *symbol,char *signedtx)
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr);
printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
//printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
}
else

9
iguana/exchanges/LP_signatures.c

@ -35,7 +35,7 @@ struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srch
rp->desthash = desthash;
rp->destamount = destsatoshis;
rp->quoteid = basilisk_quoteid(rp);
printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount));
//printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount));
return(rp);
}
@ -44,6 +44,7 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp)
double price; cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui);
jadd64bits(retjson,"aliceid",qp->aliceid);
jaddnum(retjson,"tradeid",qp->tradeid);
jaddstr(retjson,"base",qp->srccoin);
jaddstr(retjson,"rel",qp->destcoin);
if ( qp->coinaddr[0] != 0 )
@ -109,6 +110,7 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin));
safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr));
qp->aliceid = j64bits(argjson,"aliceid");
qp->tradeid = juint(argjson,"tradeid");
qp->timestamp = juint(argjson,"timestamp");
qp->quotetime = juint(argjson,"quotetime");
qp->txid = jbits256(argjson,"txid");
@ -146,7 +148,7 @@ void LP_txfees(uint64_t *txfeep,uint64_t *desttxfeep,char *base,char *rel)
{
*txfeep = LP_txfeecalc(LP_coinfind(base),0,0);
*desttxfeep = LP_txfeecalc(LP_coinfind(rel),0,0);
printf("LP_txfees(%.8f %.8f)\n",dstr(*txfeep),dstr(*desttxfeep));
//printf("LP_txfees(%.8f %.8f)\n",dstr(*txfeep),dstr(*desttxfeep));
}
int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price,uint64_t satoshis,uint64_t destsatoshis)
@ -680,8 +682,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
jaddnum(reqjson,"timestamp",time(NULL));
msg = jprint(reqjson,1);
msg2 = clonestr(msg);
// LP_addsig
printf("QUERY.(%s)\n",msg);
//printf("QUERY.(%s)\n",msg);
memset(&zero,0,sizeof(zero));
portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs < sizeof(Reserved_msgs)/sizeof(*Reserved_msgs)-2 )

88
iguana/exchanges/LP_statemachine.c

@ -1613,6 +1613,65 @@ void LP_address_monitor(struct LP_pubkeyinfo *pubp)
return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}*/
if ( flag != 0 )
{
// need to find the requestid/quoteid for aliceid
if ( (retstr= basilisk_swapentries(bot->base,bot->rel,0)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(retjson)) != 0 )
{
for (flag=j=0; j<n; j++)
{
item = jitem(retjson,j);
aliceid = j64bits(item,"aliceid");
for (i=0; i<bot->numtrades; i++)
{
if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid == 0 && tp->quoteid == 0 )
{
if ( tp->aliceid == aliceid )
{
tp->requestid = juint(item,"requestid");
tp->quoteid = juint(item,"quoteid");
printf("found aliceid.%llx to set requestid.%u quoteid.%u\n",(long long)aliceid,tp->requestid,tp->quoteid);
flag = 1;
break;
}
}
}
}
}
free_json(retjson);
}
free(retstr);
}
}
// check for finished pending swap
for (i=0; i<bot->numtrades; i++)
{
if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 )
{
if ( (retstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (status= jstr(retjson,"status")) != 0 && strcmp(status,"finished") == 0 )
{
bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol;
bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol;
bot->numpending--, bot->completed++;
printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid);
tp->finished = (uint32_t)time(NULL);
}
free_json(retjson);
}
free(retstr);
}
}
}
}
int32_t LP_utxopurge(int32_t allutxos)
{
char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0;
@ -2275,7 +2334,34 @@ void LP_price_broadcastloop(void *ctx)
retstr = clonestr("{\"result\":\"success\"}");
} else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}");
}
else*/ #ifdef FROM_JS
else*/
/*relvol = bot->totalrelvolume * .1;
p = LP_pricevol_invert(&v,bot->maxprice,relvol);
if ( bot->dispdir > 0 )
{
printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol);
}
else
{
minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum);
printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol);
}
if ( (rand() % 2) == 0 )
{
bot->relsum += relvol;
bot->basesum += v;
bot->completed++;
}
else
{
bot->pendrelsum += relvol;
bot->pendbasesum += v;
bot->numpending++;
}
bot->numtrades++;
*/
#ifdef FROM_JS
int32_t sentbytes,sock,peerind,maxind;
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;

22
iguana/exchanges/LP_swap.c

@ -275,13 +275,13 @@ int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
swap->I.pubA0.bytes[i] = data[len++];
for (i=0; i<32; i++)
swap->I.pubA1.bytes[i] = data[len++];
printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0));
//printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0));
swap->I.privBn = swap->privkeys[swap->I.otherchoosei];
memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei]));
revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn));
vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn));
swap->I.pubBn = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privBn);
printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256));
//printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256));
//basilisk_bobscripts_set(swap,1,1);
}
else
@ -290,18 +290,18 @@ int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
swap->I.pubB0.bytes[i] = data[len++];
for (i=0; i<32; i++)
swap->I.pubB1.bytes[i] = data[len++];
printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0));
//printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0));
swap->I.privAm = swap->privkeys[swap->I.otherchoosei];
memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei]));
revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm));
vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm));
swap->I.pubAm = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privAm);
printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256));
//printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256));
swap->bobdeposit.I.pubkey33[0] = 2;
swap->bobpayment.I.pubkey33[0] = 2;
for (i=0; i<32; i++)
swap->bobpayment.I.pubkey33[i+1] = swap->bobdeposit.I.pubkey33[i+1] = swap->I.pubA0.bytes[i];
printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0));
//printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0));
//basilisk_bobscripts_set(swap,0);
}
return(0);
@ -785,7 +785,7 @@ void LP_bobloop(void *_swap)
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice
{
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(10);
}
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 )
@ -798,7 +798,7 @@ void LP_bobloop(void *_swap)
basilisk_bobpayment_reclaim(swap,swap->I.callduration);
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,30);
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30);
}
}
}
@ -842,7 +842,7 @@ void LP_aliceloop(void *_swap)
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m )
{
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(10);
}
swap->sentflag = 1;
@ -852,19 +852,19 @@ void LP_aliceloop(void *_swap)
{
while ( (n= LP_numconfirms(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms )
{
char str[65];printf("%d waiting for bobpayment %s to be confirmed.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid));
char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid));
sleep(10);
}
/*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n");
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms )
{
char str[65];printf("%d waiting for alicespend %s to be confirmed.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid));
char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}*/
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,30);
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30);
}
}
}

229
iguana/exchanges/LP_tradebots.c

@ -23,10 +23,10 @@
struct LP_tradebot_trade
{
double maxprice,relvolume,basevol,relvol;
double maxprice,totalrelvolume,basevol,relvol;
uint64_t aliceid;
int32_t dispdir;
uint32_t started,finished,requestid,quoteid;
uint32_t started,finished,requestid,quoteid,tradeid;
char base[32],rel[32];
};
@ -40,21 +40,6 @@ struct LP_tradebot
struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES];
} *LP_tradebots;
/*struct tradebot_trade *tradebot_issuetrade(struct LP_tradebot *bot,char *base,char *rel,double price,double volume,int32_t dir)
{
struct tradebot_trade *tr; char *str; int32_t maxseconds = 30,dotrade = 1;
bot = realloc(bot,sizeof(*bot) + (bot->numtrades + 1) * sizeof(bot->trades[0]));
tr = &bot->trades[bot->numtrades++];
memset(tr,0,sizeof(*tr));
tr->price = price, tr->volume = volume, tr->dir = dir;
safecopy(tr->exchangestr,exchange->name,sizeof(tr->exchangestr));
safecopy(tr->base,base,sizeof(tr->base));
safecopy(tr->rel,rel,sizeof(tr->rel));
if ( (str= exchanges777_Qtrade(exchange,base,rel,maxseconds,dotrade,dir,price,volume,0)) != 0 )
free(str);
return(tr);
}*/
void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp)
{
char *swapstr,*status; int32_t flag; cJSON *swapjson;
@ -115,8 +100,11 @@ cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag)
double price,basevol; cJSON *item = cJSON_CreateObject();
if ( tp == 0 )
return(cJSON_Parse("{}"));
jaddnum(item,"requestid",tp->requestid);
jaddnum(item,"quoteid",tp->quoteid);
if ( tp->requestid != 0 && tp->quoteid != 0 )
{
jaddnum(item,"requestid",tp->requestid);
jaddnum(item,"quoteid",tp->quoteid);
} else jaddnum(item,"tradeid",tp->tradeid);
if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL )
{
if ( dispflag > 0 )
@ -154,9 +142,9 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot)
jaddnum(json,"maxprice",bot->maxprice);
jaddnum(json,"totalrelvolume",bot->totalrelvolume);
jaddnum(json,"totalbasevolume",bot->totalbasevolume);
if ( (vol= bot->relsum) > SMALLVAL )
if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL )
{
jaddnum(json,"aveprice",bot->basesum/vol);
jaddnum(json,"aveprice",vol/bot->basesum);
jaddnum(json,"volume",vol);
}
}
@ -169,15 +157,15 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot)
jaddnum(json,"minprice",aveprice);
jaddnum(json,"totalbasevolume",bot->totalrelvolume);
jaddnum(json,"totalrelvolume",basevolume);
if ( (vol= bot->relsum) > SMALLVAL )
if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL )
{
aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol);
aveprice = LP_pricevol_invert(&basevolume,vol/bot->basesum,vol);
jaddnum(json,"aveprice",aveprice);
jaddnum(json,"volume",basevolume);
}
}
array = cJSON_CreateArray();
//LP_tradebot_calcstats(bot);
LP_tradebot_calcstats(bot);
for (i=0; i<bot->numtrades; i++)
jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir));
jadd(json,"trades",array);
@ -248,67 +236,122 @@ void LP_tradebotadd(struct LP_tradebot *bot)
portable_mutex_unlock(&LP_tradebotsmutex);
}
void LP_tradebot_timeslice(struct LP_tradebot *bot)
struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pending,uint32_t tradeid)
{
struct LP_tradebot_trade *tp;
tp = calloc(1,sizeof(*tp));
tp->tradeid = tradeid;
tp->maxprice = bot->maxprice;
tp->totalrelvolume = bot->totalrelvolume;
tp->started = (uint32_t)time(NULL);
tp->dispdir = bot->dispdir;
strcpy(tp->base,bot->base);
strcpy(tp->rel,bot->rel);
tp->aliceid = j64bits(pending,"aliceid");
tp->basevol = jdouble(pending,"basevalue");
tp->relvol = jdouble(pending,"relvalue");
printf("tradebot pending basevol %.8f relvol %.8f\n",tp->basevol,tp->relvol);
bot->pendrelsum += tp->relvol;
bot->pendbasesum += tp->basevol;
bot->numpending++;
return(tp);
}
void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot)
{
double minprice,basevol,relvol,p,v;
if ( bot->dead == 0 )
double remaining; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending;
memset(destpubkey.bytes,0,sizeof(destpubkey));
if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) )
{
if ( bot->pause == 0 )
if ( (liststr= LP_recent_swaps(0)) != 0 )
{
//if ( (rand() % 100) == 0 )
if ( (retjson= cJSON_Parse(liststr)) != 0 )
{
relvol = bot->totalrelvolume * .1;
p = LP_pricevol_invert(&v,bot->maxprice,relvol);
if ( bot->dispdir > 0 )
{
printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol);
}
else
{
minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum);
printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol);
}
if ( (rand() % 2) == 0 )
if ( jobj(retjson,"pending") == 0 )
{
bot->relsum += relvol;
bot->basesum += v;
bot->completed++;
remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum);
printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice);
tradeid = rand();
if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey,tradeid)) != 0 )
{
if ( (retjson2= cJSON_Parse(retstr)) != 0 )
{
if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid )
{
bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid);
if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL )
bot->dead = (uint32_t)time(NULL);
else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL )
bot->pause = (uint32_t)time(NULL);
} else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr);
free_json(retjson2);
} else printf("%s\n",retstr);
free(retstr);
}
}
else
{
bot->pendrelsum += relvol;
bot->pendbasesum += v;
bot->numpending++;
}
bot->numtrades++;
if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL )
bot->dead = (uint32_t)time(NULL);
else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL )
bot->pause = (uint32_t)time(NULL);
printf("%s\n",jprint(LP_tradebot_json(bot),1));
free_json(retjson);
}
free(liststr);
}
}
else
else if ( bot->pause == 0 )
bot->pause = (uint32_t)time(NULL);
}
void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid)
{
struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp;
DL_FOREACH_SAFE(LP_tradebots,bot,tmp)
{
//DL_DELETE(LP_tradebots,bot);
//free(bot);
for (i=0; i<bot->numtrades; i++)
{
if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid )
{
tp->requestid = requestid;
tp->quoteid = quoteid;
bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol;
bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol;
bot->numpending--, bot->completed++;
printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid);
tp->finished = (uint32_t)time(NULL);
break;
}
}
}
}
void LP_tradebot_timeslices(void *ignore)
void LP_tradebot_timeslices(void *ctx)
{
struct LP_tradebot *bot,*tmp;
struct LP_tradebot_trade *tp; struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; int32_t i,lastnumfinished = 0;
while ( 1 )
{
DL_FOREACH_SAFE(LP_tradebots,bot,tmp)
{
portable_mutex_lock(&LP_tradebotsmutex);
LP_tradebot_timeslice(bot);
portable_mutex_unlock(&LP_tradebotsmutex);
sleep(1);
if ( (relcoin= LP_coinfind(bot->rel)) != 0 )
LP_listunspent_issue(bot->rel,relcoin->smartaddr,1);
if ( bot->numpending > 0 && LP_numfinished > lastnumfinished )
{
// expire pending trades and see if any still need their requestid/quoteid
for (i=0; i<bot->numtrades; i++)
{
if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 )
{
if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 )
{
bot->pendbasesum -= tp->basevol;
bot->pendrelsum -= tp->relvol;
bot->numpending--;
tp->finished = (uint32_t)time(NULL);
printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades);
}
}
}
}
else if ( bot->numpending == 0 )
LP_tradebot_timeslice(ctx,bot);
}
sleep(10);
lastnumfinished = LP_numfinished;
sleep(60);
}
}
@ -324,11 +367,63 @@ char *LP_tradebot_list(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; struct iguana_info *basecoin,*relcoin;
struct LP_tradebot *bot; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t 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 ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
abalance += j64bits(item,"satoshis");
}
}
free_json(array);
}
txfees = 10 * relcoin->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();
jaddstr(retjson,"error","not enough funds");
jaddstr(retjson,"coin",rel);
jaddnum(retjson,"balance",dstr(abalance));
jaddnum(retjson,"relvolume",relvolume);
jaddnum(retjson,"txfees",dstr(txfees));
shortfall = (relvolume + dstr(txfees)) - dstr(balance);
jaddnum(retjson,"shortfall",shortfall);
if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*(shortfall+relvolume/77.) )
{
char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item;
outputjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,relcoin->smartaddr,relvolume+dstr(txfees));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777);
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777);
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777);
jaddi(outputs,item);
jadd(outputjson,"outputs",outputs);
if ( (withdrawstr= LP_withdraw(relcoin,outputjson)) != 0 )
{
if ( (withdrawjson= cJSON_Parse(withdrawstr)) != 0 )
jadd(retjson,"withdraw",withdrawjson);
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);
if ( (bot= calloc(1,sizeof(*bot))) != 0 )
{

20
iguana/exchanges/LP_transaction.c

@ -1554,10 +1554,9 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i
swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1);
bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
//LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr);
int32_t i; for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
printf("%02x",swap->bobdeposit.redeemscript[i]);
printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr);
//int32_t i; for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr);
if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) )
{
basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
@ -1734,13 +1733,12 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
basilisk_dontforget_update(swap,&swap->bobdeposit);
//LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr);
int32_t i; char str[65]; for (i=0; i<swap->bobdeposit.I.datalen; i++)
printf("%02x",swap->bobdeposit.txbytes[i]);
printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid));
for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
printf("%02x",swap->bobdeposit.redeemscript[i]);
printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys);
//int32_t i; char str[65]; for (i=0; i<swap->bobdeposit.I.datalen; i++)
// printf("%02x",swap->bobdeposit.txbytes[i]);
//printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid));
//for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys);
memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen;
memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33);

2
iguana/exchanges/LP_utxo.c

@ -168,7 +168,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
}
else
{
printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout);
//printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout);
up->spendheight = 1;
if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts )
tx->outpoints[up->U.vout].spendheight = 1;

28
iguana/exchanges/LP_utxos.c

@ -229,7 +229,7 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
{
uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t iambob = 0;
uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0;
if ( symbol == 0 || destsatoshis == 0 )
{
printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis));
@ -243,16 +243,38 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
continue;
if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 )
{
if ( utxo->S.satoshis >= destsatoshis && (bestutxo == 0 || (bestutxo->S.satoshis < destsatoshis && utxo->S.satoshis >= destsatoshis) || (bestutxo->S.satoshis >= destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis)) )
bestsize = 0;
if ( bestutxo == 0 )
{
if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL )
bestsize = 1;
}
else
{
if ( bestutxo->S.satoshis < destsatoshis )
{
if ( utxo->S.satoshis > destsatoshis )
bestsize = 1;
else if ( utxo->S.satoshis > bestutxo->S.satoshis )
bestsize = 1;
}
else
{
if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis )
bestsize = 1;
}
}
if ( bestsize > 0 )
{
if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 )
{
printf("not elibible\n");
//if ( utxo->T.spentflag == 0 )
// utxo->T.spentflag = (uint32_t)time(NULL);
continue;
}
bestutxo = utxo;
} //else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis));
} // else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis));
}
}
return(bestutxo);

2
iguana/exchanges/stats.c

@ -32,7 +32,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char
char *stats_validmethods[] =
{
"getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_
"psock", "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_
"orderbook", "help", "getcoins", "pricearray", "balance"
};

Loading…
Cancel
Save