Browse Source

Merge pull request #491 from jl777/spvdex

dynamictrust
etomic
jl777 7 years ago
committed by GitHub
parent
commit
a53621829c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      crypto777/bitcoind_RPC.c
  2. 2
      iguana/dpow/dpow_network.c
  3. 58
      iguana/exchanges/LP_RTmetrics.c
  4. 28
      iguana/exchanges/LP_bitcoin.c
  5. 2
      iguana/exchanges/LP_cache.c
  6. 14
      iguana/exchanges/LP_coins.c
  7. 152
      iguana/exchanges/LP_commands.c
  8. 45
      iguana/exchanges/LP_include.h
  9. 186
      iguana/exchanges/LP_nativeDEX.c
  10. 116
      iguana/exchanges/LP_network.c
  11. 19
      iguana/exchanges/LP_ordermatch.c
  12. 2
      iguana/exchanges/LP_portfolio.c
  13. 66
      iguana/exchanges/LP_prices.c
  14. 19
      iguana/exchanges/LP_remember.c
  15. 111
      iguana/exchanges/LP_rpc.c
  16. 34
      iguana/exchanges/LP_signatures.c
  17. 11
      iguana/exchanges/LP_socket.c
  18. 23
      iguana/exchanges/LP_statemachine.c
  19. 322
      iguana/exchanges/LP_stats.c
  20. 21
      iguana/exchanges/LP_swap.c
  21. 2
      iguana/exchanges/LP_tradebots.c
  22. 27
      iguana/exchanges/LP_transaction.c
  23. 24
      iguana/exchanges/LP_utxo.c
  24. 41
      iguana/exchanges/LP_utxos.c
  25. 278
      iguana/exchanges/LP_zeroconf.c
  26. 3
      iguana/exchanges/claim
  27. 3
      iguana/exchanges/deposit
  28. 3
      iguana/exchanges/deposit1
  29. 2
      iguana/exchanges/install
  30. 12
      iguana/exchanges/mm.c
  31. 150
      iguana/exchanges/stats.c
  32. 3
      iguana/exchanges/tradesarray
  33. 2
      iguana/main.c

18
crypto777/bitcoind_RPC.c

@ -96,6 +96,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL )
{ {
retstr = jprint(result,0); retstr = jprint(result,0);
//printf("%s %s rpc retstr.%p\n",command,params,retstr);
len = strlen(retstr); len = strlen(retstr);
if ( retstr[0] == '"' && retstr[len-1] == '"' ) if ( retstr[0] == '"' && retstr[len-1] == '"' )
{ {
@ -112,7 +113,10 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
rpcstr = 0; rpcstr = 0;
} }
if ( rpcstr != 0 ) if ( rpcstr != 0 )
{
//printf("free rpcstr.%p\n",rpcstr);
free(rpcstr); free(rpcstr);
}
} else retstr = rpcstr; } else retstr = rpcstr;
free_json(json); free_json(json);
//fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr); //fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr);
@ -231,30 +235,30 @@ try_again:
free(databuf); free(databuf);
databuf = 0; databuf = 0;
} }
retstr = chunk.memory; // retstr = s.ptr;
if ( res != CURLE_OK ) if ( res != CURLE_OK )
{ {
numretries++; numretries++;
if ( specialcase != 0 || timeout != 0 ) if ( specialcase != 0 || timeout != 0 )
{ {
//printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res);
free(chunk.memory); //free(s.ptr); free(retstr);
return(0); return(0);
} }
else if ( numretries >= 4 ) else if ( numretries >= 4 )
{ {
printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
//printf("Maximum number of retries exceeded!\n"); //printf("Maximum number of retries exceeded!\n");
free(chunk.memory);//free(s.ptr); free(retstr);
return(0); return(0);
} }
free(chunk.memory);//free(s.ptr); free(retstr);
sleep((1<<numretries)); sleep((1<<numretries));
goto try_again; goto try_again;
} }
else else
{ {
retstr = chunk.memory; // retstr = s.ptr;
if ( command != 0 && specialcase == 0 ) if ( command != 0 && specialcase == 0 )
{ {
count++; count++;
@ -279,9 +283,6 @@ try_again:
return(retstr); return(retstr);
} }
} }
//printf("bitcoind_RPC: impossible case\n");
//free(s.ptr);
//return(0);
} }
/************************************************************************ /************************************************************************
@ -337,6 +338,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
{ {
//printf("curl needs %d more\n",(int32_t)realsize); //printf("curl needs %d more\n",(int32_t)realsize);
mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed);
//printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed);
mem->allocsize = needed; mem->allocsize = needed;
} }
//mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1);

2
iguana/dpow/dpow_network.c

@ -584,6 +584,8 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d
{ {
char buf[65],*retstr = 0; int32_t i,datalen; bits256 hash2; cJSON *retjson=0; struct iguana_info *coin; struct dex_request dexreq; char buf[65],*retstr = 0; int32_t i,datalen; bits256 hash2; cJSON *retjson=0; struct iguana_info *coin; struct dex_request dexreq;
*broadcastflagp = 0; *broadcastflagp = 0;
return(clonestr("{\"error\":\"basilisk disabled\"}"));
if ( strcmp(dexp->handler,"request") == 0 ) if ( strcmp(dexp->handler,"request") == 0 )
{ {
datalen = dex_rwrequest(0,dexp->packet,&dexreq); datalen = dex_rwrequest(0,dexp->packet,&dexreq);

58
iguana/exchanges/LP_RTmetrics.c

@ -27,11 +27,13 @@ struct LP_metricinfo
int32_t ind,numutxos,age,pendingswaps; int32_t ind,numutxos,age,pendingswaps;
}; };
#define LP_NUMRT 1024
struct LP_RTmetrics_pendings struct LP_RTmetrics_pendings
{ {
char refbase[65],refrel[65]; char refbase[128],refrel[128];
int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024]; int64_t pending_kmdvalue[LP_NUMRT];
bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024]; int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[LP_NUMRT];
bits256 avoidtxids[8192],whitelist[LP_NUMRT],blacklist[LP_NUMRT],pending_pubkeys[LP_NUMRT];
} LP_RTmetrics; } LP_RTmetrics;
int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val) int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val)
@ -72,11 +74,14 @@ int32_t LP_RTmetrics_blacklistadd(bits256 pubkey)
return(LP_bits256_add("LP_RTmetrics_blacklistadd blacklist",LP_RTmetrics.blacklist,&LP_RTmetrics.numblacklist,(int32_t)(sizeof(LP_RTmetrics.blacklist)/sizeof(*LP_RTmetrics.blacklist)),pubkey)); return(LP_bits256_add("LP_RTmetrics_blacklistadd blacklist",LP_RTmetrics.blacklist,&LP_RTmetrics.numblacklist,(int32_t)(sizeof(LP_RTmetrics.blacklist)/sizeof(*LP_RTmetrics.blacklist)),pubkey));
} }
int32_t LP_RTmetrics_pendingswap(bits256 pubkey) int32_t LP_RTmetrics_pendingswap(bits256 pubkey,int64_t kmdvalue)
{ {
int32_t ind; int32_t ind;
if ( (ind= LP_bits256_add("LP_RTmetrics_pendingswap",LP_RTmetrics.pending_pubkeys,&LP_RTmetrics.numpendings,(int32_t)(sizeof(LP_RTmetrics.pending_pubkeys)/sizeof(*LP_RTmetrics.pending_pubkeys)),pubkey)) >= 0 ) if ( (ind= LP_bits256_add("LP_RTmetrics_pendingswap",LP_RTmetrics.pending_pubkeys,&LP_RTmetrics.numpendings,(int32_t)(sizeof(LP_RTmetrics.pending_pubkeys)/sizeof(*LP_RTmetrics.pending_pubkeys)),pubkey)) >= 0 )
{
LP_RTmetrics.pending_swaps[ind]++; LP_RTmetrics.pending_swaps[ind]++;
LP_RTmetrics.pending_kmdvalue[ind] += kmdvalue;
}
return(ind); return(ind);
} }
@ -113,7 +118,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
base = ""; base = "";
if ( (rel= jstr(item,"rel")) == 0 ) if ( (rel= jstr(item,"rel")) == 0 )
rel = ""; rel = "";
if ( strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 ) if ( refbase[0] != 0 && strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 )
continue;
if ( refrel[0] != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 )
continue; continue;
aliceid = j64bits(item,"aliceid"); aliceid = j64bits(item,"aliceid");
basesatoshis = SATOSHIDEN * jdouble(item,"basevol"); basesatoshis = SATOSHIDEN * jdouble(item,"basevol");
@ -123,8 +130,8 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
price = jdouble(item,"price"); price = jdouble(item,"price");
requestid = juint(item,"requestid"); requestid = juint(item,"requestid");
quoteid = juint(item,"quoteid"); quoteid = juint(item,"quoteid");
LP_RTmetrics_pendingswap(srcpub); LP_RTmetrics_pendingswap(srcpub,LP_kmdvalue(base,basesatoshis));
LP_RTmetrics_pendingswap(destpub); LP_RTmetrics_pendingswap(destpub,LP_kmdvalue(rel,relsatoshis));
if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) // no need for this if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) // no need for this
{ {
if ( (swapjson= cJSON_Parse(retstr)) != 0 ) if ( (swapjson= cJSON_Parse(retstr)) != 0 )
@ -142,9 +149,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
} }
} }
void LP_RTmetrics_update(char *base,char *rel) /*void LP_RTmetrics_init()
{ {
struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 zero; char *retstr; cJSON *statsjson,*swaps; struct LP_pubkey_info *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps;
memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics));
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{ {
@ -152,31 +159,38 @@ void LP_RTmetrics_update(char *base,char *rel)
LP_RTmetrics_whitelistadd(pubp->pubkey); LP_RTmetrics_whitelistadd(pubp->pubkey);
else if ( pubp->istrusted < 0 ) else if ( pubp->istrusted < 0 )
LP_RTmetrics_blacklistadd(pubp->pubkey); LP_RTmetrics_blacklistadd(pubp->pubkey);
pubp->swaps_kmdvalue = 0;
} }
futuretime = (uint32_t)time(NULL) + 3600*100; futuretime = (uint32_t)time(NULL) + 3600*100;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
if ( (retstr= LP_statslog_disp(100,futuretime,futuretime,"",zero)) != 0 ) if ( (statsjson= LP_statslog_disp(futuretime,futuretime,"",zero,0,0)) != 0 )
{ {
if ( (statsjson= cJSON_Parse(retstr)) != 0 ) if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 )
{ {
if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
{ if ( numswaps > 0 )
//printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); LP_RTmetrics_swapsinfo("","",swaps,numswaps);
if ( numswaps > 0 )
LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps);
}
free_json(statsjson);
} }
free(retstr); free_json(statsjson);
} }
for (i=0; i<LP_RTmetrics.numpendings; i++) for (i=0; i<LP_RTmetrics.numpendings; i++)
{
pubkey = LP_RTmetrics.pending_pubkeys[i];
if ( LP_RTmetrics.pending_swaps[i] > LP_MAXPENDING_SWAPS ) if ( LP_RTmetrics.pending_swaps[i] > LP_MAXPENDING_SWAPS )
{ {
char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,LP_RTmetrics.pending_pubkeys[i]),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS);
LP_RTmetrics_blacklistadd(LP_RTmetrics.pending_pubkeys[i]); LP_RTmetrics_blacklistadd(pubkey);
} }
else if ( (pubp= LP_pubkeyfind(pubkey)) != 0 )
{
char str[65]; printf("%s has %d pending swaps %.8f kmdvalue\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],dstr(LP_RTmetrics.pending_kmdvalue[i]));
pubp->swaps_kmdvalue = LP_RTmetrics.pending_kmdvalue[i];
}
}
//printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); //printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids);
} }*/
double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume) double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume)
{ {

28
iguana/exchanges/LP_bitcoin.c

@ -1959,13 +1959,13 @@ int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint3
return(n); return(n);
} }
int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t cltv_rmd160[20],uint8_t anytime_rmd160[20]) int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t *cltvpub33,uint8_t *elsepub33)
{ {
script[n++] = SCRIPT_OP_IF; script[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(script,n,unlocktimestamp); n = bitcoin_checklocktimeverify(script,n,unlocktimestamp);
n = bitcoin_standardspend(script,n,cltv_rmd160); n = bitcoin_pubkeyspend(script,n,cltvpub33);
script[n++] = SCRIPT_OP_ELSE; script[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(script,n,anytime_rmd160); n = bitcoin_pubkeyspend(script,n,elsepub33);
script[n++] = SCRIPT_OP_ENDIF; script[n++] = SCRIPT_OP_ENDIF;
calc_rmd160_sha256(p2sh_rmd160,script,n); calc_rmd160_sha256(p2sh_rmd160,script,n);
return(n); return(n);
@ -3309,9 +3309,9 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht
dest.vins[i].userdatalen = 0; dest.vins[i].userdatalen = 0;
} }
len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash);
for (i=0; i<len; i++) //for (i=0; i<len; i++)
printf("%02x",serialized[i]); // printf("%02x",serialized[i]);
printf(" <- sigtx len.%d supp.%d user[0].%d\n",len,suppress_pubkeys,dest.vins[0].userdatalen); //printf(" <- sigtx len.%d supp.%d user[0].%d\n",len,suppress_pubkeys,dest.vins[0].userdatalen);
if ( len > 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && if ( len > 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 &&
{ {
#ifdef BTC2_VERSION #ifdef BTC2_VERSION
@ -3322,7 +3322,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht
revsigtxid = bits256_doublesha256(0,serialized,len); revsigtxid = bits256_doublesha256(0,serialized,len);
for (i=0; i<sizeof(revsigtxid); i++) for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i]; sigtxid.bytes[31-i] = revsigtxid.bytes[i];
char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out); //char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out);
} }
free(dest.vins); free(dest.vins);
free(dest.vouts); free(dest.vouts);
@ -3355,6 +3355,20 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj
return(len); return(len);
} }
uint32_t LP_sighash(char *symbol,int32_t zcash)
{
uint32_t sighash;
sighash = SIGHASH_ALL;
if ( zcash == LP_IS_BITCOINCASH )
sighash |= SIGHASH_FORKID;
else if ( zcash == LP_IS_BITCOINGOLD )
{
sighash |= SIGHASH_FORKID;
sighash |= (LP_IS_BITCOINGOLD << 8);
}
return(sighash);
}
int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
{ {
int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid;

2
iguana/exchanges/LP_cache.c

@ -330,7 +330,7 @@ uint64_t LP_unspents_load(char *symbol,char *addr)
balance += j64bits(item,"value"); balance += j64bits(item,"value");
} }
} }
electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1); electrum_process_array(coin,coin->electrum,addr,retjson,1);
free_json(retjson); free_json(retjson);
} }
free(arraystr); free(arraystr);

14
iguana/exchanges/LP_coins.c

@ -286,20 +286,6 @@ cJSON *LP_coinsjson(int32_t showwif)
return(array); return(array);
} }
uint32_t LP_sighash(char *symbol,int32_t zcash)
{
uint32_t sighash;
sighash = SIGHASH_ALL;
if ( zcash == LP_IS_BITCOINCASH )
sighash |= SIGHASH_FORKID;
else if ( zcash == LP_IS_BITCOINGOLD )
{
sighash |= SIGHASH_FORKID;
sighash |= (LP_IS_BITCOINGOLD << 8);
}
return(sighash);
}
char *LP_getcoin(char *symbol) char *LP_getcoin(char *symbol)
{ {
int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson;

152
iguana/exchanges/LP_commands.c

@ -38,7 +38,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
method = jstr(argjson,"method"); method = jstr(argjson,"method");
if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) )
return(0); return(0);
//printf("stats_JSON %s\n",method); //printf("stats_JSON.(%s)\n",jprint(argjson,0));
/*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) )
{ {
if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 )
@ -68,8 +68,16 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
} }
if ( strcmp(method,"hello") == 0 ) if ( strcmp(method,"hello") == 0 )
{ {
//int32_t i; cJSON *array = cJSON_CreateArray();
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"status","got hello");
//for (i=0; i<10000; i++)
// jaddinum(array,i);
//jadd(retjson,"array",array);
return(jprint(retjson,1));
//printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport);
return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); //return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}"));
} }
/*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) /*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 )
{ {
@ -94,8 +102,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
else if ( strcmp(method,"help") == 0 ) else if ( strcmp(method,"help") == 0 )
return(clonestr("{\"result\":\" \ return(clonestr("{\"result\":\" \
available localhost RPC commands: \n \ available localhost RPC commands: \n \
pricearray(base, rel, starttime=0, endtime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ setprice(base, rel, price, broadcast=1)\n\
setprice(base, rel, price)\n\
autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\ autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\
goal(coin=*, val=<autocalc>)\n\ goal(coin=*, val=<autocalc>)\n\
myprice(base, rel)\n\ myprice(base, rel)\n\
@ -103,7 +110,9 @@ enable(coin)\n\
disable(coin)\n\ disable(coin)\n\
notarizations(coin)\n\ notarizations(coin)\n\
parselog()\n\ parselog()\n\
statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\
tradesarray(base, rel, starttime=<now>-timescale*1024, endtime=<now>, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]\n\
pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
getrawtransaction(coin, txid)\n\ getrawtransaction(coin, txid)\n\
inventory(coin, reset=0, [passphrase=])\n\ inventory(coin, reset=0, [passphrase=])\n\
bestfit(rel, relvolume)\n\ bestfit(rel, relvolume)\n\
@ -146,7 +155,8 @@ bot_settings(botid, newprice, newvolume)\n\
bot_status(botid)\n\ bot_status(botid)\n\
bot_stop(botid)\n\ bot_stop(botid)\n\
bot_pause(botid)\n\ bot_pause(botid)\n\
bot_resume(botid)\n\ zeroconf_deposit(weeks, amount, broadcast=0)\n\
zeroconf_claim(address, expiration=0)\n\
\"}")); \"}"));
//sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\
@ -183,6 +193,26 @@ bot_resume(botid)\n\
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
} }
else if ( strcmp(method,"zeroconf_deposit") == 0 )
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
if ( jint(argjson,"weeks") < 0 || jdouble(argjson,"amount") < 10. )
return(clonestr("{\"error\":\"deposit_create needs to have weeks and amount\"}"));
else return(LP_zeroconf_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast")));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
else if ( strcmp(method,"zeroconf_claim") == 0 )
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
if ( jstr(argjson,"address") == 0 )
return(clonestr("{\"error\":\"deposit_claim needs to have address\"}"));
else return(LP_zeroconf_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration")));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
/*else if ( strcmp(method,"sendmessage") == 0 ) /*else if ( strcmp(method,"sendmessage") == 0 )
{ {
if ( jobj(argjson,"method2") == 0 ) if ( jobj(argjson,"method2") == 0 )
@ -242,14 +272,13 @@ bot_resume(botid)\n\
} }
else if ( strcmp(method,"parselog") == 0 ) else if ( strcmp(method,"parselog") == 0 )
{ {
bits256 zero; int32_t n = LP_statslog_parse(); bits256 zero;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
return(LP_statslog_disp(n,2000000000,2000000000,"",zero)); return(jprint(LP_statslog_disp(2000000000,2000000000,"",zero,0,0),1));
} }
else if ( strcmp(method,"statsdisp") == 0 ) else if ( strcmp(method,"statsdisp") == 0 )
{ {
int32_t n = LP_statslog_parse(); return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1));
return(LP_statslog_disp(n,juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey")));
} }
else if ( strcmp(method,"secretaddresses") == 0 ) else if ( strcmp(method,"secretaddresses") == 0 )
{ {
@ -262,13 +291,31 @@ bot_resume(botid)\n\
{ {
uint32_t requestid,quoteid; uint32_t requestid,quoteid;
if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 )
{
return(basilisk_swapentry(requestid,quoteid)); return(basilisk_swapentry(requestid,quoteid));
}
else if ( coin[0] != 0 ) else if ( coin[0] != 0 )
return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); return(basilisk_swapentries(coin,0,jint(argjson,"limit")));
else if ( base[0] != 0 && rel[0] != 0 ) else if ( base[0] != 0 && rel[0] != 0 )
return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); return(basilisk_swapentries(base,rel,jint(argjson,"limit")));
else return(basilisk_swaplist(0,0)); else return(basilisk_swaplist(0,0));
} }
else if ( strcmp(method,"dynamictrust") == 0 )
{
struct LP_address *ap; char *coinaddr;
if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 )
{
if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"address",coinaddr);
jaddnum(retjson,"zcredits",dstr(ap->zeroconf_credits));
return(jprint(retjson,1));
}
}
return(clonestr("{\"error\":\"cant find address\"}"));
}
else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 )
return(retstr); return(retstr);
if ( base[0] != 0 && rel[0] != 0 ) if ( base[0] != 0 && rel[0] != 0 )
@ -280,6 +327,20 @@ bot_resume(botid)\n\
return(clonestr("{\"error\":\"couldnt set autoprice\"}")); return(clonestr("{\"error\":\"couldnt set autoprice\"}"));
else return(clonestr("{\"result\":\"success\"}")); else return(clonestr("{\"result\":\"success\"}"));
} }
else if ( strcmp(method,"pricearray") == 0 )
{
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"starttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"endtime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
}
else if ( strcmp(method,"tradesarray") == 0 )
{
return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}
if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}")); return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
price = jdouble(argjson,"price"); price = jdouble(argjson,"price");
@ -289,22 +350,10 @@ bot_resume(botid)\n\
return(clonestr("{\"error\":\"couldnt set price\"}")); return(clonestr("{\"error\":\"couldnt set price\"}"));
//else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 )
// return(clonestr("{\"error\":\"couldnt set price\"}")); // return(clonestr("{\"error\":\"couldnt set price\"}"));
else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); else if ( jint(argjson,"broadcast") != 0 || jobj(argjson,"broadcast") == 0 )
} return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio));
else if ( strcmp(method,"pricearray") == 0 ) else return(clonestr("{\"result\":\"success\"}"));
{
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
} }
/*else if ( strcmp(method,"pricearray") == 0 )
{
return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}*/
else if ( strcmp(method,"orderbook") == 0 ) else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration"))); return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"myprice") == 0 ) else if ( strcmp(method,"myprice") == 0 )
@ -361,13 +410,19 @@ bot_resume(botid)\n\
{ {
ptr->inactive = 0; ptr->inactive = 0;
cJSON *array; cJSON *array;
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
if ( LP_getheight(ptr) <= 0 ) if ( LP_getheight(ptr) <= 0 )
{ {
ptr->inactive = (uint32_t)time(NULL); ptr->inactive = (uint32_t)time(NULL);
return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); return(clonestr("{\"error\":\"coin cant be activated till synced\"}"));
} else LP_unspents_load(coin,ptr->smartaddr); }
else
{
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
LP_unspents_load(coin,ptr->smartaddr);
if ( strcmp(ptr->symbol,"KMD") == 0 )
LP_importaddress("KMD",BOTS_BONDADDRESS);
}
array = cJSON_CreateArray(); array = cJSON_CreateArray();
jaddi(array,LP_coinjson(ptr,0)); jaddi(array,LP_coinjson(ptr,0));
return(jprint(array,1)); return(jprint(array,1));
@ -397,20 +452,13 @@ bot_resume(botid)\n\
LP_address(ptr,coinaddr); LP_address(ptr,coinaddr);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 )
{ {
LP_listunspent_issue(coin,coinaddr,2); //LP_listunspent_issue(coin,coinaddr,2);
LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
//LP_smartutxos_push(ptr);
if ( ptr->electrum != 0 )
return(LP_unspents_filestr(coin,ptr->smartaddr));
else return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
}
else
{
return(clonestr("{\"error\":\"not my address\"}"));
} }
return(jprint(LP_listunspent(coin,coinaddr),1));
} }
return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); }
} else return(clonestr("{\"error\":\"no address specified\"}")); return(clonestr("{\"error\":\"no address specified\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}")); } else return(clonestr("{\"error\":\"cant find coind\"}"));
} }
else if ( strcmp(method,"balance") == 0 ) else if ( strcmp(method,"balance") == 0 )
@ -539,9 +587,22 @@ bot_resume(botid)\n\
} }
argjson = reqjson; argjson = reqjson;
} }
if ( strcmp(method,"gettradestatus") == 0 )
retstr = clonestr("{\"result\":\"success\"}");
}
else
{
if ( strcmp(method,"gettradestatus") == 0 )
return(LP_gettradestatus(j64bits(argjson,"aliceid")));
else if ( strcmp(method,"tradesarray") == 0 )
{
return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}
} }
// received response // received response
if ( strcmp(method,"postprice") == 0 ) if ( strcmp(method,"swapstatus") == 0 )
return(LP_swapstatus_recv(argjson));
else if ( strcmp(method,"postprice") == 0 )
return(LP_postprice_recv(argjson)); return(LP_postprice_recv(argjson));
else if ( strcmp(method,"postutxos") == 0 ) else if ( strcmp(method,"postutxos") == 0 )
return(LP_postutxos_recv(argjson)); return(LP_postutxos_recv(argjson));
@ -568,8 +629,15 @@ bot_resume(botid)\n\
else if ( strcmp(method,"tradestatus") == 0 ) else if ( strcmp(method,"tradestatus") == 0 )
{ {
bits256 zero; cJSON *tmpjson;
LP_tradecommand_log(argjson); LP_tradecommand_log(argjson);
printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); //printf("GOT TRADESTATUS! %s\n",jprint(argjson,0));
if ( LP_statslog_parse() > 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( (tmpjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps
free_json(tmpjson);
}
retstr = clonestr("{\"result\":\"success\"}"); retstr = clonestr("{\"result\":\"success\"}");
} }
else if ( strcmp(method,"wantnotify") == 0 ) else if ( strcmp(method,"wantnotify") == 0 )

45
iguana/exchanges/LP_include.h

@ -23,7 +23,7 @@
#define LP_MAJOR_VERSION "0" #define LP_MAJOR_VERSION "0"
#define LP_MINOR_VERSION "1" #define LP_MINOR_VERSION "1"
#define LP_BUILD_NUMBER "15256" #define LP_BUILD_NUMBER "15377"
#define LP_BARTERDEX_VERSION 1 #define LP_BARTERDEX_VERSION 1
#define LP_MAGICBITS 8 #define LP_MAGICBITS 8
@ -49,6 +49,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_KEEPALIVE 60
#define LP_ELECTRUM_MAXERRORS 777 #define LP_ELECTRUM_MAXERRORS 777
#define LP_MEMPOOL_TIMEINCR 10 #define LP_MEMPOOL_TIMEINCR 10
#define LP_SCREENWIDTH 1024
#define LP_MIN_PEERS 8 #define LP_MIN_PEERS 8
#define LP_MAX_PEERS 32 #define LP_MAX_PEERS 32
@ -82,7 +83,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_SWAPSTEP_TIMEOUT 30 #define LP_SWAPSTEP_TIMEOUT 30
#define LP_MIN_TXFEE 10000 #define LP_MIN_TXFEE 10000
#define LP_MINVOL 20 #define LP_MINVOL 20
#define LP_MINCLIENTVOL 100 #define LP_MINCLIENTVOL 20
#define LP_MINSIZE_TXFEEMULT 10 #define LP_MINSIZE_TXFEEMULT 10
#define LP_REQUIRED_TXFEE 0.8 #define LP_REQUIRED_TXFEE 0.8
@ -98,6 +99,10 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" #define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define BOTS_BONDADDRESS "RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P"
#define BOTS_BONDPUBKEY33 "03e641d22e1ff5a7d45c8880537e0b0a114d7b9fee2c18a6b4a8a80b6285292990"
#define LP_WEEKMULT (7 * 24 * 2600)
#define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT
//#define BASILISK_DISABLEWAITTX //#define BASILISK_DISABLEWAITTX
//#define BASILISK_DISABLESENDTX //#define BASILISK_DISABLESENDTX
@ -268,7 +273,7 @@ struct iguana_info
portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee; uint64_t txfee;
int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; uint32_t loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime,electrumzeroconf;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms;
char symbol[128],smartaddr[64],userpass[1024],serverport[128]; char symbol[128],smartaddr[64],userpass[1024],serverport[128];
// portfolio // portfolio
@ -317,7 +322,7 @@ struct LP_address
UT_hash_handle hh; UT_hash_handle hh;
struct LP_address_utxo *utxos; struct LP_address_utxo *utxos;
bits256 pubkey; bits256 pubkey;
int64_t balance,total; int64_t balance,total,zeroconf_credits;
uint32_t timestamp,n,unspenttime; uint32_t timestamp,n,unspenttime;
int32_t unspentheight; int32_t unspentheight;
char coinaddr[40]; char coinaddr[40];
@ -373,14 +378,27 @@ struct LP_pubkey_quote
uint8_t baseind,relind,numutxos,scale; uint8_t baseind,relind,numutxos,scale;
}; };
struct LP_swapstats
{
UT_hash_handle hh;
struct LP_quoteinfo Q;
bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent;
double qprice;
uint64_t aliceid;
uint32_t ind,methodind,finished,expired,lasttime;
char alicegui[32],bobgui[32];
};
struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; };
#define LP_MAXPRICEINFOS 256 #define LP_MAXPRICEINFOS 256
struct LP_pubkeyinfo struct LP_pubkey_info
{ {
UT_hash_handle hh; UT_hash_handle hh;
bits256 pubkey; bits256 pubkey;
struct LP_pubkey_quote *quotes; struct LP_pubkey_quote *quotes;
//float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; struct LP_pubswap *bobswaps,*aliceswaps;
//uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; uint64_t dynamictrust;
uint32_t timestamp,numerrors,lasttime; uint32_t timestamp,numerrors,lasttime;
int32_t istrusted; int32_t istrusted;
uint8_t rmd160[20],sig[65],pubsecp[33],siglen; uint8_t rmd160[20],sig[65],pubsecp[33],siglen;
@ -400,7 +418,7 @@ struct electrum_info
}; };
uint32_t LP_sighash(char *symbol,int32_t zcash); uint32_t LP_sighash(char *symbol,int32_t zcash);
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item); int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item);
int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp);
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson);
struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr); struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr);
@ -408,7 +426,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx);
uint32_t basilisk_requestid(struct basilisk_request *rp); uint32_t basilisk_requestid(struct basilisk_request *rp);
uint32_t basilisk_quoteid(struct basilisk_request *rp); uint32_t basilisk_quoteid(struct basilisk_request *rp);
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp); struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust);
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params);
uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend);
//double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub); //double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub);
@ -421,10 +439,12 @@ struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port);
uint64_t LP_value_extract(cJSON *obj,int32_t addinterest); uint64_t LP_value_extract(cJSON *obj,int32_t addinterest);
int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout); int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen); char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen);
int64_t LP_kmdvalue(char *symbol,int64_t satoshis);
int64_t LP_komodo_interest(bits256 txid,int64_t value); int64_t LP_komodo_interest(bits256 txid,int64_t value);
void LP_availableset(bits256 txid,int32_t vout); void LP_availableset(bits256 txid,int32_t vout);
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_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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock);
int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item);
void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag);
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired); 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);
@ -440,6 +460,7 @@ struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32); int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price); char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height); int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height);
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr);
int32_t _LP_utxos_remove(bits256 txid,int32_t vout); int32_t _LP_utxos_remove(bits256 txid,int32_t vout);
int32_t LP_utxos_remove(bits256 txid,int32_t vout); int32_t LP_utxos_remove(bits256 txid,int32_t vout);
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins);
@ -453,7 +474,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout);
int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_destaddr(char *destaddr,cJSON *item);
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration);
char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey); cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel);
uint32_t LP_heighttime(char *symbol,int32_t height); uint32_t LP_heighttime(char *symbol,int32_t height);
uint64_t LP_unspents_load(char *symbol,char *addr); uint64_t LP_unspents_load(char *symbol,char *addr);
int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
@ -472,6 +493,8 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr); void LP_postutxos(char *symbol,char *coinaddr);
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag); int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag);
uint16_t LP_randpeer(char *destip); uint16_t LP_randpeer(char *destip);
uint32_t LP_atomic_locktime(char *base,char *rel);
struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey);
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired);
char *LP_unspents_filestr(char *symbol,char *addr); char *LP_unspents_filestr(char *symbol,char *addr);
cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
@ -481,6 +504,8 @@ int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid);
double LP_getestimatedrate(struct iguana_info *coin); double LP_getestimatedrate(struct iguana_info *coin);
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout); struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout);
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout); struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout);
int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue);
struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr);
void LP_listunspent_query(char *symbol,char *coinaddr); void LP_listunspent_query(char *symbol,char *coinaddr);
int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype);

186
iguana/exchanges/LP_nativeDEX.c

@ -17,19 +17,20 @@
// LP_nativeDEX.c // LP_nativeDEX.c
// marketmaker // marketmaker
// //
// feature requests:
// electrum memleak?
// alice waiting for bestprice // alice waiting for bestprice
// MNZ getcoin strangeness // USD paxprice based USDvalue in portfolio
// [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, // cancel bid/ask
// trying to do bot_sell and the output he sent me is this
//{"base":"KMD","rel":"MNZ","basevolume":"0.08","minprice":5.608418011097937,"gui":"gecko","method":"bot_sell","userpass":"4011dddbfd920f9fab037907c2a13ba7eec207245487efa61cd0c484f8b1d607"}
//{"error":"not enough funds","coin":"KMD","abalance":0.00204856,"balance":9.9999,"relvolume":0.08,"txfees":0.001,"shortfall":-9.9189,"withdraw":
//i assume bot_sell detected he didn't had the proper utxos, tried to make some with the withdraw-method and failed with "not enough funds"
// the reason: bot_sell uses basevolume:0.08 and the withdraw-method uses relvolume:0.08
// https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG
// improve critical section detection when parallel trades //
// reduce mem: dont redundant store pubkey utxo info // bugs, validations:
// waiting for alice and alice disconnects, can find bobpayment based on Q.txid
// portfolio value based on ask?
// disable basilisk
// verify encrypted destpubkey, broadcast:0 setprice
// improve critical section detection when parallel trades
// previously, it used to show amount, kmd equiv, perc // previously, it used to show amount, kmd equiv, perc
// dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections
// bigendian architectures need to use little endian for sighash calcs // bigendian architectures need to use little endian for sighash calcs
@ -89,21 +90,21 @@ void LP_millistats_update(struct LP_millistats *mp)
} }
#include "LP_include.h" #include "LP_include.h"
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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex; 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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex;
int32_t LP_canbind; int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000]; char *Broadcaststr,*Reserved_msgs[2][1000];
int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos; struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins; struct iguana_info *LP_coins;
struct LP_pubkeyinfo *LP_pubkeyinfos; struct LP_pubkey_info *LP_pubkeyinfos;
struct rpcrequest_info *LP_garbage_collector; struct rpcrequest_info *LP_garbage_collector;
struct LP_address_utxo *LP_garbage_collector2; struct LP_address_utxo *LP_garbage_collector2;
//uint32_t LP_deadman_switch; //uint32_t LP_deadman_switch;
uint16_t LP_fixed_pairport,LP_publicport; uint16_t LP_fixed_pairport,LP_publicport;
uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical; uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount;
int32_t LP_mybussock = -1; int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1; int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1; int32_t LP_mypullsock = -1;
@ -181,6 +182,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
#include "LP_transaction.c" #include "LP_transaction.c"
#include "LP_stats.c" #include "LP_stats.c"
#include "LP_remember.c" #include "LP_remember.c"
#include "LP_zeroconf.c"
#include "LP_swap.c" #include "LP_swap.c"
#include "LP_peers.c" #include "LP_peers.c"
#include "LP_utxos.c" #include "LP_utxos.c"
@ -194,7 +196,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{ {
char *retstr=0; char *retstr=0; cJSON *retjson; bits256 zero;
if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 )
return(0); return(0);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 )
@ -205,7 +207,13 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson
//if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 &&
//LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0);
} }
} //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); }
else if ( LP_statslog_parse() > 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( (retjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps
free_json(retjson);
}
return(retstr); return(retstr);
} }
@ -315,8 +323,8 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
else else
{ {
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
/*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) ) if ( 0 && (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) )
printf("broadcast.(%s)\n",Broadcaststr);*/ printf("broadcast.(%s)\n",Broadcaststr);
LP_reserved_msg(0,"","",zero,jprint(reqjson,0)); LP_reserved_msg(0,"","",zero,jprint(reqjson,0));
} }
retstr = clonestr("{\"result\":\"success\"}"); retstr = clonestr("{\"result\":\"success\"}");
@ -538,6 +546,11 @@ void LP_coinsloop(void *_coins)
coin->longestchain = LP_getheight(coin); coin->longestchain = LP_getheight(coin);
if ( (ep= coin->electrum) != 0 ) if ( (ep= coin->electrum) != 0 )
{ {
if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 )
{
LP_zeroconf_deposits(coin);
coin->electrumzeroconf = (uint32_t)time(NULL);
}
if ( (backupep= ep->prev) == 0 ) if ( (backupep= ep->prev) == 0 )
backupep = ep; backupep = ep;
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
@ -547,8 +560,9 @@ void LP_coinsloop(void *_coins)
} }
HASH_ITER(hh,coin->addresses,ap,atmp) HASH_ITER(hh,coin->addresses,ap,atmp)
{ {
break;
//printf("call unspent %s\n",ap->coinaddr); //printf("call unspent %s\n",ap->coinaddr);
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
free_json(retjson); free_json(retjson);
} }
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
@ -647,7 +661,7 @@ void LP_coinsloop(void *_coins)
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport) int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport)
{ {
static uint32_t counter; static uint32_t counter,didzeroconf;
struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0;
if ( (origipaddr= myipaddr) == 0 ) if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1"; origipaddr = "127.0.0.1";
@ -656,6 +670,11 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{ {
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
if ( coin->inactive == 0 && didzeroconf == 0 && strcmp("KMD",coin->symbol) == 0 )
{
LP_zeroconf_deposits(coin);
didzeroconf = now;
}
if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 ) if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 )
{ {
//printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
@ -694,7 +713,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
{ {
if ( LP_getheight(coin) <= 0 ) if ( LP_getheight(coin) <= 0 )
coin->inactive = (uint32_t)time(NULL); coin->inactive = (uint32_t)time(NULL);
else LP_unspents_load(coin->symbol,coin->smartaddr); else
{
LP_unspents_load(coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") == 0 )
LP_importaddress("KMD",BOTS_BONDADDRESS);
}
if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 )
coin->txfee = LP_MIN_TXFEE; coin->txfee = LP_MIN_TXFEE;
} }
@ -811,7 +835,7 @@ void LP_privkeysloop(void *ctx)
void LP_swapsloop(void *ignore) void LP_swapsloop(void *ignore)
{ {
char *retstr; char *retstr; struct iguana_info *coin;
strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); strcpy(LP_swapsloop_stats.name,"LP_swapsloop");
LP_swapsloop_stats.threshold = 605000.; LP_swapsloop_stats.threshold = 605000.;
sleep(50); sleep(50);
@ -823,6 +847,124 @@ void LP_swapsloop(void *ignore)
if ( (retstr= basilisk_swapentry(0,0)) != 0 ) if ( (retstr= basilisk_swapentry(0,0)) != 0 )
free(retstr); free(retstr);
sleep(600); sleep(600);
if ( (coin= LP_coinfind("KMD")) != 0 )
LP_zeroconf_deposits(coin);
}
}
void gc_loop(void *arg)
{
uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0;
strcpy(LP_gcloop_stats.name,"gc_loop");
LP_gcloop_stats.threshold = 11000.;
while ( 1 )
{
flag = 0;
LP_millistats_update(&LP_gcloop_stats);
portable_mutex_lock(&LP_gcmutex);
DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp)
{
DL_DELETE(LP_garbage_collector,req);
//printf("garbage collect ipbits.%x\n",req->ipbits);
free(req);
flag++;
}
now = (uint32_t)time(NULL);
DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp)
{
if ( now > (uint32_t)up->spendheight+120 )
{
DL_DELETE(LP_garbage_collector2,up);
//char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight);
free(up);
}
flag++;
}
portable_mutex_unlock(&LP_gcmutex);
if ( 0 && flag != 0 )
printf("gc_loop.%d\n",flag);
sleep(10);
}
}
void queue_loop(void *arg)
{
struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0;
strcpy(queue_loop_stats.name,"queue_loop");
queue_loop_stats.threshold = 1000.;
while ( 1 )
{
LP_millistats_update(&queue_loop_stats);
//printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0);
n = nonz = flag = 0;
DL_FOREACH_SAFE(LP_Q,ptr,tmp)
{
n++;
flag = 0;
if ( ptr->sock >= 0 )
{
if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 )
{
if ( LP_sockcheck(ptr->sock) > 0 )
{
bits256 magic;
magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256)));
memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic));
if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen )
printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen);
else flag++;
ptr->sock = -1;
if ( ptr->peerind > 0 )
ptr->starttime = (uint32_t)time(NULL);
}
else
{
if ( ptr->notready++ > 1000 )
flag = 1;
}
}
}
else if ( 0 && time(NULL) > ptr->starttime+13 )
{
LP_crc32find(&duplicate,-1,ptr->crc32);
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag++;
}
else if ( 0 ) // too much beyond duplicate filter when network is busy
{
printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound);
ptr->peerind++;
if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 )
{
printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q);
flag++;
LP_Qerrors++;
}
}
}
if ( flag != 0 )
{
nonz++;
portable_mutex_lock(&LP_networkmutex);
DL_DELETE(LP_Q,ptr);
portable_mutex_unlock(&LP_networkmutex);
free(ptr);
ptr = 0;
break;
}
}
if ( arg == 0 )
break;
if ( nonz == 0 )
{
if ( IAMLP == 0 )
usleep(50000);
else usleep(10000);
}
} }
} }
@ -969,6 +1111,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_nanorecvsmutex); portable_mutex_init(&LP_nanorecvsmutex);
portable_mutex_init(&LP_tradebotsmutex); portable_mutex_init(&LP_tradebotsmutex);
portable_mutex_init(&LP_cJSONmutex); portable_mutex_init(&LP_cJSONmutex);
portable_mutex_init(&LP_logmutex);
myipaddr = clonestr("127.0.0.1"); myipaddr = clonestr("127.0.0.1");
#ifndef _WIN32 #ifndef _WIN32
#ifndef FROM_JS #ifndef FROM_JS
@ -1125,6 +1268,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
exit(-1); exit(-1);
} }
int32_t nonz; int32_t nonz;
LP_statslog_parse();
while ( 1 ) while ( 1 )
{ {
nonz = 0; nonz = 0;

116
iguana/exchanges/LP_network.c

@ -265,122 +265,6 @@ int32_t LP_peerindsock(int32_t *peerindp)
return(-1); return(-1);
} }
void gc_loop(void *arg)
{
uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0;
strcpy(LP_gcloop_stats.name,"gc_loop");
LP_gcloop_stats.threshold = 11000.;
while ( 1 )
{
flag = 0;
LP_millistats_update(&LP_gcloop_stats);
portable_mutex_lock(&LP_gcmutex);
DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp)
{
DL_DELETE(LP_garbage_collector,req);
//printf("garbage collect ipbits.%x\n",req->ipbits);
free(req);
flag++;
}
now = (uint32_t)time(NULL);
DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp)
{
if ( now > (uint32_t)up->spendheight+120 )
{
DL_DELETE(LP_garbage_collector2,up);
//char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight);
free(up);
}
flag++;
}
portable_mutex_unlock(&LP_gcmutex);
if ( 0 && flag != 0 )
printf("gc_loop.%d\n",flag);
sleep(10);
}
}
void queue_loop(void *arg)
{
struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0;
strcpy(queue_loop_stats.name,"queue_loop");
queue_loop_stats.threshold = 1000.;
while ( 1 )
{
LP_millistats_update(&queue_loop_stats);
//printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0);
n = nonz = flag = 0;
DL_FOREACH_SAFE(LP_Q,ptr,tmp)
{
n++;
flag = 0;
if ( ptr->sock >= 0 )
{
if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 )
{
if ( LP_sockcheck(ptr->sock) > 0 )
{
bits256 magic;
magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256)));
memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic));
if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen )
printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen);
else flag++;
ptr->sock = -1;
if ( ptr->peerind > 0 )
ptr->starttime = (uint32_t)time(NULL);
}
else
{
if ( ptr->notready++ > 1000 )
flag = 1;
}
}
}
else if ( 0 && time(NULL) > ptr->starttime+13 )
{
LP_crc32find(&duplicate,-1,ptr->crc32);
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag++;
}
else if ( 0 ) // too much beyond duplicate filter when network is busy
{
printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound);
ptr->peerind++;
if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 )
{
printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q);
flag++;
LP_Qerrors++;
}
}
}
if ( flag != 0 )
{
nonz++;
portable_mutex_lock(&LP_networkmutex);
DL_DELETE(LP_Q,ptr);
portable_mutex_unlock(&LP_networkmutex);
free(ptr);
ptr = 0;
break;
}
}
if ( arg == 0 )
break;
if ( nonz == 0 )
{
if ( IAMLP == 0 )
usleep(50000);
else usleep(10000);
}
}
}
void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack)
{ {
int32_t maxind,peerind = 0; //sentbytes, int32_t maxind,peerind = 0; //sentbytes,

19
iguana/exchanges/LP_ordermatch.c

@ -454,7 +454,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c
printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid);
return(-1); return(-1);
} }
if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)) > 0)) == 0 )
{ {
printf("cant initialize swap\n"); printf("cant initialize swap\n");
return(-1); return(-1);
@ -614,6 +614,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0);
return(clonestr("{\"error\":\"no price set\"}")); return(clonestr("{\"error\":\"no price set\"}"));
} }
//LP_RTmetrics_update(Q.srccoin,Q.destcoin);
printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value));
price = bid; price = bid;
if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) if ( (coin= LP_coinfind(Q.destcoin)) == 0 )
@ -625,7 +626,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 )
{ {
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)) > 0)) == 0 )
{ {
jaddstr(retjson,"error","couldnt swapinit"); jaddstr(retjson,"error","couldnt swapinit");
LP_availableset(Q.desttxid,Q.vout); LP_availableset(Q.desttxid,Q.vout);
@ -733,7 +734,7 @@ char *LP_bestfit(char *rel,double relvolume)
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}")); return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); return(clonestr("{\"error\":\"cant find utxo that is close enough in size\"}"));
return(jprint(LP_utxojson(autxo),1)); return(jprint(LP_utxojson(autxo),1));
} }
@ -786,7 +787,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
LP_quoteparse(&Q,argjson); LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
LP_tradecommand_log(argjson); LP_tradecommand_log(argjson);
printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f | RT.%d %d\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount);
retval = 1; retval = 1;
autxo = &A; autxo = &A;
butxo = &B; butxo = &B;
@ -907,7 +908,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( counter > 3 || price > bestprice ) // skip if late or bad price if ( counter > 3 || price > bestprice ) // skip if late or bad price
return(retval); return(retval);
} else return(retval); } else return(retval);
LP_RTmetrics_update(Q.srccoin,Q.destcoin); //LP_RTmetrics_update(Q.srccoin,Q.destcoin);
if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 )
{ {
printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash));
@ -1019,7 +1020,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma
struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey)
{ {
bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0;
maxiters = 100; maxiters = 100;
*ordermatchpricep = 0.; *ordermatchpricep = 0.;
*bestsatoshisp = *bestdestsatoshisp = 0; *bestsatoshisp = *bestdestsatoshisp = 0;
@ -1149,9 +1150,9 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
memset(pubkeys,0,sizeof(pubkeys)); memset(pubkeys,0,sizeof(pubkeys));
LP_txfees(&txfee,&desttxfee,base,rel); LP_txfees(&txfee,&desttxfee,base,rel);
destsatoshis = SATOSHIDEN * relvolume; destsatoshis = SATOSHIDEN * relvolume;
LP_address_utxo_reset(relcoin); //LP_address_utxo_reset(relcoin);
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 )
return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); return(clonestr("{\"error\":\"cant find alice utxo that is close enough in size\"}"));
//printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis)); //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis));
if ( destsatoshis - desttxfee < autxo->S.satoshis ) if ( destsatoshis - desttxfee < autxo->S.satoshis )
{ {
@ -1181,7 +1182,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); LP_mypriceset(&changed,autxo->coin,base,1. / maxprice);
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
#ifdef oldway #ifdef oldway
LP_RTmetrics_update(base,rel); //LP_RTmetrics_update(base,rel);
while ( 1 ) while ( 1 )
{ {
if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )

2
iguana/exchanges/LP_portfolio.c

@ -94,7 +94,7 @@ char *LP_portfolio()
if ( iter == 0 ) if ( iter == 0 )
{ {
//printf("from portfolio\n"); //printf("from portfolio\n");
LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519); //LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519);
coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr); coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr);
coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr); coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") != 0 ) if ( strcmp(coin->symbol,"KMD") != 0 )

66
iguana/exchanges/LP_prices.c

@ -18,7 +18,15 @@
// marketmaker // marketmaker
// //
struct LP_orderbookentry { bits256 pubkey; double price; uint64_t avesatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; }; struct LP_orderbookentry
{
bits256 pubkey;
double price;
uint64_t avesatoshis,maxsatoshis,depth,dynamictrust;
uint32_t timestamp;
int32_t numutxos;
char coinaddr[64];
};
struct LP_priceinfo struct LP_priceinfo
{ {
@ -49,7 +57,7 @@ struct LP_cacheinfo
} *LP_cacheinfos; } *LP_cacheinfos;
float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind)
{ {
struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64;
*numutxosp = 0; *numutxosp = 0;
@ -75,7 +83,7 @@ float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatos
return(0); return(0);
} }
void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo) void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo)
{ {
struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale;
DL_FOREACH_SAFE(pubp->quotes,pq,tmp) DL_FOREACH_SAFE(pubp->quotes,pq,tmp)
@ -214,9 +222,9 @@ struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout
return(ptr); return(ptr);
} }
struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20]) struct LP_pubkey_info *LP_pubkey_rmd160find(uint8_t rmd160[20])
{ {
struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_pubkey_info *pubp=0,*tmp;
portable_mutex_lock(&LP_pubkeymutex); portable_mutex_lock(&LP_pubkeymutex);
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{ {
@ -230,7 +238,7 @@ struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20])
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
{ {
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp; uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp;
HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap);
if ( ap != 0 && bits256_nonz(ap->pubkey) == 0 ) if ( ap != 0 && bits256_nonz(ap->pubkey) == 0 )
{ {
@ -246,7 +254,7 @@ struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
{ {
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp; uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp;
ap = calloc(1,sizeof(*ap)); ap = calloc(1,sizeof(*ap));
safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr));
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr); bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr);
@ -260,18 +268,18 @@ struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
return(ap); return(ap);
} }
struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey) struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey)
{ {
struct LP_pubkeyinfo *pubp=0; struct LP_pubkey_info *pubp=0;
portable_mutex_lock(&LP_pubkeymutex); portable_mutex_lock(&LP_pubkeymutex);
HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp);
portable_mutex_unlock(&LP_pubkeymutex); portable_mutex_unlock(&LP_pubkeymutex);
return(pubp); return(pubp);
} }
struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey) struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey)
{ {
char str[65]; struct LP_pubkeyinfo *pubp=0; char str[65]; struct LP_pubkey_info *pubp=0;
portable_mutex_lock(&LP_pubkeymutex); portable_mutex_lock(&LP_pubkeymutex);
HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp);
if ( pubp == 0 ) if ( pubp == 0 )
@ -294,7 +302,7 @@ struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey)
int32_t LP_pubkey_istrusted(bits256 pubkey) int32_t LP_pubkey_istrusted(bits256 pubkey)
{ {
struct LP_pubkeyinfo *pubp; struct LP_pubkey_info *pubp;
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
return(pubp->istrusted != 0); return(pubp->istrusted != 0);
return(0); return(0);
@ -302,7 +310,7 @@ int32_t LP_pubkey_istrusted(bits256 pubkey)
char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval) char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval)
{ {
struct LP_pubkeyinfo *pubp; struct LP_pubkey_info *pubp;
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
{ {
pubp->istrusted = trustval; pubp->istrusted = trustval;
@ -313,7 +321,7 @@ char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval)
char *LP_pubkey_trusted() char *LP_pubkey_trusted()
{ {
struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray(); struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{ {
if ( pubp->istrusted != 0 ) if ( pubp->istrusted != 0 )
@ -343,7 +351,7 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
return(metric); return(metric);
} }
cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) cJSON *LP_pubkeyjson(struct LP_pubkey_info *pubp)
{ {
int32_t baseid,relid,numutxos; int64_t avesatoshis,maxsatoshis; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj; int32_t baseid,relid,numutxos; int64_t avesatoshis,maxsatoshis; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj;
obj = cJSON_CreateObject(); obj = cJSON_CreateObject();
@ -380,7 +388,7 @@ cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp)
char *LP_prices() char *LP_prices()
{ {
struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray(); struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{ {
jaddi(array,LP_pubkeyjson(pubp)); jaddi(array,LP_pubkeyjson(pubp));
@ -390,7 +398,7 @@ char *LP_prices()
/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) /*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
{ {
struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; struct LP_pubkey_info *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); now = (uint32_t)time(NULL);
pubkey = jbits256(obj,"pubkey"); pubkey = jbits256(obj,"pubkey");
if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
@ -555,7 +563,7 @@ char *LP_myprices()
int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
{ {
struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; struct LP_pubkey_info *pubp;
*changedp = 0; *changedp = 0;
if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {
@ -750,11 +758,12 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op)
jaddnum(item,"depth",dstr(op->depth)*0.8); jaddnum(item,"depth",dstr(op->depth)*0.8);
jaddbits256(item,"pubkey",op->pubkey); jaddbits256(item,"pubkey",op->pubkey);
jaddnum(item,"age",time(NULL)-op->timestamp); jaddnum(item,"age",time(NULL)-op->timestamp);
jaddnum(item,"zcredits",dstr(op->dynamictrust));
} }
return(item); return(item);
} }
struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance) struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance,uint64_t dynamictrust)
{ {
struct LP_orderbookentry *op; struct LP_orderbookentry *op;
if ( (op= calloc(1,sizeof(*op))) != 0 ) if ( (op= calloc(1,sizeof(*op))) != 0 )
@ -767,13 +776,14 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d
op->pubkey = pubkey; op->pubkey = pubkey;
op->timestamp = timestamp; op->timestamp = timestamp;
op->depth = balance; op->depth = balance;
op->dynamictrust = dynamictrust;
} }
return(op); return(op);
} }
void LP_pubkeys_query() void LP_pubkeys_query()
{ {
uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkeyinfo *pubp=0,*tmp; uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkey_info *pubp=0,*tmp;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
memset(zeroes,0,sizeof(zeroes)); memset(zeroes,0,sizeof(zeroes));
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
@ -792,7 +802,7 @@ void LP_pubkeys_query()
int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration)
{ {
char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis; char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkey_info *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis;
if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 )
baseid = basepp->ind; baseid = basepp->ind;
else return(num); else return(num);
@ -827,7 +837,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
} }
//printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total)); //printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total));
} }
if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 ) if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance,pubp->dynamictrust)) != 0 )
{ {
*arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1));
(*arrayp)[num++] = op; (*arrayp)[num++] = op;
@ -977,6 +987,16 @@ uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance)
return(KMDvalue); return(KMDvalue);
} }
int64_t LP_kmdvalue(char *symbol,int64_t satoshis)
{
struct iguana_info *coin; int64_t kmdvalue = 0;
if ( (coin= LP_coinfind(symbol)) != 0 )
kmdvalue = LP_KMDvalue(coin,satoshis);
if ( kmdvalue == 0 )
kmdvalue = satoshis;
return(kmdvalue);
}
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32])
{ {
LP_priceinfoupdate(base,rel,price); LP_priceinfoupdate(base,rel,price);
@ -1112,7 +1132,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i
void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo)
{ {
struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp;
//printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey));
if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {

19
iguana/exchanges/LP_remember.c

@ -389,6 +389,7 @@ uint32_t LP_extract(uint32_t requestid,uint32_t quoteid,char *rootfname,char *fi
t = (t << 8) | redeem[2]; t = (t << 8) | redeem[2];
//printf("extracted timestamp.%u\n",t); //printf("extracted timestamp.%u\n",t);
} }
free_json(json);
} }
free(filestr); free(filestr);
} }
@ -483,7 +484,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
if ( rswap->sentflags[i] != 0 ) if ( rswap->sentflags[i] != 0 )
jaddistr(array,txnames[i]); jaddistr(array,txnames[i]);
if ( rswap->txbytes[i] != 0 ) if ( rswap->txbytes[i] != 0 )
free(rswap->txbytes[i]); free(rswap->txbytes[i]), rswap->txbytes[i] = 0;
} }
jadd(item,"sentflags",array); jadd(item,"sentflags",array);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
@ -637,6 +638,7 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
} }
} }
} }
free_json(txobj);
} }
rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent); rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent);
rswap->finishedflag = rswap->origfinishedflag; rswap->finishedflag = rswap->origfinishedflag;
@ -773,6 +775,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
//printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); //printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value));
} }
} }
free_json(txobj);
} //else printf("no symbol\n"); } //else printf("no symbol\n");
free(fstr); free(fstr);
} else if ( 0 && rswap->finishedflag == 0 ) } else if ( 0 && rswap->finishedflag == 0 )
@ -1140,6 +1143,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
jaddstr(item,"method","tradestatus"); jaddstr(item,"method","tradestatus");
jaddnum(item,"finishtime",rswap.finishtime); jaddnum(item,"finishtime",rswap.finishtime);
jaddstr(item,"gui",G.gui); jaddstr(item,"gui",G.gui);
//jaddbits256(item,"srchash",rswap.Q.srchash);
//jaddbits256(item,"desthash",rswap.desthash);
itemstr = jprint(item,0); itemstr = jprint(item,0);
fprintf(fp,"%s\n",itemstr); fprintf(fp,"%s\n",itemstr);
LP_tradecommand_log(item); LP_tradecommand_log(item);
@ -1150,7 +1155,10 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
fclose(fp); fclose(fp);
} }
} }
return(item); for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
if ( rswap.txbytes[i] != 0 )
free(rswap.txbytes[i]), rswap.txbytes[i] = 0;
return(item);
} }
char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
@ -1234,13 +1242,6 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
else if ( Ktotal < 0 && Btotal > 0 ) else if ( Ktotal < 0 && Btotal > 0 )
jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); jaddnum(retjson,"avesell",(double)-Btotal/Ktotal);
} }
/*array = cJSON_CreateArray();
for (i=0; i<sizeof(myinfo->linfos)/sizeof(*myinfo->linfos); i++)
{
if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 )
jaddi(array,linfo_json(&myinfo->linfos[i]));
}
jadd(retjson,"quotes",array);*/
portable_mutex_unlock(&LP_swaplistmutex); portable_mutex_unlock(&LP_swaplistmutex);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }

111
iguana/exchanges/LP_rpc.c

@ -586,7 +586,7 @@ cJSON *LP_validateaddress(char *symbol,char *address)
} }
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20); bitcoin_address(coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20);
jadd(retjson,"ismine",strcmp(address,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse()); jadd(retjson,"ismine",strcmp(address,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse());
jadd(retjson,"iswatchonly",cJSON_CreateFalse()); jadd(retjson,"iswatchonly",cJSON_CreateTrue());
jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse()); jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse());
return(retjson); return(retjson);
} }
@ -599,12 +599,30 @@ cJSON *LP_validateaddress(char *symbol,char *address)
int32_t LP_address_ismine(char *symbol,char *address) int32_t LP_address_ismine(char *symbol,char *address)
{ {
int32_t doneflag = 0; cJSON *retjson; int32_t doneflag = 0; cJSON *retjson,*obj;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(0); return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{ {
if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 ) if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 )
{
doneflag = 1;
//printf("%s ismine (%s)\n",address,jprint(retjson,0));
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
return(doneflag);
}
int32_t LP_address_iswatched(char *symbol,char *address)
{
int32_t doneflag = 0; cJSON *retjson,*obj;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( (obj= jobj(retjson,"iswatched")) != 0 && is_cJSON_True(obj) != 0 )
{ {
doneflag = 1; doneflag = 1;
//printf("%s ismine (%s)\n",address,jprint(retjson,0)); //printf("%s ismine (%s)\n",address,jprint(retjson,0));
@ -635,26 +653,76 @@ int32_t LP_address_isvalid(char *symbol,char *address)
cJSON *LP_listunspent(char *symbol,char *coinaddr) cJSON *LP_listunspent(char *symbol,char *coinaddr)
{ {
char buf[128]; cJSON *retjson; int32_t numconfs; struct iguana_info *coin; char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}")); return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol); coin = LP_coinfind(symbol);
//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
return(cJSON_Parse("{\"error\":\"no coin\"}")); return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
{ {
if ( LP_address_ismine(symbol,coinaddr) > 0 ) if ( (ap= LP_addressfind(coin,symbol)) != 0 )
{
if ( ap->unspenttime == 0 )
usecache = 0;
else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 )
usecache = 0;
if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
return(retjson);
}
}
if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatched(symbol,coinaddr) > 0 )
{ {
if ( strcmp(symbol,"BTC") == 0 ) if ( strcmp(symbol,"BTC") == 0 )
numconfs = 0; numconfs = 0;
else numconfs = 1; else numconfs = 1;
sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr);
return(bitcoin_json(coin,"listunspent",buf)); //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
retjson = bitcoin_json(coin,"listunspent",buf);
retstr = jprint(retjson,0);
LP_unspents_cache(coin->symbol,coinaddr,retstr,1);
free(retstr);
if ( ap != 0 )
ap->unspenttime = (uint32_t)time(NULL);
return(retjson);
} else return(LP_address_utxos(coin,coinaddr,0)); } else return(LP_address_utxos(coin,coinaddr,0));
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1));
} }
cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr)
{
char buf[128],*addr; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol);
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum == 0 )
{
sprintf(buf,"[1, false, true]");
if ( (array= bitcoin_json(coin,"listreceivedbyaddress",buf)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (addr= jstr(item,"address")) != 0 && strcmp(addr,coinaddr) == 0 )
{
retjson = jduplicate(jobj(item,"txids"));
free_json(array);
return(retjson);
}
}
}
}
return(cJSON_Parse("[]"));
} else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr));
}
int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{ {
struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0; struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0;
@ -664,7 +732,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{ {
if ( coin->electrum != 0 ) if ( coin->electrum != 0 )
{ {
if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)) != 0 ) if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag)) != 0 )
{ {
n = cJSON_GetArraySize(retjson); n = cJSON_GetArraySize(retjson);
//printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0)); //printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0));
@ -672,17 +740,8 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
} }
else else
{ {
if ( strcmp(coin->smartaddr,coinaddr) == 0 ) retjson = LP_listunspent(symbol,coinaddr);
{ coin->numutxos = cJSON_GetArraySize(retjson);
retjson = LP_listunspent(symbol,coinaddr);
coin->numutxos = cJSON_GetArraySize(retjson);
//printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr);
}
else if ( IAMLP == 0 )
{
//printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
LP_listunspent_query(coin->symbol,coin->smartaddr);
}
if ( retjson != 0 ) if ( retjson != 0 )
{ {
n = cJSON_GetArraySize(retjson); n = cJSON_GetArraySize(retjson);
@ -998,17 +1057,19 @@ bits256 LP_getbestblockhash(struct iguana_info *coin)
char *LP_blockhashstr(char *symbol,int32_t height) char *LP_blockhashstr(char *symbol,int32_t height)
{ {
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin; char params[64],*retstr; struct iguana_info *coin; //cJSON *array;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(0); return(0);
coin = LP_coinfind(symbol); coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 ) if ( coin == 0 || coin->electrum != 0 )
return(0); return(0);
array = cJSON_CreateArray(); //array = cJSON_CreateArray();
jaddinum(array,height); //jaddinum(array,height);
paramstr = jprint(array,1); //paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr); sprintf(params,"[%d]",height);
free(paramstr); retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",params);
//free(paramstr);
//printf("blockhashstr.(%s)\n",retstr);
return(retstr); return(retstr);
} }

34
iguana/exchanges/LP_signatures.c

@ -276,7 +276,7 @@ bits256 LP_utxos_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,bits
int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,bits256 utxoshash) int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,bits256 utxoshash)
{ {
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkeyinfo *pubp; static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkey_info *pubp;
if ( ctx == 0 ) if ( ctx == 0 )
ctx = bitcoin_ctx(); ctx = bitcoin_ctx();
pubp = LP_pubkeyfind(pubkey); pubp = LP_pubkeyfind(pubkey);
@ -362,7 +362,7 @@ struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; };
char *LP_postutxos_recv(cJSON *argjson) char *LP_postutxos_recv(cJSON *argjson)
{ {
struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkeyinfo *pubp; struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkey_info *pubp;
printf("LP_postutxos_recv deprecated\n"); printf("LP_postutxos_recv deprecated\n");
pubkey = jbits256(argjson,"pubkey"); pubkey = jbits256(argjson,"pubkey");
pubp = LP_pubkeyfind(pubkey); pubp = LP_pubkeyfind(pubkey);
@ -416,7 +416,7 @@ int32_t LP_utxosQ_process()
int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64) int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64)
{ {
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkeyinfo *pubp; static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkey_info *pubp;
if ( ctx == 0 ) if ( ctx == 0 )
ctx = bitcoin_ctx(); ctx = bitcoin_ctx();
pubp = LP_pubkeyfind(pubkey); pubp = LP_pubkeyfind(pubkey);
@ -454,7 +454,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
struct iguana_info *basecoin,*relcoin; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; struct iguana_info *basecoin,*relcoin; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson;
reqjson = cJSON_CreateObject(); reqjson = cJSON_CreateObject();
// LP_addsig // LP_addsig
if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 )
{ {
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
jaddbits256(reqjson,"pubkey",G.LP_mypub25519); jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
@ -521,7 +521,7 @@ int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub
return(LP_bitcoinsig_add(item,priv,pubsecp,sighash)); return(LP_bitcoinsig_add(item,priv,pubsecp,sighash));
} }
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item)
{ {
int32_t i,len,siglen,retval=-1; uint8_t rmd160[20],checkrmd160[20],pubsecp[33],sig[65],zeroes[20]; char *sigstr,*hexstr,*pubsecpstr; int32_t i,len,siglen,retval=-1; uint8_t rmd160[20],checkrmd160[20],pubsecp[33],sig[65],zeroes[20]; char *sigstr,*hexstr,*pubsecpstr;
if ( (hexstr= jstr(item,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) if ( (hexstr= jstr(item,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) )
@ -603,7 +603,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock)
char *LP_notify_recv(cJSON *argjson) char *LP_notify_recv(cJSON *argjson)
{ {
bits256 pub; struct LP_pubkeyinfo *pubp; char *ipaddr; bits256 pub; struct LP_pubkey_info *pubp; char *ipaddr;
pub = jbits256(argjson,"pub"); pub = jbits256(argjson,"pub");
if ( bits256_nonz(pub) != 0 ) if ( bits256_nonz(pub) != 0 )
{ {
@ -700,8 +700,8 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
{ {
if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 )
{ {
LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash);
LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash);
} }
else else
{ {
@ -718,13 +718,15 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
msg = jprint(reqjson,1); msg = jprint(reqjson,1);
msg2 = clonestr(msg); msg2 = clonestr(msg);
printf("QUERY.(%s)\n",msg); printf("QUERY.(%s)\n",msg);
memset(&zero,0,sizeof(zero)); if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 )
portable_mutex_lock(&LP_reservedmutex); {
if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) memset(&zero,0,sizeof(zero));
Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 )
Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; Reserved_msgs[1][num_Reserved_msgs[1]++] = msg;
//LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2); if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 )
portable_mutex_unlock(&LP_reservedmutex); Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2;
portable_mutex_unlock(&LP_reservedmutex);
} else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg2);
} }

11
iguana/exchanges/LP_socket.c

@ -606,12 +606,9 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
//LP_postutxos(coin->symbol,addr); //LP_postutxos(coin->symbol,addr);
updatedflag = 1; updatedflag = 1;
} }
if ( strcmp(addr,coin->smartaddr) == 0 ) retstr = jprint(retjson,0);
{ LP_unspents_cache(coin->symbol,addr,retstr,1);
retstr = jprint(retjson,0); free(retstr);
LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1);
free(retstr);
}
if ( ap != 0 ) if ( ap != 0 )
{ {
ap->unspenttime = (uint32_t)time(NULL); ap->unspenttime = (uint32_t)time(NULL);
@ -627,7 +624,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
} }
if ( retjson == 0 ) if ( retjson == 0 )
{ {
if ( strcmp(addr,coin->smartaddr) == 0 && (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) if ( (retstr= LP_unspents_filestr(symbol,addr)) != 0 )
{ {
retjson = cJSON_Parse(retstr); retjson = cJSON_Parse(retstr);
free(retstr); free(retstr);

23
iguana/exchanges/LP_statemachine.c

@ -3039,6 +3039,29 @@ if ( (0) )
#undef aptr #undef aptr
#undef bptr #undef bptr
}*/ }*/
/*if ( (sobj= jobj(v,"scriptPubKey")) != 0 )
{
if ( (scriptstr= jstr(sobj,"hex")) != 0 )
{
printf("amount64 %.8f vout.%d (%s) weeki.%d %.8f (%s)\n",dstr(amount64),vout,jprint(v,0),weeki,dstr(satoshis),scriptstr);
len = (int32_t)strlen(scriptstr) >> 1;
if ( len <= sizeof(spendscript)/sizeof(*spendscript) )
{
decode_hex(spendscript,len,scriptstr);
if ( spendscript[11] == 33 )
{
pub33 = &spendscript[12];
redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,pub33);
if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 )
{
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33);
printf("%s -> matched %s script t.%u weeki.%d deposit %.8f\n",coinaddr,p2shaddr,timestamp,(timestamp-LP_FIRSTWEEKTIME)/LP_WEEKMULT,dstr(satoshis));
// add to pubp->credits;
}
}
}
}
}*/
/*portable_mutex_lock(&ep->pendingQ.mutex); /*portable_mutex_lock(&ep->pendingQ.mutex);
if ( ep->pendingQ.list != 0 ) if ( ep->pendingQ.list != 0 )

322
iguana/exchanges/LP_stats.c

@ -20,32 +20,17 @@
#define LP_STATSLOG_FNAME "stats.log" #define LP_STATSLOG_FNAME "stats.log"
struct LP_swapstats struct LP_swapstats *LP_swapstats,*LP_RTstats;
{
UT_hash_handle hh;
struct LP_quoteinfo Q;
bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent;
double qprice;
uint64_t aliceid;
uint32_t ind,methodind,finished,expired;
char alicegui[32],bobgui[32];
} *LP_swapstats;
int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); int32_t LP_statslog_parsequote(char *method,cJSON *lineobj);
char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" };
uint32_t LP_atomic_locktime(char *base,char *rel)
{
if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 )
return(INSTANTDEX_LOCKTIME);
else return(INSTANTDEX_LOCKTIME * 10);
}
static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids; static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids;
void LP_tradecommand_log(cJSON *argjson) void LP_tradecommand_log(cJSON *argjson)
{ {
static FILE *logfp; char *jsonstr; static FILE *logfp; char *jsonstr;
portable_mutex_lock(&LP_logmutex);
if ( logfp == 0 ) if ( logfp == 0 )
{ {
if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 )
@ -59,6 +44,7 @@ void LP_tradecommand_log(cJSON *argjson)
free(jsonstr); free(jsonstr);
fflush(logfp); fflush(logfp);
} }
portable_mutex_unlock(&LP_logmutex);
} }
void LP_statslog_parseline(cJSON *lineobj) void LP_statslog_parseline(cJSON *lineobj)
@ -130,18 +116,22 @@ int32_t LP_statslog_parse()
struct LP_swapstats *LP_swapstats_find(uint64_t aliceid) struct LP_swapstats *LP_swapstats_find(uint64_t aliceid)
{ {
struct LP_swapstats *sp; struct LP_swapstats *sp;
HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp); HASH_FIND(hh,LP_RTstats,&aliceid,sizeof(aliceid),sp);
if ( sp == 0 )
HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp);
return(sp); return(sp);
} }
struct LP_swapstats *LP_swapstats_add(uint64_t aliceid) struct LP_swapstats *LP_swapstats_add(uint64_t aliceid,int32_t RTflag)
{ {
struct LP_swapstats *sp; struct LP_swapstats *sp;
if ( (sp= LP_swapstats_find(aliceid)) == 0 ) if ( (sp= LP_swapstats_find(aliceid)) == 0 )
{ {
sp = calloc(1,sizeof(*sp)); sp = calloc(1,sizeof(*sp));
sp->aliceid = aliceid; sp->aliceid = aliceid;
HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp); if ( RTflag != 0 )
HASH_ADD(hh,LP_RTstats,aliceid,sizeof(aliceid),sp);
else HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp);
} }
return(LP_swapstats_find(aliceid)); return(LP_swapstats_find(aliceid));
} }
@ -180,6 +170,7 @@ bits256 LP_swapstats_txid(cJSON *argjson,char *name,bits256 oldtxid)
int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSON *lineobj) int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSON *lineobj)
{ {
char *statusstr,*base,*rel,gui[64]; uint32_t requestid,quoteid; uint64_t satoshis,destsatoshis; char *statusstr,*base,*rel,gui[64]; uint32_t requestid,quoteid; uint64_t satoshis,destsatoshis;
sp->lasttime = (uint32_t)time(NULL);
safecopy(gui,sp->Q.gui,sizeof(gui)); safecopy(gui,sp->Q.gui,sizeof(gui));
if ( strcmp(LP_stats_methods[sp->methodind],"tradestatus") == 0 ) if ( strcmp(LP_stats_methods[sp->methodind],"tradestatus") == 0 )
{ {
@ -189,7 +180,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
quoteid = juint(lineobj,"quoteid"); quoteid = juint(lineobj,"quoteid");
satoshis = jdouble(lineobj,"srcamount") * SATOSHIDEN; satoshis = jdouble(lineobj,"srcamount") * SATOSHIDEN;
destsatoshis = jdouble(lineobj,"destamount") * SATOSHIDEN; destsatoshis = jdouble(lineobj,"destamount") * SATOSHIDEN;
if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && ((satoshis+2*sp->Q.txfee)|1) == (sp->Q.satoshis|1) && ((destsatoshis+2*sp->Q.desttxfee)|1) == (sp->Q.destsatoshis|1) ) if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && llabs((int64_t)(satoshis+2*sp->Q.txfee) - (int64_t)sp->Q.satoshis) <= sp->Q.txfee && llabs((int64_t)(destsatoshis+2*sp->Q.desttxfee) - (int64_t)sp->Q.destsatoshis) <= sp->Q.desttxfee )
{ {
sp->bobdeposit = LP_swapstats_txid(lineobj,"bobdeposit",sp->bobdeposit); sp->bobdeposit = LP_swapstats_txid(lineobj,"bobdeposit",sp->bobdeposit);
sp->alicepayment = LP_swapstats_txid(lineobj,"alicepayment",sp->alicepayment); sp->alicepayment = LP_swapstats_txid(lineobj,"alicepayment",sp->alicepayment);
@ -208,7 +199,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
} }
else else
{ {
if ( requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid ) //if ( requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid )
printf("mismatched tradestatus aliceid.%22llu b%s/%s r%s/%s r%u/%u q%u/%u %.8f/%.8f -> %.8f/%.8f\n",(long long)sp->aliceid,base,sp->Q.srccoin,rel,sp->Q.destcoin,requestid,sp->Q.R.requestid,quoteid,sp->Q.R.quoteid,dstr(satoshis+2*sp->Q.txfee),dstr(sp->Q.satoshis),dstr(destsatoshis+2*sp->Q.desttxfee),dstr(sp->Q.destsatoshis)); printf("mismatched tradestatus aliceid.%22llu b%s/%s r%s/%s r%u/%u q%u/%u %.8f/%.8f -> %.8f/%.8f\n",(long long)sp->aliceid,base,sp->Q.srccoin,rel,sp->Q.destcoin,requestid,sp->Q.R.requestid,quoteid,sp->Q.R.quoteid,dstr(satoshis+2*sp->Q.txfee),dstr(sp->Q.satoshis),dstr(destsatoshis+2*sp->Q.desttxfee),dstr(sp->Q.destsatoshis));
return(-1); return(-1);
} }
@ -222,7 +213,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
{ {
static uint32_t unexpected; static uint32_t unexpected;
struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; struct LP_swapstats *sp,*tmp; struct LP_pubkey_info *pubp; struct LP_pubswap *ptr; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,RTflag,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *statusstr,*gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
memset(numtrades,0,sizeof(numtrades)); memset(numtrades,0,sizeof(numtrades));
memset(basevols,0,sizeof(basevols)); memset(basevols,0,sizeof(basevols));
memset(relvols,0,sizeof(relvols)); memset(relvols,0,sizeof(relvols));
@ -242,8 +233,11 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
if ( (sp= LP_swapstats_find(aliceid)) != 0 ) if ( (sp= LP_swapstats_find(aliceid)) != 0 )
{ {
sp->methodind = methodind; sp->methodind = methodind;
sp->Q.R.requestid = requestid;
sp->Q.R.quoteid = quoteid;
if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) if ( LP_swapstats_update(sp,&Q,lineobj) == 0 )
flag = 1; flag = 1;
//else printf("LP_swapstats_update error\n");
} }
if ( flag == 0 ) if ( flag == 0 )
{ {
@ -253,14 +247,16 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
{ {
sp->methodind = methodind; sp->methodind = methodind;
if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) if ( LP_swapstats_update(sp,&Q,lineobj) == 0 )
{
flag = 1; flag = 1;
else printf("error after delayed match\n"); break;
break; }
printf("error after delayed match\n");
} }
} }
} }
if ( flag == 0 ) if ( flag == 0 )
printf("unexpected.%d tradestatus.(%s)\n",unexpected++,jprint(lineobj,0)); printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0));
return(0); return(0);
} }
if ( LP_quoteparse(&Q,lineobj) < 0 ) if ( LP_quoteparse(&Q,lineobj) < 0 )
@ -290,6 +286,9 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
destvout = jint(lineobj,"destvout"); destvout = jint(lineobj,"destvout");
feetxid = jbits256(lineobj,"feetxid"); feetxid = jbits256(lineobj,"feetxid");
feevout = jint(lineobj,"feevout"); feevout = jint(lineobj,"feevout");
if ( (statusstr= jstr(lineobj,"status")) != 0 && strcmp(statusstr,"finished") == 0 )
RTflag = 0;
else RTflag = 1;
qprice = ((double)destsatoshis / (satoshis - txfee)); qprice = ((double)destsatoshis / (satoshis - txfee));
//printf("%s/v%d %s/v%d\n",bits256_str(str,desttxid),destvout,bits256_str(str2,feetxid),feevout); //printf("%s/v%d %s/v%d\n",bits256_str(str,desttxid),destvout,bits256_str(str2,feetxid),feevout);
aliceid = LP_aliceid_calc(desttxid,destvout,feetxid,feevout); aliceid = LP_aliceid_calc(desttxid,destvout,feetxid,feevout);
@ -305,16 +304,31 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
} }
else else
{ {
if ( (sp= LP_swapstats_add(aliceid)) != 0 ) //printf("create aliceid.%llu\n",(long long)aliceid);
if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 )
{ {
sp->Q = Q; sp->Q = Q;
sp->qprice = qprice; sp->qprice = qprice;
sp->methodind = methodind; sp->methodind = methodind;
sp->ind = LP_aliceids++; sp->ind = LP_aliceids++;
sp->lasttime = (uint32_t)time(NULL);
strcpy(sp->bobgui,"nogui"); strcpy(sp->bobgui,"nogui");
strcpy(sp->alicegui,"nogui"); strcpy(sp->alicegui,"nogui");
//LP_swapstats_line(numtrades,basevols,relvols,line,sp); if ( sp->finished == 0 && sp->expired == 0 )
//printf("%s\n",line); {
if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 )
{
ptr = calloc(1,sizeof(*ptr));
ptr->swap = sp;
DL_APPEND(pubp->bobswaps,ptr);
}
if ( (pubp= LP_pubkeyadd(sp->Q.desthash)) != 0 )
{
ptr = calloc(1,sizeof(*ptr));
ptr->swap = sp;
DL_APPEND(pubp->aliceswaps,ptr);
}
}
} else printf("unexpected LP_swapstats_add failure\n"); } else printf("unexpected LP_swapstats_add failure\n");
} }
if ( sp != 0 ) if ( sp != 0 )
@ -330,11 +344,103 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
return(duplicate == 0); return(duplicate == 0);
} }
char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey) cJSON *LP_swapstats_json(struct LP_swapstats *sp)
{
cJSON *item = cJSON_CreateObject();
jaddnum(item,"timestamp",sp->Q.timestamp);
jadd64bits(item,"aliceid",sp->aliceid);
jaddbits256(item,"src",sp->Q.srchash);
jaddstr(item,"base",sp->Q.srccoin);
jaddnum(item,"basevol",dstr(sp->Q.satoshis));
jaddbits256(item,"dest",sp->Q.desthash);
jaddstr(item,"rel",sp->Q.destcoin);
jaddnum(item,"relvol",dstr(sp->Q.destsatoshis));
jaddnum(item,"price",sp->qprice);
jaddnum(item,"requestid",sp->Q.R.requestid);
jaddnum(item,"quoteid",sp->Q.R.quoteid);
jaddnum(item,"finished",sp->finished);
jaddnum(item,"expired",sp->expired);
jaddnum(item,"ind",sp->methodind);
//jaddstr(item,"line",line);
return(item);
}
char *LP_swapstatus_recv(cJSON *argjson)
{
struct LP_swapstats *sp; int32_t methodind;
//printf("swapstatus.(%s)\n",jprint(argjson,0));
if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 )
{
sp->lasttime = (uint32_t)time(NULL);
if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) )
{
if ( sp->finished == 0 && sp->expired == 0 )
printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],juint(argjson,"finished"),juint(argjson,"expired"));
sp->methodind = methodind;
sp->finished = juint(argjson,"finished");
sp->expired = juint(argjson,"expired");
}
}
return(clonestr("{\"result\":\"success\"}"));
}
char *LP_gettradestatus(uint64_t aliceid)
{ {
cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,dispflag,numtrades[LP_MAXPRICEINFOS]; char line[1024]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; struct LP_swapstats *sp; cJSON *reqjson; bits256 zero;
//printf("gettradestatus.(%llu)\n",(long long)aliceid);
if ( (sp= LP_swapstats_find(aliceid)) != 0 && time(NULL) > sp->lasttime+60 )
{
if ( (reqjson= LP_swapstats_json(sp)) != 0 )
{
jaddstr(reqjson,"method","swapstatus");
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
}
}
return(clonestr("{\"error\":\"cant find aliceid\"}"));
}
int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttime,uint32_t endtime,char *refbase,char *refrel,char *refgui,bits256 refpubkey)
{
int32_t dispflag,retval = 0;
if ( sp->finished == 0 && sp->expired == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 )
sp->expired = (uint32_t)time(NULL);
if ( sp->finished != 0 || sp->expired != 0 )
retval = 1;
dispflag = 0;
if ( starttime == 0 && endtime == 0 )
dispflag = 1;
else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 )
dispflag = 1;
else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime )
dispflag = 1;
if ( refbase != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 )
dispflag = 0;
if ( refrel != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 )
dispflag = 0;
if ( dispflag != 0 )
{
dispflag = 0;
if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 )
{
if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 )
dispflag = 1;
}
}
if ( dispflag != 0 )
jaddi(array,LP_swapstats_json(sp));
return(retval);
}
cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel)
{
static int32_t rval;
cJSON *retjson,*array,*item,*reqjson; struct LP_pubkey_info *pubp,*ptmp; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
if ( rval == 0 )
rval = (LP_rand() % 300) + 60;
if ( starttime > endtime ) if ( starttime > endtime )
starttime = endtime; starttime = endtime;
n = LP_statslog_parse();
memset(basevols,0,sizeof(basevols)); memset(basevols,0,sizeof(basevols));
memset(relvols,0,sizeof(relvols)); memset(relvols,0,sizeof(relvols));
memset(numtrades,0,sizeof(numtrades)); memset(numtrades,0,sizeof(numtrades));
@ -342,45 +448,41 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu
jaddstr(retjson,"result","success"); jaddstr(retjson,"result","success");
jaddnum(retjson,"newlines",n); jaddnum(retjson,"newlines",n);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
HASH_ITER(hh,LP_swapstats,sp,tmp) LP_RTcount = LP_swapscount = 0;
now = (uint32_t)time(NULL);
HASH_ITER(hh,LP_RTstats,sp,tmp)
{ {
if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 ) if ( LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey) > 0 )
sp->expired = (uint32_t)time(NULL);
dispflag = 0;
if ( starttime == 0 && endtime == 0 )
dispflag = 1;
else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 )
dispflag = 1;
else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime )
dispflag = 1;
if ( dispflag != 0 )
{ {
dispflag = 0; HASH_DELETE(hh,LP_RTstats,sp);
if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 ) HASH_ADD(hh,LP_swapstats,aliceid,sizeof(sp->aliceid),sp);
{
if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 )
dispflag = 1;
}
} }
if ( dispflag != 0 ) else
{ {
LP_swapstats_line(numtrades,basevols,relvols,line,sp); LP_RTcount++;
item = cJSON_CreateObject(); if ( now > sp->lasttime+rval )
jadd64bits(item,"aliceid",sp->aliceid); {
jaddbits256(item,"src",sp->Q.srchash); reqjson = cJSON_CreateObject();
jaddstr(item,"base",sp->Q.srccoin); jaddstr(reqjson,"method","gettradestatus");
jaddnum(item,"basevol",dstr(sp->Q.satoshis)); jadd64bits(reqjson,"aliceid",sp->aliceid);
jaddbits256(item,"dest",sp->Q.desthash); memset(zero.bytes,0,sizeof(zero));
jaddstr(item,"rel",sp->Q.destcoin); LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); }
jaddnum(item,"price",sp->qprice);
jaddnum(item,"requestid",sp->Q.R.requestid);
jaddnum(item,"quoteid",sp->Q.R.quoteid);
jaddstr(item,"line",line);
jaddi(array,item);
} }
} }
HASH_ITER(hh,LP_swapstats,sp,tmp)
{
LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey);
LP_swapscount++;
}
HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp)
{
pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0);
}
//printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount);
jadd(retjson,"swaps",array); jadd(retjson,"swaps",array);
jaddnum(retjson,"RTcount",LP_RTcount);
jaddnum(retjson,"swapscount",LP_swapscount);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
for (i=0; i<LP_MAXPRICEINFOS; i++) for (i=0; i<LP_MAXPRICEINFOS; i++)
{ {
@ -405,7 +507,99 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu
jaddnum(retjson,"uniques",LP_aliceids); jaddnum(retjson,"uniques",LP_aliceids);
jaddnum(retjson,"tradestatus",LP_tradestatuses); jaddnum(retjson,"tradestatus",LP_tradestatuses);
jaddnum(retjson,"unknown",LP_unknowns); jaddnum(retjson,"unknown",LP_unknowns);
return(jprint(retjson,1)); return(retjson);
}
//tradesarray(base, rel, starttime=<now>-timescale*1024, endtime=<now>, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]
struct LP_ohlc
{
uint32_t timestamp,firsttime,lasttime,numtrades;
double high,low,open,close,relsum,basesum;
};
cJSON *LP_ohlc_json(struct LP_ohlc *bar)
{
cJSON *item;
if ( bar->numtrades != 0 && bar->relsum > SMALLVAL && bar->basesum > SMALLVAL )
{
item = cJSON_CreateArray();
jaddinum(item,bar->timestamp);
jaddinum(item,bar->high);
jaddinum(item,bar->low);
jaddinum(item,bar->open);
jaddinum(item,bar->close);
jaddinum(item,bar->relsum);
jaddinum(item,bar->basesum);
jaddinum(item,bar->relsum / bar->basesum);
jaddinum(item,bar->numtrades);
return(item);
}
return(0);
}
void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double relvol)
{
double price;
if ( basevol > SMALLVAL && relvol > SMALLVAL )
{
price = relvol / basevol;
if ( bar->firsttime == 0 || timestamp < bar->firsttime )
{
bar->firsttime = timestamp;
bar->open = price;
}
if ( bar->lasttime == 0 || timestamp > bar->lasttime )
{
bar->lasttime = timestamp;
bar->close = price;
}
if ( bar->low == 0. || price < bar->low )
bar->low = price;
if ( bar->high == 0. || price > bar->high )
bar->high = price;
bar->basesum += basevol;
bar->relsum += relvol;
bar->numtrades++;
//printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price);
}
} }
cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,int32_t timescale)
{
struct LP_ohlc *bars; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; int32_t i,n,numbars,bari;
if ( timescale < 60 )
return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}"));
memset(zero.bytes,0,sizeof(zero));
if ( endtime == 0 )
endtime = (((uint32_t)time(NULL) / timescale) * timescale);
if ( starttime == 0 || starttime >= endtime )
starttime = (endtime - LP_SCREENWIDTH*timescale);
numbars = ((endtime - starttime) / timescale) + 1;
bars = calloc(numbars,sizeof(*bars));
for (bari=0; bari<numbars; bari++)
bars[bari].timestamp = starttime + bari*timescale;
if ( (statsjson= LP_statslog_disp(starttime,endtime,"",zero,base,rel)) != 0 )
{
if ( (swaps= jarray(&n,statsjson,"swaps")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(swaps,i);
if ( (timestamp= juint(item,"timestamp")) != 0 && timestamp >= starttime && timestamp <= endtime )
{
bari = (timestamp - starttime) / timescale;
LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol"));
} else printf("skip.(%s)\n",jprint(item,0));
}
}
free_json(statsjson);
}
array = cJSON_CreateArray();
for (bari=0; bari<numbars; bari++)
if ( (item= LP_ohlc_json(&bars[bari])) != 0 )
jaddi(array,item);
free(bars);
return(array);
}

21
iguana/exchanges/LP_swap.c

@ -109,6 +109,13 @@
*/ */
uint32_t LP_atomic_locktime(char *base,char *rel)
{
if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 )
return(INSTANTDEX_LOCKTIME);
else return(INSTANTDEX_LOCKTIME * 10);
}
void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx)
{ {
if ( rawtx->vins != 0 ) if ( rawtx->vins != 0 )
@ -1041,7 +1048,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
} else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr);
} }
struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp) struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp,int32_t dynamictrust)
{ {
//FILE *fp; char fname[512]; //FILE *fp; char fname[512];
uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin;
@ -1101,14 +1108,18 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.iambob = 0; swap->I.iambob = 0;
swap->I.otherhash = swap->I.req.desthash; swap->I.otherhash = swap->I.req.desthash;
swap->I.aliceistrusted = 1; swap->I.aliceistrusted = 1;
swap->I.otheristrusted = swap->I.bobistrusted = LP_pubkey_istrusted(swap->I.req.srchash); if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.srchash) != 0 )
dynamictrust = 1;
swap->I.otheristrusted = swap->I.bobistrusted = dynamictrust;
} }
else else
{ {
swap->I.iambob = 1; swap->I.iambob = 1;
swap->I.otherhash = swap->I.req.srchash; swap->I.otherhash = swap->I.req.srchash;
swap->I.bobistrusted = 1; swap->I.bobistrusted = 1;
swap->I.otheristrusted = swap->I.aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash); if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.desthash) != 0 )
dynamictrust = 1;
swap->I.otheristrusted = swap->I.aliceistrusted = dynamictrust;
} }
if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE )
{ {
@ -1198,7 +1209,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
return(swap); return(swap);
} }
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp) struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust)
{ {
struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33]; struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33];
swap = calloc(1,sizeof(*swap)); swap = calloc(1,sizeof(*swap));
@ -1217,7 +1228,7 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256
swap->persistent_privkey = privkey; swap->persistent_privkey = privkey;
memcpy(swap->persistent_pubkey33,pubkey33,33); memcpy(swap->persistent_pubkey33,pubkey33,33);
calc_rmd160_sha256(swap->changermd160,pubkey33,33); calc_rmd160_sha256(swap->changermd160,pubkey33,33);
if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp) == 0 ) if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp,dynamictrust) == 0 )
{ {
printf("error doing swapinit\n"); printf("error doing swapinit\n");
free(swap); free(swap);

2
iguana/exchanges/LP_tradebots.c

@ -195,7 +195,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot)
jadd(json,"trades",array); jadd(json,"trades",array);
if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 )
{ {
jaddnum(json,"completed",bot->completed); jadd(json,"complete",bot->completed!=0?jtrue():jfalse());
jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume)); jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume));
if ( bot->dispdir > 0 ) if ( bot->dispdir > 0 )
{ {

27
iguana/exchanges/LP_transaction.c

@ -420,7 +420,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
//printf(" scriptlen.%d\n",scriptlen); //printf(" scriptlen.%d\n",scriptlen);
//printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen);
sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash);
printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen);
if ( bits256_nonz(sigtxid) != 0 ) if ( bits256_nonz(sigtxid) != 0 )
{ {
vp = &V[vini]; vp = &V[vini];
@ -461,14 +461,14 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
{ {
flag++; flag++;
numsigs++; numsigs++;
int32_t z; char tmpaddr[64]; /*int32_t z; char tmpaddr[64];
for (z=0; z<siglen-1; z++) for (z=0; z<siglen-1; z++)
printf("%02x",sig[z]); printf("%02x",sig[z]);
printf(" <- sig[%d]\n",j); printf(" <- sig[%d]\n",j);
for (z=0; z<33; z++) for (z=0; z<33; z++)
printf("%02x",vp->signers[j].pubkey[z]); printf("%02x",vp->signers[j].pubkey[z]);
bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33);
printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/
} }
} }
if ( numsigs >= vp->M ) if ( numsigs >= vp->M )
@ -731,7 +731,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt
jaddstr(retjson,"error","interpreter rejects tx"); jaddstr(retjson,"error","interpreter rejects tx");
else complete = 1; else complete = 1;
jadd(retjson,"interpreter",log); jadd(retjson,"interpreter",log);
jaddnum(retjson,"complete",complete); jadd(retjson,"complete",complete!=0?jtrue():jfalse());
free(serialized), free(serialized2); free(serialized), free(serialized2);
if ( signedtx != 0 ) if ( signedtx != 0 )
free(signedtx); free(signedtx);
@ -980,8 +980,10 @@ cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime)
{ {
int32_t minutes; uint64_t interest = 0; int32_t minutes; uint64_t interest = 0;
if ( (minutes= (tiptime - nLockTime) / 60) >= 60 ) if ( tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 )
{ {
//minutes.71582779 tiptime.1511292969 locktime.1511293505
printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime);
if ( minutes > 365 * 24 * 60 ) if ( minutes > 365 * 24 * 60 )
minutes = 365 * 24 * 60; minutes = 365 * 24 * 60;
minutes -= 59; minutes -= 59;
@ -1124,20 +1126,21 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
if ( LP_validSPV(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 ) if ( LP_validSPV(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 )
continue; continue;
} }
if ( LP_allocated(up->U.txid,up->U.vout) != 0 )
continue;
up->spendheight = 1; up->spendheight = 1;
total += up->U.value; total += up->U.value;
remains -= up->U.value; remains -= up->U.value;
interest = 0; interest = 0;
if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 )
{ {
if ( 0 && (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 )
{ {
interestsum += interest; interestsum += interest;
char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum));
} }
} }
//printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout);
vp = &V[n++]; vp = &V[n++];
vp->N = vp->M = 1; vp->N = vp->M = 1;
vp->signers[0].privkey = privkey; vp->signers[0].privkey = privkey;
@ -1146,7 +1149,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
vp->suppress_pubkeys = suppress_pubkeys; vp->suppress_pubkeys = suppress_pubkeys;
vp->ignore_cltverr = ignore_cltverr; vp->ignore_cltverr = ignore_cltverr;
jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr));
LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+600,G.LP_mypub25519); LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519);
if ( remains <= 0 && i >= numpre-1 ) if ( remains <= 0 && i >= numpre-1 )
break; break;
if ( numunspents < 0 ) if ( numunspents < 0 )
@ -1264,6 +1267,12 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
if ( addrtype == coin->pubtype ) if ( addrtype == coin->pubtype )
spendlen = bitcoin_standardspend(spendscript,0,rmd160); spendlen = bitcoin_standardspend(spendscript,0,rmd160);
else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); else spendlen = bitcoin_p2shspend(spendscript,0,rmd160);
if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 )
{
printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change));
value += change;
change = 0;
}
txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust);
} }
else else

24
iguana/exchanges/LP_utxo.c

@ -99,9 +99,10 @@ struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256
{ {
if ( bits256_nonz(otherpub) != 0 ) if ( bits256_nonz(otherpub) != 0 )
lp->otherpub = otherpub; lp->otherpub = otherpub;
if ( expiration > lp->expiration || expiration == 0 ) //if ( expiration > lp->expiration || expiration == 0 )
lp->expiration = expiration; lp->expiration = expiration;
} }
char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout);
return(lp); return(lp);
} else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse); } else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse);
return(0); return(0);
@ -446,20 +447,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin)
{ {
//{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700} //{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700}
item = jitem(array,i); item = jitem(array,i);
if ( coin->electrum != 0 ) value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
}
else
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
value = LP_value_extract(item,0);
height = LP_txheight(coin,txid);
}
LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1);
if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 )
printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value));
@ -573,9 +561,9 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
} }
else else
{ {
if ( strcmp(coin->smartaddr,coinaddr) == 0 ) //if ( strcmp(coin->smartaddr,coinaddr) == 0 )
balance = LP_unspents_load(coin->symbol,coinaddr); balance = LP_unspents_load(coin->symbol,coinaddr);
else /*else
{ {
if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{ {
@ -589,7 +577,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
} }
free_json(array); free_json(array);
} }
} }*/
} }
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success"); jaddstr(retjson,"result","success");

41
iguana/exchanges/LP_utxos.c

@ -559,6 +559,26 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe
return(mini); return(mini);
} }
int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item)
{
int64_t satoshis = 0;
if ( coin->electrum == 0 )
{
*txidp = jbits256(item,"txid");
*voutp = juint(item,"vout");
satoshis = LP_value_extract(item,0);
*heightp = LP_txheight(coin,*txidp);
}
else
{
*txidp = jbits256(item,"tx_hash");
*voutp = juint(item,"tx_pos");
satoshis = j64bits(item,"value");
*heightp = jint(item,"height");
}
return(satoshis);
}
int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub)
{ {
int32_t enable_utxos = 0; int32_t enable_utxos = 0;
@ -572,8 +592,8 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
return(0); return(0);
coin->privkeydepth++; coin->privkeydepth++;
LP_address(coin,coin->smartaddr); LP_address(coin,coin->smartaddr);
if ( coin->inactive == 0 ) //if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr,0); // LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
array = LP_listunspent(coin->symbol,coin->smartaddr); array = LP_listunspent(coin->symbol,coin->smartaddr);
if ( array != 0 ) if ( array != 0 )
{ {
@ -591,20 +611,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
item = jitem(array,i); item = jitem(array,i);
if ( coin->electrum == 0 ) value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
value = LP_value_extract(item,0);
height = LP_txheight(coin,txid);//LP_getheight(coin) - jint(item,"confirmations") + 1;
}
else
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
}
satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout);
if ( satoshis != 0 && satoshis != value ) if ( satoshis != 0 && satoshis != value )
printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest"));
@ -848,7 +855,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
else if ( IAMLP == 0 || coin->inactive == 0 ) else if ( IAMLP == 0 || coin->inactive == 0 )
{ {
//printf("from updates %s\n",coin->symbol); //printf("from updates %s\n",coin->symbol);
if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 )
{ {
//LP_postutxos(coin->symbol,coin->smartaddr); //LP_postutxos(coin->symbol,coin->smartaddr);
} }

278
iguana/exchanges/LP_zeroconf.c

@ -0,0 +1,278 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_zeroconf.c
// marketmaker
//
int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33)
{
uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n;
decode_hex(elsepub33,33,BOTS_BONDPUBKEY33);
n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33);
bitcoin_address(p2shaddr,taddr,p2shtype,script,n);
return(n);
}
char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast)
{
char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64;
if ( strcmp(coin->symbol,"KMD") != 0 )
return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}"));
if ( amount < 10.0 )
return(clonestr("{\"error\":\"minimum zeroconf deposit is 10 KMD\"}"));
if ( weeks < 0 || weeks > 52 )
return(clonestr("{\"error\":\"weeks must be between 0 and 52\"}"));
if ( weeks > 0 )
{
timestamp = (uint32_t)time(NULL);
timestamp /= LP_WEEKMULT;
timestamp += weeks+1;
timestamp *= LP_WEEKMULT;
weeki = (timestamp - LP_FIRSTWEEKTIME) / LP_WEEKMULT;
if ( weeks >= 10000 )
return(clonestr("{\"error\":\"numweeks must be less than 10000\"}"));
} else timestamp = (uint32_t)time(NULL) + 300, weeki = 0;
scriptlen = LP_deposit_addr(p2shaddr,script,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp);
argjson = cJSON_CreateObject();
array = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,p2shaddr,amount);
jaddi(array,item);
item = cJSON_CreateObject();
amount64 = (amount * SATOSHIDEN) / 1000;
amount64 = (amount64 / 10000) * 10000 + weeki;
jaddnum(item,BOTS_BONDADDRESS,dstr(amount64));
jaddi(array,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,0.0001);
jaddi(array,item);
jadd(argjson,"outputs",array);
//printf("deposit.(%s)\n",jprint(argjson,0));
if ( (retstr= LP_withdraw(coin,argjson)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"result") != 0 )
jdelete(retjson,"result");
jaddstr(retjson,"address",p2shaddr);
jaddnum(retjson,"expiration",timestamp);
jaddnum(retjson,"deposit",amount);
if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 )
{
txid = jbits256(retjson,"txid");
if ( broadcast != 0 )
{
if (bits256_nonz(txid) != 0 )
{
sendtxid = LP_broadcast("deposit","KMD",hexstr,txid);
if ( bits256_cmp(sendtxid,txid) != 0 )
{
jaddstr(retjson,"error","broadcast txid mismatch");
jaddbits256(retjson,"broadcast",sendtxid);
free(retstr);
return(jprint(retjson,1));
}
else
{
jaddstr(retjson,"result","success");
jaddbits256(retjson,"broadcast",sendtxid);
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"error","couldnt broadcast since no txid created");
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"result","success");
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"error","couldnt create deposit txid");
free(retstr);
return(jprint(retjson,1));
}
free_json(retjson);
}
free(retstr);
}
return(clonestr("{\"error\":\"error with LP_withdraw for zeroconf deposit\"}"));
}
char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration)
{
static void *ctx;
uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( strcmp(coin->symbol,"KMD") != 0 )
return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}"));
now = (uint32_t)time(NULL);
sum = 0;
txids = cJSON_CreateArray();
timestamp = (now / LP_WEEKMULT) * LP_WEEKMULT + LP_WEEKMULT;
while ( timestamp > LP_FIRSTWEEKTIME )
{
if ( expiration != 0 )
timestamp = expiration;
else timestamp -= LP_WEEKMULT;
redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp);
if ( strcmp(depositaddr,vinaddr) == 0 )
{
claimtime = (uint32_t)time(NULL)-777/2;
if ( claimtime <= timestamp )
{
printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime);
}
else
{
printf("found %s at timestamp.%u\n",vinaddr,timestamp);
if ( (array= LP_listunspent(coin->symbol,vinaddr)) != 0 )
{
userdata[0] = 0x51;
userdatalen = 1;
utxovout = 0;
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item);
if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 )
{
printf("signedtx.(%s)\n",signedtx);
sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid);
if ( bits256_cmp(sendtxid,signedtxid) == 0 )
{
jaddibits256(txids,sendtxid);
sum += (satoshis-coin->txfee);
}
else printf("error sending %s\n",bits256_str(str,signedtxid));
free(signedtx);
} else printf("error claiming zeroconf deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis));
}
}
free_json(array);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"claimed",dstr(sum));
jadd(retjson,"txids",txids);
return(jprint(retjson,1));
}
}
}
if ( expiration != 0 )
break;
}
return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}"));
}
void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr)
{
uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD");
if ( coin != 0 )
{
timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT;
if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 )
{
ap->zeroconf_credits += satoshis;
printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits));
}
}
}
void LP_zeroconf_deposits(struct iguana_info *coin)
{
cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64;
HASH_ITER(hh,coin->addresses,ap,tmp)
{
ap->zeroconf_credits = 0;
}
if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 )
{
//printf("ZEROCONF.(%s)\n",jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( coin->electrum != 0 )
{
item = jitem(array,i);
LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
} else txid = jbits256i(array,i);
if ( (txjson= LP_gettx(coin->symbol,txid)) != 0 )
{
// vout0 deposit, vout1 botsfee, vout2 smartaddress
if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 )
{
amount64 = LP_value_extract(jitem(vouts,1),0);
weeki = (amount64 % 10000);
v = jitem(vouts,0);
satoshis = LP_value_extract(v,0);
//printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki);
if ( LP_destaddr(p2shaddr,v) == 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 )
{
free_json(txobj);
LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr);
}
}
}
free_json(txjson);
}
}
}
free_json(array);
}
}
int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue)
{
struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0;
if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 )
{
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33);
if ((ap= LP_address(coin,coinaddr)) != 0 )//&& ap->zeroconf_credits >= kmdvalue )
{
DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 )
swaps_kmdvalue += LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis);
}
DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 )
swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis);
}
//printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue));
//if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue )
return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue));
}
}
return(0);
}

3
iguana/exchanges/claim

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_claim\",\"address\":\"$1\",\"expiration\":$2}"

3
iguana/exchanges/deposit

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":0,\"amount\":10.0,\"broadcast\":1}"

3
iguana/exchanges/deposit1

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}"

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
cp invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts cp tradesarray claim deposit invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp coins.json .. cp coins.json ..
cd ../dexscripts cd ../dexscripts
#cp ../exchanges/passphrase ../exchanges/userpass . #cp ../exchanges/passphrase ../exchanges/userpass .

12
iguana/exchanges/mm.c

@ -881,6 +881,18 @@ int main(int argc, const char * argv[])
double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr;
cJSON *retjson,*loginjson; int32_t i; cJSON *retjson,*loginjson; int32_t i;
OS_init(); OS_init();
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{
uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64];
bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]);
bitcoin_address(coinaddr,0,60,rmd160,20);
bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr);
bitcoin_address(coinaddr2,0,0,rmd160b,20);
printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2);
if ( strcmp((char *)argv[1],coinaddr2) != 0 )
printf("ERROR\n");
exit(0);
}
sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname);

150
iguana/exchanges/stats.c

@ -33,7 +33,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char
char *stats_validmethods[] = char *stats_validmethods[] =
{ {
"psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent", "psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent",
"orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus" "orderbook", "help", "getcoins", "pricearray", "balance", "tradesarray"
}; };
int32_t LP_valid_remotemethod(cJSON *argjson) int32_t LP_valid_remotemethod(cJSON *argjson)
@ -310,7 +310,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr)
jaddstr(json,key,value); jaddstr(json,key,value);
else jaddistr(array,key); else jaddistr(array,key);
len += (n + 1); len += (n + 1);
if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) if ( (strcmp(key,"Content-Length") == 0 || strcmp(key,"content-length") == 0) && (datalen= atoi(value)) > 0 )
{ {
data = &urlstr[totallen - datalen]; data = &urlstr[totallen - datalen];
data[-1] = 0; data[-1] = 0;
@ -329,8 +329,7 @@ extern void *bitcoin_ctx();
char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port)
{ {
static void *ctx; static void *ctx;
cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0;
//printf("rpcparse.(%s)\n",urlstr);
if ( ctx == 0 ) if ( ctx == 0 )
ctx = bitcoin_ctx(); ctx = bitcoin_ctx();
for (i=0; i<sizeof(urlmethod)-1&&urlstr[i]!=0&&urlstr[i]!=' '; i++) for (i=0; i<sizeof(urlmethod)-1&&urlstr[i]!=0&&urlstr[i]!=' '; i++)
@ -339,6 +338,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
n = i; n = i;
//printf("URLMETHOD.(%s)\n",urlmethod); //printf("URLMETHOD.(%s)\n",urlmethod);
*postflagp = (strcmp(urlmethod,"POST") == 0); *postflagp = (strcmp(urlmethod,"POST") == 0);
//printf("POST.%d rpcparse.(%s)\n",*postflagp,urlstr);
for (i=0; i<sizeof(url)-1&&urlstr[n+i]!=0&&urlstr[n+i]!=' '; i++) for (i=0; i<sizeof(url)-1&&urlstr[n+i]!=0&&urlstr[n+i]!=' '; i++)
url[i] = urlstr[n+i]; url[i] = urlstr[n+i];
url[i++] = 0; url[i++] = 0;
@ -412,7 +412,13 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
{ {
jadd(json,"tokens",tokens); jadd(json,"tokens",tokens);
jaddstr(json,"urlmethod",urlmethod); jaddstr(json,"urlmethod",urlmethod);
if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) if ( (data= jstr(json,"POST")) != 0 )
{
free_json(argjson);
argjson = cJSON_Parse(data);
//printf("data.(%s)\n",data);
}
if ( argjson != 0 )
{ {
userpass = jstr(argjson,"userpass"); userpass = jstr(argjson,"userpass");
//printf("userpass.(%s)\n",userpass); //printf("userpass.(%s)\n",userpass);
@ -499,62 +505,62 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
} }
} }
} }
} if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 )
if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 )
{
cJSON *retitem,*retarray = cJSON_CreateArray();
origargjson = argjson;
symbol[0] = 0;
for (i=0; i<n; i++)
{ {
argjson = jitem(origargjson,i); cJSON *retitem,*retarray = cJSON_CreateArray();
if ( userpass != 0 && jstr(argjson,"userpass") == 0 ) origargjson = argjson;
jaddstr(argjson,"userpass",userpass); symbol[0] = 0;
//printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); for (i=0; i<n; i++)
#ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(argjson) > 0 )
{ {
argjson = jitem(origargjson,i);
if ( userpass != 0 && jstr(argjson,"userpass") == 0 )
jaddstr(argjson,"userpass",userpass);
//printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0));
#ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(argjson) > 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{
if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem);
free(retstr);
}
} else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{ {
if ( (retitem= cJSON_Parse(retstr)) != 0 ) if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem); jaddi(retarray,retitem);
free(retstr); free(retstr);
} }
} else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{
if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem);
free(retstr);
}
#endif #endif
//printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr); //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr);
}
free_json(origargjson);
retstr = jprint(retarray,1);
} }
free_json(origargjson); else
retstr = jprint(retarray,1);
}
else
{
cJSON *arg;
if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 )
{ {
arg = jobj(argjson,"params"); cJSON *arg;
if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 )
arg = jitem(arg,0); {
} else arg = argjson; arg = jobj(argjson,"params");
//printf("ARGJSON.(%s)\n",jprint(arg,0)); if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 )
if ( userpass != 0 && jstr(arg,"userpass") == 0 ) arg = jitem(arg,0);
jaddstr(arg,"userpass",userpass); } else arg = argjson;
//printf("ARGJSON.(%s)\n",jprint(arg,0));
if ( userpass != 0 && jstr(arg,"userpass") == 0 )
jaddstr(arg,"userpass",userpass);
#ifdef FROM_MARKETMAKER #ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 ) if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 )
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
else retstr = clonestr("{\"error\":\"invalid remote method\"}"); else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else #else
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
#endif #endif
}
free_json(argjson);
} }
free_json(argjson);
free_json(json); free_json(json);
if ( tmpjson != 0 ) if ( tmpjson != 0 )
free(tmpjson); free(tmpjson);
@ -562,15 +568,17 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
} }
free_json(argjson); free_json(argjson);
if ( tmpjson != 0 ) if ( tmpjson != 0 )
free(tmpjson); free_json(tmpjson);
if ( tokens != 0 )
free_json(tokens);
*jsonflagp = 1; *jsonflagp = 1;
return(clonestr("{\"error\":\"couldnt process packet\"}")); return(clonestr("{\"error\":\"couldnt process packet\"}"));
} }
int32_t iguana_getcontentlen(char *buf,int32_t recvlen) int32_t iguana_getcontentlen(char *buf,int32_t recvlen)
{ {
char *str,*clenstr = "Content-Length: "; int32_t len = -1; char *str,*clenstr = "Content-Length: ",*clenstr2 = "content-length: "; int32_t len = -1;
if ( (str= strstr(buf,clenstr)) != 0 ) if ( (str= strstr(buf,clenstr)) != 0 || (str= strstr(buf,clenstr2)) != 0 )
{ {
//printf("strstr.(%s)\n",str); //printf("strstr.(%s)\n",str);
str += strlen(clenstr); str += strlen(clenstr);
@ -597,15 +605,16 @@ void LP_rpc_processreq(void *_ptr)
static uint32_t spawned,maxspawned; static uint32_t spawned,maxspawned;
char filetype[128],content_type[128]; char filetype[128],content_type[128];
int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len;
char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr; char helpname[512],remoteaddr[64],*buf,*retstr,space[8192],space2[32786],*jsonbuf; struct rpcrequest_info *req = _ptr;
uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512;
ipbits = req->ipbits;; ipbits = req->ipbits;;
expand_ipbits(remoteaddr,ipbits); expand_ipbits(remoteaddr,ipbits);
sock = req->sock; sock = req->sock;
recvlen = flag = 0; recvlen = flag = 0;
retstr = 0; retstr = 0;
space = calloc(1,size); //space = calloc(1,size);
jsonbuf = calloc(1,size); jsonbuf = calloc(1,size);
//printf("alloc jsonbuf.%p\n",jsonbuf);
remains = size-1; remains = size-1;
buf = jsonbuf; buf = jsonbuf;
spawned++; spawned++;
@ -624,10 +633,12 @@ void LP_rpc_processreq(void *_ptr)
printf("EAGAIN for len %d, remains.%d\n",len,remains); printf("EAGAIN for len %d, remains.%d\n",len,remains);
usleep(10000); usleep(10000);
} }
//printf("errno.%d len.%d remains.%d\n",errno,len,remains);
break; break;
} }
else else
{ {
//printf("received len.%d\n%s\n",len,buf);
if ( len > 0 ) if ( len > 0 )
{ {
buf[len] = 0; buf[len] = 0;
@ -694,16 +705,23 @@ void LP_rpc_processreq(void *_ptr)
//printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag);
if ( jsonflag != 0 || postflag != 0 ) if ( jsonflag != 0 || postflag != 0 )
{ {
if ( retstr == 0 ) if ( strlen(retstr)+1024+1+1 < sizeof(space2) )
retstr = clonestr("{}"); response = space2;
response = malloc(strlen(retstr)+1024+1+1); else
{
response = malloc(strlen(retstr)+1024+1+1);
printf("alloc response.%p\n",response);
}
sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr));
response[0] = '\0'; response[0] = '\0';
strcat(response,hdrs); strcat(response,hdrs);
strcat(response,retstr); strcat(response,retstr);
strcat(response,"\n"); strcat(response,"\n");
if ( retstr != space ) if ( retstr != space )
{
//printf("free retstr0.%p\n",retstr);
free(retstr); free(retstr);
}
retstr = response; retstr = response;
//printf("RET.(%s)\n",retstr); //printf("RET.(%s)\n",retstr);
} }
@ -727,16 +745,28 @@ void LP_rpc_processreq(void *_ptr)
printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf); printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf);
} }
} }
if ( retstr != space) if ( retstr != space && retstr != space2 )
{
//printf("free retstr.%p\n",retstr);
free(retstr); free(retstr);
}
} }
free(space); //free(space);
//printf("free jsonbuf.%p\n",jsonbuf);
free(jsonbuf); free(jsonbuf);
closesocket(sock); closesocket(sock);
portable_mutex_lock(&LP_gcmutex); if ( 1 )
DL_APPEND(LP_garbage_collector,req); {
portable_mutex_lock(&LP_gcmutex);
DL_APPEND(LP_garbage_collector,req);
portable_mutex_unlock(&LP_gcmutex);
}
else
{
//printf("free req.%p\n",req);
free(req);
}
spawned--; spawned--;
portable_mutex_unlock(&LP_gcmutex);
} }
extern int32_t IAMLP; extern int32_t IAMLP;
@ -787,10 +817,12 @@ void stats_rpcloop(void *args)
memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits));
if ( port == RPC_port && ipbits != localhostbits ) if ( port == RPC_port && ipbits != localhostbits )
{ {
//printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits);
closesocket(sock); closesocket(sock);
continue; continue;
} }
req = calloc(1,sizeof(*req)); req = calloc(1,sizeof(*req));
//printf("alloc req.%p\n",req);
req->sock = sock; req->sock = sock;
req->ipbits = ipbits; req->ipbits = ipbits;
req->port = port; req->port = port;

3
iguana/exchanges/tradesarray

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"tradesarray\",\"base\":\"REVS\",\"rel\":\"KMD\",\"timescale\":3600}"

2
iguana/main.c

@ -793,7 +793,7 @@ void iguana_launchdaemons(struct supernet_info *myinfo)
if ( COMMANDLINE_ARGFILE == 0 ) if ( COMMANDLINE_ARGFILE == 0 )
iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess
printf("launch mainloop\n"); printf("launch mainloop\n");
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo); // disable basilisk: OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo);
mainloop(myinfo); mainloop(myinfo);

Loading…
Cancel
Save