Browse Source

Test

etomic
jl777 7 years ago
parent
commit
2996372795
  1. 37
      iguana/exchanges/LP_commands.c
  2. 28
      iguana/exchanges/LP_forwarding.c
  3. 7
      iguana/exchanges/LP_include.h
  4. 57
      iguana/exchanges/LP_nativeDEX.c
  5. 216
      iguana/exchanges/LP_prices.c
  6. 52
      iguana/exchanges/LP_quotes.c
  7. 2
      iguana/exchanges/LP_rpc.c
  8. 42
      iguana/exchanges/LP_statemachine.c
  9. 50
      iguana/exchanges/LP_utxos.c

37
iguana/exchanges/LP_commands.c

@ -45,7 +45,7 @@ double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits25
LP_forward(qp->srchash,jprint(reqjson,1),1); LP_forward(qp->srchash,jprint(reqjson,1),1);
for (i=0; i<30; i++) for (i=0; i<30; i++)
{ {
if ( (price= LP_pricecache(qp,base,rel,qp->txid,qp->vout)) != 0. ) if ( (price= LP_pricecache(qp,base,rel,qp->txid,qp->vout)) > SMALLVAL )
{ {
if ( flag == 0 || bits256_nonz(qp->desthash) != 0 ) if ( flag == 0 || bits256_nonz(qp->desthash) != 0 )
{ {
@ -61,7 +61,7 @@ double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits25
int32_t LP_connectstart(int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *myipaddr,char *base,char *rel,double profitmargin) int32_t LP_connectstart(int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *myipaddr,char *base,char *rel,double profitmargin)
{ {
char *retstr,pairstr[512]; cJSON *retjson; double price; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; uint64_t destvalue; struct LP_quoteinfo Q; struct basilisk_swap *swap; char *retstr,pairstr[512]; cJSON *retjson; double price; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; uint64_t destvalue; struct LP_quoteinfo Q; struct basilisk_swap *swap;
if ( (price= LP_price(base,rel)) != 0. ) if ( (price= LP_price(base,rel)) > SMALLVAL )
{ {
price *= (1. + profitmargin); price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 ) if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
@ -182,7 +182,7 @@ int32_t LP_tradecommand(char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *d
retval = 1; retval = 1;
if ( LP_isavailable(utxo) > 0 ) if ( LP_isavailable(utxo) > 0 )
{ {
if ( (price= LP_price(base,rel)) != 0. ) if ( (price= LP_price(base,rel)) > SMALLVAL )
{ {
price *= (1. + profitmargin); price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 ) if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
@ -210,7 +210,7 @@ int32_t LP_tradecommand(char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *d
if ( pubsock >= 0 ) if ( pubsock >= 0 )
LP_send(pubsock,retstr,1); LP_send(pubsock,retstr,1);
else LP_forward(utxo->S.otherpubkey,retstr,1); else LP_forward(utxo->S.otherpubkey,retstr,1);
utxo->T.published = (uint32_t)time(NULL); utxo->T.lasttime = (uint32_t)time(NULL);
} else printf("null price\n"); } else printf("null price\n");
} else printf("swappending.%u swap.%p\n",utxo->T.swappending,utxo->S.swap); } else printf("swappending.%u swap.%p\n",utxo->T.swappending,utxo->S.swap);
} }
@ -245,7 +245,7 @@ cJSON *LP_dereference(cJSON *argjson,char *excludemethod)
char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port
{ {
char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t otherpeers,othernumutxos; struct LP_utxoinfo *utxo,*tmp; struct LP_peerinfo *peer; cJSON *retjson; struct iguana_info *ptr; char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t otherpeers,othernumutxos; struct LP_peerinfo *peer; cJSON *retjson; struct iguana_info *ptr;
if ( (method= jstr(argjson,"method")) == 0 ) if ( (method= jstr(argjson,"method")) == 0 )
return(clonestr("{\"error\":\"need method in request\"}")); return(clonestr("{\"error\":\"need method in request\"}"));
else if ( strcmp(method,"help") == 0 ) else if ( strcmp(method,"help") == 0 )
@ -289,31 +289,22 @@ forwardhex(pubkey,hex)\n\
return(clonestr("{\"error\":\"authentication error\"}")); return(clonestr("{\"error\":\"authentication error\"}"));
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 ) if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{ {
//char str[65]; double price;
if ( LP_isdisabled(base,rel) != 0 ) if ( LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}")); return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
if ( strcmp(method,"setprice") == 0 ) if ( strcmp(method,"setprice") == 0 )
{ {
if ( LP_mypriceset(base,rel,jdouble(argjson,"price")) < 0 ) if ( (price= jdouble(argjson,"price")) > SMALLVAL )
return(clonestr("{\"error\":\"couldnt set price\"}"));
else
{ {
if ( IAMLP != 0 ) if ( LP_mypriceset(base,rel,price) < 0 )
{ return(clonestr("{\"error\":\"couldnt set price\"}"));
HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp) else return(LP_pricepings(LP_mypubsock,base,rel,price * LP_profitratio));
{ } else return(clonestr("{\"error\":\"no price\"}"));
if ( LP_ismine(utxo) > 0 && strcmp(utxo->coin,base) == 0 )//|| strcmp(utxo->coin,rel) == 0) )
LP_priceping(LP_mypubsock,utxo,rel,LP_profitratio - 1.);
//else printf("notmine.(%s %s)\n",utxo->coin,bits256_str(str,utxo->txid));
}
}
return(clonestr("{\"result\":\"success\"}"));
}
} }
else if ( strcmp(method,"myprice") == 0 ) else if ( strcmp(method,"myprice") == 0 )
{ {
double bid,ask; double bid,ask;
if ( LP_myprice(&bid,&ask,base,rel) != 0. ) if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL )
{ {
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
jaddstr(retjson,"base",base); jaddstr(retjson,"base",base);
@ -417,7 +408,7 @@ forwardhex(pubkey,hex)\n\
else if ( strcmp(method,"broadcast") == 0 ) else if ( strcmp(method,"broadcast") == 0 )
retstr = LP_broadcasted(argjson); retstr = LP_broadcasted(argjson);
else if ( strcmp(method,"getprice") == 0 ) else if ( strcmp(method,"getprice") == 0 )
retstr = LP_pricestr(jstr(argjson,"base"),jstr(argjson,"rel")); retstr = LP_pricestr(jstr(argjson,"base"),jstr(argjson,"rel"),0.);
else if ( strcmp(method,"orderbook") == 0 ) else if ( strcmp(method,"orderbook") == 0 )
retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel")); retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel"));
else if ( strcmp(method,"forward") == 0 ) else if ( strcmp(method,"forward") == 0 )
@ -454,7 +445,7 @@ forwardhex(pubkey,hex)\n\
if ( juint(argjson,"timestamp") > time(NULL)-60 ) if ( juint(argjson,"timestamp") > time(NULL)-60 )
{ {
printf("utxonotify.(%s)\n",jprint(argjson,0)); printf("utxonotify.(%s)\n",jprint(argjson,0));
LP_addutxo(1,LP_mypubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),j64bits(argjson,"valuesats"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),j64bits(argjson,"valuesats2"),jstr(argjson,"script"),jstr(argjson,"address"),jbits256(argjson,"pubkey"),jdouble(argjson,"profit")); LP_utxoaddjson(1,LP_mypubsock,argjson);
} }
retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}"); retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}");
} }

28
iguana/exchanges/LP_forwarding.c

@ -146,24 +146,30 @@ char *LP_forwardhex(bits256 pubkey,char *hexstr)
int32_t LP_forward(bits256 pubkey,char *jsonstr,int32_t freeflag) int32_t LP_forward(bits256 pubkey,char *jsonstr,int32_t freeflag)
{ {
struct LP_forwardinfo *ptr; struct LP_peerinfo *peer,*tmp; char *hexstr,*retstr; int32_t len,retval = -1; cJSON *retjson,*reqjson; struct LP_forwardinfo *ptr; struct LP_peerinfo *peer,*tmp; char *hexstr,*retstr; int32_t len,retval = -1; cJSON *retjson,*reqjson;
if ( jsonstr == 0 || jsonstr[0] == 0 || bits256_nonz(pubkey) == 0 ) if ( jsonstr == 0 || jsonstr[0] == 0 )
return(-1); return(-1);
if ( IAMLP != 0 && (ptr= LP_forwardfind(pubkey)) != 0 && ptr->pushsock >= 0 && ptr->lasttime > time(NULL)-LP_KEEPALIVE ) if ( bits256_nonz(pubkey) != 0 )
{ {
return(LP_send(ptr->pushsock,jsonstr,1)); if ( IAMLP != 0 && (ptr= LP_forwardfind(pubkey)) != 0 && ptr->pushsock >= 0 && ptr->lasttime > time(NULL)-LP_KEEPALIVE )
{
return(LP_send(ptr->pushsock,jsonstr,1));
}
} }
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {
if ( (retstr= issue_LP_lookup(peer->ipaddr,peer->port,pubkey)) != 0 ) if ( bits256_nonz(pubkey) != 0 )
{ {
if ( (retjson= cJSON_Parse(retstr)) != 0 ) if ( (retstr= issue_LP_lookup(peer->ipaddr,peer->port,pubkey)) != 0 )
{ {
if ( jint(retjson,"forwarding") != 0 && peer->pushsock >= 0 ) if ( (retjson= cJSON_Parse(retstr)) != 0 )
retval = 0; {
free_json(retjson); if ( jint(retjson,"forwarding") != 0 && peer->pushsock >= 0 )
retval = 0;
free_json(retjson);
}
free(retstr);
} }
free(retstr); } else retval = 0;
}
if ( retval == 0 && peer->pushsock >= 0 ) if ( retval == 0 && peer->pushsock >= 0 )
{ {
printf("found LPnode.(%s) forward.(%s)\n",peer->ipaddr,jsonstr); printf("found LPnode.(%s) forward.(%s)\n",peer->ipaddr,jsonstr);
@ -178,7 +184,7 @@ int32_t LP_forward(bits256 pubkey,char *jsonstr,int32_t freeflag)
jaddbits256(reqjson,"pubkey",pubkey); jaddbits256(reqjson,"pubkey",pubkey);
free(hexstr); free(hexstr);
return(LP_send(peer->pushsock,jprint(reqjson,1),1)); return(LP_send(peer->pushsock,jprint(reqjson,1),1));
} } else retval = -1;
} }
return(-1); return(-1);
} }

7
iguana/exchanges/LP_include.h

@ -147,7 +147,7 @@ struct iguana_info
struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; }; struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; };
struct LP_utxostats { uint32_t lasttime,errors,swappending,published,spentflag,lastspentcheck; }; struct LP_utxostats { uint32_t lasttime,errors,swappending,spentflag,lastspentcheck; };
struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; }; struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; };
@ -218,6 +218,9 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub); double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub);
int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys); int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys);
void LP_quotesinit(char *base,char *rel); void LP_quotesinit(char *base,char *rel);
int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double profitmargin); int32_t LP_forward(bits256 pubkey,char *jsonstr,int32_t freeflag);
int32_t LP_ismine(struct LP_utxoinfo *utxo);
int32_t LP_isavailable(struct LP_utxoinfo *utxo);
#endif #endif

57
iguana/exchanges/LP_nativeDEX.c

@ -32,7 +32,7 @@ char USERPASS[65],USERPASS_WIFSTR[64],USERHOME[512] = { "/root" };
char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196" , "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", "5.9.253.204" }; // char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196" , "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", "5.9.253.204" }; //
portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex; portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex;
int32_t LP_mypubsock = -1; int32_t LP_mypubsock = -1;
int32_t USERPASS_COUNTER,IAMLP = 0; int32_t USERPASS_COUNTER,IAMLP = 0;
double LP_profitratio = 1.; double LP_profitratio = 1.;
@ -154,27 +154,6 @@ int32_t LP_subsock_check(struct LP_peerinfo *peer)
return(nonz); return(nonz);
} }
int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double profitmargin)
{
double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr;
if ( (now= (uint32_t)time(NULL)) > utxo->T.swappending )
utxo->T.swappending = 0;
if ( now > utxo->T.published+60 && utxo->T.swappending == 0 && utxo->S.swap == 0 && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 0. )
{
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1);
//printf("PING.(%s)\n",retstr);
LP_send(pubsock,retstr,1);
utxo->T.published = now;
return(0);
}
return(-1);
}
void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitmargin) void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitmargin)
{ {
struct _LP_utxoinfo u; char str[65]; uint32_t now = (uint32_t)time(NULL); struct _LP_utxoinfo u; char str[65]; uint32_t now = (uint32_t)time(NULL);
@ -193,13 +172,14 @@ void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitma
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value)); printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value));
LP_spentnotify(utxo,1); LP_spentnotify(utxo,1);
} }
else if ( LP_ismine(utxo) > 0 ) /*else if ( LP_ismine(utxo) > 0 )
{ {
printf("iterate through all locally generated quotes and update, or change to price feed\n");
// jl777: iterated Q's // jl777: iterated Q's
if ( strcmp(utxo->coin,"KMD") == 0 ) if ( strcmp(utxo->coin,"KMD") == 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin); LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin); else LP_priceping(pubsock,utxo,"KMD",profitmargin);
} }*/
} }
} }
@ -209,9 +189,23 @@ void LP_utxo_updates(int32_t pubsock,char *passphrase,double profitmargin)
LP_privkey_updates(pubsock,passphrase); LP_privkey_updates(pubsock,passphrase);
} }
void LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,double profitmargin,int32_t interval)
{
int32_t lastn;
if ( now > peer->lastutxos+interval )
{
peer->lastutxos = now;
//lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
//if ( lastn < LP_PROPAGATION_SLACK * 2 )
lastn = LP_PROPAGATION_SLACK * 2;
if ( mypeer == 0 || strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,profitmargin);
}
}
void LP_mainloop(char *myipaddr,struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,char *pushaddr,int32_t pullsock,uint16_t myport,char *passphrase,double profitmargin,cJSON *coins,char *seednode) void LP_mainloop(char *myipaddr,struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,char *pushaddr,int32_t pullsock,uint16_t myport,char *passphrase,double profitmargin,cJSON *coins,char *seednode)
{ {
char *retstr; uint8_t r; int32_t i,n,j,counter=0,nonz,lastn; struct LP_peerinfo *peer,*tmp; uint32_t now,lastforward = 0; cJSON *item; struct LP_utxoinfo *utxo,*utmp; char *retstr; uint8_t r; int32_t i,n,j,counter=0,nonz; struct LP_peerinfo *peer,*tmp; uint32_t now,lastforward = 0; cJSON *item; struct LP_utxoinfo *utxo,*utmp;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 )
{ {
printf("error launching stats rpcloop for port.%u\n",myport); printf("error launching stats rpcloop for port.%u\n",myport);
@ -278,6 +272,7 @@ void LP_mainloop(char *myipaddr,struct LP_peerinfo *mypeer,uint16_t mypubport,in
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {
nonz += LP_subsock_check(peer); nonz += LP_subsock_check(peer);
LP_peer_utxosquery(LP_mypeer,myport,pubsock,peer,now,profitmargin,600);
} }
if ( pullsock >= 0 ) if ( pullsock >= 0 )
{ {
@ -325,17 +320,8 @@ void LP_mainloop(char *myipaddr,struct LP_peerinfo *mypeer,uint16_t mypubport,in
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 ) if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,mypeer->ipaddr,myport,profitmargin); LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,mypeer->ipaddr,myport,profitmargin);
} }
if ( peer->numutxos != mypeer->numutxos && now > peer->lastutxos+60 )
{
peer->lastutxos = now;
lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
if ( lastn < LP_PROPAGATION_SLACK * 2 )
lastn = LP_PROPAGATION_SLACK * 2;
// printf("%s numutxos.%d vs %d lastn.%d\n",peer->ipaddr,peer->numutxos,mypeer->numutxos,lastn);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer->ipaddr,myport,profitmargin);
}
nonz += LP_subsock_check(peer); nonz += LP_subsock_check(peer);
LP_peer_utxosquery(LP_mypeer,myport,pubsock,peer,now,profitmargin,60);
} }
if ( (counter % 100) == 0 ) if ( (counter % 100) == 0 )
{ {
@ -373,6 +359,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
portable_mutex_init(&LP_swaplistmutex); portable_mutex_init(&LP_swaplistmutex);
portable_mutex_init(&LP_cachemutex); portable_mutex_init(&LP_cachemutex);
portable_mutex_init(&LP_forwardmutex); portable_mutex_init(&LP_forwardmutex);
portable_mutex_init(&LP_pubkeymutex);
if ( profitmargin == 0. || profitmargin == 0.01 ) if ( profitmargin == 0. || profitmargin == 0.01 )
{ {
profitmargin = 0.01 + (double)(rand() % 100)/100000; profitmargin = 0.01 + (double)(rand() % 100)/100000;

216
iguana/exchanges/LP_prices.c

@ -18,6 +18,8 @@
// marketmaker // marketmaker
// //
struct LP_orderbookentry { bits256 txid; double price; uint64_t basesatoshis; int32_t vout; };
#define LP_MAXPRICEINFOS 64 #define LP_MAXPRICEINFOS 64
struct LP_priceinfo struct LP_priceinfo
{ {
@ -39,6 +41,13 @@ struct LP_cacheinfo
uint32_t timestamp; uint32_t timestamp;
} *LP_cacheinfos; } *LP_cacheinfos;
struct LP_pubkeyinfo
{
UT_hash_handle hh;
bits256 pubkey;
double matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
} *LP_pubkeyinfos;
int32_t LP_cachekey(uint8_t *key,char *base,char *rel,bits256 txid,int32_t vout) int32_t LP_cachekey(uint8_t *key,char *base,char *rel,bits256 txid,int32_t vout)
{ {
uint64_t basebits,relbits; int32_t offset = 0; uint64_t basebits,relbits; int32_t offset = 0;
@ -70,6 +79,29 @@ struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout
return(ptr); return(ptr);
} }
struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey)
{
struct LP_pubkeyinfo *pubp=0;
portable_mutex_lock(&LP_pubkeymutex);
HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp);
portable_mutex_unlock(&LP_pubkeymutex);
return(pubp);
}
struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey)
{
struct LP_pubkeyinfo *pubp=0;
if ( (pubp= LP_pubkeyfind(pubkey)) == 0 )
{
portable_mutex_lock(&LP_pubkeymutex);
HASH_ADD(hh,LP_pubkeyinfos,pubkey,sizeof(pubkey),pubp);
portable_mutex_unlock(&LP_pubkeymutex);
if ( (pubp= LP_pubkeyfind(pubkey)) == 0 )
printf("pubkeyadd find error after add\n");
}
return(pubp);
}
double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout) double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout)
{ {
struct LP_cacheinfo *ptr; struct LP_cacheinfo *ptr;
@ -79,7 +111,7 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i
(*qp) = ptr->Q; (*qp) = ptr->Q;
if ( ptr->price == 0. && ptr->Q.satoshis != 0 ) if ( ptr->price == 0. && ptr->Q.satoshis != 0 )
{ {
printf("null ptr->price? "); printf("LP_pricecache: null ptr->price? ");
ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis; ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis;
} }
//printf("found %s/%s %.8f\n",base,rel,ptr->price); //printf("found %s/%s %.8f\n",base,rel,ptr->price);
@ -136,9 +168,9 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel)
*bidp = *askp = 0.; *bidp = *askp = 0.;
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {
if ( (*askp= basepp->myprices[relpp->ind]) != 0. ) if ( (*askp= basepp->myprices[relpp->ind]) > SMALLVAL )
{ {
if ( (val= relpp->myprices[basepp->ind]) != 0. ) if ( (val= relpp->myprices[basepp->ind]) > SMALLVAL )
{ {
*bidp = 1. / val; *bidp = 1. / val;
} else *bidp = *askp * 0.99; } else *bidp = *askp * 0.99;
@ -146,7 +178,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel)
} }
else else
{ {
if ( (val= relpp->myprices[basepp->ind]) != 0. ) if ( (val= relpp->myprices[basepp->ind]) > SMALLVAL )
{ {
*bidp = 1. / val; *bidp = 1. / val;
*askp = *bidp / 0.99; *askp = *bidp / 0.99;
@ -159,7 +191,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel)
int32_t LP_mypriceset(char *base,char *rel,double price) int32_t LP_mypriceset(char *base,char *rel,double price)
{ {
struct LP_priceinfo *basepp,*relpp; struct LP_priceinfo *basepp,*relpp;
if ( price != 0. && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( price > SMALLVAL && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {
basepp->myprices[relpp->ind] = price; // ask basepp->myprices[relpp->ind] = price; // ask
relpp->myprices[basepp->ind] = (1. / price); // bid relpp->myprices[basepp->ind] = (1. / price); // bid
@ -197,7 +229,7 @@ cJSON *LP_priceinfomatrix(int32_t usemyprices)
{ {
if ( usemyprices == 0 || (val= pp->myprices[j]) == 0. ) if ( usemyprices == 0 || (val= pp->myprices[j]) == 0. )
val = pp->relvals[j]; val = pp->relvals[j];
if ( val != 0. ) if ( val > SMALLVAL )
{ {
sum += val; sum += val;
n++; n++;
@ -214,8 +246,11 @@ cJSON *LP_priceinfomatrix(int32_t usemyprices)
pp = LP_priceinfos; pp = LP_priceinfos;
for (i=0; i<LP_numpriceinfos; i++,pp++) for (i=0; i<LP_numpriceinfos; i++,pp++)
{ {
pp->diagval /= total; if ( pp->diagval > SMALLVAL )
jaddnum(vectorjson,pp->symbol,pp->diagval); {
pp->diagval /= total;
jaddnum(vectorjson,pp->symbol,pp->diagval);
}
} }
} }
return(vectorjson); return(vectorjson);
@ -269,8 +304,8 @@ struct LP_cacheinfo *LP_cacheadd(char *base,char *rel,bits256 txid,int32_t vout,
static int _cmp_orderbook(const void *a,const void *b) static int _cmp_orderbook(const void *a,const void *b)
{ {
int32_t retval = 0; int32_t retval = 0;
#define ptr_a (*(struct LP_cacheinfo **)a)->price #define ptr_a (*(struct LP_orderbookentry **)a)->price
#define ptr_b (*(struct LP_cacheinfo **)b)->price #define ptr_b (*(struct LP_orderbookentry **)b)->price
if ( ptr_b > ptr_a ) if ( ptr_b > ptr_a )
retval = 1; retval = 1;
else if ( ptr_b < ptr_a ) else if ( ptr_b < ptr_a )
@ -279,8 +314,8 @@ static int _cmp_orderbook(const void *a,const void *b)
{ {
#undef ptr_a #undef ptr_a
#undef ptr_b #undef ptr_b
#define ptr_a ((struct LP_cacheinfo *)a)->Q.satoshis #define ptr_a ((struct LP_orderbookentry *)a)->basesatoshis
#define ptr_b ((struct LP_cacheinfo *)b)->Q.satoshis #define ptr_b ((struct LP_orderbookentry *)b)->basesatoshis
if ( ptr_b > ptr_a ) if ( ptr_b > ptr_a )
return(1); return(1);
else if ( ptr_b < ptr_a ) else if ( ptr_b < ptr_a )
@ -297,23 +332,88 @@ static int _cmp_orderbookrev(const void *a,const void *b)
return(-_cmp_orderbook(a,b)); return(-_cmp_orderbook(a,b));
} }
cJSON *LP_orderbookjson(struct LP_cacheinfo *ptr,int32_t polarity) cJSON *LP_orderbookjson(struct LP_orderbookentry *op)
{ {
double price; cJSON *item = cJSON_CreateObject(); cJSON *item = cJSON_CreateObject();
if ( ptr->Q.satoshis != 0 && ptr->Q.destsatoshis != 0 ) if ( op->price > SMALLVAL )
{ {
price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis; jaddnum(item,"price",op->price );
jaddnum(item,"price",polarity > 0 ? price : 1. / price); jaddnum(item,"volume",dstr(op->basesatoshis));
jaddnum(item,"volume",polarity > 0 ? dstr(ptr->Q.satoshis) : dstr(ptr->Q.destsatoshis)); jaddbits256(item,"txid",op->txid);
jaddbits256(item,"txid",ptr->Q.txid); jaddnum(item,"vout",op->vout);
jaddnum(item,"vout",ptr->Q.vout);
} }
return(item); return(item);
} }
struct LP_orderbookentry *LP_orderbookentry(char *base,char *rel,bits256 txid,int32_t vout,double price,uint64_t basesatoshis)
{
struct LP_orderbookentry *op;
if ( (op= calloc(1,sizeof(*op))) != 0 )
{
op->txid = txid;
op->vout = vout;
op->price = price;
op->basesatoshis = basesatoshis;
}
return(op);
}
int32_t LP_orderbookfind(struct LP_orderbookentry **array,int32_t num,bits256 txid,int32_t vout)
{
int32_t i;
for (i=0; i<num; i++)
if ( array[i]->vout == vout && bits256_cmp(array[i]->txid,txid) == 0 )
return(i);
return(-1);
}
int32_t LP_orderbook_utxoentries(uint32_t now,char *base,char *rel,char *symbol,double price,struct LP_orderbookentry **array,int32_t num,int32_t cachednum,bits256 pubkey)
{
struct LP_utxoinfo *utxo,*tmp; struct LP_peerinfo *peer,*ptmp; char *retstr; cJSON *retjson; struct LP_orderbookentry *op; uint64_t basesatoshis;
HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp)
{
if ( LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 && LP_isavailable(utxo) > 0 )
{
if ( LP_orderbookfind(array,cachednum,utxo->payment.txid,utxo->payment.vout) < 0 )
{
char str[65]; printf("found utxo not in orderbook %s/v%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout);
array = realloc(array,sizeof(*array) * (num+1));
if ( strcmp(base,symbol) == 0 )
basesatoshis = utxo->payment.value;
else basesatoshis = utxo->payment.value * price;
if ( (op= LP_orderbookentry(base,rel,utxo->payment.txid,utxo->payment.vout,price,basesatoshis)) != 0 )
array[num++] = op;
if ( bits256_cmp(utxo->pubkey,LP_mypubkey) == 0 && utxo->T.lasttime == 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,ptmp)
{
if ( (retstr= issue_LP_notifyutxo(peer->ipaddr,peer->port,utxo)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"error") == 0 )
utxo->T.lasttime = (uint32_t)time(NULL);
free_json(retjson);
}
free(retstr);
}
if ( utxo->T.lasttime != 0 )
break;
}
}
}
}
}
return(num);
}
char *LP_orderbook(char *base,char *rel) char *LP_orderbook(char *base,char *rel)
{ {
uint32_t now,i; struct LP_cacheinfo *ptr,*tmp,**bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0; uint32_t now,i; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_pubkeyinfo *pubp,*ptmp; struct LP_cacheinfo *ptr,*tmp; struct LP_orderbookentry *op,**bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid;
if ( (basepp= LP_priceinfofind(base)) == 0 || (relpp= LP_priceinfofind(rel)) == 0 )
return(clonestr("{\"error\":\"base or rel not added\"}"));
baseid = basepp->ind;
relid = relpp->ind;
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
HASH_ITER(hh,LP_cacheinfos,ptr,tmp) HASH_ITER(hh,LP_cacheinfos,ptr,tmp)
{ {
@ -322,23 +422,28 @@ char *LP_orderbook(char *base,char *rel)
if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 ) if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 )
{ {
asks = realloc(asks,sizeof(*asks) * (numasks+1)); asks = realloc(asks,sizeof(*asks) * (numasks+1));
asks[numasks++] = ptr; if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->price,ptr->Q.satoshis)) != 0 )
asks[numasks++] = op;
} }
else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 ) else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 )
{ {
bids = realloc(bids,sizeof(*bids) * (numbids+1)); bids = realloc(bids,sizeof(*bids) * (numbids+1));
bids[numbids++] = ptr; if ( (op= LP_orderbookentry(base,rel,ptr->Q.desttxid,ptr->Q.destvout,1./ptr->price,ptr->Q.satoshis)) != 0 )
bids[numbids++] = op;
} }
} }
cachenumbids = numbids, cachenumasks = numasks;
HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp)
{
if ( pubp->matrix[baseid][relid] > SMALLVAL )
numasks = LP_orderbook_utxoentries(now,base,rel,base,pubp->matrix[baseid][relid],asks,numasks,cachenumasks,pubp->pubkey);
if ( pubp->matrix[relid][baseid] > SMALLVAL )
numasks = LP_orderbook_utxoentries(now,base,rel,rel,pubp->matrix[relid][baseid],bids,numbids,cachenumbids,pubp->pubkey);
}
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
array = cJSON_CreateArray(); array = cJSON_CreateArray();
if ( numbids > 1 ) if ( numbids > 1 )
qsort(bids,numbids,sizeof(*bids),_cmp_orderbookrev); qsort(bids,numbids,sizeof(*bids),_cmp_orderbookrev);
for (i=0; i<numbids; i++)
jaddi(array,LP_orderbookjson(bids[i],-1));
jadd(retjson,"bids",array);
jaddnum(retjson,"numbids",numbids);
array = cJSON_CreateArray();
if ( numasks > 1 ) if ( numasks > 1 )
{ {
for (i=0; i<numasks; i++) for (i=0; i<numasks; i++)
@ -349,29 +454,43 @@ char *LP_orderbook(char *base,char *rel)
printf("%.8f ",asks[i]->price); printf("%.8f ",asks[i]->price);
printf("sorted asks.%d\n",numasks); printf("sorted asks.%d\n",numasks);
} }
for (i=0; i<numbids; i++)
{
jaddi(array,LP_orderbookjson(bids[i]));
free(bids[i]);
bids[i] = 0;
}
jadd(retjson,"bids",array);
jaddnum(retjson,"numbids",numbids);
array = cJSON_CreateArray();
for (i=0; i<numasks; i++) for (i=0; i<numasks; i++)
jaddi(array,LP_orderbookjson(asks[i],1)); {
jaddi(array,LP_orderbookjson(asks[i]));
free(asks[i]);
asks[i] = 0;
}
jadd(retjson,"asks",array); jadd(retjson,"asks",array);
jaddnum(retjson,"numasks",numasks); jaddnum(retjson,"numasks",numasks);
jaddstr(retjson,"base",base); jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel); jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",now); jaddnum(retjson,"timestamp",now);
//if ( numbids == 0 && numasks == 0 ) if ( bids != 0 )
// LP_quotesinit(base,rel); free(bids);
if ( asks != 0 )
free(asks);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) char *LP_pricestr(char *base,char *rel,double origprice)
{
LP_priceinfoupdate(base,rel,price);
}
char *LP_pricestr(char *base,char *rel)
{ {
double price = 0.; cJSON *retjson; cJSON *retjson; double price = 0.;
if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 ) if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 )
{
price = LP_price(base,rel); price = LP_price(base,rel);
if ( price != 0. ) if ( origprice > SMALLVAL && origprice < price )
price = origprice;
}
if ( price > SMALLVAL )
{ {
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success"); jaddstr(retjson,"result","success");
@ -386,11 +505,24 @@ char *LP_pricestr(char *base,char *rel)
} else return(clonestr("{\"error\":\"cant find baserel pair\"}")); } else return(clonestr("{\"error\":\"cant find baserel pair\"}"));
} }
char *LP_postedprice(cJSON *argjson) void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32])
{ {
printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); LP_priceinfoupdate(base,rel,price);
return(clonestr("{\"result\":\"need to update stats\"}"));
} }
void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price)
{
struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; char str[65];
printf("PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey));
if ( price > SMALLVAL && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
pubp->matrix[basepp->ind][relpp->ind] = price;
else printf("error creating pubkey entry\n");
} else printf("error finding %s/%s %.8f\n",base,rel,price);
}

52
iguana/exchanges/LP_quotes.c

@ -13,6 +13,7 @@
* Removal or modification of this copyright notice is prohibited. * * Removal or modification of this copyright notice is prohibited. *
* * * *
******************************************************************************/ ******************************************************************************/
// //
// LP_quotes.c // LP_quotes.c
// marketmaker // marketmaker
@ -172,11 +173,49 @@ char *LP_quotereceived(cJSON *argjson)
if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 ) if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 )
{ {
ptr->Q = Q; ptr->Q = Q;
//char str[65]; printf("received.(%s) quote %.8f\n",bits256_str(str,Q.txid),price); char str[65]; printf("received.(%s) quote %.8f\n",bits256_str(str,Q.txid),price);
return(clonestr("{\"result\":\"updated\"}")); return(clonestr("{\"result\":\"updated\"}"));
} else return(clonestr("{\"error\":\"nullptr\"}")); } else return(clonestr("{\"error\":\"nullptr\"}"));
} }
char *LP_pricepings(int32_t pubsock,char *base,char *rel,double price)
{
bits256 zero; cJSON *reqjson = cJSON_CreateObject();
jaddbits256(reqjson,"pubkey",LP_mypubkey);
jaddstr(reqjson,"base",base);
jaddstr(reqjson,"rel",rel);
jaddnum(reqjson,"price",price);
if ( pubsock >= 0 )
{
jaddstr(reqjson,"method","postprice");
LP_send(pubsock,jprint(reqjson,1),1);
}
else
{
jaddstr(reqjson,"method","forward");
jaddstr(reqjson,"method2","postprice");
memset(zero.bytes,0,sizeof(zero));
LP_forward(zero,jprint(reqjson,1),1);
}
return(clonestr("{\"result\":\"success\"}"));
}
char *LP_postedprice(cJSON *argjson)
{
bits256 pubkey; double price; char *base,*rel,str[65];
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL )
{
pubkey = jbits256(argjson,"pubkey");
if ( bits256_nonz(pubkey) != 0 )
{
LP_pricefeedupdate(pubkey,base,rel,price);
printf("PRICE POSTED.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey));
return(clonestr("{\"result\":\"success\"}"));
}
}
return(clonestr("{\"error\":\"missing fields in posted price\"}"));
}
int32_t LP_sizematch(uint64_t mysatoshis,uint64_t othersatoshis) int32_t LP_sizematch(uint64_t mysatoshis,uint64_t othersatoshis)
{ {
if ( mysatoshis >= othersatoshis ) if ( mysatoshis >= othersatoshis )
@ -199,11 +238,6 @@ int32_t LP_arrayfind(cJSON *array,bits256 txid,int32_t vout)
cJSON *LP_tradecandidates(char *base) cJSON *LP_tradecandidates(char *base)
{ {
struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*retarray=0,*item; int32_t i,n,totaladded,added; struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*retarray=0,*item; int32_t i,n,totaladded,added;
/*if ( (price= LP_price(base,myutxo->coin)) == .0 )
{
printf("no LP_price (%s -> %s)\n",base,myutxo->coin);
return(0);
}*/
totaladded = 0; totaladded = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {
@ -296,17 +330,17 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
price = LP_query("price",&Q[i],base,myutxo->coin,zero); price = LP_query("price",&Q[i],base,myutxo->coin,zero);
Q[i].destsatoshis = price * Q[i].satoshis; Q[i].destsatoshis = price * Q[i].satoshis;
} }
if ( (prices[i]= price) != 0. && (bestprice == 0. || price < bestprice) ) if ( (prices[i]= price) > SMALLVAL && (bestprice == 0. || price < bestprice) )
bestprice = price; bestprice = price;
char str[65]; printf("i.%d of %d: (%s) -> txid.%s price %.8f best %.8f dest %.8f\n",i,n,jprint(item,0),bits256_str(str,Q[i].txid),price,bestprice,dstr(Q[i].destsatoshis)); char str[65]; printf("i.%d of %d: (%s) -> txid.%s price %.8f best %.8f dest %.8f\n",i,n,jprint(item,0),bits256_str(str,Q[i].txid),price,bestprice,dstr(Q[i].destsatoshis));
} }
if ( bestprice != 0. ) if ( bestprice > SMALLVAL )
{ {
bestmetric = 0.; bestmetric = 0.;
besti = -1; besti = -1;
for (i=0; i<n && i<sizeof(prices)/sizeof(*prices); i++) for (i=0; i<n && i<sizeof(prices)/sizeof(*prices); i++)
{ {
if ( (price= prices[i]) != 0. && myutxo->S.satoshis >= Q[i].destsatoshis+Q[i].desttxfee ) if ( (price= prices[i]) > SMALLVAL && myutxo->S.satoshis >= Q[i].destsatoshis+Q[i].desttxfee )
{ {
metric = price / bestprice; metric = price / bestprice;
printf("%f %f %f %f ",price,metric,dstr(Q[i].destsatoshis),metric * metric * metric); printf("%f %f %f %f ",price,metric,dstr(Q[i].destsatoshis),metric * metric * metric);

2
iguana/exchanges/LP_rpc.c

@ -52,7 +52,7 @@ char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,
char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo) char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo)
{ {
char url[4096],str[65],str2[65]; char url[4096],str[65],str2[65];
sprintf(url,"http://%s:%u/api/stats/notified?pubkey=%s&profit=%.6f&coin=%s&txid=%s&vout=%d&valuesats=%llu&txid2=%s&vout2=%d&valuesats2=%llu&script=%s&address=%s&timestamp=%u",destip,destport,bits256_str(str2,utxo->pubkey),utxo->S.profitmargin,utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL)); sprintf(url,"http://%s:%u/api/stats/notified?pubkey=%s&profit=%.6f&coin=%s&txid=%s&vout=%d&value=%llu&txid2=%s&vout2=%d&value2=%llu&script=%s&address=%s&timestamp=%u",destip,destport,bits256_str(str2,utxo->pubkey),utxo->S.profitmargin,utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL));
if ( strlen(url) > 1024 ) if ( strlen(url) > 1024 )
printf("WARNING long url.(%s)\n",url); printf("WARNING long url.(%s)\n",url);
return(issue_curl(url)); return(issue_curl(url));

42
iguana/exchanges/LP_statemachine.c

@ -1264,3 +1264,45 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu
} }
portable_mutex_unlock(&myinfo->DEX_swapmutex); portable_mutex_unlock(&myinfo->DEX_swapmutex);
}*/ }*/
/*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice)
{
double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr;
if ( (now= (uint32_t)time(NULL)) > utxo->T.swappending && utxo->S.swap == 0 )
utxo->T.swappending = 0;
if ( now > utxo->T.published+60 && LP_isavailable(utxo) && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 0. )
{
if ( origprice < price )
price = origprice;
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1);
//printf("PING.(%s)\n",retstr);
if ( pubsock >= 0 )
LP_send(pubsock,retstr,1);
else
{
// verify it is in list
// push if it isnt
}
utxo->T.published = now;
return(0);
}
return(-1);
}*/
/*if ( addflag != 0 && LP_utxofind(1,Q.txid,Q.vout) == 0 )
{
LP_utxoadd(1,-1,Q.srccoin,Q.txid,Q.vout,Q.value,Q.txid2,Q.vout2,Q.value2,"",Q.srcaddr,Q.srchash,0.);
LP_utxoadd(0,-1,Q.destcoin,Q.desttxid,Q.destvout,Q.destvalue,Q.feetxid,Q.feevout,Q.feevalu,"",Q.destaddr,Q.desthash,0.);
}*/
/*struct LP_utxoinfo *utxo,*tmp;
HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp)
{
if ( LP_ismine(utxo) > 0 && strcmp(utxo->coin,base) == 0 )
LP_priceping(LP_mypubsock,utxo,rel,price * LP_profitratio);
}*/

50
iguana/exchanges/LP_utxos.c

@ -338,7 +338,7 @@ int32_t LP_iseligible(int32_t iambob,char *coin,bits256 txid,int32_t vout,uint64
return(0); return(0);
} }
struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,double profitmargin) struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,double profitmargin)
{ {
char str[65]; uint64_t tmpsatoshis; int32_t spendvini,selector; bits256 spendtxid; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; char str[65]; uint64_t tmpsatoshis; int32_t spendvini,selector; bits256 spendtxid; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
if ( symbol == 0 || symbol[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 ) if ( symbol == 0 || symbol[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )
@ -351,19 +351,19 @@ struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *symbol,bit
else tmpsatoshis = value; else tmpsatoshis = value;
if ( LP_iseligible(iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) if ( LP_iseligible(iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 )
{ {
printf("LP_addutxo got spent txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",dstr(value),dstr(value2),dstr(tmpsatoshis)); printf("utxoadd got spent txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",dstr(value),dstr(value2),dstr(tmpsatoshis));
return(0); return(0);
} }
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 ) if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
{ {
printf("LP_addutxo selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); printf("utxoadd selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(0); return(0);
} }
if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 )
{ {
if ( LP_ismine(utxo) == 0 ) if ( LP_ismine(utxo) == 0 )
{ {
char str2[65],str3[65]; printf("iambob.%d %s %s LP_addutxo.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis));
} }
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
@ -372,7 +372,7 @@ struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *symbol,bit
utxo->T.errors++; utxo->T.errors++;
char str[65],str2[65],str3[65],str4[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",bits256_str(str,txid),bits256_str(str2,utxo->payment.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str3,pubkey),bits256_str(str4,utxo->pubkey)); char str[65],str2[65],str3[65],str4[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",bits256_str(str,txid),bits256_str(str2,utxo->payment.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str3,pubkey),bits256_str(str4,utxo->pubkey));
} }
else if ( profitmargin != 0. ) else if ( profitmargin > SMALLVAL )
utxo->S.profitmargin = profitmargin; utxo->S.profitmargin = profitmargin;
} }
else else
@ -401,7 +401,7 @@ struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *symbol,bit
} }
LP_utxosetkey(utxo->key,txid,vout); LP_utxosetkey(utxo->key,txid,vout);
LP_utxosetkey(utxo->key2,txid2,vout2); LP_utxosetkey(utxo->key2,txid2,vout2);
char str[65],str2[65],str3[65]; printf("iambob.%d %s %s LP_addutxo.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,utxo->pubkey),utxo->coin,dstr(value),dstr(value2),bits256_str(str,utxo->payment.txid),bits256_str(str2,txid2)); char str[65],str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,utxo->pubkey),utxo->coin,dstr(value),dstr(value2),bits256_str(str,utxo->payment.txid),bits256_str(str2,txid2));
portable_mutex_lock(&LP_utxomutex); portable_mutex_lock(&LP_utxomutex);
HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
@ -415,14 +415,14 @@ struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *symbol,bit
return(utxo); return(utxo);
} }
int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) struct LP_utxoinfo *LP_utxoaddjson(int32_t iambob,int32_t pubsock,cJSON *argjson)
{
return(LP_utxoadd(iambob,pubsock,jstr(argjson,"coin"),jbits256(argjson,"txid2"),jint(argjson,"vout"),j64bits(argjson,"value"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),j64bits(argjson,"value2"),jstr(argjson,"script"),jstr(argjson,"address"),jbits256(argjson,"pubkey"),jdouble(argjson,"profit")));
}
int32_t LP_utxosparse(int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{ {
struct LP_peerinfo *destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo; struct LP_peerinfo *destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
if ( IAMLP == 0 )
{
printf("LP_utxosparse not for clientside\n");
return(-1);
}
if ( (array= cJSON_Parse(retstr)) != 0 ) if ( (array= cJSON_Parse(retstr)) != 0 )
{ {
if ( (n= cJSON_GetArraySize(array)) > 0 ) if ( (n= cJSON_GetArraySize(array)) > 0 )
@ -443,11 +443,8 @@ int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa
{ {
txid = jbits256(item,"txid"); txid = jbits256(item,"txid");
//printf("parse.(%s)\n",jprint(item,0)); //printf("parse.(%s)\n",jprint(item,0));
utxo = LP_addutxo(1,mypubsock,jstr(item,"coin"),txid,jint(item,"vout"),j64bits(item,"value"),jbits256(item,"txid2"),jint(item,"vout2"),j64bits(item,"value2"),jstr(item,"script"),jstr(item,"address"),jbits256(item,"pubkey"),jdouble(item,"profit")); if ( (utxo= LP_utxoaddjson(1,mypubsock,item)) != 0 )
if ( utxo != 0 )
{
utxo->T.lasttime = now; utxo->T.lasttime = now;
}
} }
} // else printf("skip.(%s)\n",jprint(item,0)); } // else printf("skip.(%s)\n",jprint(item,0));
} }
@ -463,27 +460,20 @@ int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa
void LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit) void LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit)
{ {
char *retstr; struct LP_peerinfo *peer; int32_t i,firsti; uint32_t now; char *retstr; struct LP_peerinfo *peer; uint32_t now;
if ( IAMLP == 0 )
{
printf("LP_utxosquery not for clientside\n");
return;
}
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( mypeer == 0 ) //(peer != 0 && peer->errors > 0) ||
return;
if ( coin == 0 ) if ( coin == 0 )
coin = ""; coin = "";
if ( (retstr= issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer->numpeers,mypeer->numutxos)) != 0 ) if ( (retstr= issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer != 0 ? mypeer->numpeers : 0,mypeer != 0 ? mypeer->numutxos : 0)) != 0 )
{ {
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
LP_utxosparse(mypeer,mypubsock,destipaddr,destport,retstr,now); LP_utxosparse(mypubsock,destipaddr,destport,retstr,now);
free(retstr); free(retstr);
i = 0; /*i = 0;
if ( lastn >= mypeer->numutxos ) if ( lastn >= mypeer->numutxos )
firsti = -1; firsti = -1;
else firsti = (mypeer->numutxos - lastn); else firsti = (mypeer->numutxos - lastn);
/*HASH_ITER(hh,LP_utxoinfos,utxo,tmp) HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
{ {
if ( i++ < firsti ) if ( i++ < firsti )
continue; continue;
@ -602,14 +592,14 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr
values[i] = 0, used++; values[i] = 0, used++;
if ( iambob != 0 ) if ( iambob != 0 )
{ {
if ( (utxo= LP_addutxo(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_mypeer != 0 ? LP_mypeer->profitmargin : 0.01)) != 0 ) if ( (utxo= LP_utxoadd(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_mypeer != 0 ? LP_mypeer->profitmargin : 0.01)) != 0 )
{ {
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9()); //utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
} }
} }
else else
{ {
if ( (utxo= LP_addutxo(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0)) != 0 ) if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0.)) != 0 )
{ {
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9()); //utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
} }

Loading…
Cancel
Save