Browse Source

Merge branch 'spvdex' of https://github.com/jl777/SuperNET into dev-decker-spvdex

etomic
DeckerSU 8 years ago
parent
commit
2a2cbcb663
  1. 41
      iguana/exchanges/LP_commands.c
  2. 4
      iguana/exchanges/LP_include.h
  3. 109
      iguana/exchanges/LP_nativeDEX.c
  4. 63
      iguana/exchanges/LP_ordermatch.c
  5. 8
      iguana/exchanges/LP_prices.c
  6. 34
      iguana/exchanges/LP_remember.c
  7. 18
      iguana/exchanges/LP_rpc.c
  8. 2
      iguana/exchanges/LP_socket.c
  9. 2
      iguana/exchanges/LP_swap.c
  10. 10
      iguana/exchanges/LP_transaction.c
  11. 31
      iguana/exchanges/LP_utxo.c
  12. 16
      iguana/exchanges/LP_utxos.c
  13. 1
      iguana/exchanges/enable
  14. 3
      iguana/exchanges/listunspent
  15. 2
      iguana/exchanges/mm.c
  16. 283
      iguana/exchanges/stats.c

41
iguana/exchanges/LP_commands.c

@ -120,7 +120,7 @@ getprices(base, rel)\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\ sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
getmessages(firsti=0, num=100)\n\ getmessages(firsti=0, num=100)\n\
clearmessages(firsti=0, num=100)\n\ clearmessages(firsti=0, num=100)\n\
secretaddresses(passphrase, num=10, pubtype=60, taddr=0)\n\ secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
electrum(coin, ipaddr, port)\n\ electrum(coin, ipaddr, port)\n\
snapshot(coin, height)\n\ snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\ snapshot_balance(coin, height, addresses[])\n\
@ -186,7 +186,7 @@ dividends(coin, height, <args>)\n\
uint8_t taddr,pubtype; uint8_t taddr,pubtype;
pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype"); pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype");
taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr"); taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr");
return(LP_secretaddresses(ctx,jstr(argjson,"passphrase"),juint(argjson,"num"),taddr,pubtype)); return(LP_secretaddresses(ctx,jstr(argjson,"prefix"),jstr(argjson,"passphrase"),juint(argjson,"num"),taddr,pubtype));
} }
if ( base != 0 && rel != 0 ) if ( base != 0 && rel != 0 )
{ {
@ -311,6 +311,7 @@ dividends(coin, height, <args>)\n\
jaddnum(retjson,"timestamp",time(NULL)); jaddnum(retjson,"timestamp",time(NULL));
jadd(retjson,"alice",LP_inventory(coin)); jadd(retjson,"alice",LP_inventory(coin));
//jadd(retjson,"bob",LP_inventory(coin,1)); //jadd(retjson,"bob",LP_inventory(coin,1));
LP_smartutxos_push(ptr);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
} }
@ -376,9 +377,19 @@ dividends(coin, height, <args>)\n\
char *coinaddr; char *coinaddr;
if ( (coinaddr= jstr(argjson,"address")) != 0 ) if ( (coinaddr= jstr(argjson,"address")) != 0 )
{ {
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 ) if ( coinaddr[0] != 0 )
LP_privkey_init(-1,ptr,G.LP_mypriv25519,G.LP_mypub25519); {
LP_listunspent_issue(coin,coinaddr); LP_listunspent_issue(coin,coinaddr);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 )
{
LP_privkey_init(-1,ptr,G.LP_mypriv25519,G.LP_mypub25519);
//LP_smartutxos_push(ptr);
}
else
{
}
}
return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
} else return(clonestr("{\"error\":\"no address specified\"}")); } else return(clonestr("{\"error\":\"no address specified\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}")); } else return(clonestr("{\"error\":\"cant find coind\"}"));
@ -405,6 +416,26 @@ dividends(coin, height, <args>)\n\
} }
else if ( strcmp(method,"checktxid") == 0 ) else if ( strcmp(method,"checktxid") == 0 )
retstr = LP_spentcheck(argjson); retstr = LP_spentcheck(argjson);
else if ( strcmp(method,"addr_unspents") == 0 )
{
//printf("GOT ADDR_UNSPENTS\n");
if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 )
{
char *coinaddr; //cJSON *array,*item,*req; int32_t i,n,vout,height; bits256 zero,txid; uint64_t value;
if ( (coinaddr= jstr(argjson,"address")) != 0 )
{
if ( coinaddr[0] != 0 )
{
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 )
{
//printf("%s %s is my address being asked for!\n",ptr->symbol,coinaddr);
ptr->addr_listunspent_requested = (uint32_t)time(NULL);
}
}
}
}
retstr = clonestr("{\"result\":\"success\"}");
}
else if ( strcmp(method,"getcoins") == 0 ) else if ( strcmp(method,"getcoins") == 0 )
return(jprint(LP_coinsjson(0),1)); return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"numutxos") == 0 ) else if ( strcmp(method,"numutxos") == 0 )

4
iguana/exchanges/LP_include.h

@ -183,7 +183,7 @@ struct iguana_info
portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee; uint64_t txfee;
int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,unspenttime,obooktime; uint32_t addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,unspenttime,obooktime;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag;
char symbol[16],smartaddr[64],userpass[1024],serverport[128],lastunspent[64]; char symbol[16],smartaddr[64],userpass[1024],serverport[128],lastunspent[64];
// portfolio // portfolio
@ -312,6 +312,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); int32_t LP_mempoolscan(char *symbol,bits256 searchtxid);
int32_t LP_txheight(struct iguana_info *coin,bits256 txid); int32_t LP_txheight(struct iguana_info *coin,bits256 txid);
int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight);
void LP_smartutxos_push(struct iguana_info *coin);
cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret); cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret);
cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout); cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr); void LP_postutxos(char *symbol,char *coinaddr);
@ -325,5 +326,6 @@ double LP_getestimatedrate(struct iguana_info *coin);
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout); struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout);
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout); struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout);
void LP_listunspent_query(char *symbol,char *coinaddr);
#endif #endif

109
iguana/exchanges/LP_nativeDEX.c

@ -257,12 +257,14 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
{ {
if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 ) if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 )
printf("self.(%s)\n",str); printf("self.(%s)\n",str);
portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
{ {
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
free(retstr); free(retstr);
} }
free_json(argjson); free_json(argjson);
portable_mutex_unlock(&LP_commandmutex);
} }
free(str); free(str);
} }
@ -310,21 +312,71 @@ void command_rpcloop(void *myipaddr)
if ( nonz == 0 ) if ( nonz == 0 )
{ {
if ( IAMLP != 0 ) if ( IAMLP != 0 )
usleep(10); usleep(1000);
else usleep(1000); else usleep(10000);
} }
} }
} }
void LP_smartutxos_push(struct iguana_info *coin)
{
struct LP_peerinfo *peer,*tmp; uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; char *retstr; cJSON *array,*item,*req;
if ( coin->smartaddr[0] == 0 )
return;
if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
printf("PUSH %s %s\n",coin->symbol,coin->smartaddr);
for (i=0; i<n; i++)
{
item = jitem(array,i);
txid = jbits256(item,"tx_hash");
vout = jint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
if ( 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( (retstr= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,vout,height,value)) != 0 )
free(retstr);
}
}
else
{
req = cJSON_CreateObject();
jaddstr(req,"method","uitem");
jaddstr(req,"coin",coin->symbol);
jaddstr(req,"coinaddr",coin->smartaddr);
jaddbits256(req,"txid",txid);
jaddnum(req,"vout",vout);
jaddnum(req,"ht",height);
jadd64bits(req,"value",value);
//printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0));
LP_broadcast_message(LP_mypubsock,"","",zero,jprint(req,1));
}
}
}
free_json(array);
}
}
int32_t LP_utxos_sync(struct LP_peerinfo *peer) int32_t LP_utxos_sync(struct LP_peerinfo *peer)
{ {
int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2,*array3; uint64_t total,total2,metric; struct iguana_info *coin,*ctmp; struct LP_address *ap; char *retstr,*retstr2,*coinaddr; int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2,*array3; uint64_t total,total2,metric; struct iguana_info *coin,*ctmp; struct LP_address *ap; char *retstr,*retstr2,*coinaddr;
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
return(0);
HASH_ITER(hh,LP_coins,coin,ctmp) HASH_ITER(hh,LP_coins,coin,ctmp)
{ {
if ( coin->inactive != 0 )//|| (coin->electrum != 0 && coin->obooktime == 0) ) if ( IAMLP == 0 && coin->inactive != 0 )//|| (coin->electrum != 0 && coin->obooktime == 0) )
continue;
if ( coin->smartaddr[0] == 0 )
continue; continue;
total = 0; total = 0;
LP_listunspent_both(coin->symbol,coin->smartaddr); if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr)) == 0 )
continue;
if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 )
{ {
if ( (n= cJSON_GetArraySize(array)) > 0 ) if ( (n= cJSON_GetArraySize(array)) > 0 )
@ -337,6 +389,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer)
} }
if ( n > 0 && total > 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr)) != 0 ) if ( n > 0 && total > 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr)) != 0 )
{ {
//printf("UTXO sync.%d %s n.%d total %.8f -> %s (%s)\n",j,coin->symbol,n,dstr(total),peer->ipaddr,retstr);
total2 = 0; total2 = 0;
if ( (array2= cJSON_Parse(retstr)) != 0 ) if ( (array2= cJSON_Parse(retstr)) != 0 )
{ {
@ -362,7 +415,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer)
} }
if ( j == m ) if ( j == m )
{ {
//printf("%s missing %s\n",peer->ipaddr,jprint(item,0)); //printf("%s missing %s %s\n",peer->ipaddr,coin->symbol,jprint(item,0));
if ( (retstr2= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"))) != 0 ) if ( (retstr2= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"))) != 0 )
free(retstr2); free(retstr2);
posted++; posted++;
@ -370,13 +423,26 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer)
} }
if ( 0 && posted != 0 ) if ( 0 && posted != 0 )
printf(">>>>>>>> %s compare %s %s (%.8f n%d) (%.8f m%d)\n",peer->ipaddr,coin->symbol,coin->smartaddr,dstr(total),n,dstr(total2),m); printf(">>>>>>>> %s compare %s %s (%.8f n%d) (%.8f m%d)\n",peer->ipaddr,coin->symbol,coin->smartaddr,dstr(total),n,dstr(total2),m);
} //else printf("%s matches\n",peer->ipaddr); } //else printf("%s matches %s\n",peer->ipaddr,coin->symbol);
free_json(array2); free_json(array2);
} } else printf("parse error (%s)\n",retstr);
free(retstr); free(retstr);
} }
else if ( n != 0 && total != 0 )
{
//printf("no response from %s for %s %s\n",peer->ipaddr,coin->symbol,coin->smartaddr);
for (i=0; i<n; i++)
{
item = jitem(array,i);
txid = jbits256(item,"tx_hash");
v = jint(item,"tx_pos");
if ( (retstr2= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"))) != 0 )
free(retstr2);
}
}
free_json(array);
} }
if ( (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,"")) != 0 ) if ( 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,"")) != 0 )
{ {
if ( (array2= cJSON_Parse(retstr)) != 0 ) if ( (array2= cJSON_Parse(retstr)) != 0 )
{ {
@ -387,7 +453,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer)
item = jitem(array2,j); item = jitem(array2,j);
if ( (coinaddr= jfieldname(item)) != 0 ) if ( (coinaddr= jfieldname(item)) != 0 )
{ {
metric = j64bits(item,"coinaddr"); metric = j64bits(item,coinaddr);
//printf("(%s) -> %.8f n.%d\n",coinaddr,dstr(metric>>16),(uint16_t)metric); //printf("(%s) -> %.8f n.%d\n",coinaddr,dstr(metric>>16),(uint16_t)metric);
if ( (ap= LP_addressfind(coin,coinaddr)) == 0 || _LP_unspents_metric(ap->total,ap->n) != metric ) if ( (ap= LP_addressfind(coin,coinaddr)) == 0 || _LP_unspents_metric(ap->total,ap->n) != metric )
{ {
@ -441,24 +507,28 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
if ( IAMLP == 0 ) if ( IAMLP == 0 )
continue; continue;
} }
if ( now > peer->lastpeers+60 && peer->numpeers > 0 && (peer->numpeers != numpeers || (rand() % 1000) == 0) ) if ( now > peer->lastpeers+60 || (rand() % 10000) == 0 )
{ {
peer->lastpeers = now;
if ( strcmp(peer->ipaddr,myipaddr) != 0 ) if ( strcmp(peer->ipaddr,myipaddr) != 0 )
{ {
nonz++;
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport);
peer->diduquery = 0; peer->diduquery = 0;
LP_utxos_sync(peer); LP_utxos_sync(peer);
} }
peer->lastpeers = now;
} }
if ( peer->diduquery == 0 ) if ( peer->diduquery == 0 )
{ {
nonz++;
needpings++;
LP_peer_pricesquery(peer); LP_peer_pricesquery(peer);
LP_utxos_sync(peer); LP_utxos_sync(peer);
peer->diduquery = now; peer->diduquery = now;
} }
if ( peer->needping != 0 ) if ( peer->needping != 0 )
{ {
nonz++;
needpings++; needpings++;
if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 )
free(retstr); free(retstr);
@ -467,16 +537,24 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
} }
if ( needpings != 0 || (counter % 6000) == 5 ) if ( needpings != 0 || (counter % 6000) == 5 )
{ {
nonz++;
//printf("needpings.%d send notify\n",needpings); //printf("needpings.%d send notify\n",needpings);
LP_notify_pubkeys(ctx,pubsock); LP_notify_pubkeys(ctx,pubsock);
} }
if ( (counter % 6000) == 10 ) if ( (counter % 6000) == 10 )
{ {
nonz++;
LP_privkey_updates(ctx,pubsock,0); LP_privkey_updates(ctx,pubsock,0);
} }
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{ {
memset(&zero,0,sizeof(zero)); memset(&zero,0,sizeof(zero));
if ( coin->addr_listunspent_requested != 0 )
{
printf("addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
LP_smartutxos_push(coin);
coin->addr_listunspent_requested = 0;
}
if ( coin->inactive != 0 ) if ( coin->inactive != 0 )
continue; continue;
if ( coin->electrum != 0 ) if ( coin->electrum != 0 )
@ -485,6 +563,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
// continue; // continue;
if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR )
{ {
nonz++;
if ( (height= LP_getheight(coin)) > coin->longestchain ) if ( (height= LP_getheight(coin)) > coin->longestchain )
{ {
coin->longestchain = height; coin->longestchain = height;
@ -529,6 +608,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
} }
if ( j < 100 ) if ( j < 100 )
continue; continue;
nonz++;
//LP_getestimatedrate(coin); //LP_getestimatedrate(coin);
break; break;
} }
@ -537,6 +617,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
if ( (retstr= basilisk_swapentry(0,0)) != 0 ) if ( (retstr= basilisk_swapentry(0,0)) != 0 )
{ {
//printf("SWAPS.(%s)\n",retstr); //printf("SWAPS.(%s)\n",retstr);
nonz++;
free(retstr); free(retstr);
} }
} }
@ -773,8 +854,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 )
nonz++; nonz++;
if ( nonz == 0 ) if ( nonz == 0 )
usleep(50000); usleep(10000);
else usleep(5000); else if ( IAMLP != 0 )
usleep(1000);
else usleep(10000);
} }
} }

63
iguana/exchanges/LP_ordermatch.c

@ -244,6 +244,18 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock)
LP_broadcast_message(pubsock,"","",zero,msg); LP_broadcast_message(pubsock,"","",zero,msg);
} }
void LP_listunspent_query(char *symbol,char *coinaddr)
{
bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject();
memset(zero.bytes,0,sizeof(zero));
jaddstr(reqjson,"method","addr_unspents");
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"address",coinaddr);
msg = jprint(reqjson,1);
printf("BROADCAST.(%s)\n",msg);
LP_broadcast_message(LP_mypubsock,"","",zero,msg);
}
char *LP_postedprice(cJSON *argjson) char *LP_postedprice(cJSON *argjson)
{ {
bits256 pubkey; double price; char *base,*rel; bits256 pubkey; double price; char *base,*rel;
@ -449,13 +461,13 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **u
if ( (backupep= ep->prev) == 0 ) if ( (backupep= ep->prev) == 0 )
backupep = ep; backupep = ep;
} }
//printf("LP_nearest_utxovalue %s utxos[%d]\n",coin->symbol,n); printf("LP_nearest_utxovalue %s utxos[%d] target %.8f\n",coin->symbol,n,dstr(targetval));
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
if ( (up= utxos[i]) != 0 ) if ( (up= utxos[i]) != 0 )
{ {
dist = (up->U.value - targetval); dist = (up->U.value - targetval);
//printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight); printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
if ( up->spendheight <= 0 ) if ( up->spendheight <= 0 )
{ {
if ( coin->electrum != 0 ) if ( coin->electrum != 0 )
@ -478,7 +490,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **u
} }
} }
} }
//printf("return mini.%d\n",mini); printf("return mini.%d\n",mini);
return(mini); return(mini);
} }
@ -511,7 +523,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
up = utxos[mini]; up = utxos[mini];
utxos[mini] = 0; utxos[mini] = 0;
targetval2 = (targetval / 8) * 9 + 2*txfee; targetval2 = (targetval / 8) * 9 + 2*txfee;
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(utxos[mini]->U.value),dstr(targetval),dstr(targetval2),(double)utxos[mini]->U.value/targetval); printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
if ( (double)up->U.value/targetval < LP_MINVOL-1 ) if ( (double)up->U.value/targetval < LP_MINVOL-1 )
{ {
if ( (mini= LP_nearest_utxovalue(coin,utxos,m,targetval2 * 1.01)) >= 0 ) if ( (mini= LP_nearest_utxovalue(coin,utxos,m,targetval2 * 1.01)) >= 0 )
@ -724,7 +736,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
int32_t LP_listunspent_both(char *symbol,char *coinaddr) int32_t LP_listunspent_both(char *symbol,char *coinaddr)
{ {
int32_t i,v,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol); int32_t i,v,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin != 0 && coin->inactive == 0 ) if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) )
{ {
if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 )
{ {
@ -943,9 +955,26 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
return(jprint(bestitem,0)); return(jprint(bestitem,0));
} }
struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui)
{
uint64_t basesatoshis; struct LP_utxoinfo *bestutxo;
basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee);
if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 )
{
bestutxo->pubkey = pubkey;
safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui));
*bestsatoshisp = basesatoshis;
*ordermatchpricep = price;
*bestdestsatoshisp = asatoshis;
return(bestutxo);
}
return(0);
}
struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids) struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids)
{ {
bits256 pubkey; char *obookstr,coinaddr[64],str[65]; cJSON *orderbook,*asks,*item; int32_t i,j,n,numasks,max = 10000; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; struct iguana_info *basecoin; uint64_t basesatoshis; struct LP_utxoinfo *bestutxo = 0; bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*item; int32_t maxiters,i,j,numasks,max = 10000; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0;
maxiters = 100;
*ordermatchpricep = 0.; *ordermatchpricep = 0.;
*bestsatoshisp = *bestdestsatoshisp = 0; *bestsatoshisp = *bestdestsatoshisp = 0;
basecoin = LP_coinfind(base); basecoin = LP_coinfind(base);
@ -978,22 +1007,20 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
if ( bits256_cmp(pubkey,G.LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) if ( bits256_cmp(pubkey,G.LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
{ {
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
n = LP_listunspent_both(base,coinaddr); LP_listunspent_query(base,coinaddr);
//printf("unspent.(%s) n.%d\n",coinaddr,n); LP_listunspent_both(base,coinaddr);
if ( n > 1 ) asatoshis = autxo->S.satoshis;
for (j=0; j<maxiters; j++)
{ {
basesatoshis = LP_basesatoshis(dstr(autxo->S.satoshis),price,txfee,desttxfee); if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,gui)) != 0 )
if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 )
{ {
bestutxo->pubkey = pubp->pubkey; printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee));
safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui));
*bestsatoshisp = basesatoshis;
*ordermatchpricep = price;
*bestdestsatoshisp = autxo->S.satoshis;
printf("ordermatch %.8f %.8f %.8f txfees (%.8f %.8f)\n",price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee));
break; break;
} }
} else printf("no unspents %s %s %s\n",base,coinaddr,bits256_str(str,pubkey)); asatoshis = (asatoshis / 64) * 63;
}
if ( j < maxiters )
break;
} else printf("self trading or blacklisted peer\n"); } else printf("self trading or blacklisted peer\n");
} }
else else

8
iguana/exchanges/LP_prices.c

@ -360,6 +360,8 @@ void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
void LP_peer_pricesquery(struct LP_peerinfo *peer) void LP_peer_pricesquery(struct LP_peerinfo *peer)
{ {
char *retstr; cJSON *array; int32_t i,n; char *retstr; cJSON *array; int32_t i,n;
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
return;
peer->needping = (uint32_t)time(NULL); peer->needping = (uint32_t)time(NULL);
if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 ) if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 )
{ {
@ -771,9 +773,10 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
jaddi(array,LP_orderbookjson(rel,bids[i])); jaddi(array,LP_orderbookjson(rel,bids[i]));
if ( bids[i]->numutxos == 0 )//|| relcoin->electrum == 0 ) if ( bids[i]->numutxos == 0 )//|| relcoin->electrum == 0 )
{ {
LP_address(relcoin,bids[i]->coinaddr);
if ( relcoin->electrum == 0 ) if ( relcoin->electrum == 0 )
LP_listunspent_issue(rel,bids[i]->coinaddr); LP_listunspent_issue(rel,bids[i]->coinaddr);
else LP_address(relcoin,bids[i]->coinaddr); LP_listunspent_query(rel,bids[i]->coinaddr);
n++; n++;
} }
free(bids[i]); free(bids[i]);
@ -789,9 +792,10 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
jaddi(array,LP_orderbookjson(base,asks[i])); jaddi(array,LP_orderbookjson(base,asks[i]));
if ( asks[i]->numutxos == 0 )//|| basecoin->electrum == 0 ) if ( asks[i]->numutxos == 0 )//|| basecoin->electrum == 0 )
{ {
LP_address(basecoin,asks[i]->coinaddr);
if ( basecoin->electrum == 0 ) if ( basecoin->electrum == 0 )
LP_listunspent_issue(base,asks[i]->coinaddr); LP_listunspent_issue(base,asks[i]->coinaddr);
else LP_address(basecoin,asks[i]->coinaddr); LP_listunspent_query(base,asks[i]->coinaddr);
n++; n++;
} }
free(asks[i]); free(asks[i]);

34
iguana/exchanges/LP_remember.c

@ -346,7 +346,7 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag
n++; n++;
if ( n == 0 ) if ( n == 0 )
{ {
printf("if nothing sent, it is finished\n"); //printf("if nothing sent, it is finished\n");
return(1); return(1);
} }
if ( iambob != 0 ) if ( iambob != 0 )
@ -661,8 +661,18 @@ int32_t LP_refht_update(char *symbol,bits256 txid)
int32_t LP_swap_load(struct LP_swap_remember *rswap) int32_t LP_swap_load(struct LP_swap_remember *rswap)
{ {
int32_t i,needflag,addflag; long fsize; char fname[1024],str[65],*fstr,*symbol,*rstr; cJSON *txobj,*sentobj; bits256 txid,checktxid; uint64_t value; int32_t i,needflag,addflag; long fsize; char fname[1024],str[65],*fstr,*symbol,*rstr; cJSON *txobj,*sentobj,*fileobj; bits256 txid,checktxid; uint64_t value;
rswap->iambob = -1; rswap->iambob = -1;
sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap->requestid,rswap->quoteid), OS_compatible_path(fname);
if ( (fstr= OS_filestr(&fsize,fname)) != 0 )
{
if ( (fileobj= cJSON_Parse(fstr)) != 0 )
{
rswap->origfinishedflag = rswap->finishedflag = 1;
free_json(fileobj);
}
free(fstr);
}
for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++) for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
{ {
needflag = addflag = 0; needflag = addflag = 0;
@ -748,8 +758,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
} }
free_json(sentobj); free_json(sentobj);
} }
if ( rswap->finishedflag == 0 ) printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value));
printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value));
} }
} }
} //else printf("no symbol\n"); } //else printf("no symbol\n");
@ -851,13 +860,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
printf("Bob.%p is null or Alice.%p is null\n",bob,alice); printf("Bob.%p is null or Alice.%p is null\n",bob,alice);
return(cJSON_Parse("{\"error\":\"null bob or alice coin\"}")); return(cJSON_Parse("{\"error\":\"null bob or alice coin\"}"));
} }
printf("ALICE.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.Adestaddr,alice->symbol,alice->firstrefht,alice->firstscanht,alice->lastscanht);
printf("BOB.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.destaddr,bob->symbol,bob->firstrefht,bob->firstscanht,bob->lastscanht);
//printf("iambob.%d finishedflag.%d %s %.8f txfee, %s %.8f txfee\n",rswap.iambob,rswap.finishedflag,rswap.alicecoin,dstr(rswap.Atxfee),rswap.bobcoin,dstr(rswap.Btxfee)); //printf("iambob.%d finishedflag.%d %s %.8f txfee, %s %.8f txfee\n",rswap.iambob,rswap.finishedflag,rswap.alicecoin,dstr(rswap.Atxfee),rswap.bobcoin,dstr(rswap.Btxfee));
//printf("privAm.(%s) %p/%p\n",bits256_str(str,rswap.privAm),Adest,AAdest); //printf("privAm.(%s) %p/%p\n",bits256_str(str,rswap.privAm),Adest,AAdest);
//printf("privBn.(%s) %p/%p\n",bits256_str(str,rswap.privBn),Bdest,ABdest); //printf("privBn.(%s) %p/%p\n",bits256_str(str,rswap.privBn),Bdest,ABdest);
if ( rswap.finishedflag == 0 && rswap.bobcoin[0] != 0 && rswap.alicecoin[0] != 0 ) if ( rswap.finishedflag == 0 && rswap.bobcoin[0] != 0 && rswap.alicecoin[0] != 0 )
{ {
//printf("ALICE.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.Adestaddr,alice->symbol,alice->firstrefht,alice->firstscanht,alice->lastscanht);
//printf("BOB.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.destaddr,bob->symbol,bob->firstrefht,bob->firstscanht,bob->lastscanht);
if ( alice->inactive != 0 || bob->inactive != 0 ) if ( alice->inactive != 0 || bob->inactive != 0 )
{ {
printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",rswap.alicecoin,alice->inactive,rswap.bobcoin,bob->inactive); printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",rswap.alicecoin,alice->inactive,rswap.bobcoin,bob->inactive);
@ -1075,30 +1084,33 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
printf("depositspent.(%s) alice.%d bob.%d %s %.8f\n",bits256_str(str,rswap.depositspent),rswap.sentflags[BASILISK_ALICECLAIM],rswap.sentflags[BASILISK_BOBREFUND],rswap.bobcoin,dstr(rswap.values[BASILISK_BOBDEPOSIT])); printf("depositspent.(%s) alice.%d bob.%d %s %.8f\n",bits256_str(str,rswap.depositspent),rswap.sentflags[BASILISK_ALICECLAIM],rswap.sentflags[BASILISK_BOBREFUND],rswap.bobcoin,dstr(rswap.values[BASILISK_BOBDEPOSIT]));
} }
LP_totals_update(rswap.iambob,rswap.alicecoin,rswap.bobcoin,KMDtotals,BTCtotals,rswap.sentflags,rswap.values); LP_totals_update(rswap.iambob,rswap.alicecoin,rswap.bobcoin,KMDtotals,BTCtotals,rswap.sentflags,rswap.values);
int32_t numspent = 0;
if ( bits256_nonz(rswap.paymentspent) == 0 ) if ( bits256_nonz(rswap.paymentspent) == 0 )
{ {
if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 ) if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 )
rswap.paymentspent = rswap.txids[BASILISK_ALICESPEND]; rswap.paymentspent = rswap.txids[BASILISK_ALICESPEND];
else rswap.paymentspent = rswap.txids[BASILISK_BOBRECLAIM]; else rswap.paymentspent = rswap.txids[BASILISK_BOBRECLAIM];
} } else numspent++;
if ( bits256_nonz(rswap.depositspent) == 0 ) if ( bits256_nonz(rswap.depositspent) == 0 )
{ {
if ( bits256_nonz(rswap.txids[BASILISK_BOBREFUND]) != 0 ) if ( bits256_nonz(rswap.txids[BASILISK_BOBREFUND]) != 0 )
rswap.depositspent = rswap.txids[BASILISK_BOBREFUND]; rswap.depositspent = rswap.txids[BASILISK_BOBREFUND];
else rswap.depositspent = rswap.txids[BASILISK_ALICECLAIM]; else rswap.depositspent = rswap.txids[BASILISK_ALICECLAIM];
} } else numspent++;
if ( bits256_nonz(rswap.Apaymentspent) == 0 ) if ( bits256_nonz(rswap.Apaymentspent) == 0 )
{ {
if ( bits256_nonz(rswap.txids[BASILISK_BOBSPEND]) != 0 ) if ( bits256_nonz(rswap.txids[BASILISK_BOBSPEND]) != 0 )
rswap.Apaymentspent = rswap.txids[BASILISK_BOBSPEND]; rswap.Apaymentspent = rswap.txids[BASILISK_BOBSPEND];
else rswap.Apaymentspent = rswap.txids[BASILISK_ALICERECLAIM]; else rswap.Apaymentspent = rswap.txids[BASILISK_ALICERECLAIM];
} } else numspent++;
rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent); if ( numspent == 3 )
rswap.finishedflag = 1;
else rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent);
item = LP_swap_json(&rswap); item = LP_swap_json(&rswap);
if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 ) if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 )
{ {
char fname[1024],*itemstr; FILE *fp; char fname[1024],*itemstr; FILE *fp;
//printf("SWAP %u-%u finished!\n",requestid,quoteid); printf("SWAP %u-%u finished!\n",requestid,quoteid);
sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 ) if ( (fp= fopen(fname,"wb")) != 0 )
{ {

18
iguana/exchanges/LP_rpc.c

@ -94,10 +94,11 @@ char *issue_LP_getprices(char *destip,uint16_t destport)
char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr)
{ {
char url[512]; char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr); sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr);
//printf("listunspent.(%s)\n",url); retstr = LP_issue_curl("listunspent",destip,destport,url);
return(LP_issue_curl("listunspent",destip,destport,url)); //printf("listunspent.(%s) -> (%s)\n",url,retstr);
return(retstr);
} }
char *LP_apicall(struct iguana_info *coin,char *method,char *params) char *LP_apicall(struct iguana_info *coin,char *method,char *params)
@ -425,7 +426,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr)
return(cJSON_Parse("{\"error\":\"null symbol\"}")); return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol); coin = LP_coinfind(symbol);
//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
if ( coin == 0 || coin->inactive != 0 ) if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
return(cJSON_Parse("{\"error\":\"no coin\"}")); return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
{ {
@ -439,7 +440,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr)
int32_t LP_listunspent_issue(char *symbol,char *coinaddr) int32_t LP_listunspent_issue(char *symbol,char *coinaddr)
{ {
struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0,destip[64]; uint16_t destport; struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0;// uint16_t destport;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(0); return(0);
if ( (coin= LP_coinfind(symbol)) != 0 ) if ( (coin= LP_coinfind(symbol)) != 0 )
@ -459,11 +460,14 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr)
retjson = LP_listunspent(symbol,coinaddr); retjson = LP_listunspent(symbol,coinaddr);
//printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr); //printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr);
} }
else if ( (destport= LP_randpeer(destip)) > 0 ) else if ( IAMLP == 0 )
LP_listunspent_query(coin->symbol,coin->smartaddr);
/*else if ( (destport= LP_randpeer(destip)) > 0 )
{ {
retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr); retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr);
printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr); retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n"); } else printf("LP_listunspent_issue couldnt get a random peer?\n");*/
if ( retjson != 0 ) if ( retjson != 0 )
{ {
n = cJSON_GetArraySize(retjson); n = cJSON_GetArraySize(retjson);

2
iguana/exchanges/LP_socket.c

@ -909,7 +909,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
} }
else else
{ {
printf("launched.(%s:%u)\n",ep->ipaddr,ep->port); printf("launched electrum.(%s:%u)\n",ep->ipaddr,ep->port);
jaddstr(retjson,"result","success"); jaddstr(retjson,"result","success");
ep->prev = coin->electrum; ep->prev = coin->electrum;
coin->electrum = ep; coin->electrum = ep;

2
iguana/exchanges/LP_swap.c

@ -671,7 +671,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime)
{ {
char *retstr; cJSON *retjson=0; uint32_t divisor=8,expiration = (uint32_t)(time(NULL) + duration); char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration);
printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid);
sleep(10); sleep(10);
//if ( sleeptime < divisor*60 ) //if ( sleeptime < divisor*60 )

10
iguana/exchanges/LP_transaction.c

@ -935,13 +935,21 @@ bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 ut
bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout)
{ {
bits256 spendtxid; int32_t spendvin; char coinaddr[64],str[65]; bits256 spendtxid; int32_t spendvin; char coinaddr[64],str[65]; cJSON *retjson; struct iguana_info *coin;
// listtransactions or listspents // listtransactions or listspents
destaddr[0] = 0; destaddr[0] = 0;
coinaddr[0] = 0; coinaddr[0] = 0;
memset(&spendtxid,0,sizeof(spendtxid)); memset(&spendtxid,0,sizeof(spendtxid));
if ( LP_spendsearch(&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 ) if ( LP_spendsearch(&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 )
printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout); printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout);
else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 )
{
if ( (retjson= LP_gettxout(symbol,coinaddr,utxotxid,vout)) == 0 )
{
decode_hex(spendtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
printf("couldnt find spend of %s/v%d, but no gettxout\n",bits256_str(str,utxotxid),vout);
} else free_json(retjson);
}
return(spendtxid); return(spendtxid);
//char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid)); //char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid));
} }

31
iguana/exchanges/LP_utxo.c

@ -189,7 +189,7 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina
int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight)
{ {
struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65]; struct LP_address *ap; cJSON *txobj; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65];
//printf("%s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); //printf("%s add addr.%s ht.%d\n",coin->symbol,coinaddr,height);
if ( coin == 0 ) if ( coin == 0 )
return(0); return(0);
@ -216,6 +216,14 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,
} }
if ( flag == 0 ) if ( flag == 0 )
{ {
if ( coin->electrum == 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 )
{
//printf("prevent utxoadd since gettxout %s/v%d missing\n",bits256_str(str,txid),vout);
return(0);
} else free_json(txobj);
}
up = calloc(1,sizeof(*up)); up = calloc(1,sizeof(*up));
up->U.txid = txid; up->U.txid = txid;
up->U.vout = vout; up->U.vout = vout;
@ -333,7 +341,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256
cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret) cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret)
{ {
cJSON *array,*item; int32_t n; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; struct electrum_info *ep,*backupep=0; cJSON *array,*item; int32_t n; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; cJSON *txobj; struct electrum_info *ep,*backupep=0;
array = cJSON_CreateArray(); array = cJSON_CreateArray();
if ( coinaddr != 0 && coinaddr[0] != 0 ) if ( coinaddr != 0 && coinaddr[0] != 0 )
{ {
@ -350,11 +358,20 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum
{ {
if ( up->spendheight <= 0 && up->U.height > 0 ) if ( up->spendheight <= 0 && up->U.height > 0 )
{ {
if ( backupep != 0 && up->SPV == 0 ) if ( coin->electrum == 0 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); {
jaddi(array,LP_address_item(coin,up,electrumret)); if ( (txobj= LP_gettxout(coin->symbol,coinaddr,up->U.txid,up->U.vout)) == 0 )
n++; up->spendheight = 1;
total += up->U.value; else free_json(txobj);
}
if ( up->spendheight <= 0 )
{
if ( backupep != 0 && up->SPV == 0 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
jaddi(array,LP_address_item(coin,up,electrumret));
n++;
total += up->U.value;
}
//printf("new array %s\n",jprint(array,0)); //printf("new array %s\n",jprint(array,0));
} }
} }

16
iguana/exchanges/LP_utxos.c

@ -345,7 +345,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t
} }
if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 ) if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 )
{ {
printf("LP_utxoadd reject2 numconfirms.%d\n",numconfirms); printf("LP_utxoadd reject2 numconfirms.%d %s %s/v%d\n",numconfirms,symbol,bits256_str(str,txid2),vout2);
return(0); return(0);
} }
} }
@ -472,7 +472,7 @@ cJSON *LP_inventory(char *symbol)
// LP_utxo_clientpublish(utxo); // LP_utxo_clientpublish(utxo);
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
} }
else if ( LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 ) else if ( 0 && LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 )
printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0);
} }
return(array); return(array);
@ -512,9 +512,9 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
{ {
int32_t enable_utxos = 0; int32_t enable_utxos = 0;
char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,depositval,value,total = 0; int64_t targetval; char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,depositval,value,total = 0; int64_t targetval;
if ( coin == 0 || coin->inactive != 0 ) if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
{ {
printf("coin not active\n"); //printf("coin not active\n");
return(0); return(0);
} }
//printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); //printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr);
@ -654,10 +654,12 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
return(flag); return(flag);
} }
char *LP_secretaddresses(void *ctx,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype) char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype)
{ {
int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson; int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson;
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
if ( prefix == 0 || prefix[0] == 0 )
prefix = "secretaddress";
if ( passphrase == 0 || passphrase[0] == 0 ) if ( passphrase == 0 || passphrase[0] == 0 )
passphrase = "password"; passphrase = "password";
if ( n <= 0 ) if ( n <= 0 )
@ -670,7 +672,7 @@ char *LP_secretaddresses(void *ctx,char *passphrase,int32_t n,uint8_t taddr,uint
sprintf(output,"\"addresses\":["); sprintf(output,"\"addresses\":[");
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
sprintf(buf,"secretaddress %s %03d",passphrase,i); sprintf(buf,"%s %s %03d",prefix,passphrase,i);
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf)); conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype);
bitcoin_priv2wif(0,wifstr,privkey,188); bitcoin_priv2wif(0,wifstr,privkey,188);
@ -781,7 +783,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
} }
//printf("i.%d of %d\n",i,LP_numcoins); //printf("i.%d of %d\n",i,LP_numcoins);
else if ( coin->inactive == 0 ) else if ( IAMLP == 0 || coin->inactive == 0 )
{ {
if ( LP_privkey_init(pubsock,coin,G.LP_mypriv25519,G.LP_mypub25519) == 0 && (rand() % 10) == 0 ) if ( LP_privkey_init(pubsock,coin,G.LP_mypriv25519,G.LP_mypub25519) == 0 && (rand() % 10) == 0 )
LP_postutxos(coin->symbol,coin->smartaddr); LP_postutxos(coin->symbol,coin->smartaddr);

1
iguana/exchanges/enable

@ -1,3 +1,4 @@
#!/bin/bash #!/bin/bash
source userpass source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CHIPS\"}"

3
iguana/exchanges/listunspent

@ -1,3 +1,2 @@
#!/bin/bash
source userpass source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"listunspent\",\"coin\":\"BTC\",\"address\":\"1DPDsPCNNCF5SHhPPrddXcJe78rM6CBcH3\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"listunspent\",\"coin\":\"CHIPS\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}"

2
iguana/exchanges/mm.c

@ -886,7 +886,7 @@ int main(int argc, const char * argv[])
{ {
printf("error launching LP_main (%s)\n",jprint(retjson,0)); printf("error launching LP_main (%s)\n",jprint(retjson,0));
exit(-1); exit(-1);
} else printf("(%s) launched.(%s)\n",argv[1],passphrase); } //else printf("(%s) launched.(%s)\n",argv[1],passphrase);
incr = 100.; incr = 100.;
while ( (1) ) while ( (1) )
sleep(1); sleep(1);

283
iguana/exchanges/stats.c

@ -556,163 +556,194 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen)
return(recvlen); return(recvlen);
} }
void stats_rpcloop(void *args) uint16_t RPC_port;
extern portable_mutex_t LP_commandmutex;
void LP_rpc_processreq(void *_ptr)
{ {
static char *jsonbuf; uint64_t arg64 = *(uint64_t *)_ptr;
uint16_t port; char filetype[128],content_type[128]; char filetype[128],content_type[128];
int32_t recvlen,flag,bindsock,postflag=0,contentlen,sock,remains,numsent,jsonflag=0,hdrsize,len; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len;
socklen_t clilen; char helpname[512],remoteaddr[64],*buf,*retstr,*space; char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf;
struct sockaddr_in cli_addr; uint32_t ipbits,i,size = 32*IGUANA_MAXPACKETSIZE + 512; uint32_t ipbits,i,size = 32*IGUANA_MAXPACKETSIZE + 512;
if ( (port= *(uint16_t *)args) == 0 ) ipbits = (arg64 >> 32);
port = 7779; expand_ipbits(remoteaddr,ipbits);
if ( jsonbuf == 0 ) sock = (arg64 & 0xffffffff);
jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); recvlen = flag = 0;
while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) retstr = 0;
{
//if ( coin->MAXPEERS == 1 )
// break;
//exit(-1);
sleep(3);
}
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);
space = calloc(1,size); space = calloc(1,size);
while ( bindsock >= 0 ) jsonbuf = calloc(1,size);
remains = size-1;
buf = jsonbuf;
while ( remains > 0 )
{ {
clilen = sizeof(cli_addr); //printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen);
sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 )
if ( sock < 0 )
{
//printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno));
continue;
}
memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits));
expand_ipbits(remoteaddr,ipbits);
//printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits);
memset(jsonbuf,0,IGUANA_MAXPACKETSIZE);
remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1);
buf = jsonbuf;
recvlen = flag = 0;
retstr = 0;
while ( remains > 0 )
{ {
//printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen); if ( errno == EAGAIN )
if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 )
{ {
if ( errno == EAGAIN ) printf("EAGAIN for len %d, remains.%d\n",len,remains);
{ usleep(10000);
printf("EAGAIN for len %d, remains.%d\n",len,remains);
usleep(10000);
}
break;
} }
else break;
}
else
{
if ( len > 0 )
{ {
if ( len > 0 ) buf[len] = 0;
if ( recvlen == 0 )
{ {
buf[len] = 0; if ( (contentlen= iguana_getcontentlen(buf,recvlen)) > 0 )
if ( recvlen == 0 )
{ {
if ( (contentlen= iguana_getcontentlen(buf,recvlen)) > 0 ) hdrsize = iguana_getheadersize(buf,recvlen);
if ( hdrsize > 0 )
{ {
hdrsize = iguana_getheadersize(buf,recvlen); if ( len < (hdrsize + contentlen) )
if ( hdrsize > 0 )
{ {
if ( len < (hdrsize + contentlen) ) remains = (hdrsize + contentlen) - len;
{ buf = &buf[len];
remains = (hdrsize + contentlen) - len; flag = 1;
buf = &buf[len]; //printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len);
flag = 1; continue;
//printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len);
continue;
}
} }
} }
} }
recvlen += len;
remains -= len;
buf = &buf[len];
if ( flag == 0 || remains <= 0 )
break;
}
else
{
usleep(10000);
//printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len);
//retstr = iguana_rpcparse(space,size,&postflag,jsonbuf);
if ( flag == 0 )
break;
} }
recvlen += len;
remains -= len;
buf = &buf[len];
if ( flag == 0 || remains <= 0 )
break;
} }
} else
content_type[0] = 0;
if ( recvlen > 0 )
{
retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,port);
if ( filetype[0] != 0 )
{ {
static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; usleep(10000);
sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR); //printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len);
if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 ) //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf);
{ if ( flag == 0 )
mimejson = cJSON_Parse(tmp); break;
free(tmp);
}
if ( mimejson != 0 )
{
if ( (typestr= jstr(mimejson,filetype)) != 0 )
sprintf(content_type,"Content-Type: %s\r\n",typestr);
} else printf("parse error.(%s)\n",tmp);
//printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type);
} }
} }
if ( retstr != 0 ) }
content_type[0] = 0;
if ( recvlen > 0 )
{
jsonflag = postflag = 0;
portable_mutex_lock(&LP_commandmutex);
retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port);
//if ( strcmp("5.9.253.195",remoteaddr) == 0 )
// printf("RPC.(%s)%s\n",jsonbuf,retstr);
portable_mutex_unlock(&LP_commandmutex);
if ( filetype[0] != 0 )
{ {
char *response,hdrs[1024]; static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize;
//printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR);
if ( jsonflag != 0 || postflag != 0 ) if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 )
{ {
if ( retstr == 0 ) mimejson = cJSON_Parse(tmp);
retstr = clonestr("{}"); free(tmp);
response = malloc(strlen(retstr)+1024+1+1);
sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr));
response[0] = '\0';
strcat(response,hdrs);
strcat(response,retstr);
strcat(response,"\n");
if ( retstr != space )
free(retstr);
retstr = response;
//printf("RET.(%s)\n",retstr);
} }
remains = (int32_t)strlen(retstr); if ( mimejson != 0 )
i = 0;
while ( remains > 0 )
{ {
if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) if ( (typestr= jstr(mimejson,filetype)) != 0 )
{ sprintf(content_type,"Content-Type: %s\r\n",typestr);
if ( errno != EAGAIN && errno != EWOULDBLOCK ) } else printf("parse error.(%s)\n",tmp);
{ //printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type);
//printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); }
break; }
} if ( retstr != 0 )
} {
else if ( remains > 0 ) char *response,hdrs[1024];
//printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag);
if ( jsonflag != 0 || postflag != 0 )
{
if ( retstr == 0 )
retstr = clonestr("{}");
response = malloc(strlen(retstr)+1024+1+1);
sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr));
response[0] = '\0';
strcat(response,hdrs);
strcat(response,retstr);
strcat(response,"\n");
if ( retstr != space )
free(retstr);
retstr = response;
//printf("RET.(%s)\n",retstr);
}
remains = (int32_t)strlen(retstr);
i = 0;
while ( remains > 0 )
{
if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 )
{
if ( errno != EAGAIN && errno != EWOULDBLOCK )
{ {
remains -= numsent; //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock);
i += numsent; break;
if ( remains > 0 )
printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen);
} }
} }
if ( retstr != space) else if ( remains > 0 )
free(retstr); {
remains -= numsent;
i += numsent;
if ( remains > 0 )
printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen);
}
}
if ( retstr != space)
free(retstr);
}
free(space);
free(jsonbuf);
closesocket(sock);
}
void stats_rpcloop(void *args)
{
uint16_t port; int32_t sock,bindsock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint64_t arg64; void *arg64ptr;
if ( (port= *(uint16_t *)args) == 0 )
port = 7779;
RPC_port = port;
while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 )
{
//if ( coin->MAXPEERS == 1 )
// break;
//exit(-1);
sleep(3);
}
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);
while ( bindsock >= 0 )
{
clilen = sizeof(cli_addr);
sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen);
if ( sock < 0 )
{
//printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno));
continue;
} }
closesocket(sock); memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits));
//printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits);
arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff);
arg64ptr = malloc(sizeof(arg64));
memcpy(arg64ptr,&arg64,sizeof(arg64));
if ( 1 )
{
LP_rpc_processreq((void *)&arg64);
free(arg64ptr);
}
else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 )
{
printf("error launching rpc handler on port %d\n",port);
}
// yes, small leak per command
} }
} }
#ifndef FROM_MARKETMAKER #ifndef FROM_MARKETMAKER
portable_mutex_t LP_commandmutex;
void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timestamp,char *key,cJSON *kvjson,bits256 pubkey,bits256 sigprev) void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timestamp,char *key,cJSON *kvjson,bits256 pubkey,bits256 sigprev)
{ {
struct tai T; int32_t seconds,datenum,n; struct tai T; int32_t seconds,datenum,n;

Loading…
Cancel
Save