Browse Source

Merge pull request #451 from jl777/spvdex

Spvdex
etomic
jl777 7 years ago
committed by GitHub
parent
commit
233e0b7c51
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      crypto777/OS_portable.h
  2. 171
      iguana/exchanges/LP_commands.c
  3. 7
      iguana/exchanges/LP_include.h
  4. 149
      iguana/exchanges/LP_nativeDEX.c
  5. 11
      iguana/exchanges/LP_network.c
  6. 4
      iguana/exchanges/LP_ordermatch.c
  7. 81
      iguana/exchanges/LP_peers.c
  8. 4
      iguana/exchanges/LP_prices.c
  9. 84
      iguana/exchanges/LP_rpc.c
  10. 7
      iguana/exchanges/LP_signatures.c
  11. 221
      iguana/exchanges/LP_statemachine.c
  12. 7
      iguana/exchanges/LP_transaction.c
  13. 2
      iguana/exchanges/mm.c
  14. 52
      iguana/exchanges/stats.c

1
crypto777/OS_portable.h

@ -149,6 +149,7 @@ struct rpcrequest_info
pthread_t T;
int32_t sock;
uint32_t ipbits;
uint16_t port,pad;
};
struct OS_mappedptr

171
iguana/exchanges/LP_commands.c

@ -34,10 +34,10 @@ char *LP_numutxos()
char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port
{
char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport=0,pushport,subport; int32_t changed,otherpeers,flag = 0; struct LP_peerinfo *peer; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr;
char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr;
//printf("stats_JSON(%s)\n",jprint(argjson,0));
method = jstr(argjson,"method");
if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) )
/*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) )
{
if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 )
{
@ -50,23 +50,18 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
{
if ( 0 && (otherpeers= jint(argjson,"numpeers")) > peer->numpeers )
peer->numpeers = otherpeers;
/*if ( 0 && (othernumutxos= jint(argjson,"numutxos")) > peer->numutxos )
{
printf("change.(%s) numutxos.%d -> %d mynumutxos.%d\n",peer->ipaddr,peer->numutxos,othernumutxos,LP_mypeer != 0 ? LP_mypeer->numutxos:0);
peer->numutxos = othernumutxos;
}*/
if ( peer->sessionid == 0 )
peer->sessionid = juint(argjson,"session");
//printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0));
} else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jint(argjson,"numpeers"),jint(argjson,"numutxos"),juint(argjson,"session"));
}
}
}*/
if ( method == 0 )
{
if ( is_cJSON_Array(argjson) != 0 )
printf("RAWARRAY command? %s\n",jprint(argjson,0));
if ( flag == 0 || jobj(argjson,"result") != 0 )
printf("stats_JSON no method: (%s) (%s:%u)\n",jprint(argjson,0),ipaddr,argport);
printf("stats_JSON no method: (%s)\n",jprint(argjson,0));
return(0);
}
if ( strcmp(method,"hello") == 0 )
@ -74,7 +69,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
//printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport);
return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}"));
}
else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 )
/*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 )
{
static char *laststr;
char *newstr; bits256 pubkey = jbits256(argjson,"pubkey");
@ -91,7 +86,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
retstr = clonestr(laststr);
}
} else retstr = clonestr("{\"error\":\"duplicate message\"}");
}
}*/
//else if ( strcmp(method,"nn_tests") == 0 )
// return(clonestr("{\"result\":\"success\"}"));
else if ( strcmp(method,"help") == 0 )
@ -132,9 +127,9 @@ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\
balance(coin, address)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
getmessages(firsti=0, num=100)\n\
deletemessages(firsti=0, num=100)\n\
//sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
//getmessages(firsti=0, num=100)\n\
//deletemessages(firsti=0, num=100)\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
electrum(coin, ipaddr, port)\n\
snapshot(coin, height)\n\
@ -186,7 +181,7 @@ bot_resume(botid)\n\
return(jprint(retjson,1));
}
}
else if ( strcmp(method,"sendmessage") == 0 )
/*else if ( strcmp(method,"sendmessage") == 0 )
{
if ( jobj(argjson,"method2") == 0 )
{
@ -194,6 +189,17 @@ bot_resume(botid)\n\
}
return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"getmessages") == 0 )
{
if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 )
return(jprint(retjson,1));
else return(clonestr("{\"error\":\"null messages\"}"));
}
else if ( strcmp(method,"deletemessages") == 0 )
{
LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num"));
return(clonestr("{\"result\":\"success\"}"));
}*/
else if ( strcmp(method,"recentswaps") == 0 )
{
return(LP_recent_swaps(jint(argjson,"limit")));
@ -208,17 +214,12 @@ bot_resume(botid)\n\
LP_millistats_update(0);
return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"getmessages") == 0 )
{
if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 )
return(jprint(retjson,1));
else return(clonestr("{\"error\":\"null messages\"}"));
}
else if ( strcmp(method,"deletemessages") == 0 )
{
LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num"));
return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"getprices") == 0 )
return(LP_prices());
else if ( strcmp(method,"getpeers") == 0 )
return(LP_peers());
else if ( strcmp(method,"getcoins") == 0 )
return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"notarizations") == 0 )
{
int32_t height,bestheight;
@ -290,8 +291,20 @@ bot_resume(botid)\n\
}
else if ( strcmp(method,"pricearray") == 0 )
{
return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
}
/*else if ( strcmp(method,"pricearray") == 0 )
{
return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}*/
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"myprice") == 0 )
{
if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL )
@ -370,6 +383,41 @@ bot_resume(botid)\n\
return(jprint(array,1));
} else return(clonestr("{\"error\":\"couldnt find coin\"}"));
}
else if ( strcmp(method,"listunspent") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
char *coinaddr;
if ( (coinaddr= jstr(argjson,"address")) != 0 )
{
if ( coinaddr[0] != 0 )
{
LP_address(ptr,coinaddr);
LP_listunspent_issue(coin,coinaddr,1);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 )
{
//printf("network invoked\n");
LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
//LP_smartutxos_push(ptr);
if ( ptr->electrum != 0 )
return(LP_unspents_filestr(coin,ptr->smartaddr));
else return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
}
else
{
return(clonestr("{\"error\":\"not my address\"}"));
}
}
return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
} else return(clonestr("{\"error\":\"no address specified\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"balance") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1));
else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"electrum") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
@ -495,39 +543,29 @@ bot_resume(botid)\n\
return(LP_uitem_recv(argjson));
else if ( strcmp(method,"notify") == 0 )
return(LP_notify_recv(argjson));
else if ( strcmp(method,"getpeers") == 0 )
retstr = clonestr("{\"error\":\"deprecated\"}");
/*else if ( strcmp(method,"getpeers") == 0 )
{
char *tmpstr;
if ( (tmpstr= jstr(argjson,"LPnode")) != 0 )
LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,1,G.LP_sessionid);
if ( IAMLP != 0 )
{
printf("send peers list %s\n",LP_peers());
bits256 zero; memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(0,"","",zero,LP_peers());
}
retstr = clonestr("{\"result\":\"success\"}");
}*/
// end received response
// public access, even from http
else if ( strcmp(method,"tradestatus") == 0 )
{
LP_tradecommand_log(argjson);
printf("GOT TRADESTATUS! %s\n",jprint(argjson,0));
retstr = clonestr("{\"result\":\"success\"}");
}
else if ( strcmp(method,"balance") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1));
else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"pricearray") == 0 )
{
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
}
else if ( strcmp(method,"getprices") == 0 )
return(LP_prices());
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"getpeers") == 0 )
return(LP_peers());
else if ( strcmp(method,"getcoins") == 0 )
return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"wantnotify") == 0 )
{
bits256 pub; static uint32_t lastnotify;
@ -541,35 +579,6 @@ bot_resume(botid)\n\
}
retstr = clonestr("{\"result\":\"success\"}");
}
else if ( strcmp(method,"listunspent") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
char *coinaddr;
if ( (coinaddr= jstr(argjson,"address")) != 0 )
{
if ( coinaddr[0] != 0 )
{
LP_address(ptr,coinaddr);
LP_listunspent_issue(coin,coinaddr,1);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 )
{
//printf("network invoked\n");
LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
//LP_smartutxos_push(ptr);
if ( ptr->electrum != 0 )
return(LP_unspents_filestr(coin,ptr->smartaddr));
else return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
}
else
{
return(clonestr("{\"error\":\"not my address\"}"));
}
}
return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
} else return(clonestr("{\"error\":\"no address specified\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"addr_unspents") == 0 )
{
//printf("GOT ADDR_UNSPENTS %s %s\n",jstr(argjson,"coin"),jstr(argjson,"address"));

7
iguana/exchanges/LP_include.h

@ -34,7 +34,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#endif
//#define LP_STRICTPEERS
#define LP_BARTERDEX_VERSION 0
#define LP_BARTERDEX_VERSION 1
#define LP_MAGICBITS 8
#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL)
@ -59,7 +59,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_COMMAND_RECVSOCK NN_PULL
#define DPOW_MIN_ASSETCHAIN_SIGS 11
#define LP_ENCRYPTED_MAXSIZE (4096 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES)
#define LP_ENCRYPTED_MAXSIZE (16384 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES)
#define LP_MAXPUBKEY_ERRORS 10
#define PSOCK_KEEPALIVE 3600
@ -314,7 +314,7 @@ struct LP_peerinfo
UT_hash_handle hh;
uint64_t ip_port;
uint32_t ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid;
int32_t pushsock,subsock;
int32_t pushsock,subsock,isLP;
uint16_t port;
char ipaddr[64];
};
@ -425,6 +425,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr);
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag);
uint16_t LP_randpeer(char *destip);
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired);
char *LP_unspents_filestr(char *symbol,char *addr);
cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
//int32_t LP_butxo_findeither(bits256 txid,int32_t vout);

149
iguana/exchanges/LP_nativeDEX.c

@ -333,6 +333,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 )
{
methodstr[0] = 0;
//printf("%s.(%s)\n",typestr,(char *)ptr);
if ( 0 )
{
cJSON *recvjson; char *mstr;//,*cstr;
@ -448,7 +449,7 @@ void command_rpcloop(void *myipaddr)
void utxosQ_loop(void *myipaddr)
{
strcpy(utxosQ_loop_stats.name,"utxosQ_loop");
utxosQ_loop_stats.threshold = 150.;
utxosQ_loop_stats.threshold = 500.;
while ( 1 )
{
LP_millistats_update(&utxosQ_loop_stats);
@ -457,89 +458,6 @@ void utxosQ_loop(void *myipaddr)
}
}
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; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2;
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
return(0);
HASH_ITER(hh,LP_coins,coin,ctmp)
{
if ( IAMLP == 0 && coin->inactive != 0 )
continue;
if ( coin->smartaddr[0] == 0 )
continue;
total = 0;
if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 )
continue;
if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
total += j64bits(item,"value");
}
}
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;
if ( (array2= cJSON_Parse(retstr)) != 0 )
{
if ( (m= cJSON_GetArraySize(array2)) > 0 )
{
for (i=0; i<m; i++)
{
item2 = jitem(array2,i);
total2 += j64bits(item2,"value");
}
}
if ( total != total2 || n != m )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
txid = jbits256(item,"tx_hash");
v = jint(item,"tx_pos");
for (j=0; j<m; j++)
{
if ( v == jint(jitem(array2,i),"tx_pos") && bits256_cmp(txid,jbits256(jitem(array2,i),"tx_hash")) == 0 )
break;
}
if ( j == m )
{
//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 )
free(retstr2);
posted++;
}
}
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);
} //else printf("%s matches %s\n",peer->ipaddr,coin->symbol);
free_json(array2);
} else printf("parse error (%s)\n",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);
}
}
return(posted);
}
void LP_coinsloop(void *_coins)
{
struct LP_address *ap=0,*atmp; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
@ -656,7 +574,7 @@ void LP_coinsloop(void *_coins)
continue;
}
nonz++;
if ( coin->lastscanht < coin->longestchain-3 )
if ( 0 && coin->lastscanht < coin->longestchain-3 )
printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
for (j=0; j<100; j++)
{
@ -679,14 +597,15 @@ void LP_coinsloop(void *_coins)
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport)
{
static uint32_t counter,numpeers;
struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t needpings,height,nonz = 0;
now = (uint32_t)time(NULL);
static uint32_t counter;//,numpeers;
struct iguana_info *coin,*ctmp; char *origipaddr; int32_t height,nonz = 0;//struct LP_peerinfo *peer,*tmp; uint32_t now;
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
if ( mypeer == 0 )
myipaddr = "127.0.0.1";
numpeers = LP_numpeers();
/*
now = (uint32_t)time(NULL);
numpeers = LP_numpeers();
needpings = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
@ -706,10 +625,11 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
{
nonz++;
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport);
peer->diduquery = 0;
LP_peer_pricesquery(peer);
LP_utxos_sync(peer);
//issue_LP_getpeers(peer->ipaddr,peer->port);
//LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport);
//if ( peer->diduquery == 0 )
// LP_peer_pricesquery(peer);
//LP_utxos_sync(peer);
needpings++;
}
peer->lastpeers = now;
@ -723,7 +643,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
peer->needping = 0;
needpings++;
}
}
}*/
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION )
@ -786,12 +706,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
printf("privkey updates\n");
}
void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode)
void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode,uint16_t pushport,uint16_t subport)
{
int32_t i,j; uint32_t r;
if ( IAMLP != 0 )
{
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,G.LP_sessionid);
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,G.LP_sessionid);
if ( myipaddr == 0 || mypeer == 0 )
{
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
@ -801,11 +721,9 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
{
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{
//if ( (rand() % 100) > 25 )
// continue;
LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport);
LP_addpeer(mypeer,pubsock,default_LPnodes[i],myport,pushport,subport,0,G.LP_sessionid);
}
} else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport);
} else LP_addpeer(mypeer,pubsock,seednode,myport,pushport,subport,0,G.LP_sessionid);
}
else
{
@ -816,13 +734,16 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
}
if ( seednode == 0 || seednode[0] == 0 )
{
LP_addpeer(mypeer,pubsock,"5.9.253.195",myport,pushport,subport,0,G.LP_sessionid);
OS_randombytes((void *)&r,sizeof(r));
for (j=0; j<sizeof(default_LPnodes)/sizeof(*default_LPnodes); j++)
{
i = (r + j) % (sizeof(default_LPnodes)/sizeof(*default_LPnodes));
LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport);
LP_addpeer(mypeer,pubsock,default_LPnodes[i],myport,pushport,subport,0,G.LP_sessionid);
//issue_LP_getpeers(default_LPnodes[i],myport);
//LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport);
}
} else LP_peersquery(mypeer,pubsock,seednode,myport,"127.0.0.1",myport);
} else LP_addpeer(mypeer,pubsock,seednode,myport,pushport,subport,0,G.LP_sessionid);
}
}
@ -845,7 +766,7 @@ void LP_pubkeysloop(void *ctx)
coin->lastunspent = (uint32_t)time(NULL);
}
}
if ( time(NULL) > lasttime+60 )
if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 )
{
//printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL));
LP_notify_pubkeys(ctx,LP_mypubsock);
@ -883,7 +804,7 @@ void LP_swapsloop(void *ignore)
//printf("LP_swapsloop %u\n",LP_counter);
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
free(retstr);
LP_millistats_update(0);
//LP_millistats_update(0);
sleep(600);
}
}
@ -1067,7 +988,8 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
LP_mypubsock = pubsock;
}
printf("got %s, initpeers\n",myipaddr);
LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode"));
LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode"),mypullport,mypubport);
RPC_port = myport;
printf("get public socket\n");
LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0);
strcpy(LP_publicaddr,pushaddr);
@ -1115,6 +1037,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
uint16_t myport2 = myport-1;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 )
{
printf("error launching command_rpcloop for port.%u\n",myport);
@ -1165,7 +1093,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
printf("error launching LP_swapsloop for port.%u\n",myport);
exit(-1);
}
int32_t nonz; uint32_t lasthello = 0;
/*char request[128];
if ( IAMLP == 0 )
sprintf(request,"{\"method\":\"getpeers\",\"timestamp\":%u}",(uint32_t)time(NULL));
else sprintf(request,"{\"method\":\"getpeers\",\"LPnode\":\"%s\",\"timestamp\":%u}",myipaddr,(uint32_t)time(NULL));
LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); */
int32_t nonz; //uint32_t lasthello = 0;
while ( 1 )
{
nonz = 0;
@ -1181,7 +1114,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
usleep(1000);
else if ( IAMLP == 0 )
usleep(1000);
if ( IAMLP != 0 && time(NULL) > lasthello+600 )
/*if ( IAMLP != 0 && time(NULL) > lasthello+600 )
{
char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock;
allgood = 0;
@ -1214,7 +1147,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
}
}
}
}
}*/
}
#endif
}

11
iguana/exchanges/LP_network.c

@ -183,7 +183,7 @@ bits256 LP_calc_magic(uint8_t *msg,int32_t len)
sum += (OS_milliseconds() - millis);
nsum += n;
counter++;
if ( n > maxn || (rand() % 100) == 0 )
if ( n > maxn || (rand() % 10000) == 0 )
{
if ( n > maxn )
{
@ -763,15 +763,6 @@ char *LP_psock(char *myipaddr,int32_t ispaired)
both are combined in LP_psock_get
*/
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired)
{
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport,ispaired);
//return(LP_issue_curl("psock",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3);
printf("issue_LP_psock got (%s) from %s\n",retstr,destip);
return(retstr);
}
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired)
{

4
iguana/exchanges/LP_ordermatch.c

@ -859,8 +859,8 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
item = jitem(asks,i);
price = jdouble(item,"price");
if ( price/maxprice < .9 )
price *= 1.025;
else price *= 1.001;
price *= 1.05;
else price *= 1.01;
pubkey = jbits256(item,"pubkey");
if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 )
continue;

81
iguana/exchanges/LP_peers.c

@ -31,7 +31,7 @@ struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port)
cJSON *LP_peerjson(struct LP_peerinfo *peer)
{
cJSON *item = cJSON_CreateObject();
jaddstr(item,"ipaddr",peer->ipaddr);
jaddstr(item,"isLP",peer->ipaddr);
jaddnum(item,"port",peer->port);
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
{
@ -49,15 +49,15 @@ char *LP_peers()
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
//if ( peer->errors < LP_MAXPEER_ERRORS )
if ( peer->isLP != 0 )
jaddi(peersjson,LP_peerjson(peer));
}
return(jprint(peersjson,1));
}
struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t numpeers,int32_t numutxos,uint32_t sessionid)
struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t isLP,uint32_t sessionid)
{
uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0;
printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport);
#ifdef LP_STRICTPEERS
if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 )
return(0);
@ -68,6 +68,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
{
if ( (peer= LP_peerfind(ipbits,port)) != 0 )
{
peer->isLP = isLP;
/*if ( numpeers > peer->numpeers )
peer->numpeers = numpeers;
if ( numutxos > peer->numutxos )
@ -77,6 +78,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
}
else
{
printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport);
peer = calloc(1,sizeof(*peer));
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
peer->sessionid = G.LP_sessionid;
@ -145,15 +147,15 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
if ( mypeer != 0 )
{
mypeer->numpeers++;
printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d %d)\n",ipaddr,mypeer->numpeers,mypubsock,numpeers,numutxos);
printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d)\n",ipaddr,mypeer->numpeers,mypubsock,isLP);
} else peer->numpeers = 1; // will become mypeer
portable_mutex_unlock(&LP_peermutex);
if ( IAMLP != 0 && mypubsock >= 0 )
{
struct iguana_info *coin,*ctmp; bits256 zero; char busaddr[64];
memset(zero.bytes,0,sizeof(zero));
struct iguana_info *coin,*ctmp; char busaddr[64]; //
//memset(zero.bytes,0,sizeof(zero));
//LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1);
LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1));
//LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1));
if ( 0 )
{
HASH_ITER(hh,LP_coins,coin,ctmp)
@ -202,71 +204,6 @@ int32_t LP_coinbus(uint16_t coin_busport)
return(bussock);
}
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 numpeers,i,n=0;
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
{
numpeers = LP_numpeers();
if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) )
peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session"));
}
if ( peer != 0 )
{
peer->lasttime = now;
if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n )
peer->numpeers = n;
}
}
}
}
free_json(array);
}
return(n);
}
void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport)
{
char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,mypeer!=0?mypeer->numpeers:0)) != 0 )
{
//printf("got.(%s)\n",retstr);
now = (uint32_t)time(NULL);
LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
if ( IAMLP != 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->lasttime != now )
{
printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now);
flag++;
memset(&zero,0,sizeof(zero));
if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,peer->sessionid,0,zero)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing peers\n");
}
}
}
int32_t LP_numpeers()
{

4
iguana/exchanges/LP_prices.c

@ -314,7 +314,7 @@ char *LP_prices()
return(jprint(array,1));
}
void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
{
struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now;
now = (uint32_t)time(NULL);
@ -382,7 +382,7 @@ void LP_peer_pricesquery(struct LP_peerinfo *peer)
{
//printf("%s needs ping\n",peer->ipaddr);
}
}
}*/
double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout)
{

84
iguana/exchanges/LP_rpc.c

@ -22,10 +22,12 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url)
{
char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destip),port);
if ( strcmp(destip,"127.0.0.1") != 0 )
port--;
maxerrs = LP_MAXPEER_ERRORS;
if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) )
{
//printf("issue.(%s)\n",url);
printf("issue.(%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 )
{
if ( peer != 0 )
@ -49,65 +51,37 @@ char *LP_isitme(char *destip,uint16_t destport)
} else return(0);
}
char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers)
void LP_peer_request(char *destip,uint16_t destport,cJSON *argjson)
{
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers);
retstr = LP_issue_curl("getpeers",destip,port,url);
//printf("%s -> getpeers.(%s)\n",destip,retstr);
return(retstr);
struct LP_peerinfo *peer; uint8_t *msg; int32_t msglen; uint32_t crc32;
peer = LP_peerfind((uint32_t)calc_ipbits(destip),destport);
msg = (void *)jprint(argjson,0);
msglen = (int32_t)strlen((char *)msg) + 1;
crc32 = calc_crc32(0,&msg[2],msglen - 2);
LP_queuesend(crc32,peer->pushsock,"","",msg,msglen);
free_json(argjson);
}
char *issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t height,uint64_t value)
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired)
{
char url[512],*retstr,str[65];
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
sprintf(url,"http://%s:%u/api/stats/uitem?coin=%s&coinaddr=%s&txid=%s&vout=%d&ht=%d&value=%llu",destip,destport,symbol,coinaddr,bits256_str(str,txid),vout,height,(long long)value);
retstr = LP_issue_curl("uitem",destip,destport,url);
//printf("uitem.(%s)\n",retstr);
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport-1,ispaired);
//return(LP_issue_curl("psock",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3);
printf("issue_LP_psock got (%s) from %s\n",retstr,destip);
return(retstr);
}
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub)
void issue_LP_getpeers(char *destip,uint16_t destport)
{
char url[512],*retstr,str[65];
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&session=%u",destip,destport,ipaddr,port,numpeers,sessionid);
if ( rmd160str != 0 && bits256_nonz(pub) != 0 )
{
sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub));
//printf("SEND (%s)\n",url);
}
return(LP_issue_curl("notify",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
char *issue_LP_getprices(char *destip,uint16_t destport)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport);
//printf("getutxo.(%s)\n",url);
return(LP_issue_curl("getprices",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
char *issue_hello(uint16_t port)
{
char url[512];
sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port);
//printf("getutxo.(%s)\n",url);
return(issue_curlt(url,600)); // might be starting a trade
}
char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr)
{
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr);
retstr = LP_issue_curl("listunspent",destip,destport,url);
//printf("listunspent.(%s) -> (%s)\n",url,retstr);
return(retstr);
cJSON *reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","getpeers");
LP_peer_request(destip,destport,reqjson);
/*char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers);
retstr = LP_issue_curl("getpeers",destip,port,url);
//printf("%s -> getpeers.(%s)\n",destip,retstr);
return(retstr);*/
}
char *LP_apicall(struct iguana_info *coin,char *method,char *params)
@ -699,7 +673,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr)
int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{
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;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (coin= LP_coinfind(symbol)) != 0 )
@ -724,7 +698,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{
//printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
LP_listunspent_query(coin->symbol,coin->smartaddr);
if ( fullflag != 0 )
/*if ( fullflag != 0 )
{
if ( (destport= LP_randpeer(destip)) > 0 )
{
@ -732,7 +706,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
//printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n");
}
}*/
}
if ( retjson != 0 )
{

7
iguana/exchanges/LP_signatures.c

@ -569,17 +569,22 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock)
timestamp = (uint32_t)time(NULL);
jaddnum(reqjson,"timestamp",timestamp);
LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp);
if ( IAMLP != 0 )
jaddstr(reqjson,"isLP",LP_myipaddr);
jaddnum(reqjson,"session",G.LP_sessionid);
LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
}
char *LP_notify_recv(cJSON *argjson)
{
bits256 pub; struct LP_pubkeyinfo *pubp;
bits256 pub; struct LP_pubkeyinfo *pubp; char *ipaddr;
pub = jbits256(argjson,"pub");
if ( bits256_nonz(pub) != 0 )
{
if ( (pubp= LP_pubkeyadd(pub)) != 0 )
LP_pubkey_sigcheck(pubp,argjson);
if ( (ipaddr= jstr(argjson,"isLP")) != 0 )
LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session"));
//char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str);
}
return(clonestr("{\"result\":\"success\",\"notify\":\"received\"}"));

221
iguana/exchanges/LP_statemachine.c

@ -132,6 +132,227 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil
}*/
return(fp);
}
#ifdef oldway
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 numpeers,i,n=0;
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
{
numpeers = LP_numpeers();
if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) )
peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session"));
}
if ( peer != 0 )
{
peer->lasttime = now;
if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n )
peer->numpeers = n;
}
}
}
}
free_json(array);
}
return(n);
}
void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport)
{
char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,mypeer!=0?mypeer->numpeers:0)) != 0 )
{
//printf("got.(%s)\n",retstr);
now = (uint32_t)time(NULL);
LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
if ( IAMLP != 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->lasttime != now )
{
printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now);
flag++;
memset(&zero,0,sizeof(zero));
if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,peer->sessionid,0,zero)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing peers\n");
}
}
}
void issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub)
{
cJSON *reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","notify");
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"coinaddr",coinaddr);
jaddbits256(reqjson,"txid",txid);
jaddnum(reqjson,"vout",vout);
jaddnum(reqjson,"ht",height);
jadd64bits(reqjson,"value",value);
LP_peer_request(destip,destport,reqjson);
/*char url[512],*retstr,str[65];
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&session=%u",destip,destport,ipaddr,port,numpeers,sessionid);
if ( rmd160str != 0 && bits256_nonz(pub) != 0 )
{
sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub));
//printf("SEND (%s)\n",url);
}
return(LP_issue_curl("notify",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));*/
}
char *issue_hello(uint16_t port)
{
char url[512];
sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port);
//printf("getutxo.(%s)\n",url);
return(issue_curlt(url,600)); // might be starting a trade
}
void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t height,uint64_t value)
{
cJSON *reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","uitem");
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"coinaddr",coinaddr);
jaddbits256(reqjson,"txid",txid);
jaddnum(reqjson,"vout",vout);
jaddnum(reqjson,"ht",height);
jadd64bits(reqjson,"value",value);
LP_peer_request(destip,destport,reqjson);
/*char url[512],*retstr,str[65];
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
sprintf(url,"http://%s:%u/api/stats/uitem?coin=%s&coinaddr=%s&txid=%s&vout=%d&ht=%d&value=%llu",destip,destport,symbol,coinaddr,bits256_str(str,txid),vout,height,(long long)value);
retstr = LP_issue_curl("uitem",destip,destport,url);
//printf("uitem.(%s)\n",retstr);
return(retstr);*/
}
char *issue_LP_getprices(char *destip,uint16_t destport)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport);
//printf("getutxo.(%s)\n",url);
return(LP_issue_curl("getprices",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr)
{
cJSON *reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","listunspent");
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"address",coinaddr);
LP_peer_request(destip,destport,reqjson);
/*char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr);
retstr = LP_issue_curl("listunspent",destip,destport,url);
//printf("listunspent.(%s) -> (%s)\n",url,retstr);
return(retstr);*/
}
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; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2;
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
return(0);
HASH_ITER(hh,LP_coins,coin,ctmp)
{
if ( IAMLP == 0 && coin->inactive != 0 )
continue;
if ( coin->smartaddr[0] == 0 )
continue;
total = 0;
if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 )
continue;
if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
total += j64bits(item,"value");
}
}
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;
if ( (array2= cJSON_Parse(retstr)) != 0 )
{
if ( (m= cJSON_GetArraySize(array2)) > 0 )
{
for (i=0; i<m; i++)
{
item2 = jitem(array2,i);
total2 += j64bits(item2,"value");
}
}
if ( total != total2 || n != m )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
txid = jbits256(item,"tx_hash");
v = jint(item,"tx_pos");
for (j=0; j<m; j++)
{
if ( v == jint(jitem(array2,i),"tx_pos") && bits256_cmp(txid,jbits256(jitem(array2,i),"tx_hash")) == 0 )
break;
}
if ( j == m )
{
//printf("%s missing %s %s\n",peer->ipaddr,coin->symbol,jprint(item,0));
issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"));
posted++;
}
}
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);
} //else printf("%s matches %s\n",peer->ipaddr,coin->symbol);
free_json(array2);
} else printf("parse error (%s)\n",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");
issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"));
}
}
free_json(array);
}
}
return(posted);
}
/*char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo)
{
char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2;

7
iguana/exchanges/LP_transaction.c

@ -922,7 +922,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
if ( dustcombine >= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) )
preselected[numpre++] = min1;
else min1 = 0;
printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents);
printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents,dstr(amount));
for (i=0; i<numunspents+numpre; i++)
{
if ( i < numpre )
@ -962,6 +962,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
up->spendheight = 1;
total += up->U.value;
remains -= up->U.value;
interest = 0;
if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 )
{
if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 )
@ -970,6 +971,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum));
}
}
printf("vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f\n",n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum));
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
@ -1030,6 +1032,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
amount += value;
printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount));
}
else
{
@ -1053,7 +1056,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
suppress_pubkeys = 1;
scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160);
numvins = LP_vins_select(ctx,coin,&total,amount,V,utxos,numutxos,suppress_pubkeys,ignore_cltverr,privkey,privkeys,vins,script,scriptlen,utxotxid,utxovout,dustcombine);
if ( total < amount )
if ( numvins <= 0 || total < amount )
{
printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d, txfee %.8f\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts,dstr(txfee));
printf("not enough inputs for amount %.8f < %.8f txfee %.8f\n",dstr(total),dstr(amount),dstr(txfee));

2
iguana/exchanges/mm.c

@ -869,7 +869,7 @@ void LP_main(void *ptr)
LP_profitratio += profitmargin;
if ( (port= juint(argjson,"rpcport")) < 1000 )
port = LP_RPCPORT;
LPinit(port,LP_RPCPORT+1,LP_RPCPORT+2,LP_RPCPORT+3,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson);
LPinit(port,LP_RPCPORT+10,LP_RPCPORT+20,LP_RPCPORT+30,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson);
}
}

52
iguana/exchanges/stats.c

@ -33,7 +33,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char
char *stats_validmethods[] =
{
"psock", "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_
"orderbook", "help", "getcoins", "pricearray", "balance"
"orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus"
};
int32_t LP_valid_remotemethod(cJSON *argjson)
@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port)
return(-1);
}
}
if ( listen(sock,64) != 0 )
if ( listen(sock,1) != 0 )
{
printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno);
if ( sock >= 0 )
@ -669,7 +669,7 @@ void LP_rpc_processreq(void *_ptr)
{
jsonflag = postflag = 0;
portable_mutex_lock(&LP_commandmutex);
retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port);
retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,req->port);
portable_mutex_unlock(&LP_commandmutex);
if ( filetype[0] != 0 )
{
@ -724,7 +724,7 @@ void LP_rpc_processreq(void *_ptr)
remains -= numsent;
i += numsent;
if ( remains > 0 )
printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen);
printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf);
}
}
if ( retstr != space)
@ -740,41 +740,41 @@ void LP_rpc_processreq(void *_ptr)
}
extern int32_t IAMLP;
int32_t LP_bindsock_reset,LP_bindsock = -1;
//int32_t LP_bindsock_reset,LP_bindsock = -1;
void stats_rpcloop(void *args)
{
uint16_t port; int32_t retval,sock,initial_bindsock_reset; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp;
uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp;
if ( (port= *(uint16_t *)args) == 0 )
port = 7779;
RPC_port = port;
printf("Start stats_rpcloop.%u\n",port);
localhostbits = (uint32_t)calc_ipbits("127.0.0.1");
initial_bindsock_reset = LP_bindsock_reset;
while ( LP_bindsock_reset == initial_bindsock_reset )
//initial_bindsock_reset = LP_bindsock_reset;
while ( 1 )//LP_bindsock_reset == initial_bindsock_reset )
{
//printf("LP_bindsock.%d\n",LP_bindsock);
if ( LP_bindsock < 0 )
if ( bindsock < 0 )
{
while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 )
while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 )
usleep(10000);
#ifndef _WIN32
fcntl(LP_bindsock, F_SETFL, fcntl(LP_bindsock, F_GETFL, 0) | O_NONBLOCK);
//fcntl(bindsock, F_SETFL, fcntl(bindsock, F_GETFL, 0) | O_NONBLOCK);
#endif
//if ( counter++ < 1 )
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock);
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);
}
//printf("after LP_bindsock.%d\n",LP_bindsock);
//printf("after sock.%d\n",sock);
clilen = sizeof(cli_addr);
sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen);
#ifdef _WIN32
sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen);
//#ifdef _WIN32
if ( sock < 0 )
{
printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno));
closesocket(LP_bindsock);
LP_bindsock = -1;
printf("iguana_rpcloop ERROR on accept port.%u usock.%d errno %d %s\n",port,sock,errno,strerror(errno));
closesocket(bindsock);
bindsock = -1;
continue;
}
#else
/*#else
if ( sock < 0 )
{
//fprintf(stderr,".");
@ -783,19 +783,25 @@ void stats_rpcloop(void *args)
else usleep(2500);
continue;
}
#endif
#endif*/
memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits));
if ( port == RPC_port && ipbits != localhostbits )
{
closesocket(sock);
continue;
}
req = calloc(1,sizeof(*req));
req->sock = sock;
req->ipbits = ipbits;
req->port = port;
LP_rpc_processreq(req);
continue;
// this leads to cant open file errors
if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 )
{
printf("error launching rpc handler on port %d, retval.%d\n",port,retval);
closesocket(LP_bindsock);
LP_bindsock = -1;
closesocket(sock);
sock = -1;
portable_mutex_lock(&LP_gcmutex);
DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp)
{

Loading…
Cancel
Save