Browse Source

New utxoinfo

etomic
jl777 8 years ago
parent
commit
9130b5e367
  1. 2
      iguana/coins/genltc
  2. 8
      iguana/exchanges/LP_coins.c
  3. 336
      iguana/exchanges/LP_commands.c
  4. 165
      iguana/exchanges/LP_forwarding.c
  5. 66
      iguana/exchanges/LP_include.h
  6. 344
      iguana/exchanges/LP_nativeDEX.c
  7. 24
      iguana/exchanges/LP_peers.c
  8. 54
      iguana/exchanges/LP_quotes.c
  9. 18
      iguana/exchanges/LP_rpc.c
  10. 84
      iguana/exchanges/LP_swap.c
  11. 53
      iguana/exchanges/LP_transaction.c
  12. 394
      iguana/exchanges/LP_utxos.c

2
iguana/coins/genltc

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
curl --url "http://127.0.0.1:7776" --data "{\"RELAY\":1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}"

8
iguana/exchanges/LP_coins.c

@ -185,6 +185,7 @@ void LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetnam
coin->pubtype = pubtype; coin->pubtype = pubtype;
coin->p2shtype = p2shtype; coin->p2shtype = p2shtype;
coin->wiftype = wiftype; coin->wiftype = wiftype;
coin->inactive = (uint32_t)time(NULL);
LP_userpass(coin->userpass,symbol,assetname,name); LP_userpass(coin->userpass,symbol,assetname,name);
} }
@ -256,7 +257,7 @@ struct iguana_info *LP_coinfind(char *symbol)
struct iguana_info *LP_coincreate(cJSON *item) struct iguana_info *LP_coincreate(cJSON *item)
{ {
struct iguana_info cdata,*coin; int32_t isPoS,longestchain = 1000000; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*symbol,*assetname; struct iguana_info cdata,*coin=0; int32_t isPoS,longestchain = 1000000; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*symbol,*assetname;
if ( (symbol= jstr(item,"coin")) != 0 && symbol[0] != 0 && strlen(symbol) < 16 && LP_coinfind(symbol) == 0 && (port= juint(item,"rpcport")) != 0 ) if ( (symbol= jstr(item,"coin")) != 0 && symbol[0] != 0 && strlen(symbol) < 16 && LP_coinfind(symbol) == 0 && (port= juint(item,"rpcport")) != 0 )
{ {
isPoS = jint(item,"isPoS"); isPoS = jint(item,"isPoS");
@ -275,9 +276,10 @@ struct iguana_info *LP_coincreate(cJSON *item)
else if ( (name= jstr(item,"name")) == 0 ) else if ( (name= jstr(item,"name")) == 0 )
name = symbol; name = symbol;
LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain); LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain);
if ( (coin= LP_coinadd(&cdata)) != 0 ) coin = LP_coinadd(&cdata);
coin->inactive = !jint(item,"active");
} }
if ( coin != 0 && item != 0 )
coin->inactive = (strcmp("KMD",coin->symbol) == 0) ? 0 : !jint(item,"active");
return(0); return(0);
} }

336
iguana/exchanges/LP_commands.c

@ -18,71 +18,159 @@
// marketmaker // marketmaker
// //
double LP_query(char *method,struct LP_quoteinfo *qp,char *ipaddr,uint16_t port,char *base,char *rel,bits256 mypub) double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub)
{ {
cJSON *reqjson; struct LP_peerinfo *peer; int32_t i,flag = 0,pushsock = -1; double price = 0.; cJSON *reqjson; int32_t i,flag = 0; double price = 0.; struct LP_utxoinfo *utxo;
if ( ipaddr != 0 && port >= 1000 ) qp->desthash = mypub;
strcpy(qp->srccoin,base);
strcpy(qp->destcoin,rel);
if ( strcmp(method,"request") == 0 )
{ {
if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),port)) == 0 ) qp->quotetime = (uint32_t)time(NULL);
peer = LP_addpeer(1,0,-1,ipaddr,port,port+1,port+2,0,0,0); if ( (utxo= LP_utxofind(0,qp->desttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 )
if ( peer != 0 ) LP_unavailableset(utxo,qp->srchash);
else
{ {
if ( (pushsock= peer->pushsock) >= 0 ) printf("couldnt find my txid to make request\n");
return(0.);
}
}
reqjson = LP_quotejson(qp);
if ( bits256_nonz(qp->desthash) != 0 )
flag = 1;
jaddstr(reqjson,"method",method);
if ( strcmp(method,"price") != 0 )
printf("QUERY.(%s)\n",jprint(reqjson,0));
LP_pubkey_send(qp->srchash,jprint(reqjson,1),1);
for (i=0; i<30; i++)
{
if ( (price= LP_pricecache(qp,base,rel,qp->txid,qp->vout)) != 0. )
{
if ( flag == 0 || bits256_nonz(qp->desthash) != 0 )
{ {
qp->desthash = mypub; //printf("break out of loop.%d price %.8f\n",i,price);
strcpy(qp->srccoin,base); break;
strcpy(qp->destcoin,rel); }
if ( strcmp(method,"request") == 0 ) }
qp->quotetime = (uint32_t)time(NULL); usleep(100000);
reqjson = LP_quotejson(qp);
if ( bits256_nonz(qp->desthash) != 0 )
flag = 1;
jaddstr(reqjson,"method",method);
if ( strcmp(method,"price") != 0 )
printf("QUERY.(%s)\n",jprint(reqjson,0));
LP_send(pushsock,jprint(reqjson,1),1);
for (i=0; i<30; i++)
{
if ( (price= LP_pricecache(qp,base,rel,qp->txid,qp->vout)) != 0. )
{
if ( flag == 0 || bits256_nonz(qp->desthash) != 0 )
{
//printf("break out of loop.%d price %.8f\n",i,price);
break;
}
}
usleep(100000);
}
} else printf("no pushsock for peer.%s:%u\n",ipaddr,port);
} else printf("cant find/create peer.%s:%u\n",ipaddr,port);
} }
return(price); return(price);
} }
int32_t LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,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;
if ( (price= LP_price(base,rel)) != 0. )
{
price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
if ( LP_quoteparse(&Q,argjson) < 0 )
return(-2);
//printf("connect with.(%s)\n",jprint(argjson,0));
Q.destsatoshis = Q.satoshis * price;
privkey = LP_privkey(utxo->coinaddr);
if ( bits256_nonz(utxo->S.mypub) == 0 )
utxo->S.mypub = LP_pubkey(privkey);
if ( LP_iseligible(1,Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) == 0 )
{
printf("not eligible\n");
return(-1);
}
if ( bits256_nonz(privkey) != 0 && Q.quotetime >= Q.timestamp-3 && Q.quotetime < utxo->T.swappending && bits256_cmp(utxo->S.mypub,Q.srchash) == 0 && (destvalue= LP_txvalue(rel,Q.desttxid,Q.destvout)) >= price*Q.satoshis+Q.desttxfee && destvalue >= Q.destsatoshis+Q.desttxfee )
{
nanomsg_tcpname(pairstr,myipaddr,10000+(rand() % 10000));
if ( (pair= nn_socket(AF_SP,NN_PAIR)) < 0 )
printf("error creating utxo->pair\n");
else if ( nn_bind(pair,pairstr) >= 0 )
{
LP_requestinit(&Q.R,Q.srchash,Q.desthash,base,Q.satoshis,rel,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector);
swap = LP_swapinit(1,0,privkey,&Q.R,&Q);
swap->N.pair = pair;
utxo->S.swap = swap;
swap->utxo = utxo;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 )
{
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","connected");
jaddstr(retjson,"pair",pairstr);
jaddnum(retjson,"requestid",Q.R.requestid);
jaddnum(retjson,"quoteid",Q.R.quoteid);
retstr = jprint(retjson,1);
if ( pubsock >= 0 )
LP_send(pubsock,retstr,1);
else LP_pubkey_send(utxo->S.otherpubkey,retstr,1);
retval = 0;
} else printf("error launching swaploop\n");
} else printf("printf error nn_connect to %s\n",pairstr);
}
else
{
printf("dest %.8f < required %.8f (%d %d %d %d %d %d) %.8f %.8f\n",dstr(Q.satoshis),dstr(price*(utxo->S.satoshis-Q.txfee)),bits256_nonz(privkey) != 0 ,Q.timestamp == utxo->T.swappending-LP_RESERVETIME ,Q.quotetime >= Q.timestamp ,Q.quotetime < utxo->T.swappending ,bits256_cmp(utxo->S.mypub,Q.srchash) == 0 , LP_txvalue(rel,Q.desttxid,Q.destvout) >= price*Q.satoshis+Q.desttxfee,dstr(LP_txvalue(rel,Q.desttxid,Q.destvout)),dstr(price*Q.satoshis+Q.desttxfee));
}
} else printf("no price for %s/%s\n",base,rel);
if ( retval < 0 )
{
if ( pair >= 0 )
nn_close(pair);
LP_availableset(utxo);
}
return(retval);
}
char *LP_connected(cJSON *argjson) // alice
{
cJSON *retjson; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *utxo; struct LP_quoteinfo Q; struct basilisk_swap *swap;
retjson = cJSON_CreateObject();
LP_quoteparse(&Q,argjson);
if ( IAMLP == 0 && bits256_cmp(Q.desthash,LP_mypubkey) == 0 && (utxo= LP_utxofind(0,Q.desttxid,Q.destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 )
{
if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 )
jaddstr(retjson,"error","couldnt create pairsock");
else if ( nn_connect(pairsock,pairstr) >= 0 )
{
LP_unavailableset(utxo,Q.srchash);
Q.privkey = LP_privkey(Q.destaddr);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis,Q.destcoin,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector);
swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q);
swap->N.pair = pairsock;
utxo->S.swap = swap;
swap->utxo = utxo;
printf("alice pairstr.(%s)\n",pairstr);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 )
{
jaddstr(retjson,"result","success");
jadd(retjson,"trade",LP_quotejson(&Q));
jaddnum(retjson,"requestid",Q.R.requestid);
jaddnum(retjson,"quoteid",Q.R.quoteid);
} else jaddstr(retjson,"error","couldnt aliceloop");
}
} else jaddstr(retjson,"result","update stats");
return(jprint(retjson,1));
}
int32_t LP_tradecommand(char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin)
{ {
char *method,*base,*rel,*retstr,pairstr[512]; cJSON *retjson; double price; bits256 privkey,txid; struct LP_utxoinfo *utxo; int32_t retval = -1,DEXselector = 0; uint64_t destvalue; struct basilisk_request R; struct LP_quoteinfo Q; char *method,*base,*rel,*retstr; cJSON *retjson; double price; bits256 txid; struct LP_utxoinfo *utxo; int32_t retval = -1; struct LP_quoteinfo Q;
if ( IAMCLIENT == 0 && (method= jstr(argjson,"method")) != 0 ) if ( (method= jstr(argjson,"method")) != 0 )
{ {
txid = jbits256(argjson,"txid"); txid = jbits256(argjson,"txid");
if ( (utxo= LP_utxofind(txid,jint(argjson,"vout"))) != 0 && strcmp(utxo->ipaddr,mypeer->ipaddr) == 0 && utxo->port == mypeer->port && (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && strcmp(base,utxo->coin) == 0 ) if ( (utxo= LP_utxofind(1,txid,jint(argjson,"vout"))) != 0 && LP_ismine(utxo) != 0 && (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && strcmp(base,utxo->coin) == 0 )
{ {
printf("LP_command.(%s)\n",jprint(argjson,0)); printf("LP_command.(%s)\n",jprint(argjson,0));
if ( time(NULL) > utxo->swappending ) if ( utxo->S.swap == 0 && time(NULL) > utxo->T.swappending )
utxo->swappending = 0; utxo->T.swappending = 0;
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 ) if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 ) // bob
{ {
retval = 1; retval = 1;
if ( utxo->swappending == 0 ) if ( LP_isavailable(utxo) > 0 )
{ {
if ( strcmp(method,"request") == 0 && utxo->pair >= 0 )
nn_close(utxo->pair), utxo->pair = -1;
if ( (price= LP_price(base,rel)) != 0. ) if ( (price= LP_price(base,rel)) != 0. )
{ {
price *= (1. + profitmargin); price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 ) if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1); return(-1);
if ( LP_iseligible(Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) == 0 ) if ( LP_iseligible(1,Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) == 0 )
{ {
printf("not eligible\n"); printf("not eligible\n");
return(-1); return(-1);
@ -90,121 +178,40 @@ int32_t LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uin
if ( strcmp(method,"price") == 0 ) if ( strcmp(method,"price") == 0 )
Q.timestamp = (uint32_t)time(NULL); Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q); retjson = LP_quotejson(&Q);
utxo->S.otherpubkey = jbits256(argjson,"desthash");
if ( strcmp(method,"request") == 0 ) if ( strcmp(method,"request") == 0 )
{ {
retval |= 2; retval |= 2;
utxo->swappending = (uint32_t)(time(NULL) + LP_RESERVETIME); LP_unavailableset(utxo,jbits256(argjson,"desthash"));
utxo->otherpubkey = jbits256(argjson,"desthash");
jaddnum(retjson,"quotetime",juint(argjson,"quotetime")); jaddnum(retjson,"quotetime",juint(argjson,"quotetime"));
jaddnum(retjson,"pending",utxo->swappending); jaddnum(retjson,"pending",utxo->T.swappending);
jaddbits256(retjson,"desthash",utxo->otherpubkey); jaddbits256(retjson,"desthash",utxo->S.otherpubkey);
jaddstr(retjson,"method","reserved"); jaddstr(retjson,"method","reserved");
} }
else jaddstr(retjson,"method","quote"); else jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1); retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1); if ( pubsock >= 0 )
utxo->published = (uint32_t)time(NULL); LP_send(pubsock,retstr,1);
else LP_pubkey_send(utxo->S.otherpubkey,retstr,1);
utxo->T.published = (uint32_t)time(NULL);
} else printf("null price\n"); } else printf("null price\n");
} else printf("swappending.%u pair.%d\n",utxo->swappending,utxo->pair); } else printf("swappending.%u swap.%p\n",utxo->T.swappending,utxo->S.swap);
} }
else if ( strcmp(method,"connect") == 0 ) else if ( strcmp(method,"connect") == 0 ) // bob
{ {
retval = 4; retval = 4;
if ( utxo->pair < 0 ) if ( utxo->T.swappending != 0 && utxo->S.swap == 0 )
{ LP_connectstart(pubsock,utxo,argjson,myipaddr,base,rel,profitmargin);
if ( (price= LP_price(base,rel)) != 0. ) else printf("swap %p when connect came in (%s)\n",utxo->S.swap,jprint(argjson,0));
{
price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
if ( LP_quoteparse(&Q,argjson) < 0 )
return(-2);
//printf("connect with.(%s)\n",jprint(argjson,0));
Q.destsatoshis = Q.satoshis * price;
privkey = LP_privkey(utxo->coinaddr);
if ( bits256_nonz(utxo->mypub) == 0 )
utxo->mypub = LP_pubkey(privkey);
if ( LP_iseligible(Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) == 0 )
{
printf("not eligible\n");
return(-1);
}
if ( bits256_nonz(privkey) != 0 && Q.quotetime >= Q.timestamp-3 && Q.quotetime < utxo->swappending && bits256_cmp(utxo->mypub,Q.srchash) == 0 && (destvalue= LP_txvalue(rel,Q.desttxid,Q.destvout)) >= price*Q.satoshis+Q.desttxfee && destvalue >= Q.destsatoshis+Q.desttxfee )
{
nanomsg_tcpname(pairstr,mypeer->ipaddr,10000+(rand() % 10000));
if ( (utxo->pair= nn_socket(AF_SP,NN_PAIR)) < 0 )
printf("error creating utxo->pair\n");
else if ( nn_bind(utxo->pair,pairstr) >= 0 )
{
LP_requestinit(&R,Q.srchash,Q.desthash,base,Q.satoshis,rel,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)utxo) == 0 )
{
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","connected");
jaddstr(retjson,"pair",pairstr);
jaddnum(retjson,"requestid",R.requestid);
jaddnum(retjson,"quoteid",R.quoteid);
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
utxo->swap = LP_swapinit(1,0,privkey,&R,&Q);
}
else
{
printf("error launching swaploop\n");
free(utxo->swap);
utxo->swap = 0;
nn_close(utxo->pair);
utxo->pair = -1;
}
}
else
{
printf("printf error nn_connect to %s\n",pairstr);
nn_close(utxo->pair);
utxo->pair = -1;
}
} else printf("dest %.8f < required %.8f (%d %d %d %d %d %d) %.8f %.8f\n",dstr(Q.satoshis),dstr(price*(utxo->satoshis-Q.txfee)),bits256_nonz(privkey) != 0 ,Q.timestamp == utxo->swappending-LP_RESERVETIME ,Q.quotetime >= Q.timestamp ,Q.quotetime < utxo->swappending ,bits256_cmp(utxo->mypub,Q.srchash) == 0 , LP_txvalue(rel,Q.desttxid,Q.destvout) >= price*Q.satoshis+Q.desttxfee,dstr(LP_txvalue(rel,Q.desttxid,Q.destvout)),dstr(price*Q.satoshis+Q.desttxfee));
} else printf("no price for %s/%s\n",base,rel);
} else printf("utxo->pair.%d when connect came in (%s)\n",utxo->pair,jprint(argjson,0));
} }
} }
} }
return(retval); return(retval);
} }
char *LP_connected(cJSON *argjson)
{
cJSON *retjson; int32_t pairsock = -1; char *pairstr; struct LP_quoteinfo *qp; int32_t DEXselector = 0;
retjson = cJSON_CreateObject();
if ( IAMCLIENT == 0 )
jaddstr(retjson,"result","update stats");
else
{
if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 )
jaddstr(retjson,"error","couldnt create pairsock");
else if ( nn_connect(pairsock,pairstr) >= 0 )
{
qp = calloc(1,sizeof(*qp));
LP_quoteparse(qp,argjson);
qp->pair = pairsock;
qp->privkey = LP_privkey(qp->destaddr);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector);
printf("alice pairstr.(%s)\n",pairstr);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)qp) == 0 )
{
jaddstr(retjson,"result","success");
jadd(retjson,"trade",LP_quotejson(qp));
} else jaddstr(retjson,"error","couldnt aliceloop");
}
}
return(jprint(retjson,1));
}
// addcoin api
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 amclient,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_utxoinfo *utxo,*tmp; 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 )
@ -226,6 +233,9 @@ getutxos()\n\
getutxos(coin, lastn)\n\ getutxos(coin, lastn)\n\
orderbook(base, rel)\n\ orderbook(base, rel)\n\
getprice(base, rel)\n\ getprice(base, rel)\n\
register(pubkey,pushaddr)\n\
lookup(pubkey)\n\
forward(pubkey,hexstr)\n\
\"}")); \"}"));
if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 )
{ {
@ -250,9 +260,9 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"couldnt set price\"}")); return(clonestr("{\"error\":\"couldnt set price\"}"));
else else
{ {
if ( IAMCLIENT == 0 ) if ( IAMLP != 0 )
{ {
HASH_ITER(hh,LP_utxoinfos,utxo,tmp) HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp)
{ {
if ( LP_ismine(utxo) != 0 && (strcmp(utxo->coin,base) == 0 || strcmp(utxo->coin,rel) == 0) ) if ( LP_ismine(utxo) != 0 && (strcmp(utxo->coin,base) == 0 || strcmp(utxo->coin,rel) == 0) )
LP_priceping(LP_mypubsock,utxo,rel,LP_profitratio - 1.); LP_priceping(LP_mypubsock,utxo,rel,LP_profitratio - 1.);
@ -294,10 +304,10 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"coin is disabled\"}")); return(clonestr("{\"error\":\"coin is disabled\"}"));
if ( strcmp(method,"inventory") == 0 ) if ( strcmp(method,"inventory") == 0 )
{ {
LP_privkey_init(0,-1,coin,0,USERPASS_WIFSTR,1); LP_privkey_init(-1,coin,0,USERPASS_WIFSTR,0);
return(LP_inventory(coin)); return(LP_inventory(coin,jobj(argjson,"client") != 0 ? jint(argjson,"client") : 0));
} }
else if ( IAMCLIENT != 0 && (strcmp(method,"candidates") == 0 || strcmp(method,"autotrade") == 0) ) else if ( (strcmp(method,"candidates") == 0 || strcmp(method,"autotrade") == 0) )
{ {
bits256 txid; int32_t vout; struct LP_utxoinfo *utxo; bits256 txid; int32_t vout; struct LP_utxoinfo *utxo;
txid = jbits256(argjson,"txid"); txid = jbits256(argjson,"txid");
@ -306,7 +316,7 @@ getprice(base, rel)\n\
if ( jobj(argjson,"vout") == 0 ) if ( jobj(argjson,"vout") == 0 )
return(clonestr("{\"error\":\"missing vout\"}")); return(clonestr("{\"error\":\"missing vout\"}"));
vout = jint(argjson,"vout"); vout = jint(argjson,"vout");
if ( (utxo= LP_utxofind(txid,vout)) == 0 ) if ( (utxo= LP_utxofind(1,txid,vout)) == 0 )
return(clonestr("{\"error\":\"txid/vout not found\"}")); return(clonestr("{\"error\":\"txid/vout not found\"}"));
if ( strcmp(method,"candidates") == 0 ) if ( strcmp(method,"candidates") == 0 )
return(jprint(LP_tradecandidates(coin),1)); return(jprint(LP_tradecandidates(coin),1));
@ -325,7 +335,6 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"at least one of coins disabled\"}")); return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
if ( LP_isdisabled(jstr(argjson,"coin"),0) != 0 ) if ( LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
return(clonestr("{\"error\":\"coin is disabled\"}")); return(clonestr("{\"error\":\"coin is disabled\"}"));
amclient = (LP_mypeer == 0);
if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 ) if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 )
{ {
if ( strcmp(ipaddr,"127.0.0.1") != 0 && port >= 1000 ) if ( strcmp(ipaddr,"127.0.0.1") != 0 && port >= 1000 )
@ -344,7 +353,7 @@ getprice(base, rel)\n\
peer->numutxos = othernumutxos; peer->numutxos = othernumutxos;
} }
//printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0)); //printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0));
} else LP_addpeer(amclient,LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jdouble(argjson,"profit"),jint(argjson,"numpeers"),jint(argjson,"numutxos")); } else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jdouble(argjson,"profit"),jint(argjson,"numpeers"),jint(argjson,"numutxos"));
} }
} }
//printf("CMD.(%s)\n",jprint(argjson,0)); //printf("CMD.(%s)\n",jprint(argjson,0));
@ -362,21 +371,30 @@ getprice(base, rel)\n\
retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel")); retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel"));
else if ( strcmp(method,"getpeers") == 0 ) else if ( strcmp(method,"getpeers") == 0 )
retstr = LP_peers(); retstr = LP_peers();
else if ( IAMCLIENT == 0 && strcmp(method,"getutxos") == 0 && (coin= jstr(argjson,"coin")) != 0 ) else if ( IAMLP != 0 )
{
retstr = LP_utxos(LP_mypeer,coin,jint(argjson,"lastn"));
//printf("RETURN. %d utxos\n",cJSON_GetArraySize(cJSON_Parse(retstr)));
}
else if ( IAMCLIENT == 0 && strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
else if ( IAMCLIENT == 0 && strcmp(method,"notified") == 0 )
{ {
if ( juint(argjson,"timestamp") > time(NULL)-60 ) if ( strcmp(method,"getutxos") == 0 && (coin= jstr(argjson,"coin")) != 0 )
{ {
printf("utxonotify.(%s)\n",jprint(argjson,0)); retstr = LP_utxos(1,LP_mypeer,coin,jint(argjson,"lastn"));
LP_addutxo(amclient,LP_mypeer,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"),jstr(argjson,"ipaddr"),juint(argjson,"port"),jdouble(argjson,"profit")); //printf("RETURN. %d utxos\n",cJSON_GetArraySize(cJSON_Parse(retstr)));
}
else if ( strcmp(method,"register") == 0 )
retstr = LP_register(jbits256(argjson,"pubkey"),jstr(argjson,"pushaddr"));
else if ( strcmp(method,"lookup") == 0 )
retstr = LP_lookup(jbits256(argjson,"pubkey"));
else if ( strcmp(method,"forward") == 0 )
retstr = LP_forward(jbits256(argjson,"pubkey"),jstr(argjson,"hexstr"));
else if ( strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
else if ( strcmp(method,"notified") == 0 )
{
if ( juint(argjson,"timestamp") > time(NULL)-60 )
{
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"));
}
retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}");
} }
retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}");
} }
if ( retstr != 0 ) if ( retstr != 0 )
return(retstr); return(retstr);

165
iguana/exchanges/LP_forwarding.c

@ -0,0 +1,165 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_forwarding.c
// marketmaker
//
struct LP_forwardinfo
{
UT_hash_handle hh;
bits256 pubkey;
char pushaddr[64];
int32_t pushsock;
uint32_t lasttime;
} *LP_forwardinfos;
#define LP_KEEPALIVE 300
struct LP_forwardinfo *LP_forwardfind(bits256 pubkey)
{
struct LP_forwardinfo *ptr=0;
portable_mutex_lock(&LP_forwardmutex);
HASH_FIND(hh,LP_forwardinfos,&pubkey,sizeof(pubkey),ptr);
portable_mutex_unlock(&LP_forwardmutex);
if ( ptr != 0 && ptr->lasttime > time(NULL)-LP_KEEPALIVE )
return(ptr);
else return(0);
}
char *LP_lookup(bits256 pubkey)
{
if ( LP_forwardfind(pubkey) != 0 )
return(clonestr("{\"result\":\"success\",\"forwarding\":1}"));
else return(clonestr("{\"error\":\"notfound\"}"));
}
char *LP_register(bits256 pubkey,char *pushaddr)
{
struct LP_forwardinfo *ptr=0; int32_t pushsock;
if ( is_ipaddr(pushaddr) == 0 )
return(clonestr("{\"error\":\"illegal ipaddr\"}"));
if ( (ptr= LP_forwardfind(pubkey)) != 0 )
{
ptr->lasttime = (uint32_t)time(NULL);
return(clonestr("{\"error\":\"already registered\"}"));
}
else if ( (pushsock= nn_socket(AF_SP,NN_PUSH)) < 0 )
return(clonestr("{\"error\":\"out of sockets\"}"));
else if ( nn_connect(pushsock,pushaddr) < 0 )
{
nn_close(pushsock);
return(clonestr("{\"error\":\"cant connect\"}"));
}
else
{
ptr = calloc(1,sizeof(*ptr));
ptr->pubkey = pubkey;
strcpy(ptr->pushaddr,pushaddr);
ptr->pushsock = pushsock;
ptr->lasttime = (uint32_t)time(NULL);
portable_mutex_lock(&LP_forwardmutex);
HASH_ADD_KEYPTR(hh,LP_forwardinfos,&ptr->pubkey,sizeof(ptr->pubkey),ptr);
portable_mutex_unlock(&LP_forwardmutex);
return(LP_lookup(pubkey));
}
}
char *LP_forward(bits256 pubkey,char *hexstr)
{
struct LP_forwardinfo *ptr=0; uint8_t *data; int32_t datalen=0,sentbytes=0; cJSON *retjson;
if ( hexstr == 0 || hexstr[0] == 0 )
return(clonestr("{\"error\":\"nohex\"}"));
if ( (ptr= LP_forwardfind(pubkey)) != 0 )
{
if ( ptr->pushsock >= 0 )
{
datalen = (int32_t)strlen(hexstr) >> 1;
data = malloc(datalen);
decode_hex(data,datalen,hexstr);
sentbytes = LP_send(ptr->pushsock,(char *)data,1);
}
retjson = cJSON_CreateObject();
if ( sentbytes == datalen )
{
jaddstr(retjson,"result","success");
jaddnum(retjson,"forwarded",sentbytes);
return(jprint(retjson,1));
}
else
{
jaddstr(retjson,"error","send error");
jaddnum(retjson,"sentbytes",sentbytes);
jaddnum(retjson,"datalen",datalen);
return(jprint(retjson,1));
}
} else return(clonestr("{\"error\":\"notfound\"}"));
}
void LP_forwarding_register(bits256 pubkey,char *pushaddr)
{
char *retstr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; int32_t retval = -1;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( (retstr= issue_LP_register(peer->ipaddr,peer->port,pubkey,pushaddr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jint(retjson,"registered") != 0 )
retval = 0;
free_json(retjson);
}
free(retstr);
}
if ( retval == 0 )
break;
}
}
int32_t LP_pubkey_send(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;
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)
{
if ( (retstr= issue_LP_lookup(peer->ipaddr,peer->port,pubkey)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jint(retjson,"forwarding") != 0 )
retval = 0;
free_json(retjson);
}
free(retstr);
}
if ( retval == 0 )
{
len = (int32_t)strlen(jsonstr) + 1;
hexstr = malloc(len*2 + 1);
init_hexbytes_noT(hexstr,(uint8_t *)jsonstr,len);
if ( freeflag != 0 )
free(jsonstr);
if ( peer->pushsock >= 0 )
return(LP_send(peer->pushsock,hexstr,1));
}
}
return(-1);
}

66
iguana/exchanges/LP_include.h

@ -46,7 +46,7 @@
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2)) #define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
extern char GLOBAL_DBDIR[],USERPASS[],USERPASS_WIFSTR[]; extern char GLOBAL_DBDIR[],USERPASS[],USERPASS_WIFSTR[];
extern int32_t IAMCLIENT,USERPASS_COUNTER; extern int32_t IAMLP,USERPASS_COUNTER;
struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; };
@ -139,42 +139,34 @@ struct basilisk_swapinfo
struct iguana_info struct iguana_info
{ {
uint64_t txfee; double estimatedrate; uint64_t txfee; double estimatedrate,profitmargin;
int32_t longestchain; uint32_t counter,inactive; int32_t longestchain; uint32_t counter,inactive;
uint8_t pubtype,p2shtype,isPoS,wiftype; uint8_t pubtype,p2shtype,isPoS,wiftype;
char symbol[16],smartaddr[64],userpass[1024],serverport[128]; char symbol[16],smartaddr[64],userpass[1024],serverport[128];
}; };
struct basilisk_swap struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; };
{
void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxostats { uint32_t lasttime,errors,swappending,published,spentflag,lastspentcheck; };
void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob);
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; };
FILE *fp;
bits256 persistent_privkey,persistent_pubkey; struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; };
struct basilisk_swapinfo I;
struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; struct LP_utxoswap { bits256 otherpubkey,mypub; void *swap; uint64_t satoshis; double profitmargin; };
bits256 privkeys[INSTANTDEX_DECKSIZE];
struct basilisk_swapmessage *messages; int32_t nummessages;
char Bdeposit[64],Bpayment[64];
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint8_t persistent_pubkey33[33],changermd160[20],pad[15],verifybuf[65536];
};
struct LP_utxoinfo struct LP_utxoinfo
{ {
UT_hash_handle hh,hh2; UT_hash_handle hh,hh2;
bits256 txid,txid2,feetxid,otherpubkey,mypub; bits256 pubkey;
void *swap; struct _LP_utxoinfo payment,deposit,fee;
uint64_t value,satoshis,value2; struct LP_utxostats T;
struct LP_utxoswap S;
//struct LP_utxonetwork N;
int32_t iambob,iamlp;
uint8_t key[sizeof(bits256) + sizeof(int32_t)]; uint8_t key[sizeof(bits256) + sizeof(int32_t)];
uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; uint8_t key2[sizeof(bits256) + sizeof(int32_t)];
int32_t vout,vout2,pair; char coin[16],coinaddr[64],spendscript[256];
uint32_t lasttime,errors,swappending,published,spentflag,lastspentcheck;
double profitmargin;
char ipaddr[64],coinaddr[64],spendscript[256],coin[16];
uint16_t port;
}; };
struct LP_peerinfo struct LP_peerinfo
@ -197,13 +189,33 @@ struct LP_quoteinfo
char srccoin[16],coinaddr[64],destcoin[16],destaddr[64]; char srccoin[16],coinaddr[64],destcoin[16],destaddr[64];
}; };
struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; };
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;
FILE *fp;
bits256 persistent_privkey,persistent_pubkey;
struct basilisk_swapinfo I;
struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim;
bits256 privkeys[INSTANTDEX_DECKSIZE];
struct basilisk_swapmessage *messages; int32_t nummessages;
char Bdeposit[64],Bpayment[64];
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint8_t persistent_pubkey33[33],changermd160[20],pad[15],verifybuf[65536];
};
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx);
uint32_t basilisk_requestid(struct basilisk_request *rp); uint32_t basilisk_requestid(struct basilisk_request *rp);
uint32_t basilisk_quoteid(struct basilisk_request *rp); uint32_t basilisk_quoteid(struct basilisk_request *rp);
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp); struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp);
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params);
uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend);
double LP_query(char *method,struct LP_quoteinfo *qp,char *ipaddr,uint16_t port,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);

344
iguana/exchanges/LP_nativeDEX.c

@ -17,13 +17,13 @@
// LP_nativeDEX.c // LP_nativeDEX.c
// marketmaker // marketmaker
// //
// jl777: fix price calcs based on specific txfees // jl777: profitmargin per coin, ignore peers with errors
#include <stdio.h> #include <stdio.h>
#include "LP_include.h" #include "LP_include.h"
#include "LP_network.c" #include "LP_network.c"
struct LP_utxoinfo *LP_utxoinfos,*LP_utxoinfos2; struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
char *activecoins[] = { "BTC", "KMD" }; char *activecoins[] = { "BTC", "KMD" };
@ -32,11 +32,11 @@ char USERPASS[65],USERPASS_WIFSTR[64],USERHOME[512] = { "/root" };
char *default_LPnodes[] = { "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" }; //"5.9.253.195", char *default_LPnodes[] = { "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" }; //"5.9.253.195",
portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex; portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex;
int32_t LP_mypubsock = -1; int32_t LP_mypubsock = -1;
int32_t Client_connections; int32_t USERPASS_COUNTER,IAMLP = 0;
int32_t USERPASS_COUNTER,IAMCLIENT = 0;
double LP_profitratio = 1.; double LP_profitratio = 1.;
bits256 LP_mypubkey;
// stubs // stubs
int32_t basilisk_istrustedbob(struct basilisk_swap *swap) int32_t basilisk_istrustedbob(struct basilisk_swap *swap)
@ -76,26 +76,124 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
#include "LP_peers.c" #include "LP_peers.c"
#include "LP_utxos.c" #include "LP_utxos.c"
#include "LP_quotes.c" #include "LP_quotes.c"
#include "LP_forwarding.c"
#include "LP_commands.c" #include "LP_commands.c"
void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,int32_t pullsock,uint16_t myport,int32_t amclient,char *passphrase,double profitmargin,cJSON *coins) int32_t LP_pullsock_check(char *myipaddr,int32_t pubsock,int32_t pullsock,double profitmargin)
{ {
//static uint16_t tmpport; int32_t recvsize,len,datalen,nonz = 0; void *ptr; char *retstr,*jsonstr=0; cJSON *argjson;
char *retstr; uint8_t r; int32_t i,n,j,len,recvsize,counter=0,nonz,lastn; struct LP_peerinfo *peer,*tmp; uint32_t now; struct LP_utxoinfo *utxo,*utmp; void *ptr; cJSON *argjson,*item; while ( (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 )
//if ( amclient != 0 ) {
// myport += amclient * 10; nonz++;
if ( (datalen= is_hexstr((char *)ptr,0)) > 0 )
{
datalen >>= 1;
jsonstr = malloc(datalen + 1);
decode_hex((void *)jsonstr,datalen,(char *)ptr);
jsonstr[datalen] = 0;
} else jsonstr = (char *)ptr;
if ( (argjson= cJSON_Parse(jsonstr)) != 0 )
{
len = (int32_t)strlen(jsonstr) + 1;
portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvsize - len,profitmargin) == 0 )
{
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
printf("%s PULL.[%d] %s\n",myipaddr != 0 ? myipaddr : "127.0.0.1",recvsize,(char *)ptr);
free(retstr);
}
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
}
if ( (void *)jsonstr != ptr )
free(jsonstr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
return(nonz);
}
int32_t LP_subsock_check(struct LP_peerinfo *peer)
{
int32_t recvsize,nonz = 0; char *retstr; void *ptr; cJSON *argjson;
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
{
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
return(nonz);
}
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);
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
utxo->T.lastspentcheck = now;
if ( LP_txvalue(utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(utxo->coin,u.txid,u.vout) == 0 )
{
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);
}
else if ( LP_ismine(utxo) != 0 )
{
if ( strcmp(utxo->coin,"KMD") == 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin);
}
}
}
void LP_utxo_updates(int32_t pubsock,char *passphrase,double profitmargin)
{
int32_t iambob; struct LP_utxoinfo *utxo,*tmp;
LP_utxopurge(0);
for (iambob=0; iambob<=1; iambob++)
{
LP_privkey_updates(pubsock,passphrase,iambob);
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
LP_utxo_spentcheck(pubsock,utxo,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 *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;
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);
exit(-1); exit(-1);
} }
if ( amclient == 0 ) if ( IAMLP != 0 )
{ {
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++) for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{ {
if ( (rand() % 100) > 25 ) if ( (rand() % 100) > 25 )
continue; continue;
LP_peersquery(amclient,mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport,profitmargin); LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport,profitmargin);
} }
} }
else else
@ -104,12 +202,9 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
for (j=0; j<sizeof(default_LPnodes)/sizeof(*default_LPnodes); j++) for (j=0; j<sizeof(default_LPnodes)/sizeof(*default_LPnodes); j++)
{ {
i = (r + j) % (sizeof(default_LPnodes)/sizeof(*default_LPnodes)); i = (r + j) % (sizeof(default_LPnodes)/sizeof(*default_LPnodes));
LP_peersquery(amclient,mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport,profitmargin); LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport,profitmargin);
} }
} }
//if ( amclient != 0 )
// tmpport = myport + 10;
//else tmpport = myport;
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++) for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
{ {
LP_coinfind(activecoins[i]); LP_coinfind(activecoins[i]);
@ -124,44 +219,41 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
LP_priceinfoadd(jstr(item,"coin")); LP_priceinfoadd(jstr(item,"coin"));
} }
} }
LP_privkey_updates(mypeer,pubsock,passphrase,amclient); LP_privkey_updates(pubsock,passphrase,0);
LP_privkey_updates(pubsock,passphrase,1);
if ( (retstr= basilisk_swaplist()) != 0 ) if ( (retstr= basilisk_swaplist()) != 0 )
free(retstr); free(retstr);
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {
if ( strcmp(peer->ipaddr,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1") != 0 ) if ( strcmp(peer->ipaddr,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1") != 0 )
{ {
printf("query utxo from %s\n",peer->ipaddr); //printf("query utxo from %s\n",peer->ipaddr);
LP_utxosquery(0,mypeer,pubsock,peer->ipaddr,peer->port,"",100,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,profitmargin); LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",100,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,profitmargin);
} }
} }
if ( amclient != 0 ) if ( IAMLP == 0 )
{ {
while ( 1 ) while ( 1 )
{ {
now = (uint32_t)time(NULL);
if ( lastforward < now-LP_KEEPALIVE )
{
LP_forwarding_register(LP_mypubkey,pushaddr);
lastforward = now;
}
nonz = n = 0; nonz = n = 0;
if ( (++counter % 3600) == 0 ) if ( (++counter % 5000) == 0 )
LP_privkey_updates(mypeer,pubsock,passphrase,amclient); LP_utxo_updates(pubsock,passphrase,profitmargin);
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {
n++; nonz += LP_subsock_check(peer);
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 ) }
if ( pullsock >= 0 )
{
if ( (n= LP_pullsock_check(myipaddr,pubsock,pullsock,profitmargin)) > 0 )
{ {
nonz++; nonz += n;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 ) lastforward = now;
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
//printf("subloop.(%s)\n",jprint(argjson,0));
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
} }
} }
if ( nonz == 0 ) if ( nonz == 0 )
@ -173,41 +265,8 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
while ( 1 ) while ( 1 )
{ {
nonz = 0; nonz = 0;
if ( (++counter % 2000) == 0 )
{
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
}
if ( (counter % 500) == 0 ) if ( (counter % 500) == 0 )
{ LP_utxo_updates(pubsock,passphrase,profitmargin);
char str[65];
//printf("start utxos updates\n");
HASH_ITER(hh,LP_utxoinfos,utxo,utmp)
{
now = (uint32_t)time(NULL);
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->spentflag == 0 && now > utxo->lastspentcheck+60 )
{
utxo->lastspentcheck = now;
if ( LP_txvalue(utxo->coin,utxo->txid,utxo->vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->txid),utxo->vout,dstr(utxo->value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(utxo->coin,utxo->txid2,utxo->vout2) == 0 )
{
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->txid2),utxo->vout2,dstr(utxo->value2));
LP_spentnotify(utxo,1);
}
else if ( LP_ismine(utxo) != 0 )
{
if ( strcmp(utxo->coin,"KMD") == 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin);
}
}
}
//printf("done utxos updates\n");
}
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
//printf("start peers updates\n"); //printf("start peers updates\n");
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
@ -219,7 +278,7 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
if ( peer->numpeers != mypeer->numpeers ) if ( peer->numpeers != mypeer->numpeers )
printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,mypeer->numpeers); printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,mypeer->numpeers);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 ) if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_peersquery(amclient,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 ) if ( peer->numutxos != mypeer->numutxos && now > peer->lastutxos+60 )
{ {
@ -229,47 +288,12 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
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); printf("%s numutxos.%d vs %d lastn.%d\n",peer->ipaddr,peer->numutxos,mypeer->numutxos,lastn);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 ) if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_utxosquery(0,mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer->ipaddr,myport,profitmargin); LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer->ipaddr,myport,profitmargin);
}
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
{
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
} }
nonz += LP_subsock_check(peer);
} }
while ( pullsock >= 0 && (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 ) if ( pullsock >= 0 )
{ nonz += LP_pullsock_check(myipaddr,pubsock,pullsock,profitmargin);
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
len = (int32_t)strlen((char *)ptr) + 1;
portable_mutex_lock(&LP_commandmutex);
if ( LP_command(mypeer,pubsock,argjson,&((uint8_t *)ptr)[len],recvsize - len,profitmargin) == 0 )
{
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
printf("%s PULL.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
}
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
if ( nonz == 0 ) if ( nonz == 0 )
usleep(100000); usleep(100000);
//printf("nonz.%d in mainloop\n",nonz); //printf("nonz.%d in mainloop\n",nonz);
@ -280,7 +304,7 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profitmargin,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson) void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profitmargin,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{ {
char *myipaddr=0; long filesize,n; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128]; char *myipaddr=0; long filesize,n; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128];
IAMCLIENT = amclient; IAMLP = !amclient;
LP_profitratio += profitmargin; LP_profitratio += profitmargin;
OS_randombytes((void *)&n,sizeof(n)); OS_randombytes((void *)&n,sizeof(n));
srand((int32_t)n); srand((int32_t)n);
@ -291,58 +315,70 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
portable_mutex_init(&LP_commandmutex); portable_mutex_init(&LP_commandmutex);
portable_mutex_init(&LP_swaplistmutex); portable_mutex_init(&LP_swaplistmutex);
portable_mutex_init(&LP_cachemutex); portable_mutex_init(&LP_cachemutex);
if ( amclient == 0 ) portable_mutex_init(&LP_forwardmutex);
if ( profitmargin == 0. || profitmargin == 0.01 )
{ {
if ( profitmargin == 0. || profitmargin == 0.01 ) profitmargin = 0.01 + (double)(rand() % 100)/100000;
printf("default profit margin %f\n",profitmargin);
}
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 )
{
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 )
{
n = strlen(myipaddr);
if ( myipaddr[n-1] == '\n' )
myipaddr[--n] = 0;
} else printf("error getting myipaddr\n");
} else printf("error issuing curl\n");
nanomsg_tcpname(pushaddr,myipaddr,mypullport);
if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 )
{
if ( nn_bind(pullsock,pushaddr) >= 0 )
{ {
profitmargin = 0.01 + (double)(rand() % 100)/100000; timeout = 1;
printf("default profit margin %f\n",profitmargin); nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
timeout = 1;
maxsize = 1024 * 1024;
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize));
} }
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 ) }
if ( IAMLP != 0 )
{
if ( myipaddr != 0 )
{ {
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 ) pubsock = -1;
nanomsg_tcpname(subaddr,myipaddr,mypubport);
printf(">>>>>>>>> myipaddr.%s (%s %s)\n",myipaddr,pushaddr,subaddr);
if ( (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 )
{ {
n = strlen(myipaddr); if ( nn_bind(pubsock,subaddr) >= 0 )
if ( myipaddr[n-1] == '\n' ) {
myipaddr[--n] = 0; timeout = 10;
pullsock = pubsock = -1; nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
nanomsg_tcpname(pushaddr,myipaddr,mypullport); }
nanomsg_tcpname(subaddr,myipaddr,mypubport); else
printf(">>>>>>>>> myipaddr.%s (%s %s)\n",myipaddr,pushaddr,subaddr);
if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 )
{ {
if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 ) printf("error binding to (%s).%d (%s).%d\n",pushaddr,pullsock,subaddr,pubsock);
{ if ( pubsock >= 0 )
timeout = 10; nn_close(pubsock), pubsock = -1;
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); }
timeout = 1; } else printf("error getting sockets %d %d\n",pullsock,pubsock);
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); LP_mypubsock = pubsock;
timeout = 1; LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0);
maxsize = 1024 * 1024; //printf("my ipaddr.(%s) peers.(%s)\n",ipaddr,retstr!=0?retstr:"");
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); }
}
else
{
printf("error binding to (%s).%d (%s).%d\n",pushaddr,pullsock,subaddr,pubsock);
if ( pullsock >= 0 )
nn_close(pullsock), pullsock = -1;
if ( pubsock >= 0 )
nn_close(pubsock), pubsock = -1;
}
} else printf("error getting sockets %d %d\n",pullsock,pubsock);
LP_mypubsock = pubsock;
LP_mypeer = mypeer = LP_addpeer(amclient,mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0);
//printf("my ipaddr.(%s) peers.(%s)\n",ipaddr,retstr!=0?retstr:"");
} else printf("error getting myipaddr\n");
} else printf("error issuing curl\n");
if ( myipaddr == 0 || mypeer == 0 ) if ( myipaddr == 0 || mypeer == 0 )
{ {
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer); printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
exit(-1); exit(-1);
} }
//printf("utxos.(%s)\n",LP_utxos(mypeer,"",10000));
} }
LP_mainloop(mypeer,mypubport,pubsock,pullsock,myport,amclient,passphrase,profitmargin,jobj(argjson,"coins")); else if ( myipaddr == 0 )
{
printf("couldnt get myipaddr\n");
exit(-1);
}
LP_mainloop(myipaddr,mypeer,mypubport,pubsock,pushaddr,pullsock,myport,passphrase,profitmargin,jobj(argjson,"coins"));
} }

24
iguana/exchanges/LP_peers.c

@ -47,13 +47,9 @@ char *LP_peers()
return(jprint(peersjson,1)); return(jprint(peersjson,1));
} }
struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,double profitmargin,int32_t numpeers,int32_t numutxos) struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,double profitmargin,int32_t numpeers,int32_t numutxos)
{ {
uint32_t ipbits; int32_t pushsock,subsock,timeout,enabled; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; uint32_t ipbits; int32_t pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0;
/*if ( strcmp(ipaddr,"173.208.149.42") == 0 )
return(0);
if ( strncmp(ipaddr,"5.9.253",strlen("5.9.253")) != 0 )
return(0);*/
ipbits = (uint32_t)calc_ipbits(ipaddr); ipbits = (uint32_t)calc_ipbits(ipaddr);
expand_ipbits(checkip,ipbits); expand_ipbits(checkip,ipbits);
if ( strcmp(checkip,ipaddr) == 0 ) if ( strcmp(checkip,ipaddr) == 0 )
@ -73,9 +69,6 @@ struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32
peer = calloc(1,sizeof(*peer)); peer = calloc(1,sizeof(*peer));
peer->pushsock = peer->subsock = pushsock = subsock = -1; peer->pushsock = peer->subsock = pushsock = subsock = -1;
strcpy(peer->ipaddr,ipaddr); strcpy(peer->ipaddr,ipaddr);
if ( amclient == 0 )
enabled = 1;
else enabled = 1;//(rand() % (1 << Client_connections)) == 0;
if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 )
{ {
timeout = 1000; timeout = 1000;
@ -86,7 +79,7 @@ struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32
printf("connected to push.(%s) %d\n",pushaddr,pushsock); printf("connected to push.(%s) %d\n",pushaddr,pushsock);
peer->connected = (uint32_t)time(NULL); peer->connected = (uint32_t)time(NULL);
peer->pushsock = pushsock; peer->pushsock = pushsock;
if ( enabled != 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{ {
timeout = 1; timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
@ -96,7 +89,6 @@ struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32
{ {
peer->subsock = subsock; peer->subsock = subsock;
printf("connected to sub.(%s) %d\n",subaddr,peer->subsock); printf("connected to sub.(%s) %d\n",subaddr,peer->subsock);
Client_connections += amclient;
} else nn_close(subsock); } else nn_close(subsock);
} }
} }
@ -125,7 +117,7 @@ struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32
return(peer); return(peer);
} }
int32_t LP_peersparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{ {
struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0;
if ( (array= cJSON_Parse(retstr)) != 0 ) if ( (array= cJSON_Parse(retstr)) != 0 )
@ -144,7 +136,7 @@ int32_t LP_peersparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
argipbits = (uint32_t)calc_ipbits(argipaddr); argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
{ {
peer = LP_addpeer(amclient,mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos")); peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
} }
if ( peer != 0 ) if ( peer != 0 )
{ {
@ -160,7 +152,7 @@ int32_t LP_peersparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
return(n); return(n);
} }
void LP_peersquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport,double myprofit) void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport,double myprofit)
{ {
char *retstr; struct LP_peerinfo *peer,*tmp; uint32_t now,flag = 0; char *retstr; struct LP_peerinfo *peer,*tmp; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
@ -170,9 +162,9 @@ void LP_peersquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock
{ {
//printf("got.(%s)\n",retstr); //printf("got.(%s)\n",retstr);
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
LP_peersparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now); LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr); free(retstr);
if ( amclient == 0 ) if ( IAMLP != 0 )
{ {
HASH_ITER(hh,LP_peerinfos,peer,tmp) HASH_ITER(hh,LP_peerinfos,peer,tmp)
{ {

54
iguana/exchanges/LP_quotes.c

@ -125,13 +125,13 @@ int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *
safecopy(qp->destcoin,destcoin,sizeof(qp->destcoin)); safecopy(qp->destcoin,destcoin,sizeof(qp->destcoin));
if ( (qp->txfee= LP_getestimatedrate(utxo->coin)*LP_AVETXSIZE) < 10000 ) if ( (qp->txfee= LP_getestimatedrate(utxo->coin)*LP_AVETXSIZE) < 10000 )
qp->txfee = 10000; qp->txfee = 10000;
if ( qp->txfee >= utxo->satoshis || qp->txfee >= utxo->value2 || utxo->value2 < LP_DEPOSITSATOSHIS(utxo->satoshis) ) if ( utxo->iambob == 0 || qp->txfee >= utxo->S.satoshis || qp->txfee >= utxo->deposit.value || utxo->deposit.value < LP_DEPOSITSATOSHIS(utxo->S.satoshis) )
return(-1); return(-1);
qp->txid = utxo->txid; qp->txid = utxo->payment.txid;
qp->vout = utxo->vout; qp->vout = utxo->payment.vout;
qp->txid2 = utxo->txid2; qp->txid2 = utxo->deposit.txid;
qp->vout2 = utxo->vout2; qp->vout2 = utxo->deposit.vout;
qp->satoshis = utxo->satoshis - qp->txfee; qp->satoshis = utxo->S.satoshis - qp->txfee;
qp->destsatoshis = qp->satoshis * price; qp->destsatoshis = qp->satoshis * price;
if ( (qp->desttxfee= LP_getestimatedrate(qp->destcoin) * LP_AVETXSIZE) < 10000 ) if ( (qp->desttxfee= LP_getestimatedrate(qp->destcoin) * LP_AVETXSIZE) < 10000 )
qp->desttxfee = 10000; qp->desttxfee = 10000;
@ -140,7 +140,7 @@ int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *
qp->destsatoshis -= qp->desttxfee; qp->destsatoshis -= qp->desttxfee;
safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin)); safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin));
safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr)); safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr));
qp->srchash = LP_pubkey(LP_privkey(utxo->coinaddr)); qp->srchash = utxo->pubkey;
return(0); return(0);
} }
@ -224,7 +224,7 @@ cJSON *LP_tradecandidates(char *base)
safecopy(coinstr,jstr(item,"base"),sizeof(coinstr)); safecopy(coinstr,jstr(item,"base"),sizeof(coinstr));
if ( strcmp(coinstr,base) == 0 ) if ( strcmp(coinstr,base) == 0 )
{ {
if ( LP_iseligible(Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) != 0 ) if ( LP_iseligible(1,Q.srccoin,Q.txid,Q.vout,Q.satoshis,Q.txid2,Q.vout2) != 0 )
{ {
if ( LP_arrayfind(retarray,Q.txid,Q.vout) < 0 ) if ( LP_arrayfind(retarray,Q.txid,Q.vout) < 0 )
{ {
@ -265,8 +265,8 @@ void LP_quotesinit(char *base,char *rel)
item = jitem(array,i); item = jitem(array,i);
LP_quoteparse(&Q,item); LP_quoteparse(&Q,item);
if ( iter == 0 ) if ( iter == 0 )
LP_query("price",&Q,jstr(item,"ipaddr"),jint(item,"port"),base,rel,zero); LP_query("price",&Q,base,rel,zero);
else LP_query("price",&Q,jstr(item,"ipaddr"),jint(item,"port"),rel,base,zero); else LP_query("price",&Q,rel,base,zero);
} }
} }
free_json(array); free_json(array);
@ -293,7 +293,7 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
LP_quoteparse(&Q[i],item); LP_quoteparse(&Q[i],item);
if ( (price= jdouble(item,"price")) == 0. ) if ( (price= jdouble(item,"price")) == 0. )
{ {
price = LP_query("price",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),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) != 0. && (bestprice == 0. || price < bestprice) )
@ -306,7 +306,7 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
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->satoshis >= Q[i].destsatoshis+Q[i].desttxfee ) if ( (price= prices[i]) != 0. && 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);
@ -320,7 +320,7 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
bestmetric = metric; bestmetric = metric;
} }
} }
} else printf("(%f %f) ",dstr(myutxo->satoshis),dstr(Q[i].destsatoshis)); } else printf("(%f %f) ",dstr(myutxo->S.satoshis),dstr(Q[i].destsatoshis));
} }
printf("metrics, best %f\n",bestmetric); printf("metrics, best %f\n",bestmetric);
if ( besti >= 0 )//&& bits256_cmp(myutxo->mypub,otherpubs[besti]) == 0 ) if ( besti >= 0 )//&& bits256_cmp(myutxo->mypub,otherpubs[besti]) == 0 )
@ -332,23 +332,23 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
printf("bestprice %f vs maxprice %f\n",bestprice,maxprice); printf("bestprice %f vs maxprice %f\n",bestprice,maxprice);
if ( maxprice == 0. || bestprice <= maxprice ) if ( maxprice == 0. || bestprice <= maxprice )
{ {
Q[i].desttxid = myutxo->txid; Q[i].desttxid = myutxo->payment.txid;
Q[i].destvout = myutxo->vout; Q[i].destvout = myutxo->payment.vout;
Q[i].feetxid = myutxo->txid2; Q[i].feetxid = myutxo->fee.txid;
Q[i].feevout = myutxo->vout2; Q[i].feevout = myutxo->fee.vout;
strcpy(Q[i].destaddr,myutxo->coinaddr); strcpy(Q[i].destaddr,myutxo->coinaddr);
price = LP_query("request",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),base,myutxo->coin,myutxo->mypub); price = LP_query("request",&Q[i],base,myutxo->coin,myutxo->S.mypub);
if ( jobj(bestitem,"price") != 0 ) if ( jobj(bestitem,"price") != 0 )
jdelete(bestitem,"price"); jdelete(bestitem,"price");
jaddnum(bestitem,"price",prices[i]); jaddnum(bestitem,"price",prices[i]);
if ( price <= maxprice ) if ( price <= maxprice )
{ {
Q[i].desttxid = myutxo->txid; Q[i].desttxid = myutxo->payment.txid;
Q[i].destvout = myutxo->vout; Q[i].destvout = myutxo->payment.vout;
Q[i].feetxid = myutxo->txid2; Q[i].feetxid = myutxo->fee.txid;
Q[i].feevout = myutxo->vout2; Q[i].feevout = myutxo->fee.vout;
strcpy(Q[i].destaddr,myutxo->coinaddr); strcpy(Q[i].destaddr,myutxo->coinaddr);
price = LP_query("connect",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),base,myutxo->coin,myutxo->mypub); price = LP_query("connect",&Q[i],base,myutxo->coin,myutxo->S.mypub);
LP_requestinit(&R,Q[i].srchash,Q[i].desthash,base,Q[i].satoshis,Q[i].destcoin,Q[i].destsatoshis,Q[i].timestamp,Q[i].quotetime,DEXselector); LP_requestinit(&R,Q[i].srchash,Q[i].desthash,base,Q[i].satoshis,Q[i].destcoin,Q[i].destsatoshis,Q[i].timestamp,Q[i].quotetime,DEXselector);
jaddstr(bestitem,"status","connected"); jaddstr(bestitem,"status","connected");
jaddnum(bestitem,"requestid",R.requestid); jaddnum(bestitem,"requestid",R.requestid);
@ -376,9 +376,9 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double profitmargin) 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; double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr;
if ( (now= (uint32_t)time(NULL)) > utxo->swappending ) if ( (now= (uint32_t)time(NULL)) > utxo->T.swappending )
utxo->swappending = 0; utxo->T.swappending = 0;
if ( now > utxo->published+60 && utxo->swappending == 0 && utxo->pair < 0 && utxo->swap == 0 && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 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 ) if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1); return(-1);
@ -388,7 +388,7 @@ int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double p
retstr = jprint(retjson,1); retstr = jprint(retjson,1);
//printf("PING.(%s)\n",retstr); //printf("PING.(%s)\n",retstr);
LP_send(pubsock,retstr,1); LP_send(pubsock,retstr,1);
utxo->published = now; utxo->T.published = now;
return(0); return(0);
} }
return(-1); return(-1);

18
iguana/exchanges/LP_rpc.c

@ -52,12 +52,28 @@ 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?ipaddr=%s&port=%u&profit=%.6f&coin=%s&txid=%s&vout=%d&valuesats=%llu&txid2=%s&vout2=%d&valuesats2=%llu&script=%s&address=%s&timestamp=%u",destip,destport,utxo->ipaddr,utxo->port,utxo->profitmargin,utxo->coin,bits256_str(str,utxo->txid),utxo->vout,(long long)utxo->value,bits256_str(str2,utxo->txid2),utxo->vout2,(long long)utxo->value2,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&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));
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));
} }
char *issue_LP_register(char *destip,uint16_t destport,bits256 pubkey,char *pushaddr)
{
char url[512],str[65];
sprintf(url,"http://%s:%u/api/stats/register?pubkey=%s&pushaddr=%s",destip,destport,bits256_str(str,pubkey),pushaddr);
//printf("getutxo.(%s)\n",url);
return(issue_curl(url));
}
char *issue_LP_lookup(char *destip,uint16_t destport,bits256 pubkey)
{
char url[512],str[65];
sprintf(url,"http://%s:%u/api/stats/register?pubkey=%s",destip,destport,bits256_str(str,pubkey));
//printf("getutxo.(%s)\n",url);
return(issue_curl(url));
}
cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
{ {
char *retstr; cJSON *retjson = 0; char *retstr; cJSON *retjson = 0;

84
iguana/exchanges/LP_swap.c

@ -17,22 +17,12 @@
// LP_swap.c // LP_swap.c
// marketmaker // marketmaker
// //
/* /*
resume handling: list of tx broadcast, tx pending + required items, reconnect state machine or have statemachine assume off by one or state/otherstate specific handling
make sure to broadcast deposit before claiming refund, or to just skip it if neither is done make sure to broadcast deposit before claiming refund, or to just skip it if neither is done
*/ */
// Todo: monitor blockchains, ie complete extracting scriptsig
// mode to autocreate required outputs
// more better LP commands
// depends on just three external functions:
// - basilisk_sendrawtransaction(coin,signedtx);
// - basilisk_value(rawtx->coin,0,0,myinfo->myaddr.persistent,argjson,0)
// basilisk_bitcoinrawtx(rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V)
// included from basilisk.c // included from basilisk.c
/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271
https://bitcointalk.org/index.php?topic=1364951 https://bitcointalk.org/index.php?topic=1364951
@ -148,6 +138,10 @@ void basilisk_swap_finished(struct basilisk_swap *swap)
free(swap->messages[i].data), swap->messages[i].data = 0; free(swap->messages[i].data), swap->messages[i].data = 0;
free(swap->messages), swap->messages = 0; free(swap->messages), swap->messages = 0;
swap->nummessages = 0; swap->nummessages = 0;
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair);
if ( swap->utxo != 0 )
swap->utxo->S.swap = 0;
} }
uint32_t basilisk_quoteid(struct basilisk_request *rp) uint32_t basilisk_quoteid(struct basilisk_request *rp)
@ -575,7 +569,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba
uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend)
{ {
uint8_t sendbuf[32768]; int32_t sendlen; uint8_t sendbuf[32768]; int32_t sendlen,retval = -1;
if ( LP_swapdata_rawtx(swap,data,maxlen,rawtx) != 0 ) if ( LP_swapdata_rawtx(swap,data,maxlen,rawtx) != 0 )
{ {
if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 )
@ -603,7 +597,15 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
basilisk_dontforget_update(swap,rawtx); basilisk_dontforget_update(swap,rawtx);
//printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen);
if ( suppress_swapsend == 0 ) if ( suppress_swapsend == 0 )
return(LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs)); {
retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs);
if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.signedtxid,10) < 0 )
{
char str[65]; printf("failed to find %s %s in the mempool?\n",rawtx->name,bits256_str(str,rawtx->I.actualtxid));
retval = -1;
}
return(retval);
}
else else
{ {
printf("suppress swapsend %x\n",msgbits); printf("suppress swapsend %x\n",msgbits);
@ -645,22 +647,20 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t
} else return(-1); } else return(-1);
} }
void LP_bobloop(void *_utxo) void LP_bobloop(void *_swap)
{ {
uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo; uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap = _swap;
fprintf(stderr,"start swap iambob\n"); fprintf(stderr,"start swap iambob\n");
maxlen = 1024*1024 + sizeof(*swap); maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen); data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 10; expiration = (uint32_t)time(NULL) + 10;
while ( (swap= utxo->swap) == 0 && time(NULL) < expiration ) if ( swap != 0 )
sleep(1);
if ( (utxo->swap= swap) != 0 )
{ {
if ( LP_waitsend("pubkeys",10,utxo->pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) if ( LP_waitsend("pubkeys",10,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
printf("error waitsend pubkeys\n"); printf("error waitsend pubkeys\n");
else if ( LP_waitsend("choosei",10,utxo->pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) else if ( LP_waitsend("choosei",10,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
printf("error waitsend choosei\n"); printf("error waitsend choosei\n");
else if ( LP_waitsend("mostprivs",10,utxo->pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) else if ( LP_waitsend("mostprivs",10,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 )
printf("error waitsend mostprivs\n"); printf("error waitsend mostprivs\n");
else if ( basilisk_bobscripts_set(swap,1,1) < 0 ) else if ( basilisk_bobscripts_set(swap,1,1) < 0 )
printf("error bobscripts deposit\n"); printf("error bobscripts deposit\n");
@ -671,11 +671,11 @@ void LP_bobloop(void *_utxo)
basilisk_bobdeposit_refund(swap,swap->I.putduration); basilisk_bobdeposit_refund(swap,swap->I.putduration);
//printf("depositlen.%d\n",swap->bobdeposit.I.datalen); //printf("depositlen.%d\n",swap->bobdeposit.I.datalen);
LP_swapsfp_update(&swap->I.req); LP_swapsfp_update(&swap->I.req);
if ( LP_waitfor(utxo->pair,swap,10,LP_verify_otherfee) < 0 ) if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_otherfee) < 0 )
printf("error waiting for alicefee\n"); printf("error waiting for alicefee\n");
else if ( LP_swapdata_rawtxsend(utxo->pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 )
printf("error sending bobdeposit\n"); printf("error sending bobdeposit\n");
else if ( LP_waitfor(utxo->pair,swap,10,LP_verify_alicepayment) < 0 ) else if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicepayment) < 0 )
printf("error waiting for alicepayment\n"); printf("error waiting for alicepayment\n");
else else
{ {
@ -689,45 +689,41 @@ void LP_bobloop(void *_utxo)
} }
if ( basilisk_bobscripts_set(swap,0,1) < 0 ) if ( basilisk_bobscripts_set(swap,0,1) < 0 )
printf("error bobscripts payment\n"); printf("error bobscripts payment\n");
else if ( LP_swapdata_rawtxsend(utxo->pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 )
printf("error sending bobpayment\n"); printf("error sending bobpayment\n");
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,600); LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,600);
} }
} }
basilisk_swap_finished(swap); basilisk_swap_finished(swap);
free(utxo->swap); free(swap);
} else printf("swap timed out\n"); } else printf("swap timed out\n");
utxo->swap = 0;
nn_close(utxo->pair);
utxo->pair = -1;
} }
void LP_aliceloop(void *_qp) void LP_aliceloop(void *_swap)
{ {
uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap = 0; struct LP_quoteinfo *qp = _qp; uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap = _swap;
fprintf(stderr,"start swap iamalice pair.%d\n",qp->pair);
maxlen = 1024*1024 + sizeof(*swap); maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen); data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 10; expiration = (uint32_t)time(NULL) + 10;
swap = LP_swapinit(0,0,qp->privkey,&qp->R,qp);
if ( swap != 0 ) if ( swap != 0 )
{ {
if ( LP_sendwait("pubkeys",10,qp->pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) fprintf(stderr,"start swap iamalice pair.%d\n",swap->N.pair);
if ( LP_sendwait("pubkeys",10,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
printf("error LP_sendwait pubkeys\n"); printf("error LP_sendwait pubkeys\n");
else if ( LP_sendwait("choosei",10,qp->pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) else if ( LP_sendwait("choosei",10,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
printf("error LP_sendwait choosei\n"); printf("error LP_sendwait choosei\n");
else if ( LP_sendwait("mostprivs",10,qp->pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) else if ( LP_sendwait("mostprivs",10,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 )
printf("error LP_sendwait mostprivs\n"); printf("error LP_sendwait mostprivs\n");
else if ( basilisk_alicetxs(qp->pair,swap,data,maxlen) != 0 ) else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 )
printf("basilisk_alicetxs error\n"); printf("basilisk_alicetxs error\n");
else else
{ {
LP_swapsfp_update(&swap->I.req); LP_swapsfp_update(&swap->I.req);
if ( LP_swapdata_rawtxsend(qp->pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 ) if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 )
printf("error sending alicefee\n"); printf("error sending alicefee\n");
else if ( LP_waitfor(qp->pair,swap,10,LP_verify_bobdeposit) < 0 ) else if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_bobdeposit) < 0 )
printf("error waiting for bobdeposit\n"); printf("error waiting for bobdeposit\n");
else if ( LP_swapdata_rawtxsend(qp->pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 )
printf("error sending alicepayment\n"); printf("error sending alicepayment\n");
else else
{ {
@ -736,7 +732,7 @@ void LP_aliceloop(void *_qp)
printf("waiting for alicepayment to confirm\n"); printf("waiting for alicepayment to confirm\n");
sleep(3); sleep(3);
} }
if ( LP_waitfor(qp->pair,swap,10,LP_verify_bobpayment) < 0 ) if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_bobpayment) < 0 )
printf("error waiting for bobpayment\n"); printf("error waiting for bobpayment\n");
else else
{ {
@ -745,7 +741,7 @@ void LP_aliceloop(void *_qp)
printf("waiting for bobpayment to confirm\n"); printf("waiting for bobpayment to confirm\n");
sleep(3); sleep(3);
} }
if ( LP_swapdata_rawtxsend(qp->pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 ) if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n"); printf("error sending alicespend\n");
while ( LP_numconfirms(swap,&swap->alicespend) < 1 ) while ( LP_numconfirms(swap,&swap->alicespend) < 1 )
{ {
@ -759,8 +755,8 @@ void LP_aliceloop(void *_qp)
basilisk_swap_finished(swap); basilisk_swap_finished(swap);
free(swap); free(swap);
} }
nn_close(qp->pair); free(data);
free(qp); nn_close(swap->N.pair);
} }
bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash)

53
iguana/exchanges/LP_transaction.c

@ -189,35 +189,52 @@ int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 se
else return(0); else return(0);
} }
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) int32_t LP_mempoolscan(char *symbol,bits256 txid)
{ {
int32_t numconfirms = 100; int32_t i,n; cJSON *array;
#ifndef BASILISK_DISABLEWAITTX if ( (array= LP_getmempool(symbol)) != 0 )
cJSON *txobj,*array; int32_t i,n;
numconfirms = -1;
if ( (txobj= LP_gettx(rawtx->coin->symbol,rawtx->I.signedtxid)) != 0 )
{
numconfirms = jint(txobj,"confirmations");
free_json(txobj);
}
else if ( (array= LP_getmempool(rawtx->coin->symbol)) != 0 )
{ {
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{ {
for (i=0; i<n; i++) for (i=0; i<n; i++)
if ( bits256_cmp(rawtx->I.signedtxid,jbits256i(array,i)) == 0 ) if ( bits256_cmp(txid,jbits256i(array,i)) == 0 )
{ {
numconfirms = 0;
printf("found tx in mempool slot.%d\n",i); printf("found tx in mempool slot.%d\n",i);
break; return(i);
} }
} }
free_json(array); free_json(array);
} }
return(-1);
}
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx)
{
int32_t numconfirms = 100;
#ifndef BASILISK_DISABLEWAITTX
cJSON *txobj;
numconfirms = -1;
if ( (txobj= LP_gettx(rawtx->coin->symbol,rawtx->I.signedtxid)) != 0 )
{
numconfirms = jint(txobj,"confirmations");
free_json(txobj);
} else if ( LP_mempoolscan(rawtx->coin->symbol,rawtx->I.signedtxid) >= 0 )
numconfirms = 0;
#endif #endif
return(numconfirms); return(numconfirms);
} }
int32_t LP_waitmempool(char *symbol,bits256 txid,int32_t duration)
{
uint32_t expiration = (uint32_t)time(NULL) + duration;
while ( time(NULL) < expiration )
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
}
return(-1);
}
int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V)
{ {
int32_t vini,j,scriptlen,p2shlen,userdatalen,siglen,plen,need_op0=0,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; int32_t vini,j,scriptlen,p2shlen,userdatalen,siglen,plen,need_op0=0,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp;
@ -1530,7 +1547,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->aliceclaim.txbytes[i]); printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n"); printf(" <- aliceclaim\n");
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
return(retval); return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.signedtxid,10));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
} }
printf("error with bobdeposit\n"); printf("error with bobdeposit\n");
@ -1548,7 +1565,8 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1; swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment); basilisk_dontforget_update(swap,&swap->alicepayment);
printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.signedtxid,10));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr); //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr);
return(0); return(0);
} }
@ -1594,8 +1612,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->alicespend.txbytes[i]); printf("%02x",swap->alicespend.txbytes[i]);
printf(" <- alicespend\n\n"); printf(" <- alicespend\n\n");
swap->I.alicespent = 1; swap->I.alicespent = 1;
//basilisk_txlog(swap,&swap->alicespend,-1); return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.signedtxid,10));
return(retval);
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr);
} }
printf("error validating bobpayment\n"); printf("error validating bobpayment\n");

394
iguana/exchanges/LP_utxos.c

@ -20,75 +20,212 @@
int32_t LP_ismine(struct LP_utxoinfo *utxo) int32_t LP_ismine(struct LP_utxoinfo *utxo)
{ {
if ( strcmp(utxo->ipaddr,"127.0.0.1") == 0 ) if ( bits256_cmp(utxo->pubkey,LP_mypubkey) != 0 )
return(1); return(1);
else if ( LP_mypeer == 0 ) else if ( LP_mypeer == 0 )
return(0); return(0);
else if ( strcmp(utxo->ipaddr,LP_mypeer->ipaddr) == 0 && utxo->port == LP_mypeer->port )\ else return(0);
}
int32_t LP_isavailable(struct LP_utxoinfo *utxo)
{
if ( utxo->T.swappending == 0 && utxo->S.swap == 0 )
return(1); return(1);
else return(0); else return(0);
} }
int32_t LP_isunspent(struct LP_utxoinfo *utxo) int32_t LP_isunspent(struct LP_utxoinfo *utxo)
{ {
if ( utxo->spentflag == 0 && utxo->swappending == 0 ) if ( utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 )
return(1); return(1);
else return(0); else return(0);
} }
struct LP_utxoinfo *LP_utxofind(bits256 txid,int32_t vout) void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout)
{ {
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
memcpy(key,txid.bytes,sizeof(txid)); memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
}
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
LP_utxosetkey(key,txid,vout);
HASH_FIND(hh,LP_utxoinfos[iambob],key,sizeof(key),utxo);
return(utxo);
}
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)];
LP_utxosetkey(key2,txid2,vout2);
HASH_FIND(hh2,LP_utxoinfos2[iambob],key2,sizeof(key2),utxo);
return(utxo);
}
struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0;
portable_mutex_lock(&LP_utxomutex); portable_mutex_lock(&LP_utxomutex);
HASH_FIND(hh,LP_utxoinfos,key,sizeof(key),utxo); utxo = _LP_utxofind(iambob,txid,vout);
portable_mutex_unlock(&LP_utxomutex); portable_mutex_unlock(&LP_utxomutex);
return(utxo); return(utxo);
} }
struct LP_utxoinfo *_LP_utxo2find(bits256 txid,int32_t vout) struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{ {
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; struct LP_utxoinfo *utxo=0;
memcpy(key,txid.bytes,sizeof(txid)); portable_mutex_lock(&LP_utxomutex);
memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); utxo = _LP_utxo2find(iambob,txid2,vout2);
HASH_FIND(hh2,LP_utxoinfos2,key,sizeof(key),utxo); portable_mutex_unlock(&LP_utxomutex);
return(utxo); return(utxo);
} }
struct LP_utxoinfo *LP_utxo2find(bits256 txid,int32_t vout) int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo)
{ {
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; int32_t i;
memcpy(key,txid.bytes,sizeof(txid)); for (i=0; i<n; i++)
memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); if ( ptrs[i] == utxo )
return(n);
ptrs[n++] = utxo;
return(n);
}
int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo)
{
int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u;
portable_mutex_lock(&LP_utxomutex); portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxo2find(txid,vout); for (iambob=0; iambob<=1; iambob++)
{
if ( (utxo= _LP_utxofind(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee;
if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
}
portable_mutex_unlock(&LP_utxomutex); portable_mutex_unlock(&LP_utxomutex);
return(utxo); if ( n > 0 )
printf("LP_utxocollisions n.%d\n",n);
return(n);
}
void _LP_availableset(struct LP_utxoinfo *utxo)
{
if ( utxo != 0 )
{
memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey));
utxo->S.swap = 0;
utxo->T.swappending = 0;
}
}
void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
if ( utxo != 0 )
{
utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME);
utxo->S.otherpubkey = otherpubkey;
}
}
void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n;
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
_LP_unavailableset(ptrs[i],otherpubkey);
}
char str[65]; printf("UTXO RESERVED %s/v%d collisions.%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,n);
_LP_unavailableset(utxo,otherpubkey);
}
void LP_availableset(struct LP_utxoinfo *utxo)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n;
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
_LP_availableset(ptrs[i]);
}
char str[65]; printf("UTXO AVAIL %s/v%d collisions.%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,n);
_LP_availableset(utxo);
}
int32_t LP_utxopurge(int32_t allutxos)
{
struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0;
portable_mutex_lock(&LP_utxomutex);
for (iambob=0; iambob<=1; iambob++)
{
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
if ( allutxos != 0 || LP_ismine(utxo) == 0 )
{
if ( LP_isavailable(utxo) == 0 )
{
HASH_DELETE(hh,LP_utxoinfos[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp)
{
if ( allutxos != 0 || LP_ismine(utxo) == 0 )
{
if ( LP_isavailable(utxo) == 0 )
{
HASH_DELETE(hh,LP_utxoinfos2[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
}
portable_mutex_unlock(&LP_utxomutex);
return(n);
} }
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{ {
struct _LP_utxoinfo u;
jaddstr(item,"coin",utxo->coin); jaddstr(item,"coin",utxo->coin);
jaddnum(item,"now",time(NULL)); jaddnum(item,"now",time(NULL));
jaddstr(item,"address",utxo->coinaddr); jaddstr(item,"address",utxo->coinaddr);
jaddbits256(item,"txid",utxo->txid); jaddbits256(item,"txid",utxo->payment.txid);
jaddnum(item,"vout",utxo->vout); jaddnum(item,"vout",utxo->payment.vout);
jadd64bits(item,"value",utxo->value); jadd64bits(item,"value",utxo->payment.value);
jadd64bits(item,"satoshis",utxo->satoshis); jadd64bits(item,"satoshis",utxo->S.satoshis);
jaddbits256(item,"txid2",utxo->txid2); u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
jaddnum(item,"vout2",utxo->vout2); if ( bits256_nonz(u.txid) != 0 )
jadd64bits(item,"value2",utxo->value2); {
if ( utxo->swappending != 0 ) jaddbits256(item,"txid2",u.txid);
jaddnum(item,"pending",utxo->swappending); jaddnum(item,"vout2",u.vout);
if ( bits256_nonz(utxo->otherpubkey) != 0 ) jadd64bits(item,"value2",u.value);
jaddbits256(item,"desthash",utxo->otherpubkey); }
if ( utxo->pair >= 0 ) if ( utxo->T.swappending != 0 )
jaddnum(item,"socket",utxo->pair); jaddnum(item,"pending",utxo->T.swappending);
if ( utxo->swap != 0 ) if ( utxo->iambob != 0 )
{
jaddbits256(item,"srchash",LP_mypubkey);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"desthash",utxo->S.otherpubkey);
}
else
{
jaddbits256(item,"desthash",LP_mypubkey);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"srchash",utxo->S.otherpubkey);
}
if ( utxo->S.swap != 0 )
jaddstr(item,"swap","in progress"); jaddstr(item,"swap","in progress");
if ( utxo->spentflag != 0 ) if ( utxo->T.spentflag != 0 )
jaddnum(item,"spent",utxo->spentflag); jaddnum(item,"spent",utxo->T.spentflag);
return(item); return(item);
} }
@ -96,26 +233,25 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
{ {
cJSON *item = cJSON_CreateObject(); cJSON *item = cJSON_CreateObject();
item = LP_inventoryjson(item,utxo); item = LP_inventoryjson(item,utxo);
jaddstr(item,"ipaddr",utxo->ipaddr); jaddbits256(item,"pubkey",utxo->pubkey);
jaddnum(item,"port",utxo->port); jaddnum(item,"profit",utxo->S.profitmargin);
jaddnum(item,"profit",utxo->profitmargin);
jaddstr(item,"base",utxo->coin); jaddstr(item,"base",utxo->coin);
jaddstr(item,"script",utxo->spendscript); jaddstr(item,"script",utxo->spendscript);
return(item); return(item);
} }
char *LP_utxos(struct LP_peerinfo *mypeer,char *coin,int32_t lastn) char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *coin,int32_t lastn)
{ {
int32_t i,firsti; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray(); int32_t i,firsti; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
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[iambob],utxo,tmp)
{ {
if ( i++ < firsti ) if ( i++ < firsti )
continue; continue;
if ( (coin == 0 || coin[0] == 0 || strcmp(coin,utxo->coin) == 0) && utxo->spentflag == 0 )//&& LP_ismine(utxo) != 0 ) if ( (coin == 0 || coin[0] == 0 || strcmp(coin,utxo->coin) == 0) && utxo->T.spentflag == 0 )//&& LP_ismine(utxo) != 0 )
{ {
jaddi(utxosjson,LP_utxojson(utxo)); jaddi(utxosjson,LP_utxojson(utxo));
} }
@ -125,20 +261,23 @@ char *LP_utxos(struct LP_peerinfo *mypeer,char *coin,int32_t lastn)
void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
{ {
cJSON *argjson; cJSON *argjson; struct _LP_utxoinfo u;
utxo->spentflag = (uint32_t)time(NULL); utxo->T.spentflag = (uint32_t)time(NULL);
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--; LP_mypeer->numutxos--;
if ( LP_mypubsock >= 0 ) if ( LP_mypubsock >= 0 )
{ {
argjson = cJSON_CreateObject(); argjson = cJSON_CreateObject();
jaddstr(argjson,"method","checktxid"); jaddstr(argjson,"method","checktxid");
jaddbits256(argjson,"txid",utxo->txid); jaddbits256(argjson,"txid",utxo->payment.txid);
jaddnum(argjson,"vout",utxo->vout); jaddnum(argjson,"vout",utxo->payment.vout);
if ( selector != 0 ) if ( selector != 0 )
{ {
jaddbits256(argjson,"checktxid",utxo->txid2); if ( bits256_nonz(utxo->deposit.txid) != 0 )
jaddnum(argjson,"checkvout",utxo->vout2); u = utxo->deposit;
else u = utxo->fee;
jaddbits256(argjson,"checktxid",u.txid);
jaddnum(argjson,"checkvout",u.vout);
} }
LP_send(LP_mypubsock,jprint(argjson,1),1); LP_send(LP_mypubsock,jprint(argjson,1),1);
} }
@ -146,35 +285,41 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
char *LP_spentcheck(cJSON *argjson) char *LP_spentcheck(cJSON *argjson)
{ {
bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
txid = jbits256(argjson,"txid"); txid = jbits256(argjson,"txid");
vout = jint(argjson,"vout"); vout = jint(argjson,"vout");
if ( (utxo= LP_utxofind(txid,vout)) != 0 && utxo->spentflag == 0 ) for (iambob=0; iambob<=1; iambob++)
{ {
if ( jobj(argjson,"check") == 0 ) if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && utxo->T.spentflag == 0 )
checktxid = txid, checkvout = vout;
else
{ {
checktxid = jbits256(argjson,"checktxid"); if ( jobj(argjson,"check") == 0 )
checkvout = jint(argjson,"checkvout"); checktxid = txid, checkvout = vout;
else
{
checktxid = jbits256(argjson,"checktxid");
checkvout = jint(argjson,"checkvout");
}
if ( LP_txvalue(utxo->coin,checktxid,checkvout) == 0 )
{
//if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
// LP_mypeer->numutxos--;
utxo->T.spentflag = (uint32_t)time(NULL);
retval++;
//printf("indeed txid was spent\n");
}
} }
if ( LP_txvalue(utxo->coin,checktxid,checkvout) == 0 ) }
{ if ( retval > 0 )
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) return(clonestr("{\"result\":\"marked as spent\"}"));
LP_mypeer->numutxos--; return(clonestr("{\"error\":\"cant find txid to check spent status\"}"));
utxo->spentflag = (uint32_t)time(NULL);
//printf("indeed txid was spent\n");
return(clonestr("{\"result\":\"marked as spent\"}"));
} else return(clonestr("{\"error\":\"txid is still unspent?\"}"));
} else return(clonestr("{\"error\":\"cant find txid to check spent status\"}"));
} }
int32_t LP_iseligible(char *coin,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2) int32_t LP_iseligible(int32_t iambob,char *coin,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2)
{ {
uint64_t val,val2,threshold; uint64_t val,val2,threshold;
if ( (val= LP_txvalue(coin,txid,vout)) >= satoshis ) if ( (val= LP_txvalue(coin,txid,vout)) >= satoshis )
{ {
threshold = (IAMCLIENT == 0) ? LP_DEPOSITSATOSHIS(satoshis) : LP_DEXFEE(satoshis); threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : LP_DEXFEE(satoshis);
if ( (val2= LP_txvalue(coin,txid2,vout2)) >= threshold ) if ( (val2= LP_txvalue(coin,txid2,vout2)) >= threshold )
{ {
//printf("val %.8f and val2 %.8f vs %.8f\n",dstr(val),dstr(val2),dstr(satoshis)); //printf("val %.8f and val2 %.8f vs %.8f\n",dstr(val),dstr(val2),dstr(satoshis));
@ -184,66 +329,65 @@ int32_t LP_iseligible(char *coin,bits256 txid,int32_t vout,uint64_t satoshis,bit
return(0); return(0);
} }
struct LP_utxoinfo *LP_addutxo(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,char *ipaddr,uint16_t port,double profitmargin) struct LP_utxoinfo *LP_addutxo(int32_t iambob,int32_t mypubsock,char *coin,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,double profitmargin)
{ {
uint64_t tmpsatoshis; struct LP_utxoinfo *utxo = 0; uint64_t tmpsatoshis; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
if ( coin == 0 || coin[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 ( coin == 0 || coin[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 )
{ {
printf("malformed addutxo %d %d %d %d %d %d %d %d %d\n", coin == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); printf("malformed addutxo %d %d %d %d %d %d %d %d %d\n", coin == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0);
return(0); return(0);
} }
if ( IAMCLIENT == 0 && value2 < 9 * (value >> 3) + 100000 ) if ( iambob != 0 && value2 < 9 * (value >> 3) + 100000 )
tmpsatoshis = (((value2-100000) / 9) << 3); tmpsatoshis = (((value2-100000) / 9) << 3);
else tmpsatoshis = value; else tmpsatoshis = value;
if ( LP_iseligible(coin,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) if ( LP_iseligible(iambob,coin,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("LP_addutxo got spent txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",dstr(value),dstr(value2),dstr(tmpsatoshis));
return(0); return(0);
} }
if ( IAMCLIENT == 0 && strcmp(ipaddr,"127.0.0.1") == 0 ) if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 )
{
//printf("LP node got localhost utxo\n");
return(0);
}
if ( (utxo= LP_utxofind(txid,vout)) != 0 || (utxo= LP_utxo2find(txid,vout)) != 0 )
{ {
//printf("%.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->value),dstr(utxo->value2),dstr(utxo->satoshis)); //printf("%.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->value),dstr(utxo->value2),dstr(utxo->satoshis));
if ( bits256_cmp(txid,utxo->txid) != 0 || bits256_cmp(txid2,utxo->txid2) != 0 || vout != utxo->vout || value != utxo->value || tmpsatoshis != utxo->satoshis || vout2 != utxo->vout2 || value2 != utxo->value2 || strcmp(coin,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || strcmp(ipaddr,utxo->ipaddr) != 0 || port != utxo->port ) u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || tmpsatoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(coin,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 )
{ {
utxo->errors++; utxo->T.errors++;
char str[65],str2[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d %d\n",bits256_str(str,txid),bits256_str(str2,utxo->txid),bits256_cmp(txid,utxo->txid) != 0,bits256_cmp(txid2,utxo->txid2) != 0,vout != utxo->vout,tmpsatoshis != utxo->satoshis,vout2 != utxo->vout2,value2 != utxo->value2,strcmp(coin,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,strcmp(ipaddr,utxo->ipaddr) != 0,port != utxo->port,value != utxo->value); char str[65],str2[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d\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(coin,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value);
} }
else if ( profitmargin != 0. ) else if ( profitmargin != 0. )
utxo->profitmargin = profitmargin; utxo->S.profitmargin = profitmargin;
} }
else else
{ {
utxo = calloc(1,sizeof(*utxo)); utxo = calloc(1,sizeof(*utxo));
utxo->pair = -1; utxo->S.profitmargin = profitmargin;
utxo->profitmargin = profitmargin; utxo->pubkey = pubkey;
strcpy(utxo->ipaddr,ipaddr);
utxo->port = port;
safecopy(utxo->coin,coin,sizeof(utxo->coin)); safecopy(utxo->coin,coin,sizeof(utxo->coin));
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr)); safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript)); safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
utxo->txid = txid; utxo->payment.txid = txid;
utxo->vout = vout; utxo->payment.vout = vout;
utxo->value = value; utxo->payment.value = value;
utxo->satoshis = tmpsatoshis; utxo->S.satoshis = tmpsatoshis;
utxo->txid2 = txid2; if ( (utxo->iambob= iambob) != 0 )
utxo->vout2 = vout2; {
utxo->value2 = value2; utxo->deposit.txid = txid2;
memcpy(utxo->key,txid.bytes,sizeof(txid)); utxo->deposit.vout = vout2;
memcpy(&utxo->key[sizeof(txid)],&vout,sizeof(vout)); utxo->deposit.value = value2;
memcpy(utxo->key2,txid2.bytes,sizeof(txid2)); }
memcpy(&utxo->key2[sizeof(txid2)],&vout2,sizeof(vout2)); else
char str[65],str2[65]; printf("amclient.%d %s:%u %s LP_addutxo.(%.8f %.8f) numutxos.%d %s %s\n",IAMCLIENT,ipaddr,port,utxo->coin,dstr(value),dstr(value2),mypeer!=0?mypeer->numutxos:0,bits256_str(str,utxo->txid),bits256_str(str2,txid2)); {
utxo->fee.txid = txid2;
utxo->fee.vout = vout2;
utxo->fee.value = value2;
}
LP_utxosetkey(utxo->key,txid,vout);
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));
portable_mutex_lock(&LP_utxomutex); portable_mutex_lock(&LP_utxomutex);
HASH_ADD_KEYPTR(hh,LP_utxoinfos,utxo->key,sizeof(utxo->key),utxo); HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(txid2,vout2) == 0 ) if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2,utxo->key2,sizeof(utxo->key2),utxo); HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
if ( mypeer != 0 )
mypeer->numutxos++;
portable_mutex_unlock(&LP_utxomutex); portable_mutex_unlock(&LP_utxomutex);
if ( mypubsock >= 0 ) if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_utxojson(utxo),1),1); LP_send(mypubsock,jprint(LP_utxojson(utxo),1),1);
@ -251,10 +395,10 @@ struct LP_utxoinfo *LP_addutxo(int32_t amclient,struct LP_peerinfo *mypeer,int32
return(utxo); return(utxo);
} }
int32_t LP_utxosparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{ {
struct LP_peerinfo *peer,*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 ( amclient != 0 ) if ( IAMLP == 0 )
{ {
printf("LP_utxosparse not for clientside\n"); printf("LP_utxosparse not for clientside\n");
return(-1); return(-1);
@ -273,16 +417,16 @@ int32_t LP_utxosparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
if ( (subport= juint(item,"sub")) == 0 ) if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2; subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr); argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) //if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
peer = LP_addpeer(amclient,mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos")); // peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
if ( jobj(item,"txid") != 0 ) if ( jobj(item,"txid") != 0 )
{ {
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(amclient,mypeer,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"),argipaddr,argport,jdouble(item,"profit")); 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 != 0 ) if ( utxo != 0 )
{ {
utxo->lasttime = now; utxo->T.lasttime = now;
} }
} }
} // else printf("skip.(%s)\n",jprint(item,0)); } // else printf("skip.(%s)\n",jprint(item,0));
@ -297,10 +441,10 @@ int32_t LP_utxosparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
return(n); return(n);
} }
void LP_utxosquery(int32_t amclient,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; int32_t i,firsti; uint32_t now;
if ( amclient != 0 ) if ( IAMLP == 0 )
{ {
printf("LP_utxosquery not for clientside\n"); printf("LP_utxosquery not for clientside\n");
return; return;
@ -313,7 +457,7 @@ void LP_utxosquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock
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->numpeers,mypeer->numutxos)) != 0 )
{ {
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
LP_utxosparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now); LP_utxosparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr); free(retstr);
i = 0; i = 0;
if ( lastn >= mypeer->numutxos ) if ( lastn >= mypeer->numutxos )
@ -337,16 +481,17 @@ void LP_utxosquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock
peer->errors++; peer->errors++;
} }
char *LP_inventory(char *symbol) char *LP_inventory(char *symbol,int32_t iambob)
{ {
struct LP_utxoinfo *utxo,*tmp; char *myipaddr; cJSON *array = cJSON_CreateArray(); struct LP_utxoinfo *utxo,*tmp; char *myipaddr; cJSON *array;
array = cJSON_CreateArray();
if ( LP_mypeer != 0 ) if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr; myipaddr = LP_mypeer->ipaddr;
else myipaddr = "127.0.0.1"; else myipaddr = "127.0.0.1";
HASH_ITER(hh,LP_utxoinfos,utxo,tmp) HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{ {
//char str[65]; printf("iterate %s\n",bits256_str(str,utxo->txid)); //char str[65]; printf("iterate %s\n",bits256_str(str,utxo->txid));
if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && (IAMCLIENT != 0 || LP_ismine(utxo) != 0) ) if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) != 0 )
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
} }
return(jprint(array,1)); return(jprint(array,1));
@ -381,10 +526,10 @@ int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval)
return(mini); return(mini);
} }
uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symbol,char *passphrase,char *wifstr,int32_t amclient) uint64_t LP_privkey_init(int32_t mypubsock,char *symbol,char *passphrase,char *wifstr,int32_t iambob)
{ {
static uint32_t counter; static uint32_t counter;
char *script; struct LP_utxoinfo *utxo; cJSON *array,*item,*retjson; bits256 userpass,userpub,txid,deposittxid; int32_t used,i,n,vout,depositvout; uint64_t *values,satoshis,depositval,targetval,value,total = 0; bits256 privkey,pubkey; uint8_t pubkey33[33],tmptype,rmd160[20]; struct iguana_info *coin = LP_coinfind(symbol); char *script; struct LP_utxoinfo *utxo; cJSON *array,*item,*retjson; bits256 userpass,userpub,txid,deposittxid; int32_t used,i,n,vout,depositvout; uint64_t *values,satoshis,depositval,targetval,value,total = 0; bits256 privkey,pubkey,mypub; uint8_t pubkey33[33],tmptype,rmd160[20]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 ) if ( coin == 0 )
{ {
printf("cant add privkey for %s, coin not active\n",symbol); printf("cant add privkey for %s, coin not active\n",symbol);
@ -413,6 +558,7 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb
} }
bitcoin_addr2rmd160(&tmptype,rmd160,coin->smartaddr); bitcoin_addr2rmd160(&tmptype,rmd160,coin->smartaddr);
LP_privkeyadd(privkey,rmd160); LP_privkeyadd(privkey,rmd160);
LP_mypubkey = mypub = curve25519(privkey,curve25519_basepoint9());
if ( coin->inactive == 0 && (array= LP_listunspent(symbol,coin->smartaddr)) != 0 ) if ( coin->inactive == 0 && (array= LP_listunspent(symbol,coin->smartaddr)) != 0 )
{ {
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -438,7 +584,7 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb
script = jstr(item,"scriptPubKey"); script = jstr(item,"scriptPubKey");
depositval = values[i]; depositval = values[i];
values[i] = 0, used++; values[i] = 0, used++;
if ( amclient != 0 ) if ( iambob == 0 )
targetval = (depositval / 776) + 100000; targetval = (depositval / 776) + 100000;
else targetval = (depositval / 9) * 8 + 100000; else targetval = (depositval / 9) * 8 + 100000;
//printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval)); //printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval));
@ -451,15 +597,19 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb
{ {
value = values[i]; value = values[i];
values[i] = 0, used++; values[i] = 0, used++;
if ( amclient == 0 ) if ( iambob != 0 )
{ {
if ( (utxo= LP_addutxo(amclient,mypeer,mypubsock,symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,LP_peerinfos[0].ipaddr,LP_peerinfos[0].port,LP_peerinfos[0].profitmargin)) != 0 ) if ( (utxo= LP_addutxo(1,mypubsock,symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_peerinfos[0].profitmargin)) != 0 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9()); {
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
} }
else else
{ {
if ( (utxo= LP_addutxo(amclient,mypeer,mypubsock,symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,"127.0.0.1",0,0)) != 0 ) if ( (utxo= LP_addutxo(0,mypubsock,symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0)) != 0 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9()); {
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
} }
total += value; total += value;
} }
@ -474,13 +624,13 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb
return(total); return(total);
} }
void LP_privkey_updates(struct LP_peerinfo *mypeer,int32_t pubsock,char *passphrase,int32_t amclient) void LP_privkey_updates(int32_t pubsock,char *passphrase,int32_t iambob)
{ {
int32_t i; int32_t i;
for (i=0; i<LP_numcoins; i++) for (i=0; i<LP_numcoins; i++)
{ {
//printf("i.%d of %d\n",i,LP_numcoins); //printf("i.%d of %d\n",i,LP_numcoins);
LP_privkey_init(mypeer,pubsock,LP_coins[i].symbol,passphrase,"",amclient); LP_privkey_init(pubsock,LP_coins[i].symbol,passphrase,"",iambob);
} }
} }

Loading…
Cancel
Save