You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

744 lines
28 KiB

8 years ago
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//alice only coins GAME UNO BTM ANC: GAME BTCD PPC RDD XZC POT EAC FTC BASH SPR WDC UNO XPM XCN BELA CHC DIME MEC NAUT MED AUR MAX DGC RIC EB3 DOT BTM GEO ANC CANN ICASH WBB SRC PTC ADZ TIPS EQT START EFL FST FJC NYC GCN
8 years ago
//
8 years ago
// LP_nativeDEX.c
8 years ago
// marketmaker
//
8 years ago
// new features:
8 years ago
// bittrex balancing
8 years ago
// detect port conflicts on enable
8 years ago
// stats
7 years ago
// dynamic txid2 allocation
8 years ago
8 years ago
// unduplicated bugs:
8 years ago
// swap cancel should cleanly cancel
8 years ago
#include <stdio.h>
8 years ago
#include "LP_include.h"
7 years ago
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex;
8 years ago
int32_t LP_canbind;
7 years ago
char *Broadcaststr;
8 years ago
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
8 years ago
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
8 years ago
#include "LP_network.c"
8 years ago
8 years ago
char *activecoins[] = { "BTC", "KMD" };
8 years ago
char GLOBAL_DBDIR[] = { "DB" };
7 years ago
char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" };
8 years ago
char LP_gui[16] = { "cli" };
8 years ago
8 years ago
char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", };//"5.9.253.204" }; //
8 years ago
8 years ago
//uint32_t LP_deadman_switch;
8 years ago
uint16_t LP_fixed_pairport,LP_publicport;
8 years ago
int32_t LP_mybussock = -1;
8 years ago
int32_t LP_mypubsock = -1;
8 years ago
int32_t LP_mypullsock = -1;
7 years ago
int32_t LP_showwif,IAMLP = 0;
8 years ago
double LP_profitratio = 1.;
7 years ago
struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; };
struct LP_globals
{
struct LP_utxoinfo *LP_utxoinfos,*LP_utxoinfos2;
bits256 LP_mypub25519,LP_mypriv25519;
7 years ago
uint8_t LP_myrmd160[20],LP_pubsecp[33];
7 years ago
uint32_t LP_sessionid,counter;
int32_t LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting;
char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41];
struct LP_privkey LP_privkeys[100];
} G;
8 years ago
8 years ago
// stubs
8 years ago
void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob)
{
}
void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume)
{
// add to trades
}
8 years ago
8 years ago
char *LP_getdatadir()
{
8 years ago
return(USERHOME);
8 years ago
}
8 years ago
8 years ago
char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
return(0);
}
8 years ago
#include "LP_socket.c"
8 years ago
#include "LP_secp.c"
#include "LP_bitcoin.c"
8 years ago
#include "LP_coins.c"
#include "LP_rpc.c"
7 years ago
#include "LP_utxo.c"
7 years ago
#include "LP_prices.c"
8 years ago
#include "LP_scan.c"
8 years ago
#include "LP_transaction.c"
#include "LP_remember.c"
#include "LP_swap.c"
8 years ago
#include "LP_peers.c"
#include "LP_utxos.c"
8 years ago
#include "LP_forwarding.c"
8 years ago
#include "LP_ordermatch.c"
8 years ago
#include "LP_portfolio.c"
8 years ago
#include "LP_messages.c"
8 years ago
#include "LP_commands.c"
8 years ago
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
8 years ago
{
char *retstr=0;
8 years ago
if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 )
return(0);
8 years ago
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 )
8 years ago
{
8 years ago
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 )
8 years ago
{
8 years ago
//printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr);
8 years ago
//if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 &&
//LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0);
8 years ago
}
7 years ago
} //else printf("finished tradecommand (%s)\n",jprint(argjson,0));
8 years ago
return(retstr);
}
8 years ago
char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
{
uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES],*nonce,*cipher; int32_t recvlen,cipherlen; char *jsonstr = 0;
recvlen = *recvlenp;
nonce = &ptr[2];
cipher = &ptr[2 + crypto_box_NONCEBYTES];
cipherlen = recvlen - (2 + crypto_box_NONCEBYTES);
8 years ago
if ( cipherlen > 0 && cipherlen <= sizeof(decoded) )
8 years ago
{
7 years ago
if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,G.LP_mypriv25519)) != 0 )
8 years ago
{
recvlen = (cipherlen - crypto_box_ZEROBYTES);
if ( strlen(jsonstr)+1 != recvlen )
{
printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen);
jsonstr = 0;
} else printf("decrypted (%s)\n",jsonstr);
}
} else printf("cipher.%d too big for %d\n",cipherlen,(int32_t)sizeof(decoded));
*recvlenp = recvlen;
return(jsonstr);
}
8 years ago
char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,uint8_t *ptr,int32_t recvlen,int32_t recvsock)
8 years ago
{
8 years ago
static uint32_t dup,uniq;
8 years ago
int32_t i,len,cipherlen,datalen=0,duplicate=0,encrypted=0; char *method,*method2,*tmp,*cipherstr,*retstr=0,*jsonstr=0; cJSON *argjson; uint32_t crc32;
8 years ago
crc32 = calc_crc32(0,&ptr[2],recvlen-2);
if ( (crc32 & 0xff) == ptr[0] && ((crc32>>8) & 0xff) == ptr[1] )
encrypted = 1;
8 years ago
portable_mutex_lock(&LP_commandmutex);
8 years ago
i = LP_crc32find(&duplicate,-1,crc32);
8 years ago
if ( duplicate != 0 )
dup++;
else uniq++;
8 years ago
if ( (rand() % 1000) == 0 )
7 years ago
printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff);
8 years ago
if ( duplicate == 0 )
{
8 years ago
if ( i >= 0 )
LP_crc32find(&duplicate,i,crc32);
8 years ago
if ( encrypted != 0 )
8 years ago
jsonstr = LP_decrypt(ptr,&recvlen);
8 years ago
else if ( (datalen= is_hexstr((char *)ptr,0)) > 0 )
{
datalen >>= 1;
jsonstr = malloc(datalen + 1);
decode_hex((void *)jsonstr,datalen,(char *)ptr);
jsonstr[datalen] = 0;
} else jsonstr = (char *)ptr;
if ( jsonstr != 0 && (argjson= cJSON_Parse(jsonstr)) != 0 )
{
8 years ago
uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES];
8 years ago
//printf("[%s]\n",jsonstr);
8 years ago
cipherlen = 0;
8 years ago
if ( (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 )
{
8 years ago
method2 = jstr(argjson,"method2");
if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 0)) )
8 years ago
{
cipherlen >>= 1;
decode_hex(decoded,cipherlen,cipherstr);
crc32 = calc_crc32(0,&decoded[2],cipherlen-2);
8 years ago
if ( (tmp= LP_decrypt(decoded,&cipherlen)) != 0 )
8 years ago
{
8 years ago
jsonstr = tmp;
free_json(argjson);
8 years ago
argjson = cJSON_Parse(jsonstr);
8 years ago
recvlen = cipherlen;
8 years ago
encrypted = 1;
if ( (crc32 & 0xff) == decoded[0] && ((crc32>>8) & 0xff) == decoded[1] )
{
i = LP_crc32find(&duplicate,-1,crc32);
if ( duplicate == 0 && i >= 0 )
LP_crc32find(&duplicate,i,crc32);
}
printf("%02x %02x %08x duplicate.%d decrypted.(%s)\n",decoded[0],decoded[1],crc32,duplicate,jsonstr);
8 years ago
}
else
{
8 years ago
printf("packet not for this node %u\n",crc32);
8 years ago
}
8 years ago
} else printf("error (%s) method is %s\n",jsonstr,method);
8 years ago
}
8 years ago
if ( jsonstr != 0 && argjson != 0 )
8 years ago
{
8 years ago
len = (int32_t)strlen(jsonstr) + 1;
if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 )
{
}
free_json(argjson);
8 years ago
}
}
8 years ago
} //else printf("DUPLICATE.(%s)\n",(char *)ptr);
8 years ago
portable_mutex_unlock(&LP_commandmutex);
8 years ago
if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 )
8 years ago
free(jsonstr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
8 years ago
return(retstr);
8 years ago
}
7 years ago
int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr)
8 years ago
{
7 years ago
int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr; char *retstr,*str; struct nn_pollfd pfd;
8 years ago
if ( sock >= 0 )
{
7 years ago
while ( nonz < 100 && recvlen > 0 )
8 years ago
{
8 years ago
memset(&pfd,0,sizeof(pfd));
8 years ago
pfd.fd = sock;
pfd.events = NN_POLLIN;
7 years ago
if ( nn_poll(&pfd,1,1) != 1 )
8 years ago
break;
8 years ago
if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 )
{
7 years ago
//printf("RECV.(%s)\n",(char *)ptr);
8 years ago
nonz++;
8 years ago
if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 )
8 years ago
free(retstr);
7 years ago
if ( Broadcaststr != 0 )
{
7 years ago
//printf("self broadcast.(%s)\n",Broadcaststr);
7 years ago
str = Broadcaststr;
Broadcaststr = 0;
7 years ago
if ( (argjson= cJSON_Parse(str)) != 0 )
{
7 years ago
if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 )
printf("self.(%s)\n",str);
7 years ago
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
7 years ago
free(retstr);
7 years ago
}
7 years ago
free_json(argjson);
}
7 years ago
free(str);
}
8 years ago
}
}
}
return(nonz);
}
void command_rpcloop(void *myipaddr)
{
7 years ago
int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; void *ctx;
8 years ago
ctx = bitcoin_ctx();
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
while ( 1 )
{
nonz = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->errors >= LP_MAXPEER_ERRORS )
{
7 years ago
if ( (rand() % 10000) == 0 )
8 years ago
peer->errors--;
7 years ago
else
{
7 years ago
//printf("skip %s\n",peer->ipaddr);
7 years ago
continue;
}
8 years ago
}
8 years ago
//printf("check %s pubsock.%d\n",peer->ipaddr,peer->subsock);
7 years ago
nonz += LP_sock_check("PULL",ctx,origipaddr,LP_mypubsock,peer->subsock,peer->ipaddr);
8 years ago
}
8 years ago
/*HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
8 years ago
{
8 years ago
if ( coin->inactive != 0 )
continue;
8 years ago
if ( coin->bussock >= 0 )
nonz += LP_sock_check(coin->symbol,ctx,origipaddr,-1,coin->bussock,LP_profitratio - 1.);
8 years ago
}*/
7 years ago
if ( LP_mypullsock >= 0 )
nonz += LP_sock_check("SUB",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1");
8 years ago
//if ( LP_mybussock >= 0 )
// nonz += LP_sock_check("BUS",ctx,origipaddr,-1,LP_mybussock);
8 years ago
if ( nonz == 0 )
usleep(10000);
}
}
7 years ago
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;
HASH_ITER(hh,LP_coins,coin,ctmp)
{
if ( coin->inactive != 0 )
continue;
total = 0;
LP_listunspent_both(coin->symbol,coin->smartaddr);
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 )
{
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 )
{
7 years ago
//printf("%s missing %s\n",peer->ipaddr,jprint(item,0));
7 years ago
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++;
}
}
7 years ago
if ( 0 && posted != 0 )
7 years ago
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);
free_json(array2);
}
free(retstr);
}
}
if ( (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,"")) != 0 )
{
if ( (array2= cJSON_Parse(retstr)) != 0 )
{
if ( (m= cJSON_GetArraySize(array2)) > 0 )
{
for (j=0; j<m; j++)
{
item = jitem(array2,j);
if ( (coinaddr= jfieldname(item)) != 0 )
{
7 years ago
metric = j64bits(item,"coinaddr");
7 years ago
//printf("(%s) -> %.8f n.%d\n",coinaddr,dstr(metric>>16),(uint16_t)metric);
7 years ago
if ( (ap= LP_addressfind(coin,coinaddr)) == 0 || _LP_unspents_metric(ap->total,ap->n) != metric )
{
7 years ago
if ( ap == 0 || ap->n < (metric & 0xffff) )
7 years ago
{
if ( (retstr2= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coinaddr)) != 0 )
{
if ( (array3= cJSON_Parse(retstr2)) != 0 )
{
LP_unspents_array(coin,coinaddr,array3);
7 years ago
//printf("pulled.(%s)\n",retstr2);
7 years ago
free_json(array3);
}
free(retstr2);
}
7 years ago
} //else printf("wait for %s to pull %d vs %d\n",peer->ipaddr,ap!=0?ap->n:-1,(uint16_t)metric);
7 years ago
}
}
}
}
free_json(array2);
}
7 years ago
//printf("processed.(%s)\n",retstr);
7 years ago
free(retstr);
7 years ago
}
}
return(posted);
}
7 years ago
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport)
8 years ago
{
7 years ago
static uint32_t counter,numpeers;
7 years ago
struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; bits256 zero; int32_t needpings,height,nonz = 0;
8 years ago
now = (uint32_t)time(NULL);
8 years ago
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
if ( mypeer == 0 )
8 years ago
myipaddr = "127.0.0.1";
8 years ago
numpeers = LP_numpeers();
7 years ago
needpings = 0;
8 years ago
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
8 years ago
if ( peer->errors >= LP_MAXPEER_ERRORS )
8 years ago
{
8 years ago
if ( (rand() % 10000) == 0 )
8 years ago
{
8 years ago
peer->errors--;
7 years ago
if ( peer->errors < LP_MAXPEER_ERRORS )
peer->diduquery = 0;
8 years ago
}
8 years ago
if ( IAMLP == 0 )
continue;
8 years ago
}
7 years ago
if ( now > peer->lastpeers+60 && peer->numpeers > 0 && (peer->numpeers != numpeers || (rand() % 1000) == 0) )
8 years ago
{
peer->lastpeers = now;
8 years ago
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
7 years ago
{
8 years ago
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport);
7 years ago
peer->diduquery = 0;
7 years ago
LP_utxos_sync(peer);
8 years ago
}
8 years ago
}
if ( peer->diduquery == 0 )
{
7 years ago
LP_peer_pricesquery(peer);
8 years ago
peer->diduquery = now;
}
7 years ago
if ( peer->needping != 0 )
{
7 years ago
needpings++;
7 years ago
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);
peer->needping = 0;
}
8 years ago
}
7 years ago
if ( needpings != 0 )
{
printf("needpings.%d send notify\n",needpings);
LP_notify_pubkeys(ctx,pubsock);
}
7 years ago
if ( (counter % 6000) == 10 )
8 years ago
{
7 years ago
LP_privkey_updates(ctx,pubsock,0);
8 years ago
}
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
7 years ago
memset(&zero,0,sizeof(zero));
7 years ago
if ( coin->inactive != 0 )
continue;
7 years ago
if ( coin->electrum != 0 )
continue;
if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR )
{
7 years ago
if ( (height= LP_getheight(coin)) > coin->longestchain )
{
coin->longestchain = height;
if ( coin->firstrefht != 0 )
printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht);
} else LP_mempoolscan(coin->symbol,zero);
coin->lastgetinfo = (uint32_t)time(NULL);
}
if ( coin->firstrefht == 0 )
continue;
else if ( coin->firstscanht == 0 )
coin->lastscanht = coin->firstscanht = coin->firstrefht;
else if ( coin->firstrefht < coin->firstscanht )
{
printf("detected %s firstrefht.%d < firstscanht.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht);
coin->lastscanht = coin->firstscanht = coin->firstrefht;
}
8 years ago
if ( coin->lastscanht == coin->longestchain+1 )
continue;
8 years ago
else if ( coin->lastscanht > coin->longestchain+1 )
{
printf("detected chain rewind lastscanht.%d vs longestchain.%d, first.%d ref.%d\n",coin->lastscanht,coin->longestchain,coin->firstscanht,coin->firstrefht);
LP_undospends(coin,coin->longestchain-1);
LP_mempoolscan(coin->symbol,zero);
coin->lastscanht = coin->longestchain - 1;
if ( coin->firstscanht < coin->lastscanht )
coin->lastscanht = coin->firstscanht;
continue;
}
8 years ago
//printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
8 years ago
{
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
continue;
8 years ago
}
coin->lastscanht++;
7 years ago
LP_getestimatedrate(coin);
break;
}
8 years ago
if ( (counter % 6000) == 60 )
{
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
{
//printf("SWAPS.(%s)\n",retstr);
free(retstr);
}
}
8 years ago
counter++;
return(nonz);
}
7 years ago
void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
8 years ago
{
8 years ago
int32_t i,n; cJSON *item;
8 years ago
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
8 years ago
{
8 years ago
fprintf(stderr,"%s ",activecoins[i]);
8 years ago
LP_coinfind(activecoins[i]);
8 years ago
LP_priceinfoadd(activecoins[i]);
}
8 years ago
if ( (n= cJSON_GetArraySize(coins)) > 0 )
{
for (i=0; i<n; i++)
8 years ago
{
item = jitem(coins,i);
8 years ago
fprintf(stderr,"%s ",jstr(item,"coin"));
8 years ago
LP_coincreate(item);
LP_priceinfoadd(jstr(item,"coin"));
}
8 years ago
}
8 years ago
fprintf(stderr,"privkey updates\n");
8 years ago
}
8 years ago
void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode)
8 years ago
{
8 years ago
int32_t i,j; uint32_t r;
if ( IAMLP != 0 )
8 years ago
{
7 years ago
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,G.LP_sessionid);
8 years ago
if ( myipaddr == 0 || mypeer == 0 )
8 years ago
{
8 years ago
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
exit(-1);
8 years ago
}
8 years ago
if ( seednode == 0 || seednode[0] == 0 )
{
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{
8 years ago
//if ( (rand() % 100) > 25 )
// continue;
8 years ago
LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport);
8 years ago
}
8 years ago
} else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport);
8 years ago
}
else
{
if ( myipaddr == 0 )
{
printf("couldnt get myipaddr\n");
exit(-1);
}
if ( seednode == 0 || seednode[0] == 0 )
{
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));
8 years ago
LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport);
8 years ago
}
8 years ago
} else LP_peersquery(mypeer,pubsock,seednode,myport,"127.0.0.1",myport);
8 years ago
}
8 years ago
}
8 years ago
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
8 years ago
{
8 years ago
char *myipaddr=0; long filesize,n; int32_t timeout,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128]; void *ctx = bitcoin_ctx();
8 years ago
LP_showwif = juint(argjson,"wif");
8 years ago
if ( passphrase == 0 || passphrase[0] == 0 )
{
printf("jeezy says we cant use the nullstring as passphrase and I agree\n");
exit(-1);
}
8 years ago
IAMLP = !amclient;
8 years ago
#ifndef __linux__
if ( IAMLP != 0 )
{
printf("must run a unix node for LP node\n");
exit(-1);
}
#endif
8 years ago
OS_randombytes((void *)&n,sizeof(n));
8 years ago
if ( jobj(argjson,"gui") != 0 )
safecopy(LP_gui,jstr(argjson,"gui"),sizeof(LP_gui));
8 years ago
if ( jobj(argjson,"canbind") == 0 )
8 years ago
{
#ifndef __linux__
8 years ago
LP_canbind = IAMLP;
8 years ago
#else
8 years ago
LP_canbind = IAMLP;
8 years ago
#endif
8 years ago
}
else
{
LP_canbind = jint(argjson,"canbind");
printf(">>>>>>>>>>> set LP_canbind.%d\n",LP_canbind);
}
8 years ago
if ( LP_canbind > 1000 && LP_canbind < 65536 )
LP_fixed_pairport = LP_canbind;
if ( LP_canbind != 0 )
LP_canbind = 1;
8 years ago
srand((int32_t)n);
8 years ago
if ( userhome != 0 && userhome[0] != 0 )
8 years ago
{
8 years ago
safecopy(USERHOME,userhome,sizeof(USERHOME));
8 years ago
#ifdef __APPLE__
strcat(USERHOME,"/Library/Application Support");
#endif
}
8 years ago
portable_mutex_init(&LP_peermutex);
portable_mutex_init(&LP_utxomutex);
8 years ago
portable_mutex_init(&LP_UTXOmutex);
8 years ago
portable_mutex_init(&LP_commandmutex);
8 years ago
portable_mutex_init(&LP_swaplistmutex);
8 years ago
portable_mutex_init(&LP_cachemutex);
8 years ago
portable_mutex_init(&LP_networkmutex);
8 years ago
portable_mutex_init(&LP_forwardmutex);
8 years ago
portable_mutex_init(&LP_psockmutex);
portable_mutex_init(&LP_coinmutex);
8 years ago
portable_mutex_init(&LP_pubkeymutex);
7 years ago
portable_mutex_init(&LP_electrummutex);
8 years ago
portable_mutex_init(&LP_messagemutex);
8 years ago
portable_mutex_init(&LP_portfoliomutex);
7 years ago
portable_mutex_init(&LP_butxomutex);
8 years ago
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 )
{
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 )
{
n = strlen(myipaddr);
if ( myipaddr[n-1] == '\n' )
myipaddr[--n] = 0;
8 years ago
strcpy(LP_myipaddr,myipaddr);
8 years ago
} else printf("error getting myipaddr\n");
} else printf("error issuing curl\n");
if ( IAMLP != 0 )
{
8 years ago
pubsock = -1;
nanomsg_transportname(0,subaddr,myipaddr,mypubport);
nanomsg_transportname(1,bindaddr,myipaddr,mypubport);
if ( (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 )
8 years ago
{
8 years ago
if ( nn_bind(pubsock,bindaddr) >= 0 )
8 years ago
{
7 years ago
timeout = 1;
8 years ago
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
}
else
{
printf("error binding to (%s).%d\n",subaddr,pubsock);
if ( pubsock >= 0 )
nn_close(pubsock), pubsock = -1;
}
} else printf("error getting pubsock %d\n",pubsock);
printf(">>>>>>>>> myipaddr.%s (%s) pullsock.%d\n",myipaddr,subaddr,pubsock);
LP_mypubsock = pubsock;
8 years ago
}
8 years ago
printf("got %s, initpeers\n",myipaddr);
8 years ago
LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode"));
8 years ago
printf("get public socket\n");
8 years ago
LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0);
8 years ago
strcpy(LP_publicaddr,pushaddr);
LP_publicport = mypullport;
8 years ago
LP_mybussock = LP_coinbus(mybusport);
//LP_deadman_switch = (uint32_t)time(NULL);
printf("canbind.%d my command address is (%s) pullsock.%d pullport.%u\n",LP_canbind,pushaddr,LP_mypullsock,mypullport);
8 years ago
printf("initcoins\n");
7 years ago
LP_initcoins(ctx,pubsock,jobj(argjson,"coins"));
7 years ago
G.waiting = 1;
7 years ago
LP_passphrase_init(passphrase);
8 years ago
if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)&myipaddr) != 0 )
8 years ago
{
8 years ago
printf("error launching LP_psockloop for (%s)\n",myipaddr);
8 years ago
exit(-1);
}
8 years ago
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
8 years ago
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)&myipaddr) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)&myipaddr) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
8 years ago
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,(void *)&myipaddr) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
8 years ago
//if ( (retstr= basilisk_swapentry(0,0)) != 0 )
// free(retstr);
7 years ago
int32_t nonz;
7 years ago
printf("start mainloop\n");
8 years ago
while ( 1 )
{
7 years ago
nonz = 0;
7 years ago
G.waiting = 1;
while ( G.initializing != 0 )
{
fprintf(stderr,".");
sleep(3);
}
if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 )
7 years ago
nonz++;
if ( nonz == 0 )
7 years ago
usleep(50000);
else usleep(5000);
8 years ago
}
8 years ago
}
8 years ago