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. 64
      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
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->p2shtype = p2shtype;
coin->wiftype = wiftype;
coin->inactive = (uint32_t)time(NULL);
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 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 )
{
isPoS = jint(item,"isPoS");
@ -275,9 +276,10 @@ struct iguana_info *LP_coincreate(cJSON *item)
else if ( (name= jstr(item,"name")) == 0 )
name = symbol;
LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain);
if ( (coin= LP_coinadd(&cdata)) != 0 )
coin->inactive = !jint(item,"active");
coin = LP_coinadd(&cdata);
}
if ( coin != 0 && item != 0 )
coin->inactive = (strcmp("KMD",coin->symbol) == 0) ? 0 : !jint(item,"active");
return(0);
}

336
iguana/exchanges/LP_commands.c

@ -18,71 +18,159 @@
// 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.;
if ( ipaddr != 0 && port >= 1000 )
cJSON *reqjson; int32_t i,flag = 0; double price = 0.; struct LP_utxoinfo *utxo;
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 )
peer = LP_addpeer(1,0,-1,ipaddr,port,port+1,port+2,0,0,0);
if ( peer != 0 )
qp->quotetime = (uint32_t)time(NULL);
if ( (utxo= LP_utxofind(0,qp->desttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 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;
strcpy(qp->srccoin,base);
strcpy(qp->destcoin,rel);
if ( strcmp(method,"request") == 0 )
qp->quotetime = (uint32_t)time(NULL);
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);
//printf("break out of loop.%d price %.8f\n",i,price);
break;
}
}
usleep(100000);
}
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;
if ( IAMCLIENT == 0 && (method= jstr(argjson,"method")) != 0 )
char *method,*base,*rel,*retstr; cJSON *retjson; double price; bits256 txid; struct LP_utxoinfo *utxo; int32_t retval = -1; struct LP_quoteinfo Q;
if ( (method= jstr(argjson,"method")) != 0 )
{
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));
if ( time(NULL) > utxo->swappending )
utxo->swappending = 0;
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 )
if ( utxo->S.swap == 0 && time(NULL) > utxo->T.swappending )
utxo->T.swappending = 0;
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 ) // bob
{
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. )
{
price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
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");
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 )
Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q);
utxo->S.otherpubkey = jbits256(argjson,"desthash");
if ( strcmp(method,"request") == 0 )
{
retval |= 2;
utxo->swappending = (uint32_t)(time(NULL) + LP_RESERVETIME);
utxo->otherpubkey = jbits256(argjson,"desthash");
LP_unavailableset(utxo,jbits256(argjson,"desthash"));
jaddnum(retjson,"quotetime",juint(argjson,"quotetime"));
jaddnum(retjson,"pending",utxo->swappending);
jaddbits256(retjson,"desthash",utxo->otherpubkey);
jaddnum(retjson,"pending",utxo->T.swappending);
jaddbits256(retjson,"desthash",utxo->S.otherpubkey);
jaddstr(retjson,"method","reserved");
}
else jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
utxo->published = (uint32_t)time(NULL);
if ( pubsock >= 0 )
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("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;
if ( utxo->pair < 0 )
{
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->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));
if ( utxo->T.swappending != 0 && utxo->S.swap == 0 )
LP_connectstart(pubsock,utxo,argjson,myipaddr,base,rel,profitmargin);
else printf("swap %p when connect came in (%s)\n",utxo->S.swap,jprint(argjson,0));
}
}
}
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 *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 )
return(clonestr("{\"error\":\"need method in request\"}"));
else if ( strcmp(method,"help") == 0 )
@ -226,6 +233,9 @@ getutxos()\n\
getutxos(coin, lastn)\n\
orderbook(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 )
{
@ -250,9 +260,9 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"couldnt set price\"}"));
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) )
LP_priceping(LP_mypubsock,utxo,rel,LP_profitratio - 1.);
@ -294,10 +304,10 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"coin is disabled\"}"));
if ( strcmp(method,"inventory") == 0 )
{
LP_privkey_init(0,-1,coin,0,USERPASS_WIFSTR,1);
return(LP_inventory(coin));
LP_privkey_init(-1,coin,0,USERPASS_WIFSTR,0);
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;
txid = jbits256(argjson,"txid");
@ -306,7 +316,7 @@ getprice(base, rel)\n\
if ( jobj(argjson,"vout") == 0 )
return(clonestr("{\"error\":\"missing 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\"}"));
if ( strcmp(method,"candidates") == 0 )
return(jprint(LP_tradecandidates(coin),1));
@ -325,7 +335,6 @@ getprice(base, rel)\n\
return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
if ( LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
return(clonestr("{\"error\":\"coin is disabled\"}"));
amclient = (LP_mypeer == 0);
if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 )
{
if ( strcmp(ipaddr,"127.0.0.1") != 0 && port >= 1000 )
@ -344,7 +353,7 @@ getprice(base, rel)\n\
peer->numutxos = othernumutxos;
}
//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));
@ -362,21 +371,30 @@ getprice(base, rel)\n\
retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel"));
else if ( strcmp(method,"getpeers") == 0 )
retstr = LP_peers();
else if ( IAMCLIENT == 0 && strcmp(method,"getutxos") == 0 && (coin= jstr(argjson,"coin")) != 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 )
else if ( IAMLP != 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));
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"));
retstr = LP_utxos(1,LP_mypeer,coin,jint(argjson,"lastn"));
//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 )
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);
}

64
iguana/exchanges/LP_include.h

@ -46,7 +46,7 @@
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
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; };
@ -139,42 +139,34 @@ struct basilisk_swapinfo
struct iguana_info
{
uint64_t txfee; double estimatedrate;
uint64_t txfee; double estimatedrate,profitmargin;
int32_t longestchain; uint32_t counter,inactive;
uint8_t pubtype,p2shtype,isPoS,wiftype;
char symbol[16],smartaddr[64],userpass[1024],serverport[128];
};
struct basilisk_swap
{
void *ctx; struct iguana_info bobcoin,alicecoin;
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];
struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; };
};
struct LP_utxostats { uint32_t lasttime,errors,swappending,published,spentflag,lastspentcheck; };
struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; };
struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; };
struct LP_utxoswap { bits256 otherpubkey,mypub; void *swap; uint64_t satoshis; double profitmargin; };
struct LP_utxoinfo
{
UT_hash_handle hh,hh2;
bits256 txid,txid2,feetxid,otherpubkey,mypub;
void *swap;
uint64_t value,satoshis,value2;
bits256 pubkey;
struct _LP_utxoinfo payment,deposit,fee;
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 key2[sizeof(bits256) + sizeof(int32_t)];
int32_t vout,vout2,pair;
uint32_t lasttime,errors,swappending,published,spentflag,lastspentcheck;
double profitmargin;
char ipaddr[64],coinaddr[64],spendscript[256],coin[16];
uint16_t port;
char coin[16],coinaddr[64],spendscript[256];
};
struct LP_peerinfo
@ -197,13 +189,33 @@ struct LP_quoteinfo
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);
uint32_t basilisk_requestid(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);
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);
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);
void LP_quotesinit(char *base,char *rel);

344
iguana/exchanges/LP_nativeDEX.c

@ -17,13 +17,13 @@
// LP_nativeDEX.c
// marketmaker
//
// jl777: fix price calcs based on specific txfees
// jl777: profitmargin per coin, ignore peers with errors
#include <stdio.h>
#include "LP_include.h"
#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;
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",
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 Client_connections;
int32_t USERPASS_COUNTER,IAMCLIENT = 0;
int32_t USERPASS_COUNTER,IAMLP = 0;
double LP_profitratio = 1.;
bits256 LP_mypubkey;
// stubs
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_utxos.c"
#include "LP_quotes.c"
#include "LP_forwarding.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;
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;
//if ( amclient != 0 )
// myport += amclient * 10;
int32_t recvsize,len,datalen,nonz = 0; void *ptr; char *retstr,*jsonstr=0; cJSON *argjson;
while ( (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 )
{
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 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( amclient == 0 )
if ( IAMLP != 0 )
{
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{
if ( (rand() % 100) > 25 )
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
@ -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++)
{
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++)
{
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_privkey_updates(mypeer,pubsock,passphrase,amclient);
LP_privkey_updates(pubsock,passphrase,0);
LP_privkey_updates(pubsock,passphrase,1);
if ( (retstr= basilisk_swaplist()) != 0 )
free(retstr);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( strcmp(peer->ipaddr,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1") != 0 )
{
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);
//printf("query utxo from %s\n",peer->ipaddr);
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 )
{
now = (uint32_t)time(NULL);
if ( lastforward < now-LP_KEEPALIVE )
{
LP_forwarding_register(LP_mypubkey,pushaddr);
lastforward = now;
}
nonz = n = 0;
if ( (++counter % 3600) == 0 )
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
if ( (++counter % 5000) == 0 )
LP_utxo_updates(pubsock,passphrase,profitmargin);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
n++;
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
nonz += LP_subsock_check(peer);
}
if ( pullsock >= 0 )
{
if ( (n= LP_pullsock_check(myipaddr,pubsock,pullsock,profitmargin)) > 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);
//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;
nonz += n;
lastforward = now;
}
}
if ( nonz == 0 )
@ -173,41 +265,8 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
while ( 1 )
{
nonz = 0;
if ( (++counter % 2000) == 0 )
{
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
}
if ( (counter % 500) == 0 )
{
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");
}
LP_utxo_updates(pubsock,passphrase,profitmargin);
now = (uint32_t)time(NULL);
//printf("start peers updates\n");
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 )
printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,mypeer->numpeers);
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 )
{
@ -229,47 +288,12 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i
lastn = LP_PROPAGATION_SLACK * 2;
printf("%s numutxos.%d vs %d lastn.%d\n",peer->ipaddr,peer->numutxos,mypeer->numutxos,lastn);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_utxosquery(0,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;
LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer->ipaddr,myport,profitmargin);
}
nonz += LP_subsock_check(peer);
}
while ( pullsock >= 0 && (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 )
{
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 ( pullsock >= 0 )
nonz += LP_pullsock_check(myipaddr,pubsock,pullsock,profitmargin);
if ( nonz == 0 )
usleep(100000);
//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)
{
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;
OS_randombytes((void *)&n,sizeof(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_swaplistmutex);
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;
printf("default profit margin %f\n",profitmargin);
timeout = 1;
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 ( myipaddr[n-1] == '\n' )
myipaddr[--n] = 0;
pullsock = pubsock = -1;
nanomsg_tcpname(pushaddr,myipaddr,mypullport);
nanomsg_tcpname(subaddr,myipaddr,mypubport);
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(pubsock,subaddr) >= 0 )
{
timeout = 10;
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
}
else
{
if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 )
{
timeout = 10;
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
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));
}
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");
printf("error binding to (%s).%d (%s).%d\n",pushaddr,pullsock,subaddr,pubsock);
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(mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0);
//printf("my ipaddr.(%s) peers.(%s)\n",ipaddr,retstr!=0?retstr:"");
}
if ( myipaddr == 0 || mypeer == 0 )
{
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
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));
}
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;
/*if ( strcmp(ipaddr,"173.208.149.42") == 0 )
return(0);
if ( strncmp(ipaddr,"5.9.253",strlen("5.9.253")) != 0 )
return(0);*/
uint32_t ipbits; int32_t pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0;
ipbits = (uint32_t)calc_ipbits(ipaddr);
expand_ipbits(checkip,ipbits);
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->pushsock = peer->subsock = pushsock = subsock = -1;
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 )
{
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);
peer->connected = (uint32_t)time(NULL);
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;
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;
printf("connected to sub.(%s) %d\n",subaddr,peer->subsock);
Client_connections += amclient;
} else nn_close(subsock);
}
}
@ -125,7 +117,7 @@ struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32
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;
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);
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 )
{
@ -160,7 +152,7 @@ int32_t LP_peersparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
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;
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);
now = (uint32_t)time(NULL);
LP_peersparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now);
LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
if ( amclient == 0 )
if ( IAMLP != 0 )
{
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));
if ( (qp->txfee= LP_getestimatedrate(utxo->coin)*LP_AVETXSIZE) < 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);
qp->txid = utxo->txid;
qp->vout = utxo->vout;
qp->txid2 = utxo->txid2;
qp->vout2 = utxo->vout2;
qp->satoshis = utxo->satoshis - qp->txfee;
qp->txid = utxo->payment.txid;
qp->vout = utxo->payment.vout;
qp->txid2 = utxo->deposit.txid;
qp->vout2 = utxo->deposit.vout;
qp->satoshis = utxo->S.satoshis - qp->txfee;
qp->destsatoshis = qp->satoshis * price;
if ( (qp->desttxfee= LP_getestimatedrate(qp->destcoin) * LP_AVETXSIZE) < 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;
safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin));
safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr));
qp->srchash = LP_pubkey(LP_privkey(utxo->coinaddr));
qp->srchash = utxo->pubkey;
return(0);
}
@ -224,7 +224,7 @@ cJSON *LP_tradecandidates(char *base)
safecopy(coinstr,jstr(item,"base"),sizeof(coinstr));
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 )
{
@ -265,8 +265,8 @@ void LP_quotesinit(char *base,char *rel)
item = jitem(array,i);
LP_quoteparse(&Q,item);
if ( iter == 0 )
LP_query("price",&Q,jstr(item,"ipaddr"),jint(item,"port"),base,rel,zero);
else LP_query("price",&Q,jstr(item,"ipaddr"),jint(item,"port"),rel,base,zero);
LP_query("price",&Q,base,rel,zero);
else LP_query("price",&Q,rel,base,zero);
}
}
free_json(array);
@ -293,7 +293,7 @@ cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
LP_quoteparse(&Q[i],item);
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;
}
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;
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;
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;
}
}
} 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);
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);
if ( maxprice == 0. || bestprice <= maxprice )
{
Q[i].desttxid = myutxo->txid;
Q[i].destvout = myutxo->vout;
Q[i].feetxid = myutxo->txid2;
Q[i].feevout = myutxo->vout2;
Q[i].desttxid = myutxo->payment.txid;
Q[i].destvout = myutxo->payment.vout;
Q[i].feetxid = myutxo->fee.txid;
Q[i].feevout = myutxo->fee.vout;
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 )
jdelete(bestitem,"price");
jaddnum(bestitem,"price",prices[i]);
if ( price <= maxprice )
{
Q[i].desttxid = myutxo->txid;
Q[i].destvout = myutxo->vout;
Q[i].feetxid = myutxo->txid2;
Q[i].feevout = myutxo->vout2;
Q[i].desttxid = myutxo->payment.txid;
Q[i].destvout = myutxo->payment.vout;
Q[i].feetxid = myutxo->fee.txid;
Q[i].feevout = myutxo->fee.vout;
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);
jaddstr(bestitem,"status","connected");
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)
{
double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr;
if ( (now= (uint32_t)time(NULL)) > utxo->swappending )
utxo->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= (uint32_t)time(NULL)) > utxo->T.swappending )
utxo->T.swappending = 0;
if ( now > utxo->T.published+60 && utxo->T.swappending == 0 && utxo->S.swap == 0 && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 0. )
{
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
@ -388,7 +388,7 @@ int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double p
retstr = jprint(retjson,1);
//printf("PING.(%s)\n",retstr);
LP_send(pubsock,retstr,1);
utxo->published = now;
utxo->T.published = now;
return(0);
}
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 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 )
printf("WARNING long url.(%s)\n",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)
{
char *retstr; cJSON *retjson = 0;

84
iguana/exchanges/LP_swap.c

@ -17,22 +17,12 @@
// LP_swap.c
// 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
*/
// 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
/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271
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), swap->messages = 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)
@ -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)
{
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 ( 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);
//printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen);
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
{
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);
}
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");
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 10;
while ( (swap= utxo->swap) == 0 && time(NULL) < expiration )
sleep(1);
if ( (utxo->swap= swap) != 0 )
if ( 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");
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");
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");
else if ( basilisk_bobscripts_set(swap,1,1) < 0 )
printf("error bobscripts deposit\n");
@ -671,11 +671,11 @@ void LP_bobloop(void *_utxo)
basilisk_bobdeposit_refund(swap,swap->I.putduration);
//printf("depositlen.%d\n",swap->bobdeposit.I.datalen);
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");
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");
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");
else
{
@ -689,45 +689,41 @@ void LP_bobloop(void *_utxo)
}
if ( basilisk_bobscripts_set(swap,0,1) < 0 )
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");
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,600);
}
}
basilisk_swap_finished(swap);
free(utxo->swap);
free(swap);
} 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;
fprintf(stderr,"start swap iamalice pair.%d\n",qp->pair);
uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap = _swap;
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 10;
swap = LP_swapinit(0,0,qp->privkey,&qp->R,qp);
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");
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");
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");
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");
else
{
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");
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");
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");
else
{
@ -736,7 +732,7 @@ void LP_aliceloop(void *_qp)
printf("waiting for alicepayment to confirm\n");
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");
else
{
@ -745,7 +741,7 @@ void LP_aliceloop(void *_qp)
printf("waiting for bobpayment to confirm\n");
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");
while ( LP_numconfirms(swap,&swap->alicespend) < 1 )
{
@ -759,8 +755,8 @@ void LP_aliceloop(void *_qp)
basilisk_swap_finished(swap);
free(swap);
}
nn_close(qp->pair);
free(qp);
free(data);
nn_close(swap->N.pair);
}
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);
}
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx)
int32_t LP_mempoolscan(char *symbol,bits256 txid)
{
int32_t numconfirms = 100;
#ifndef BASILISK_DISABLEWAITTX
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 )
int32_t i,n; cJSON *array;
if ( (array= LP_getmempool(symbol)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
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);
break;
return(i);
}
}
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
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 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(" <- aliceclaim\n");
//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);
}
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 )
swap->aliceunconf = 1;
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);
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(" <- alicespend\n\n");
swap->I.alicespent = 1;
//basilisk_txlog(swap,&swap->alicespend,-1);
return(retval);
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.signedtxid,10));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr);
}
printf("error validating bobpayment\n");

394
iguana/exchanges/LP_utxos.c

@ -20,75 +20,212 @@
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);
else if ( LP_mypeer == 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);
else return(0);
}
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);
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[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);
HASH_FIND(hh,LP_utxoinfos,key,sizeof(key),utxo);
utxo = _LP_utxofind(iambob,txid,vout);
portable_mutex_unlock(&LP_utxomutex);
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)];
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
HASH_FIND(hh2,LP_utxoinfos2,key,sizeof(key),utxo);
struct LP_utxoinfo *utxo=0;
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxo2find(iambob,txid2,vout2);
portable_mutex_unlock(&LP_utxomutex);
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)];
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
int32_t i;
for (i=0; i<n; i++)
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);
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);
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)
{
struct _LP_utxoinfo u;
jaddstr(item,"coin",utxo->coin);
jaddnum(item,"now",time(NULL));
jaddstr(item,"address",utxo->coinaddr);
jaddbits256(item,"txid",utxo->txid);
jaddnum(item,"vout",utxo->vout);
jadd64bits(item,"value",utxo->value);
jadd64bits(item,"satoshis",utxo->satoshis);
jaddbits256(item,"txid2",utxo->txid2);
jaddnum(item,"vout2",utxo->vout2);
jadd64bits(item,"value2",utxo->value2);
if ( utxo->swappending != 0 )
jaddnum(item,"pending",utxo->swappending);
if ( bits256_nonz(utxo->otherpubkey) != 0 )
jaddbits256(item,"desthash",utxo->otherpubkey);
if ( utxo->pair >= 0 )
jaddnum(item,"socket",utxo->pair);
if ( utxo->swap != 0 )
jaddbits256(item,"txid",utxo->payment.txid);
jaddnum(item,"vout",utxo->payment.vout);
jadd64bits(item,"value",utxo->payment.value);
jadd64bits(item,"satoshis",utxo->S.satoshis);
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( bits256_nonz(u.txid) != 0 )
{
jaddbits256(item,"txid2",u.txid);
jaddnum(item,"vout2",u.vout);
jadd64bits(item,"value2",u.value);
}
if ( utxo->T.swappending != 0 )
jaddnum(item,"pending",utxo->T.swappending);
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");
if ( utxo->spentflag != 0 )
jaddnum(item,"spent",utxo->spentflag);
if ( utxo->T.spentflag != 0 )
jaddnum(item,"spent",utxo->T.spentflag);
return(item);
}
@ -96,26 +233,25 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
{
cJSON *item = cJSON_CreateObject();
item = LP_inventoryjson(item,utxo);
jaddstr(item,"ipaddr",utxo->ipaddr);
jaddnum(item,"port",utxo->port);
jaddnum(item,"profit",utxo->profitmargin);
jaddbits256(item,"pubkey",utxo->pubkey);
jaddnum(item,"profit",utxo->S.profitmargin);
jaddstr(item,"base",utxo->coin);
jaddstr(item,"script",utxo->spendscript);
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();
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
if ( i++ < firsti )
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));
}
@ -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)
{
cJSON *argjson;
utxo->spentflag = (uint32_t)time(NULL);
cJSON *argjson; struct _LP_utxoinfo u;
utxo->T.spentflag = (uint32_t)time(NULL);
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
if ( LP_mypubsock >= 0 )
{
argjson = cJSON_CreateObject();
jaddstr(argjson,"method","checktxid");
jaddbits256(argjson,"txid",utxo->txid);
jaddnum(argjson,"vout",utxo->vout);
jaddbits256(argjson,"txid",utxo->payment.txid);
jaddnum(argjson,"vout",utxo->payment.vout);
if ( selector != 0 )
{
jaddbits256(argjson,"checktxid",utxo->txid2);
jaddnum(argjson,"checkvout",utxo->vout2);
if ( bits256_nonz(utxo->deposit.txid) != 0 )
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);
}
@ -146,35 +285,41 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
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");
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 )
checktxid = txid, checkvout = vout;
else
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && utxo->T.spentflag == 0 )
{
checktxid = jbits256(argjson,"checktxid");
checkvout = jint(argjson,"checkvout");
if ( jobj(argjson,"check") == 0 )
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 ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
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\"}"));
}
if ( retval > 0 )
return(clonestr("{\"result\":\"marked as spent\"}"));
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;
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 )
{
//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);
}
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 )
{
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);
}
if ( IAMCLIENT == 0 && value2 < 9 * (value >> 3) + 100000 )
if ( iambob != 0 && value2 < 9 * (value >> 3) + 100000 )
tmpsatoshis = (((value2-100000) / 9) << 3);
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));
return(0);
}
if ( IAMCLIENT == 0 && strcmp(ipaddr,"127.0.0.1") == 0 )
{
//printf("LP node got localhost utxo\n");
return(0);
}
if ( (utxo= LP_utxofind(txid,vout)) != 0 || (utxo= LP_utxo2find(txid,vout)) != 0 )
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,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));
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++;
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);
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\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. )
utxo->profitmargin = profitmargin;
utxo->S.profitmargin = profitmargin;
}
else
{
utxo = calloc(1,sizeof(*utxo));
utxo->pair = -1;
utxo->profitmargin = profitmargin;
strcpy(utxo->ipaddr,ipaddr);
utxo->port = port;
utxo->S.profitmargin = profitmargin;
utxo->pubkey = pubkey;
safecopy(utxo->coin,coin,sizeof(utxo->coin));
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
utxo->txid = txid;
utxo->vout = vout;
utxo->value = value;
utxo->satoshis = tmpsatoshis;
utxo->txid2 = txid2;
utxo->vout2 = vout2;
utxo->value2 = value2;
memcpy(utxo->key,txid.bytes,sizeof(txid));
memcpy(&utxo->key[sizeof(txid)],&vout,sizeof(vout));
memcpy(utxo->key2,txid2.bytes,sizeof(txid2));
memcpy(&utxo->key2[sizeof(txid2)],&vout2,sizeof(vout2));
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->payment.txid = txid;
utxo->payment.vout = vout;
utxo->payment.value = value;
utxo->S.satoshis = tmpsatoshis;
if ( (utxo->iambob= iambob) != 0 )
{
utxo->deposit.txid = txid2;
utxo->deposit.vout = vout2;
utxo->deposit.value = value2;
}
else
{
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);
HASH_ADD_KEYPTR(hh,LP_utxoinfos,utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2,utxo->key2,sizeof(utxo->key2),utxo);
if ( mypeer != 0 )
mypeer->numutxos++;
HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
portable_mutex_unlock(&LP_utxomutex);
if ( mypubsock >= 0 )
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);
}
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;
if ( amclient != 0 )
struct LP_peerinfo *destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
if ( IAMLP == 0 )
{
printf("LP_utxosparse not for clientside\n");
return(-1);
@ -273,16 +417,16 @@ int32_t LP_utxosparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubs
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
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"));
//if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
// peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
if ( jobj(item,"txid") != 0 )
{
txid = jbits256(item,"txid");
//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 )
{
utxo->lasttime = now;
utxo->T.lasttime = now;
}
}
} // 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);
}
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;
if ( amclient != 0 )
if ( IAMLP == 0 )
{
printf("LP_utxosquery not for clientside\n");
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 )
{
now = (uint32_t)time(NULL);
LP_utxosparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now);
LP_utxosparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
i = 0;
if ( lastn >= mypeer->numutxos )
@ -337,16 +481,17 @@ void LP_utxosquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock
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 )
myipaddr = LP_mypeer->ipaddr;
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));
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));
}
return(jprint(array,1));
@ -381,10 +526,10 @@ int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval)
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;
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 )
{
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);
LP_privkeyadd(privkey,rmd160);
LP_mypubkey = mypub = curve25519(privkey,curve25519_basepoint9());
if ( coin->inactive == 0 && (array= LP_listunspent(symbol,coin->smartaddr)) != 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");
depositval = values[i];
values[i] = 0, used++;
if ( amclient != 0 )
if ( iambob == 0 )
targetval = (depositval / 776) + 100000;
else targetval = (depositval / 9) * 8 + 100000;
//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];
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 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9());
if ( (utxo= LP_addutxo(1,mypubsock,symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_peerinfos[0].profitmargin)) != 0 )
{
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
}
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 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9());
if ( (utxo= LP_addutxo(0,mypubsock,symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0)) != 0 )
{
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
}
total += value;
}
@ -474,13 +624,13 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb
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;
for (i=0; i<LP_numcoins; i++)
{
//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