jl777 8 years ago
parent
commit
9a9e7ce40d
  1. 16
      iguana/exchanges/LP_bitcoin.c
  2. 4
      iguana/exchanges/LP_coins.c
  3. 71
      iguana/exchanges/LP_commands.c
  4. 8
      iguana/exchanges/LP_include.h
  5. 192
      iguana/exchanges/LP_nativeDEX.c
  6. 22
      iguana/exchanges/LP_ordermatch.c
  7. 15
      iguana/exchanges/LP_peers.c
  8. 6
      iguana/exchanges/LP_portfolio.c
  9. 30
      iguana/exchanges/LP_prices.c
  10. 50
      iguana/exchanges/LP_rpc.c
  11. 276
      iguana/exchanges/LP_statemachine.c
  12. 24
      iguana/exchanges/LP_utxo.c
  13. 272
      iguana/exchanges/LP_utxos.c

16
iguana/exchanges/LP_bitcoin.c

@ -325,14 +325,12 @@ enum opcodetype
OP_INVALIDOPCODE = 0xff,
};
struct { bits256 privkey; uint8_t rmd160[20]; } LP_privkeys[100]; int32_t LP_numprivkeys;
bits256 LP_privkeyfind(uint8_t rmd160[20])
{
int32_t i; static bits256 zero;
for (i=0; i<LP_numprivkeys; i++)
if ( memcmp(rmd160,LP_privkeys[i].rmd160,20) == 0 )
return(LP_privkeys[i].privkey);
for (i=0; i<G.LP_numprivkeys; i++)
if ( memcmp(rmd160,G.LP_privkeys[i].rmd160,20) == 0 )
return(G.LP_privkeys[i].privkey);
//for (i=0; i<20; i++)
// printf("%02x",rmd160[i]);
//printf(" -> no privkey\n");
@ -345,13 +343,13 @@ int32_t LP_privkeyadd(bits256 privkey,uint8_t rmd160[20])
tmpkey = LP_privkeyfind(rmd160);
if ( bits256_nonz(tmpkey) != 0 )
return(-bits256_cmp(privkey,tmpkey));
LP_privkeys[LP_numprivkeys].privkey = privkey;
memcpy(LP_privkeys[LP_numprivkeys].rmd160,rmd160,20);
G.LP_privkeys[G.LP_numprivkeys].privkey = privkey;
memcpy(G.LP_privkeys[G.LP_numprivkeys].rmd160,rmd160,20);
//int32_t i; for (i=0; i<20; i++)
// printf("%02x",rmd160[i]);
//char str[65]; printf(" -> add privkey.(%s)\n",bits256_str(str,privkey));
LP_numprivkeys++;
return(LP_numprivkeys);
G.LP_numprivkeys++;
return(G.LP_numprivkeys);
}
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)

4
iguana/exchanges/LP_coins.c

@ -176,9 +176,9 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
jaddstr(item,"coin",coin->symbol);
if ( showwif != 0 )
{
bitcoin_priv2wif(coin->wiftaddr,wifstr,LP_mypriv25519,coin->wiftype);
bitcoin_priv2wif(coin->wiftaddr,wifstr,G.LP_mypriv25519,coin->wiftype);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,wifstr);
if ( bits256_cmp(LP_mypriv25519,checkkey) == 0 )
if ( bits256_cmp(G.LP_mypriv25519,checkkey) == 0 )
jaddstr(item,"wif",wifstr);
else jaddstr(item,"wif","error creating wif");
}

71
iguana/exchanges/LP_commands.c

@ -25,16 +25,16 @@ char *LP_numutxos()
{
jaddstr(retjson,"ipaddr",LP_mypeer->ipaddr);
jaddnum(retjson,"port",LP_mypeer->port);
jaddnum(retjson,"numutxos",LP_mypeer->numutxos);
//jaddnum(retjson,"numutxos",LP_mypeer->numutxos);
jaddnum(retjson,"numpeers",LP_mypeer->numpeers);
jaddnum(retjson,"session",LP_sessionid);
jaddnum(retjson,"session",G.LP_sessionid);
} else jaddstr(retjson,"error","client node");
return(jprint(retjson,1));
}
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,othernumutxos,flag = 0; struct LP_peerinfo *peer; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr;
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;
//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) )
@ -50,11 +50,11 @@ 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 )
/*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));
@ -76,7 +76,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
{
static char *laststr;
char *newstr; bits256 pubkey = jbits256(argjson,"pubkey");
if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,LP_mypub25519) == 0 )
if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,G.LP_mypub25519) == 0 )
{
newstr = jprint(argjson,0);
if ( laststr == 0 || strcmp(laststr,newstr) != 0 )
@ -112,6 +112,7 @@ getcoins()\n\
getcoin(coin)\n\
portfolio()\n\
getpeers()\n\
passphrase(passphrase)\n\
listunspent(coin, address)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
@ -128,18 +129,18 @@ dividends(coin, height, <args>)\n\
base = jstr(argjson,"base");
rel = jstr(argjson,"rel");
if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 )
if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 )
{
if ( USERPASS_COUNTER == 0 )
if ( G.USERPASS_COUNTER == 0 )
{
USERPASS_COUNTER = 1;
G.USERPASS_COUNTER = 1;
retjson = cJSON_CreateObject();
jaddstr(retjson,"userpass",USERPASS);
jaddbits256(retjson,"mypubkey",LP_mypub25519);
jaddstr(retjson,"userpass",G.USERPASS);
jaddbits256(retjson,"mypubkey",G.LP_mypub25519);
jadd(retjson,"coins",LP_coinsjson(LP_showwif));
return(jprint(retjson,1));
}
if ( (userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,USERPASS) != 0 )
if ( (userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,G.USERPASS) != 0 )
return(clonestr("{\"error\":\"authentication error\"}"));
jdelete(argjson,"userpass");
if ( strcmp(method,"sendmessage") == 0 )
@ -162,6 +163,12 @@ dividends(coin, height, <args>)\n\
LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num"));
return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"passphrase") == 0 )
{
if ( LP_passphrase_init(jstr(argjson,"passphrase")) < 0 )
return(clonestr("{\"error\":\"couldnt change passphrase\"}"));
else return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"portfolio") == 0 )
{
return(LP_portfolio());
@ -212,28 +219,6 @@ dividends(coin, height, <args>)\n\
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
/*else if ( strcmp(method,"ordermatch") == 0 )
{
if ( price > SMALLVAL )
return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,jdouble(argjson,"relvolume"),rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration")));
else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"trade") == 0 )
{
struct LP_quoteinfo Q;
if ( price > SMALLVAL || jobj(argjson,"quote") != 0 )
{
LP_quoteparse(&Q,jobj(argjson,"quote"));
return(LP_trade(ctx,myipaddr,pubsock,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set or no quote object\"}"));
}
else if ( strcmp(method,"autotrade") == 0 )
{
if ( price > SMALLVAL )
{
return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}*/
else if ( strcmp(method,"buy") == 0 )
{
if ( price > SMALLVAL )
@ -305,14 +290,14 @@ dividends(coin, height, <args>)\n\
{
//privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR);
//LP_utxopurge(0);
if ( bits256_nonz(LP_mypriv25519) != 0 )
LP_privkey_init(-1,ptr,LP_mypriv25519,LP_mypub25519);
if ( bits256_nonz(G.LP_mypriv25519) != 0 )
LP_privkey_init(-1,ptr,G.LP_mypriv25519,G.LP_mypub25519);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"coin",coin);
jaddnum(retjson,"timestamp",time(NULL));
jadd(retjson,"alice",LP_inventory(coin,0));
jadd(retjson,"bob",LP_inventory(coin,1));
jadd(retjson,"alice",LP_inventory(coin));
//jadd(retjson,"bob",LP_inventory(coin,1));
return(jprint(retjson,1));
}
}
@ -466,8 +451,18 @@ dividends(coin, height, <args>)\n\
else return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
}
else if ( strcmp(method,"notify") == 0 )
{
char *rmd160str,str[65]; bits256 pub; struct LP_pubkeyinfo *pubp;
pub = jbits256(argjson,"pub");
if ( bits256_nonz(pub) != 0 && (rmd160str= jstr(argjson,"rmd160")) != 0 && strlen(rmd160str) == 40 )
{
if ( (pubp= LP_pubkeyadd(pub)) != 0 )
decode_hex(pubp->rmd160,20,rmd160str);
printf("NOTIFIED pub %s rmd160 %s\n",bits256_str(str,pub),rmd160str);
}
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
}
}
else
{
if ( strcmp(method,"psock") == 0 )

8
iguana/exchanges/LP_include.h

@ -75,8 +75,8 @@
#define DEX_SLEEP 3
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
extern char GLOBAL_DBDIR[],USERPASS[],USERPASS_WIFSTR[];
extern int32_t IAMLP,USERPASS_COUNTER;
extern char GLOBAL_DBDIR[];
extern int32_t IAMLP;
struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; };
@ -235,7 +235,7 @@ struct LP_peerinfo
{
UT_hash_handle hh;
uint64_t ip_port;
uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid;
uint32_t ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid;
int32_t pushsock,subsock;
uint16_t port;
char ipaddr[64];
@ -290,7 +290,7 @@ void LP_availableset(struct LP_utxoinfo *utxo);
int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2);
int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock);
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired);
void LP_utxo_clientpublish(struct LP_utxoinfo *utxo);
//void LP_utxo_clientpublish(struct LP_utxoinfo *utxo);
int32_t LP_coinbus(uint16_t coin_busport);
struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);

192
iguana/exchanges/LP_nativeDEX.c

@ -33,7 +33,6 @@
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;
int32_t LP_canbind;
char *Broadcaststr;
struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
@ -41,7 +40,7 @@ struct iguana_info *LP_coins;
char *activecoins[] = { "BTC", "KMD" };
char GLOBAL_DBDIR[] = { "DB" };
char USERPASS[65],USERPASS_WIFSTR[64],LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" };
char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" };
char LP_gui[16] = { "cli" };
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" }; //
@ -51,11 +50,22 @@ uint16_t LP_fixed_pairport,LP_publicport;
int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1;
int32_t LP_pendingswaps,LP_showwif,USERPASS_COUNTER,IAMLP = 0;
uint32_t LP_sessionid;
int32_t LP_showwif,IAMLP = 0;
double LP_profitratio = 1.;
struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; };
struct LP_globals
{
struct LP_utxoinfo *LP_utxoinfos,*LP_utxoinfos2;
bits256 LP_mypub25519,LP_mypriv25519;
uint8_t LP_myrmd160[20];
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;
// stubs
@ -124,7 +134,7 @@ char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
cipherlen = recvlen - (2 + crypto_box_NONCEBYTES);
if ( cipherlen > 0 && cipherlen <= sizeof(decoded) )
{
if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,LP_mypriv25519)) != 0 )
if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,G.LP_mypriv25519)) != 0 )
{
recvlen = (cipherlen - crypto_box_ZEROBYTES);
if ( strlen(jsonstr)+1 != recvlen )
@ -151,7 +161,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
dup++;
else uniq++;
if ( (rand() % 1000) == 0 )
printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x U.%d\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff,LP_mypeer != 0 ? LP_mypeer->numutxos : -1);
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);
if ( duplicate == 0 )
{
if ( i >= 0 )
@ -217,53 +227,6 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
return(retstr);
}
void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo)
{
struct _LP_utxoinfo u; struct iguana_info *coin; char str[65]; uint32_t now = (uint32_t)time(NULL);
if ( IAMLP != 0 && (coin= LP_coinfind(utxo->coin)) != 0 && coin->inactive != 0 )
return;
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
utxo->T.lastspentcheck = now;
if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 )
{
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value));
LP_spentnotify(utxo,1);
}
}
}
void LP_myutxo_updates(void *ctx,int32_t pubsock,char *passphrase)
{
//LP_utxopurge(0); not good to disrupt existing pointers
LP_privkey_updates(ctx,pubsock,passphrase,0);
}
int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,int32_t interval,int32_t maxentries)
{
int32_t lastn,n = -1;
if ( peer->lastutxos < now-interval )
{
//lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
//if ( lastn < LP_PROPAGATION_SLACK * 2 )
lastn = LP_PROPAGATION_SLACK * 2;
if ( mypeer == 0 || strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
{
peer->lastutxos = now;
//printf("query utxos from %s\n",peer->ipaddr);
n = LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,maxentries);
}
} //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos);
return(n);
}
int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr)
{
int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr; char *retstr,*str; struct nn_pollfd pfd;
@ -307,7 +270,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
void command_rpcloop(void *myipaddr)
{
int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; void *ctx; //struct iguana_info *coin,*ctmp;
int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; void *ctx;
ctx = bitcoin_ctx();
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
@ -345,19 +308,16 @@ void command_rpcloop(void *myipaddr)
}
}
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport,char *passphrase)
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport)
{
int32_t enable_utxos = 0;
static uint32_t counter,numpeers,lastresync; //lastforward
struct LP_utxoinfo *utxo,*utmp; cJSON *retjson; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp,*mostpeer; uint32_t id,now; int32_t mostutxos,nonz = 0,n=0,num,lastn=-1;
static uint32_t counter,numpeers;
struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0;
now = (uint32_t)time(NULL);
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
if ( mypeer == 0 )
myipaddr = "127.0.0.1";
numpeers = LP_numpeers();
mostutxos = 0;
mostpeer = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->errors >= LP_MAXPEER_ERRORS )
@ -372,112 +332,35 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
}
if ( now > peer->lastpeers+60 && peer->numpeers > 0 && (peer->numpeers != numpeers || (rand() % 10000) == 0) )
{
//if ( IAMLP != 0 )
// printf("numpeers.%d updatepeer.%s lag.%d\n",numpeers,peer->ipaddr,now-peer->lastpeers);
peer->lastpeers = now;
//if ( IAMLP != 0 && peer->numpeers != numpeers )
// printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,numpeers);
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
{
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport);
LP_peer_pricesquery(peer->ipaddr,peer->port);
}
if ( enable_utxos && IAMLP != 0 && LP_mypeer != 0 && strcmp(peer->ipaddr,myipaddr) != 0 )
{
if ( (retstr= issue_LP_numutxos(peer->ipaddr,peer->port,LP_mypeer->ipaddr,LP_mypeer->port,LP_mypeer->numpeers,LP_mypeer->numutxos)) != 0 )
LP_peer_pricesquery(peer);
if ( peer->needping != 0 )
{
//printf("%d <- (%s)\n",peer->numutxos,retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (num= jint(retjson,"numutxos")) > peer->numutxos )
peer->numutxos = num;
if ( (num= jint(retjson,"numpeers")) > peer->numpeers )
peer->numpeers = num;
if ( (id= juint(retjson,"session")) != 0 )
peer->sessionid = id;
free_json(retjson);
}
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);
retstr = 0;
peer->needping = 0;
}
}
}
if ( peer->diduquery == 0 )
{
if ( enable_utxos && (lastn != n || n < 20) )
{
lastn = n;
n = LP_peer_utxosquery(mypeer,myport,pubsock,peer,now,60,100);
}
LP_peer_pricesquery(peer->ipaddr,peer->port);
LP_peer_pricesquery(peer);
peer->diduquery = now;
}
if ( peer->numutxos > mostutxos )
{
mostutxos = peer->numutxos;
mostpeer = peer;
}
}
//printf("numutxos vs mine.%d\n",LP_mypeer != 0 ? LP_mypeer->numutxos : -1);
if ( enable_utxos && LP_mypeer != 0 && mostpeer != 0 && ((LP_mypeer->numutxos < mostutxos && time(NULL) > lastresync+10) || time(NULL) > lastresync+60) )
{
//printf("myutxos.%d most.%d %s\n",LP_mypeer->numutxos,mostutxos,mostpeer->ipaddr);
LP_peer_utxosquery(LP_mypeer,myport,pubsock,mostpeer,now,60,(mostutxos-LP_mypeer->numutxos) * 2);
lastresync = (uint32_t)time(NULL);
//LP_peer_pricesquery(mostpeer->ipaddr,mostpeer->port);
}
if ( (counter % 6000) == 10 )
{
LP_myutxo_updates(ctx,pubsock,passphrase);
if ( enable_utxos )
{
HASH_ITER(hh,LP_utxoinfos[0],utxo,utmp)
{
LP_utxo_spentcheck(pubsock,utxo);
}
HASH_ITER(hh,LP_utxoinfos[1],utxo,utmp)
{
LP_utxo_spentcheck(pubsock,utxo);
if ( LP_isunspent(utxo) > 0 && utxo->T.lasttime == 0 && LP_ismine(utxo) > 0 )
{
char str[65]; printf("publish mybob %s\n",bits256_str(str,utxo->payment.txid));
LP_utxo_clientpublish(utxo);
}
}
}
LP_privkey_updates(ctx,pubsock,0);
}
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
int32_t height; bits256 zero; struct LP_address *ap,*atmp; struct LP_address_utxo *up,*utmp;
int32_t height; bits256 zero; //struct LP_address *ap,*atmp; struct LP_address_utxo *up,*utmp;
//printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( coin->inactive != 0 )
continue;
if ( time(NULL) > coin->lastmonitor+60 )
{
//portable_mutex_lock(&coin->addrmutex);
HASH_ITER(hh,coin->addresses,ap,atmp)
{
if ( coin->electrum == 0 )
{
LP_listunspent_issue(coin->symbol,ap->coinaddr);
DL_FOREACH_SAFE(ap->utxos,up,utmp)
{
if ( up->spendheight <= 0 )
{
if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 )
up->spendheight = 1;
}
}
}
else if ( 0 )
{
if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,ap->coinaddr)) != 0 )
free_json(retjson);
}
}
//portable_mutex_unlock(&coin->addrmutex);
coin->lastmonitor = (uint32_t)time(NULL);
}
if ( coin->electrum != 0 )
continue;
memset(zero.bytes,0,sizeof(zero));
@ -533,7 +416,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
return(nonz);
}
void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins,char *passphrase)
void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
{
int32_t i,n; cJSON *item;
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
@ -553,7 +436,6 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins,char *passphrase)
}
}
fprintf(stderr,"privkey updates\n");
LP_privkey_updates(ctx,pubsock,passphrase,1);
}
void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode)
@ -561,7 +443,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
int32_t i,j; uint32_t r;
if ( IAMLP != 0 )
{
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,LP_sessionid);
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,G.LP_sessionid);
if ( myipaddr == 0 || mypeer == 0 )
{
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
@ -656,8 +538,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_messagemutex);
portable_mutex_init(&LP_portfoliomutex);
portable_mutex_init(&LP_butxomutex);
LP_sessionid = (uint32_t)time(NULL);
printf("getting myipaddr sessionid.%u\n",LP_sessionid);
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 )
{
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 )
@ -700,7 +580,8 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
//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);
printf("initcoins\n");
LP_initcoins(ctx,pubsock,jobj(argjson,"coins"),passphrase);
LP_initcoins(ctx,pubsock,jobj(argjson,"coins"));
LP_passphrase_init(passphrase);
if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)&myipaddr) != 0 )
{
printf("error launching LP_psockloop for (%s)\n",myipaddr);
@ -732,11 +613,14 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
while ( 1 )
{
nonz = 0;
//fprintf(stderr,".");
if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport,passphrase) != 0 )
G.waiting = 1;
while ( G.initializing != 0 )
{
fprintf(stderr,".");
sleep(3);
}
if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 )
nonz++;
//if ( LP_mypullsock >= 0 )
// nonz += LP_sock_check("SUB",ctx,myipaddr,-1,LP_mypullsock,"127.0.0.1");
if ( nonz == 0 )
usleep(1000000 / MAINLOOP_PERSEC);
}

22
iguana/exchanges/LP_ordermatch.c

@ -215,7 +215,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
{
bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject();
memset(zero.bytes,0,sizeof(zero));
jaddbits256(reqjson,"pubkey",LP_mypub25519);
jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
jaddstr(reqjson,"base",base);
jaddstr(reqjson,"rel",rel);
jaddnum(reqjson,"price",price);
@ -611,7 +611,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
return(-1);
}
privkey = LP_privkey(utxo->coinaddr,coin->taddr);
if ( bits256_nonz(privkey) != 0 && bits256_cmp(LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending &&
if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending &&
{
if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 )
{
@ -638,7 +638,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
}
else
{
printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(LP_mypub25519,qp->srchash) == 0);
printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(G.LP_mypub25519,qp->srchash) == 0);
}
if ( retval < 0 )
{
@ -655,7 +655,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo A,B,*autxo,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin;
if ( LP_quoteparse(&Q,argjson) < 0 )
clonestr("{\"error\":\"cant parse quote\"}");
if ( bits256_cmp(Q.desthash,LP_mypub25519) != 0 )
if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 )
return(clonestr("{\"result\",\"update stats\"}"));
printf("CONNECTED.(%s)\n",jprint(argjson,0));
autxo = &A;
@ -664,7 +664,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL )
{
LP_availableset(autxo);
LP_pendingswaps--;
G.LP_pendingswaps--;
printf("quote validate error %.0f\n",qprice);
return(clonestr("{\"error\":\"quote validation error\"}"));
}
@ -672,7 +672,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
{
printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask);
LP_availableset(autxo);
LP_pendingswaps--;
G.LP_pendingswaps--;
return(clonestr("{\"error\":\"no price set\"}"));
}
// SPV validate bobs
@ -680,7 +680,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
price = bid;
if ( (coin= LP_coinfind(Q.destcoin)) == 0 )
{
LP_pendingswaps--;
G.LP_pendingswaps--;
return(clonestr("{\"error\":\"cant get alicecoin\"}"));
}
Q.privkey = LP_privkey(Q.destaddr,coin->taddr);
@ -711,7 +711,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
printf("connected result.(%s)\n",jprint(retjson,0));
if ( jobj(retjson,"error") != 0 )
LP_availableset(autxo);
else LP_pendingswaps++;
else G.LP_pendingswaps++;
return(jprint(retjson,1));
}
else
@ -729,7 +729,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
printf("LP_tradecommand: check received %s\n",method);
retval = 1;
if ( LP_quoteparse(&Q,argjson) == 0 && bits256_cmp(LP_mypub25519,Q.srchash) == 0 && bits256_cmp(LP_mypub25519,Q.desthash) != 0 )
if ( LP_quoteparse(&Q,argjson) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 )
{
if ( (coin= LP_coinfind(Q.srccoin)) == 0 || (price= LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin)) <= SMALLVAL || ask <= SMALLVAL )
{
@ -920,7 +920,7 @@ struct LP_utxoinfo *LP_buyutxo(struct LP_utxoinfo *bestutxo,double *ordermatchpr
{
printf("%s\n",jprint(item,0));
pubkey = jbits256(item,"pubkey");
if ( bits256_cmp(pubkey,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));
if ( basecoin->electrum != 0 )
@ -994,7 +994,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
}
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypub25519,autxo->coinaddr) < 0 )
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
if ( (qprice= LP_quote_validate(autxo,0,&Q,0)) <= SMALLVAL )
{

15
iguana/exchanges/LP_peers.c

@ -35,9 +35,9 @@ cJSON *LP_peerjson(struct LP_peerinfo *peer)
jaddnum(item,"port",peer->port);
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
{
jaddnum(item,"session",LP_sessionid);
if ( LP_mypeer != 0 )
jaddnum(item,"numutxos",LP_mypeer->numutxos);
jaddnum(item,"session",G.LP_sessionid);
//if ( LP_mypeer != 0 )
// jaddnum(item,"numutxos",LP_mypeer->numutxos);
} else jaddnum(item,"session",peer->sessionid);
//jaddnum(item,"profit",peer->profitmargin);
return(item);
@ -79,7 +79,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
{
peer = calloc(1,sizeof(*peer));
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
peer->sessionid = LP_sessionid;
peer->sessionid = G.LP_sessionid;
else peer->sessionid = sessionid;
peer->pushsock = peer->subsock = pushsock = subsock = -1;
strcpy(peer->ipaddr,ipaddr);
@ -217,9 +217,9 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa
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; uint32_t now,flag = 0;
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,mypeer!=0?mypeer->numutxos:0)) != 0 )
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);
@ -233,7 +233,8 @@ void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr
{
printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now);
flag++;
if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,0,peer->sessionid)) != 0 )
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);
}
}

6
iguana/exchanges/LP_portfolio.c

@ -63,7 +63,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
}
free_json(array);
}
if ( (array= LP_inventory(symbol,iambob)) != 0 )
if ( (array= LP_inventory(symbol)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
@ -93,7 +93,7 @@ char *LP_portfolio()
continue;
if ( iter == 0 )
{
LP_privkey_init(-1,coin,LP_mypriv25519,LP_mypub25519);
LP_privkey_init(-1,coin,G.LP_mypriv25519,G.LP_mypub25519);
coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr);
coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") != 0 )
@ -427,7 +427,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
strcpy(LP_portfolio_rel,"");
LP_portfolio_relvolume = 0.;
}
printf("pending.%d base buy.%s, rel sell.%s relvolume %f maxprice %.8f (%.8f %.8f)\n",LP_pendingswaps,buy->symbol,sell->symbol,sell->relvolume,maxprice,bid,ask);
printf("pending.%d base buy.%s, rel sell.%s relvolume %f maxprice %.8f (%.8f %.8f)\n",G.LP_pendingswaps,buy->symbol,sell->symbol,sell->relvolume,maxprice,bid,ask);
if ( LP_pricevalid(maxprice) > 0 )
{
relvolume = sell->relvolume;

30
iguana/exchanges/LP_prices.c

@ -143,8 +143,8 @@ struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey)
portable_mutex_lock(&LP_pubkeymutex);
pubp = calloc(1,sizeof(*pubp));
pubp->pubkey = pubkey;
if ( bits256_cmp(LP_mypub25519,pubkey) == 0 )
memcpy(pubp->rmd160,LP_myrmd160,sizeof(pubp->rmd160));
if ( bits256_cmp(G.LP_mypub25519,pubkey) == 0 )
memcpy(pubp->rmd160,G.LP_myrmd160,sizeof(pubp->rmd160));
HASH_ADD_KEYPTR(hh,LP_pubkeyinfos,&pubp->pubkey,sizeof(pubp->pubkey),pubp);
portable_mutex_unlock(&LP_pubkeymutex);
if ( (pubp= LP_pubkeyfind(pubkey)) == 0 )
@ -213,10 +213,10 @@ char *LP_prices()
return(jprint(array,1));
}
void LP_prices_parse(cJSON *obj)
void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
{
static uint8_t zeroes[20];
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; char *base,*rel,*hexstr; double askprice; uint32_t now;
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);
pubkey = jbits256(obj,"pubkey");
if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
@ -224,7 +224,12 @@ void LP_prices_parse(cJSON *obj)
if ( (hexstr= jstr(obj,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) )
{
decode_hex(rmd160,sizeof(rmd160),hexstr);
if ( memcmp(zeroes,rmd160,sizeof(rmd160)) != 0 && memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 )
if ( memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 )
mismatch = 1;
else mismatch = 0;
if ( bits256_cmp(pubkey,G.LP_mypub25519) == 0 && mismatch == 0 )
peer->needping = 0;
if ( mismatch != 0 && memcmp(zeroes,rmd160,sizeof(rmd160)) != 0 )
{
for (i=0; i<20; i++)
printf("%02x",pubp->rmd160[i]);
@ -263,22 +268,27 @@ void LP_prices_parse(cJSON *obj)
}
}
void LP_peer_pricesquery(char *destipaddr,uint16_t destport)
void LP_peer_pricesquery(struct LP_peerinfo *peer)
{
char *retstr; cJSON *array; int32_t i,n;
if ( (retstr= issue_LP_getprices(destipaddr,destport)) != 0 )
peer->needping = (uint32_t)time(NULL);
if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 )
{
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
LP_prices_parse(jitem(array,i));
LP_prices_parse(peer,jitem(array,i));
}
free_json(array);
}
free(retstr);
}
if ( peer->needping != 0 )
{
printf("%s needs ping\n",peer->ipaddr);
}
}
double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout)
@ -387,7 +397,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
basepp->myprices[relpp->ind] = price; // ask
//printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price);
//relpp->myprices[basepp->ind] = (1. / price); // bid
if ( (pubp= LP_pubkeyadd(LP_mypub25519)) != 0 )
if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 )
{
pubp->matrix[basepp->ind][relpp->ind] = price;
//pubp->matrix[relpp->ind][basepp->ind] = (1. / price);
@ -750,7 +760,7 @@ char *LP_pricestr(char *base,char *rel,double origprice)
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"method","postprice");
jaddbits256(retjson,"pubkey",LP_mypub25519);
jaddbits256(retjson,"pubkey",G.LP_mypub25519);
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"price",price);

50
iguana/exchanges/LP_rpc.c

@ -48,54 +48,26 @@ 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,int32_t numutxos)
char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers)
{
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos);
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 *issue_LP_numutxos(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub)
{
char url[512],*retstr;
printf("deprecated issue_LP_numutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/numutxos?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos);
retstr = LP_issue_curl("numutxos",destip,port,url);
//printf("%s -> getpeers.(%s)\n",destip,retstr);
char url[512],*retstr,str[65];
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
}
char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
{
char url[512];
printf("deprecated issue_LP_getutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,numpeers,numutxos);
return(LP_issue_curl("getutxos",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn)
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 )
{
char url[512];//,*retstr;
printf("deprecated issue_LP_clientgetutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn);
return(LP_issue_curl("clientgetutxos",destip,destport,url));
//retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
//printf("%s clientgetutxos.(%s)\n",url,retstr);
//return(retstr);
sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub));
printf("SEND (%s)\n",url);
}
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos,uint32_t sessionid)
{
char url[512],*retstr;
if ( (retstr= LP_isitme(destip,destport)) != 0 )
return(retstr);
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d&session=%u",destip,destport,ipaddr,port,numpeers,numutxos,sessionid);
return(LP_issue_curl("notify",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
@ -306,7 +278,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
} else printf("non-hex tx.(%s)\n",hexstr);
free(hexstr);
return(cJSON_Parse("{\"error\":\"non hex transaction\"}"));
} else printf("failed blockchain.transaction.get %s\n",buf);
} else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,buf);
return(cJSON_Parse("{\"error\":\"no transaction bytes\"}"));
}
}
@ -441,7 +413,7 @@ cJSON *LP_validateaddress(char *symbol,char *address)
strcat(script,"88ac");
jaddstr(retjson,"scriptPubKey",script);
}
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,LP_myrmd160,20);
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20);
if ( strcmp(address,coinaddr) == 0 )
jadd(retjson,"ismine",cJSON_CreateTrue());
jadd(retjson,"iswatchonly",cJSON_CreateFalse());

276
iguana/exchanges/LP_statemachine.c

@ -1473,6 +1473,282 @@ if ( (array= LP_tradecandidates(base)) != 0 )
printf("metrics, best %f\n",bestmetric);
*/
int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,int32_t maxentries)
{
char *retstr; struct LP_peerinfo *peer; uint32_t now; int32_t retval = -1;
printf("deprecated LP_utxosquery\n");
return(-1);
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( coin == 0 )
coin = "";
//printf("utxo query.(%s)\n",destipaddr);
if ( IAMLP != 0 )
retstr = issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,mypeer != 0 ? mypeer->numpeers : 0,maxentries);
else retstr = issue_LP_clientgetutxos(destipaddr,destport,coin,maxentries);
if ( retstr != 0 )
{
now = (uint32_t)time(NULL);
retval = LP_utxosparse(destipaddr,destport,retstr,now);
//printf("got.(%s)\n",retstr);
free(retstr);
}
return(retval);
}
char *issue_LP_numutxos(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
{
char url[512],*retstr;
printf("deprecated issue_LP_numutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/numutxos?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos);
retstr = LP_issue_curl("numutxos",destip,port,url);
//printf("%s -> getpeers.(%s)\n",destip,retstr);
return(retstr);
}
char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
{
char url[512];
printf("deprecated issue_LP_getutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,numpeers,numutxos);
return(LP_issue_curl("getutxos",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn)
{
char url[512];//,*retstr;
printf("deprecated issue_LP_clientgetutxos\n");
return(0);
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn);
return(LP_issue_curl("clientgetutxos",destip,destport,url));
//retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
//printf("%s clientgetutxos.(%s)\n",url,retstr);
//return(retstr);
}
/*else if ( strcmp(method,"ordermatch") == 0 )
{
if ( price > SMALLVAL )
return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,jdouble(argjson,"relvolume"),rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration")));
else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"trade") == 0 )
{
struct LP_quoteinfo Q;
if ( price > SMALLVAL || jobj(argjson,"quote") != 0 )
{
LP_quoteparse(&Q,jobj(argjson,"quote"));
return(LP_trade(ctx,myipaddr,pubsock,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set or no quote object\"}"));
}
else if ( strcmp(method,"autotrade") == 0 )
{
if ( price > SMALLVAL )
{
return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}*/
int32_t LP_utxopurge(int32_t allutxos)
{
char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0;
printf("LP_utxopurge mypub.(%s)\n",bits256_str(str,LP_mypub25519));
portable_mutex_lock(&LP_utxomutex);
for (iambob=0; iambob<=1; iambob++)
{
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
if ( LP_isavailable(utxo) > 0 )
{
if ( allutxos != 0 || LP_ismine(utxo) > 0 )
{
printf("iambob.%d delete.(%s)\n",iambob,bits256_str(str,utxo->payment.txid));
HASH_DELETE(hh,LP_utxoinfos[iambob],utxo);
//free(utxo); let the LP_utxoinfos2 free the utxo, should be 1:1
} else n++;
} else n++;
}
HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp)
{
if ( LP_isavailable(utxo) > 0 )
{
if ( allutxos != 0 || LP_ismine(utxo) > 0 )
{
printf("iambob.%d delete2.(%s)\n",iambob,bits256_str(str,utxo->payment.txid));
HASH_DELETE(hh2,LP_utxoinfos2[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
}
portable_mutex_unlock(&LP_utxomutex);
return(n);
}
int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{
struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
//printf("parse.(%s)\n",retstr);
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 )
peer = LP_addpeer(0,-1,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session"));
}
if ( jobj(item,"txid") != 0 )
{
txid = jbits256(item,"txid");
//printf("parse.(%s)\n",jprint(item,0));
if ( (utxo= LP_utxoaddjson(1,-1,item)) != 0 )
utxo->T.lasttime = now;
}
}
if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 )
{
destpeer->numutxos = n;
}
}
free_json(array);
}
return(n);
}
void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
{
//cJSON *argjson; struct _LP_utxoinfo u; char *msg;
if ( utxo == 0 )
return;
utxo->T.spentflag = (uint32_t)time(NULL);
/*if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
if ( LP_mypubsock >= 0 )
{
argjson = cJSON_CreateObject();
jaddstr(argjson,"method","checktxid");
jaddbits256(argjson,"txid",utxo->payment.txid);
jaddnum(argjson,"vout",utxo->payment.vout);
if ( selector != 0 )
{
if ( bits256_nonz(utxo->deposit.txid) != 0 )
u = utxo->deposit;
else u = utxo->fee;
jaddbits256(argjson,"checktxid",u.txid);
jaddnum(argjson,"checkvout",u.vout);
}
msg = jprint(argjson,1);
/LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1);
}*/
}
char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn)
{
int32_t i,n,m; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
printf("deprecated! LP_utxos\n");
//n = mypeer != 0 ? mypeer->numutxos : 0;
if ( lastn <= 0 )
lastn = LP_PROPAGATION_SLACK * 2;
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
//char str[65]; printf("check %s.%s\n",utxo->coin,bits256_str(str,utxo->payment.txid));
if ( (symbol == 0 || symbol[0] == 0 || strcmp(symbol,utxo->coin) == 0) && utxo->T.spentflag == 0 )
{
u = (iambob != 0) ? utxo->deposit : utxo->fee;
if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 )
{
char str[65]; printf("iambob.%d not eligible (%.8f %.8f) %s %s/v%d\n",iambob,dstr(val),dstr(val2),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout);
continue;
} else jaddi(utxosjson,LP_utxojson(utxo));
}
}
if ( (n= cJSON_GetArraySize(utxosjson)) > lastn )
{
m = n - lastn;
for (i=0; i<m; i++)
cJSON_DeleteItemFromArray(utxosjson,0);
}
return(jprint(utxosjson,1));
}
void LP_utxo_clientpublish(struct LP_utxoinfo *utxo)
{
bits256 zero; char *msg;
if ( 0 && LP_isunspent(utxo) > 0 )
{
memset(zero.bytes,0,sizeof(zero));
msg = jprint(LP_utxojson(utxo),1);
LP_broadcast_message(LP_mypubsock,utxo->coin,"",zero,msg);
}
}
void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo)
{
struct _LP_utxoinfo u; struct iguana_info *coin; char str[65]; uint32_t now = (uint32_t)time(NULL);
if ( IAMLP != 0 && (coin= LP_coinfind(utxo->coin)) != 0 && coin->inactive != 0 )
return;
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
utxo->T.lastspentcheck = now;
if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 )
{
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value));
LP_spentnotify(utxo,1);
}
}
}
int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,int32_t interval,int32_t maxentries)
{
int32_t lastn,n = -1;
if ( peer->lastutxos < now-interval )
{
//lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
//if ( lastn < LP_PROPAGATION_SLACK * 2 )
lastn = LP_PROPAGATION_SLACK * 2;
if ( mypeer == 0 || strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
{
peer->lastutxos = now;
//printf("query utxos from %s\n",peer->ipaddr);
n = LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,maxentries);
}
} //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos);
return(n);
}
/*if ( time(NULL) > coin->lastmonitor+60 )
{
//portable_mutex_lock(&coin->addrmutex);
HASH_ITER(hh,coin->addresses,ap,atmp)
{
if ( coin->electrum == 0 )
{
LP_listunspent_issue(coin->symbol,ap->coinaddr);
DL_FOREACH_SAFE(ap->utxos,up,utmp)
{
if ( up->spendheight <= 0 )
{
if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 )
up->spendheight = 1;
}
}
}
}
//portable_mutex_unlock(&coin->addrmutex);
coin->lastmonitor = (uint32_t)time(NULL);
}*/
/*cJSON *LP_tradecandidates(char *base)
{
struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*retarray=0,*item; int32_t i,n,totaladded,added;

24
iguana/exchanges/LP_utxo.c

@ -363,22 +363,37 @@ void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout)
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
if ( iambob != 0 )
{
printf("_LP_utxofind deprecated iambob\n");
return(0);
}
LP_utxosetkey(key,txid,vout);
HASH_FIND(hh,LP_utxoinfos[iambob],key,sizeof(key),utxo);
HASH_FIND(hh,G.LP_utxoinfos,key,sizeof(key),utxo);
return(utxo);
}
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)];
if ( iambob != 0 )
{
printf("_LP_utxo2find deprecated iambob\n");
return(0);
}
LP_utxosetkey(key2,txid2,vout2);
HASH_FIND(hh2,LP_utxoinfos2[iambob],key2,sizeof(key2),utxo);
HASH_FIND(hh2,G.LP_utxoinfos2,key2,sizeof(key2),utxo);
return(utxo);
}
struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0;
if ( iambob != 0 )
{
printf("LP_utxofind deprecated iambob\n");
return(0);
}
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxofind(iambob,txid,vout);
portable_mutex_unlock(&LP_utxomutex);
@ -388,6 +403,11 @@ struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0;
if ( iambob != 0 )
{
printf("LP_utxo2find deprecated iambob\n");
return(0);
}
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxo2find(iambob,txid2,vout2);
portable_mutex_unlock(&LP_utxomutex);

272
iguana/exchanges/LP_utxos.c

@ -20,7 +20,7 @@
int32_t LP_ismine(struct LP_utxoinfo *utxo)
{
if ( utxo != 0 && bits256_cmp(utxo->pubkey,LP_mypub25519) == 0 )
if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 )
return(1);
else return(0);
}
@ -154,42 +154,6 @@ void LP_availableset(struct LP_utxoinfo *utxo)
}
}
int32_t LP_utxopurge(int32_t allutxos)
{
char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0;
printf("LP_utxopurge mypub.(%s)\n",bits256_str(str,LP_mypub25519));
portable_mutex_lock(&LP_utxomutex);
for (iambob=0; iambob<=1; iambob++)
{
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
if ( LP_isavailable(utxo) > 0 )
{
if ( allutxos != 0 || LP_ismine(utxo) > 0 )
{
printf("iambob.%d delete.(%s)\n",iambob,bits256_str(str,utxo->payment.txid));
HASH_DELETE(hh,LP_utxoinfos[iambob],utxo);
//free(utxo); let the LP_utxoinfos2 free the utxo, should be 1:1
} else n++;
} else n++;
}
HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp)
{
if ( LP_isavailable(utxo) > 0 )
{
if ( allutxos != 0 || LP_ismine(utxo) > 0 )
{
printf("iambob.%d delete2.(%s)\n",iambob,bits256_str(str,utxo->payment.txid));
HASH_DELETE(hh2,LP_utxoinfos2[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
}
portable_mutex_unlock(&LP_utxomutex);
return(n);
}
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{
struct _LP_utxoinfo u;
@ -246,35 +210,6 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
return(item);
}
char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn)
{
int32_t i,n,m; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
printf("deprecated! LP_utxos\n");
//n = mypeer != 0 ? mypeer->numutxos : 0;
if ( lastn <= 0 )
lastn = LP_PROPAGATION_SLACK * 2;
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
//char str[65]; printf("check %s.%s\n",utxo->coin,bits256_str(str,utxo->payment.txid));
if ( (symbol == 0 || symbol[0] == 0 || strcmp(symbol,utxo->coin) == 0) && utxo->T.spentflag == 0 )
{
u = (iambob != 0) ? utxo->deposit : utxo->fee;
if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 )
{
char str[65]; printf("iambob.%d not eligible (%.8f %.8f) %s %s/v%d\n",iambob,dstr(val),dstr(val2),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout);
continue;
} else jaddi(utxosjson,LP_utxojson(utxo));
}
}
if ( (n= cJSON_GetArraySize(utxosjson)) > lastn )
{
m = n - lastn;
for (i=0; i<m; i++)
cJSON_DeleteItemFromArray(utxosjson,0);
}
return(jprint(utxosjson,1));
}
struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
{
uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0;
@ -283,7 +218,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis));
return(0);
}
HASH_ITER(hh,LP_utxoinfos[0],utxo,tmp)
HASH_ITER(hh,G.LP_utxoinfos,utxo,tmp)
{
//char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis);
if ( strcmp(symbol,utxo->coin) != 0 )
@ -307,29 +242,9 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
{
//cJSON *argjson; struct _LP_utxoinfo u; char *msg;
if ( utxo == 0 )
return;
utxo->T.spentflag = (uint32_t)time(NULL);
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
/*if ( LP_mypubsock >= 0 )
{
argjson = cJSON_CreateObject();
jaddstr(argjson,"method","checktxid");
jaddbits256(argjson,"txid",utxo->payment.txid);
jaddnum(argjson,"vout",utxo->payment.vout);
if ( selector != 0 )
{
if ( bits256_nonz(utxo->deposit.txid) != 0 )
u = utxo->deposit;
else u = utxo->fee;
jaddbits256(argjson,"checktxid",u.txid);
jaddnum(argjson,"checkvout",u.vout);
}
msg = jprint(argjson,1);
/LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1);
}*/
}
char *LP_spentcheck(cJSON *argjson)
@ -350,8 +265,8 @@ char *LP_spentcheck(cJSON *argjson)
}
if ( LP_txvalue(0,utxo->coin,checktxid,checkvout) == 0 )
{
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
//if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
// LP_mypeer->numutxos--;
utxo->T.spentflag = (uint32_t)time(NULL);
retval++;
printf("indeed txid was spent\n");
@ -363,17 +278,6 @@ char *LP_spentcheck(cJSON *argjson)
return(clonestr("{\"error\":\"cant find txid to check spent status\"}"));
}
void LP_utxo_clientpublish(struct LP_utxoinfo *utxo)
{
bits256 zero; char *msg;
if ( 0 && LP_isunspent(utxo) > 0 )
{
memset(zero.bytes,0,sizeof(zero));
msg = jprint(LP_utxojson(utxo),1);
LP_broadcast_message(LP_mypubsock,utxo->coin,"",zero,msg);
}
}
struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid)
{
uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
@ -382,6 +286,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
printf("session.%u malformed addutxo %d %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0);
return(0);
}
if ( iambob != 0 )
{
printf("deprecated bob utxos\n");
return(0);
}
if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
printf("LP_utxoadd reject inactive %s\n",symbol);
@ -395,7 +304,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
else return(0);
} else tmpsatoshis = (value - txfee);
char str[65],str2[65],dispflag = 0;//(iambob == 0);
if ( iambob == 0 && bits256_cmp(pubkey,LP_mypub25519) != 0 )
if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 )
{
printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout);
return(0);
@ -484,26 +393,24 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
LP_utxosetkey(utxo->key,txid,vout);
LP_utxosetkey(utxo->key2,txid2,vout2);
if ( LP_ismine(utxo) > 0 )
utxo->T.sessionid = LP_sessionid;
utxo->T.sessionid = G.LP_sessionid;
else utxo->T.sessionid = sessionid;
if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 )
{
printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
utxo->T.spentflag = (uint32_t)time(NULL);
}
printf("U.%d %s %.8f %.8f addutxo.%d pubkey.%s session.%u\n",LP_mypeer!=0?LP_mypeer->numutxos:-1,symbol,dstr(value),dstr(value2),LP_ismine(utxo) > 0,bits256_str(str,utxo->pubkey),utxo->T.sessionid);
printf(" %s %.8f %.8f addutxo.%d pubkey.%s session.%u\n",symbol,dstr(value),dstr(value2),LP_ismine(utxo) > 0,bits256_str(str,utxo->pubkey),utxo->T.sessionid);
portable_mutex_lock(&LP_utxomutex);
HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
HASH_ADD_KEYPTR(hh,G.LP_utxoinfos,utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
HASH_ADD_KEYPTR(hh2,G.LP_utxoinfos2,utxo->key2,sizeof(utxo->key2),utxo);
portable_mutex_unlock(&LP_utxomutex);
if ( iambob != 0 )
{
if ( LP_mypeer != 0 )
LP_mypeer->numutxos++;
if ( LP_ismine(utxo) > 0 )
{
LP_utxo_clientpublish(utxo);
//LP_utxo_clientpublish(utxo);
if ( LP_mypeer != 0 )
utxo->T.lasttime = (uint32_t)time(NULL);
}
@ -530,75 +437,14 @@ struct LP_utxoinfo *LP_utxoaddjson(int32_t iambob,int32_t pubsock,cJSON *argjson
return(utxo);
}
int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
cJSON *LP_inventory(char *symbol)
{
struct LP_peerinfo *destpeer,*peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
//printf("parse.(%s)\n",retstr);
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 )
peer = LP_addpeer(0,-1,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session"));
}
if ( jobj(item,"txid") != 0 )
{
txid = jbits256(item,"txid");
//printf("parse.(%s)\n",jprint(item,0));
if ( (utxo= LP_utxoaddjson(1,-1,item)) != 0 )
utxo->T.lasttime = now;
}
}
if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 )
{
destpeer->numutxos = n;
}
}
free_json(array);
}
return(n);
}
int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,int32_t maxentries)
{
char *retstr; struct LP_peerinfo *peer; uint32_t now; int32_t retval = -1;
printf("deprecated LP_utxosquery\n");
return(-1);
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( coin == 0 )
coin = "";
//printf("utxo query.(%s)\n",destipaddr);
if ( IAMLP != 0 )
retstr = issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,mypeer != 0 ? mypeer->numpeers : 0,maxentries);
else retstr = issue_LP_clientgetutxos(destipaddr,destport,coin,maxentries);
if ( retstr != 0 )
{
now = (uint32_t)time(NULL);
retval = LP_utxosparse(destipaddr,destport,retstr,now);
//printf("got.(%s)\n",retstr);
free(retstr);
}
return(retval);
}
cJSON *LP_inventory(char *symbol,int32_t iambob)
{
struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2;
struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0;
array = cJSON_CreateArray();
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else myipaddr = "127.0.0.1";
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
HASH_ITER(hh,G.LP_utxoinfos,utxo,tmp)
{
char str[65];
//printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519));
@ -612,8 +458,8 @@ cJSON *LP_inventory(char *symbol,int32_t iambob)
printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2));
continue;
}
if ( iambob != 0 )
LP_utxo_clientpublish(utxo);
//if ( iambob != 0 )
// LP_utxo_clientpublish(utxo);
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
}
else if ( LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 )
@ -764,14 +610,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
portable_mutex_lock(&LP_UTXOmutex);
if ( iambob != 0 )
{
if ( (utxo= LP_utxoadd(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_gui,LP_sessionid)) != 0 )
if ( (utxo= LP_utxoadd(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 )
{
}
}
else
{
//printf("call utxoadd\n");
if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,LP_gui,LP_sessionid)) != 0 )
if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 )
{
}
}
@ -839,7 +685,7 @@ char *LP_secretaddresses(void *ctx,char *passphrase,int32_t n,uint8_t taddr,uint
bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr)
{
static uint32_t counter;
//static uint32_t counter;
bits256 privkey,userpub,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype;
if ( passphrase != 0 && passphrase[0] != 0 )
{
@ -864,23 +710,23 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
{
coin->counter++;
bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->taddr,&tmptype,LP_myrmd160,coin->smartaddr);
LP_privkeyadd(privkey,LP_myrmd160);
bitcoin_addr2rmd160(coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr);
LP_privkeyadd(privkey,G.LP_myrmd160);
if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) )
printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase);
if ( counter++ == 0 )
if ( G.counter++ == 0 )
{
bitcoin_priv2wif(coin->wiftaddr,USERPASS_WIFSTR,privkey,188);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,USERPASS_WIFSTR);
bitcoin_priv2wif(coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR);
if ( bits256_cmp(checkkey,privkey) != 0 )
{
char str[65],str2[65];
printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey));
printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey));
exit(-1);
}
conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)USERPASS_WIFSTR,(int32_t)strlen(USERPASS_WIFSTR));
conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR));
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(USERPASS,userpub));
printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub));
}
if ( coin->electrum == 0 )
{
@ -895,23 +741,29 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
} else free_json(retjson);
}
}
LP_mypub25519 = *pubkeyp = curve25519(privkey,curve25519_basepoint9());
LP_mypriv25519 = privkey;
G.LP_mypub25519 = *pubkeyp = curve25519(privkey,curve25519_basepoint9());
G.LP_mypriv25519 = privkey;
//printf("privkey.(%s) -> LP_mypub25519.(%s)\n",bits256_str(str,privkey),bits256_str(str2,LP_mypub25519));
return(privkey);
}
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t initonly)
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
{
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33];
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly;
initonly = (passphrase != 0);
memset(privkey.bytes,0,sizeof(privkey));
pubkey = privkey;
memset(pubkey.bytes,0,sizeof(pubkey));
HASH_ITER(hh,LP_coins,coin,tmp)
{
//printf("i.%d of %d\n",i,LP_numcoins);
if ( initonly != 0 )
{
coin->counter = 0;
memset(coin->smartaddr,0,sizeof(coin->smartaddr));
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 && initonly == 0 )
}
//printf("i.%d of %d\n",i,LP_numcoins);
else if ( coin->inactive == 0 )
{
if ( LP_privkey_init(pubsock,coin,privkey,pubkey) == 0 && (rand() % 10) == 0 )
LP_postutxos(coin->symbol,coin->smartaddr);
@ -919,4 +771,40 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t inito
}
}
int32_t LP_passphrase_init(char *passphrase)
{
static void *ctx; struct LP_utxoinfo *utxo,*tmp;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( G.LP_pendingswaps != 0 )
return(-1);
G.initializing = 1;
while ( G.waiting == 0 )
{
printf("waiting for G.waiting\n");
sleep(5);
}
if ( G.LP_utxoinfos != 0 )
{
HASH_ITER(hh,G.LP_utxoinfos,utxo,tmp)
{
HASH_DELETE(hh,G.LP_utxoinfos,utxo);
free(utxo);
}
}
if ( G.LP_utxoinfos2 != 0 )
{
HASH_ITER(hh,G.LP_utxoinfos2,utxo,tmp)
{
HASH_DELETE(hh,G.LP_utxoinfos2,utxo);
free(utxo);
}
}
memset(&G,0,sizeof(G));
LP_privkey_updates(ctx,LP_mypubsock,passphrase);
init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20);
G.LP_sessionid = (uint32_t)time(NULL);
return(0);
}

Loading…
Cancel
Save